webOS Article/4. webOS 활용하기

webOS와 websocket을 이용하여 LED 제어하기 5 : 시스템 연동하기

Nahye0n 2021. 8. 6. 14:48
  • Enact-app에서 toggle후 msgtype이 'command'로 server에 전달
  • Enact web-app에서 메세지를 받은 후 서버와 클라이언트의 통신 
  • Enact-app에서 toast message가 띄워짐

 

시스템 연동


1. Enact-app에서 toggle 후 msgtype이 'command'로 server에 전달

Enact-app 기본화면

 

  • toggleHandler 함수 코드(Enact webapplication)
const toggleHandler = (e) => {
	console.log('Switch toggled ' + e.selected);
	
	var ledStatusText = 'Off';
	if(e.selected) {
		ledStatusText = 'On';
	}

	var command = {
		'msgType' : 'command',
		'deviceID' : 'CML001',
		'ledStatus' : ledStatusText
	}
	ws.send(JSON.stringify(command));
}

const lsSendOnSuccess = () => {
	console.log("Creat toast success");
}

const lsSendOnFailure = () => {
	console.log("Creat toast failure");
}

ledStatusText을 변수로 하고, 기본 값을 'off'로 설정합니다.

if문을 사용해서 e.selected인 경우 ledStatusText 가 'on'이 되도록 합니다.

위에서 정해진 ledStatusText를 msg의 변수로 받습니다.

msgType을 'command'로 server와 ESP에게 ledStatus 신호를 보냅니다.

전송이 되었는지 확인하기 위하여 console.log를 받습니다.

 

 

 

2. Enact web-app에서 메세지를 받은 후 서버와 클라이언트의 통신 

전체 시스템을 연동하는 이번 실습에서는 이전에 사용했던 가상의 서버 SimpleEcho가 아닌 SImpleIOT 서버를 사용할 것입니다.

 

  • websocket server 
IP = 'ip 주소'
PORT = 3001
server = WebSocketServer(IP, PORT, SimpleIoT)
print(IP, PORT, 'SimpleIoT')
server.serve_forever()

먼저 서버 코드의 가장 아래쪽을 자신의 pc가 할당받은 ip 주소, 그리고 port 번호를 변경해줍니다. 그리고 ESP LED, websocket 통신과는 달리 SimpleIOT 서버를 사용하기 때문에 다음과 같은 코드를 작성해줍니다.

 

ESP 및 LED ↔ server 실습websocket server 코드를 찾아보면 사용한 서버를 비교할 수 있을 것입니다.

 

class SimpleIoT(WebSocket):
    def connected(self):
        print(self.address, 'connected')
        msg = {
            'msgType' : 'command',
            'deviceID' : 'CML001',
            'ledStatus' : 'Off'
        }
        self.send_message(json.dumps(msg, indent=4))
        clients.append(self)
        
    def handle(self):
        print(self.address, 'Receive', self.data)
        
        for client in clients:
            if client != self:        

                print('Send', self.data)
                client.send_message(self.data)

    def handle_close(self):
        clients.remove(self)

clients = []

connected 함수는 최초로 서버와 클라이언트가 연결되었을 때 출력되는 default 메시지에 대한 것입니다. 만약 서버와 ESP보드가 성공적으로 연결되면 msg가 클라이언트로 전송됩니다

 

 

ESP보드 시리얼 모니터(1)

 

Enact webapplication으로부터 data를 받아오기 전 서버와 ESP보드 및 LED 사이의 데이터 교환을 출력한 시리얼 모니터입니다.

 

 

    • websocket client 

ESP 및 LED ↔ server 실습에서 사용한 websocket client 코드와 루프문 전 handshake까지는 동일하게 작성하였습니다.

void loop() {
  String data;

  if(client.connected()){
    webSocketClient.getData(data);
    if (data.length() > 0) {
      Serial.print("Received data: ");
      Serial.println(data);
      bool ledStatus = decodeJsonMsg(data);
      digitalWrite(D2, ledStatus);      
      DynamicJsonDocument msg(1024);
      msg["msgType"] = "status";
      msg["deviceID"] = "CML001";
      if(ledStatus) {
        msg["ledStatus"] = "On";
      }
      else {
        msg["ledStatus"] = "Off";
      }

      String response;
      serializeJson(msg, response);
      webSocketClient.sendData(response);
      
  delay(3000);
}

 

서버가 Enact webapplication로부터 msgType‘command’ 데이터를 받으면 위 websocket server 코드에서 handle 함수가 실행됩니다.

그 이후에는 서버가 자기 자신을 제외한 연결된 모든 클라언트들에게 메시지를 전달할 수 있도록 for문을 작성합니다.

 

 

시리얼 모니터에는 “Received data: 서버가 enact application으로부터 받은 Json 포맷의 메시지가 출력됩니다.

그리고 decodeJsonMsgdeserializeJson()를 이용해 문자열 형태를 object로 바꾸어주고, value 값을 출력해줍니다.

 

// Serial.println(String(ledStatus).compareTo("On"));
  if(!String(ledStatus).compareTo("On")) {
    return true;
  }
  else{
    return false;
  }
}

 

그리고 ledStatus“On”이면 1“Off”이면 0을 반환해주는 함수를 만들어준 후 루프문 안에서 digitalWrite(D2, ledStatus)를 통해 LED를 제어합니다.

 

 

이번에는 LED의 상태(On/Off)를 다시 서버에 응답을 전송할 차례입니다. 다시 loop() 안으로 가서 msgmsgType‘status’Json object 형태로 정의해주고, if문을 통해 ledStatus까지 정의해주었습니다.

 

그런데 데이터를 교환할 때에는 문자열로 주고받아야하기 때문에 serializeJson()으로 문자열 형태로 바꾸어주고 서버에 msgType이 ‘status’인 응답을 보냅니다.

 

 

응답을 받은 서버에는 handle 함수가 한번 더 실행되어 for문을 돌며 자기 자신을 제외한 모든 클라이언트들에게 정보를 전송하게 됩니다.

 

따라서 Enact webapplicationmsgtype'status'인 경우에만 조건문을 통과할 수 있도록 구성하여 toastMessage를 띄웁니다.

 

ESP보드 시리얼 모니터(2)

다음은 최종적으로 버튼을 toggle함에 따라 서버와 ESP 및 LED의 통신에 따른 데이터 교환에 대한 시리얼 모니터 화면 입니다. 

 

 

 

3. Enact-app에서 toast message가 띄워짐

 

  • toastMessage 함수 코드(Enact webapplication)
function MainPanel() {
	let [ledStatus, ledStatusChange] = useState(false);
	
	ws.onopen = () => {console.log("Websocket connected.")};
	ws.onmessage = (e) => {
		console.log("Receive: " + e.data);
		var msg = JSON.parse(e.data);
		if(msg.msgType == 'status') {
			if(msg.deviceID == 'CML001') {
				var toastMessage = '';
				if(msg.ledStatus == 'On') {
					ledStatusChange(true);
					toastMessage = '방에 불이 켜졌습니다.'
				}
				else {
					ledStatusChange(false);
					toastMessage = '방에 불이 꺼졌습니다.'
				}

IF문을 이용하여 ledStatus가 on/off일 때 toast가 띄워지도록 함수를 만들었습니다.  

 

 

ledStatus가 on일 때, toastMessage가 나타난 화면