플러그인 통신을 통해 센서 데이터를 수발하다

제조업의 IoT, ML에서 시간 시퀀스 데이터는 빠질 수 없습니다.센서의 시간 시퀀스 데이터를 데이터베이스 서버에 전달하기 위해 파이톤은 플러그인 통신을 구축했다.다음 코드를 통해 톱니바퀴 사이에서 센서 데이터를 무선으로 전송하고 수신할 수 있다.

컨디션

  • Raspberry pi3 x2
  • Python 3.8
  • 서버


    센서 데이터를 플러그인 통신을 통해 클라이언트에 보내다.
    server.py
    import socket
    from datetime import datetime
    import pickle
    
    class SocketServer():
      def __init__(self, host, port):
        self.host = host
        self.port = port
      # サーバー起動
      def run_server(self):
        with socket.socket(socket.AF_INET, socket.SOCKET_STREAM) as server_socket:
          server_socket.setsockopt(socket.SQL_SOCKET, socket.SO_REUSEADDR, 1)
          server_socket.bind((self.host, self.port))
          server_socket.listen(CLIENTNUM)
          print("[{}] run server".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S")))
          while True:
            # クライアントから接続要求受け入れ
            client_socket, address = server_socket.accept()
    	print("[{0}] connect clinet -> address : {1}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), address))
    	# クライアントごとにThread起動 send/recvのやり取りをする。
    	t = threading.Thread(target=self.conn_client, args=(client_socket, address))
    	t.setDaemon(True)
    	t.start()
    	
      def conn_client(self, client_socket, address):
        with client_socket:
          while True:
            # クライエントからデータ受信
            rcv_data = client_socket.recv(DATASIZE)
    	if rcv_data:
    	  print(rcv_data)
    	  # rcv_dataをclientに送る。
    	  # BM280_readData()はデータを出力する関数。出力はlist型。
    	  bme280_data = BME280_readData()
    	  client_socket.send(pickle.dumps(bme280_data))
            else:
    	  break
        print("[{0}] disconnect client -> address : {1}".format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), address))
        
    if __name__ == "__main__":
      HOST_IP = "192.168.xx.xx"
      SOCKET_PORT = 50000
      SocketServer(HOST_IP, SOCKET_PORT).run_server()
    

    클라이언트


    고객으로부터 서버로 요청을 보내다.
    4recv 함수를 통해 데이터를 수신한다.
    client.py
    import socket
    from datetime import datetime
    import time
    import pickle
    
    DATESIZE = 1024 # 受信データバイト数
    INTERVAL = 3 # ソケット接続時のリトライ待ち時間
    RETRYTIMES = 5 # ソケット接続時のリトライ回数
    
    class SocketClient():
        def __init__(self, host, port):
            self.host = host
            self.port = port
            self.socket = None
    
        def connect(self):
            client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)       
            # サーバーとの接続 RETRYTIMESの回数だけリトライ
            for x in range(RETRYTIMES):
                try:
                    client_socket.connect((self.host, self.port))
                    self.socket =  client_socket
                    print('[{0}] server connect -> address : {1}:{2}'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), self.host, self.port) )
                    break
                except socket.error:
                    # 接続を確立できない場合、INTERVAL秒待ってリトライ
                    time.sleep(INTERVAL)
                    print('[{0}] retry after wait{1}s'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), str(INTERVAL)) )
     
        # サーバーへデータ送信関数
        def send(self):
            # ターミナルから入力された文字を取得
            input_data = input()
            input_data = input_data.encode('utf-8')
            self.socket.send(input_data) # データ送信
        
        # サーバーからデータ受信関数
        def recv(self):
            rcv_data = self.socket.recv(DATESIZE) # データ受信
            rcv_data = rcv_data.decode('utf-8')
    	data = pickle.loads(response)
    	# temperature_bme280 = float(data[0])
            # relativehumidity_bme280 = float(data[1])
            # absolutehumidity_bme280 = float(data[2])
            # barometricpressure_bme280 = float(data[3])
            return data
        
        # 上記の送信/受信関数を順番に行う
        def send_rcv(self):
            self.send()
            return self.recv()
    
        # ソケットをクローズする関数
        def close(self):
            self.socket.close() # ソケットクローズ
            self.socket = None
                 
    if __name__ == '__main__':
        HOST_IP = "192.168.xx.xx"
        PORT = 50000
        client = SocketClient(HOST_IP, PORT)
        client.connect()
        while True:
            if client.socket is not None:
                client.send_rcv()
            else:
                break
    

    참고 자료


    https://www.raspberrypirulo.net/entry/socket-server
    https://www.raspberrypirulo.net/entry/socket-client

    좋은 웹페이지 즐겨찾기