[IoT] IoT 쌩초보 - 전송 시작 버튼이 눌렸는지 어떻게 알 수 있을까

Jihyeon Yun·2023년 2월 20일
0

IoT 도전기

목록 보기
6/7

난관을 맞았다.
우리 프로젝트의 시스템 플로우 차트는 다음과 같은데,

Application -> ThingsBoard -> ESP32로 넘어오는 Stop/Start 시그널을 어떻게 처리할 것인가?

RPC 사용

첫 번째 방법으로는 ThingsBoard의 RPC를 이용하는 방법이 있다. RPC란 Remote Procedure Call의 약자로 원격 메소드를 호출하는 방식을 사용하는 것이다.
자세한 내용은 ThingsBoard의 RPC document를 확인하면 사용할 수 있다.
하지만 이번 프로젝트에서는 뭔가 계속해서 문제가 생겼다. 정확하게 말하면 내가 RPC에 대해 제대로 이해하지 못했기 때문인 것 같은데 주요 문제점은 ESP32 -> ThingsBoard로 isRunning의 상태를 계속 물어보다 보니 메세지가 너무 쌓여서 거절 당했다. 그래서 방법을 바꾸기로 했다.

Share-Attributes 사용

ThingsBoard에는 Shared-Attributes가 존재한다.

이런 방식으로 동작하는데, 장치에서 공유 속성값을 요청하거나 속성 업데이트를 구독하여 사용한다. MQTT 프로토콜을 이용하여 속성 업데이트를 구독하면 실시간으로 알람을 받을 수 있다는 점에서 isRunning의 값 변화를 감지해야 하는 현재 프로젝트에 적합하다고 생각했다.

추가 과정

  1. Shared Attribute에 isRunning을 추가한다.

  2. isRunning의 값이 변경된다면 이를 구독하고 있는 ESP32로 메세지가 간다.

  3. ESP32에서는 이 변경된 값이 true인지 false인지를 확인해서 data 전송을 시작하거나 멈출 수 있다.

Application에서 Start/Stop 버튼을 누르면 Shared-Attributes 속성 중 isRunning의 값을 변경한다.
그러면 ThingsBoard에서 이를 구독하는 ESP32에게로 값이 업데이트가 되었다고 알려준다.(이 과정에서 isRunning의 값이 함께 전달된다.) ESP32는 이 값을 가지고 전송 여부를 판단할 수 있다.
계속해서 ThingsBoard에 요청하지 않아도 자동으로 값이 update되면 시작할 수 있다.

코드

전체 코드에서 Start/Stop 버튼과 관련된 부분을 정리하면 다음과 같다.

// ESP32 will send data if "isRunning" is changed to 'true'
// the callback will be called for every shared attribute changed on the device
constexpr std::array<const char*, 1U> SUBSCRIBED_SHARED_ATTRIBUTES = {
  "isRunning"
};
/// @brief callback function that called when the ThingsBoard's shared attribute is changed,
/// in this code, variable 'runningStatus' value will be replaced to "isRunning" value.
void processRunningStatusUpdate(const Shared_Attribute_Data &data) {
  // replace runningStatus's value to given isRunnning's value
  runningStatus = data["isRunning"];
  // check the runningStatus
  if(!runningStatus){
    // if runningStatus is _false_ send message to ThingsBoard that ESP32 is also stopped.
    tb.sendTelemetryData("isStop", true);
  }
  // When the shared attribute 'isRunning' is changed, built-in LED blinks 3 times.
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
}

// callback when the shared attribute is changed
// it will check all shared attributes that includes in array "SUBSCRIBED_SHARED_ATTRIBUTES"
const Shared_Attribute_Callback callback(SUBSCRIBED_SHARED_ATTRIBUTES.cbegin(), SUBSCRIBED_SHARED_ATTRIBUTES.cend(), processRunningStatusUpdate);

LED의 경우 컴퓨터와 연결을 해제하면 값 변화 여부를 시리얼 모니터로 확인할 수 없어서 ESP32에 내장된 LED를 깜빡이게 해서 사용자가 확인할 수 있도록 했다.

이제 정말 테스트만 남았다!

0개의 댓글