چگونه WeMos D1 Mini مبتنی بر ESP-12F ESP8266 را به ThingsBoard متصل کنیم؟

مقدمه

WEMOS D1 mini بر اساس یک میکروکنترلر ESP8266 32 بیتی و یک ماژول WiFi تولید شده است.
حافظه فلش دستگاه به مقدار 4 مگابایت می‌رسد.
مدل بهبود یافته WEMOS D1 mini دارای 16 مگابایت حافظه، یک آنتن SMD و یک خروجی برای اتصال آنتن خارجی است.
اندازه‌ها و موقعیت مخاطب‌ها در هر دو نوع برد یکسان است.

در این راهنما، خواهیم آموخت که چگونه یک دستگاه را در Thingsboard ایجاد کنیم، کتابخانه‌ها و ابزارهای مورد نیاز را نصب کنیم.
سپس کدهای خود را تغییر داده و آنها را در دستگاه بارگذاری کنیم و نتایج کدنویسی خود و داده‌ها را در ThingsBoard با استفاده از داشبورد وارد شده بررسی کنیم. دستگاه ما با استفاده از قابلیت‌های درخواست‌های مشترک و صفات اشتراکی با ThingsBoard همگام می‌شود.
بطور طبیعی، با استفاده از قابلیت‌های ارائه شده مانند صفات اشتراکی یا درخواست‌های RPC، دستگاه خود را کنترل خواهیم کرد.

پیشنیازها

برای ادامه این راهنما، به موارد زیر نیاز خواهیم داشت:

  • WeMos D1 Mini بر پایه ESP-12F ESP8266
  • Arduino IDE
  •  حساب ThingsBoard

 ایجاد دستگاه در ThingsBoard

به منظور سهولت، ما دستگاه را به صورت دستی با استفاده از رابط کاربری ارائه خواهیم داد.

  • ورود به نمونه ThingsBoard خود را انجام داده و به “Entities” مراجعه کرده و سپس صفحه “Devices” را انتخاب کنید.
  • روی آیکون “+” در گوشه بالا سمت راست جدول کلیک کنید و سپس “Add new device” را انتخاب کنید.
  • نام دستگاه را وارد کنید. به عنوان مثال، “دستگاه من”. در این مرحله تغییر دیگری لازم نیست. برای افزودن دستگاه، روی “Add” کلیک کنید.
  • دستگاه شما اضافه شده است.

///img

نصب کتابخانه‌ها و ابزارهای مورد نیاز

برای نصب برد در محیط Arduino IDE، به بخش File > Preferences بروید و آدرس زیر را در فیلد Additional Boards Manager URLs اضافه کنید:

http://arduino.esp8266.com/stable/package_esp8266com_index.json

سپس به بخش Tools > Board > Board Manager بروید و برد ESP8266 را نصب کنید.

  • در فیلد جستجو، ESP8266 را وارد کنید و بسته esp8266 توسط Espressif Community را نصب کنید.

//img

بعد از اتمام نصب، برد را از منوی Board انتخاب کنید:

Tools > Board > ESP8266 > LOLIN(WEMOS) D1 R2 & mini.

برای نصب ThingsBoard Arduino SDK، مراحل زیر را انجام دهید:

  • به تب “Tools” بروید و بر روی “Manage libraries” کلیک کنید.
  • “ThingsBoard” را در باکس جستجو وارد کنید و برای کتابخانه پیدا شده بر روی دکمه “INSTALL” کلیک کنید.

//img

همچنین، برای بردهایی که بر اساس چیپ ESP8266 هستند، باید کتابخانه “mbedtls” را نصب کنیم.

  • در باکس جستجوی کتابخانه، “mbetls” را وارد کنید و کتابخانه “Seeed_Arduino_mbedtls by Peter Yang” را نصب کنید.

//img

در این مرحله، ما تمامی کتابخانه‌ها و ابزارهای مورد نیاز را نصب کرده‌ایم.

اتصال دستگاه به ThingsConnect

برای اتصال دستگاه به ThingsBoard، ابتدا باید اطلاعات اعتبار دستگاه را دریافت کنید. ThingsBoard از انواع مختلف اعتبارهای دستگاه پشتیبانی می‌کند. ما پیشنهاد می‌کنیم از اعتبارهای پیش‌فرض و خودکار تولید شده استفاده کنید که برای این راهنما یک توکن دسترسی است.

  • برای باز کردن جزئیات دستگاه، بر روی ردیف دستگاه در جدول کلیک کنید.
  • روی “Copy access token” کلیک کنید. توکن به کلیپ‌بورد شما کپی خواهد شد. لطفاً آن را در یک مکان امن ذخیره کنید.

//img

حالا زمان برنامه‌نویسی برای اتصال برد به ThingsBoard فرا رسیده است.
برای انجام این کار، می‌توانید از کد زیر استفاده کنید. این کد، تمامی قابلیت‌های مورد نیاز برای این راهنما را شامل می‌شود.

#if defined(ESP8266)
  #include <ESP8266WiFi.h>
  #define THINGSBOARD_ENABLE_PROGMEM 0
#elif defined(ARDUINO_NANO_RP2040_CONNECT)
  #include <WiFiNINA_Generic.h>
#elif defined(ESP32) || defined(RASPBERRYPI_PICO) || defined(RASPBERRYPI_PICO_W)
  #include <WiFi.h>
  #include <WiFiClientSecure.h>
#endif

#define THINGSBOARD_ENABLE_PSRAM 0
#define THINGSBOARD_ENABLE_DYNAMIC 1

#ifndef LED_BUILTIN
#define LED_BUILTIN 99
#endif

#include <ThingsBoard.h>

constexpr char WIFI_SSID[] = "YOUR_WIFI_SSID";
constexpr char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";

// See https://thingsboard.io/docs/getting-started-guides/helloworld/
// to understand how to obtain an access token
constexpr char TOKEN[] = "YOUR_ACCESS_TOKEN";

// Thingsboard we want to establish a connection too
constexpr char THINGSBOARD_SERVER[] = "demo.thingsboard.io";
// MQTT port used to communicate with the server, 1883 is the default unencrypted MQTT port.
constexpr uint16_t THINGSBOARD_PORT = 1883U;

// Maximum size packets will ever be sent or received by the underlying MQTT client,
// if the size is to small messages might not be sent or received messages will be discarded
constexpr uint32_t MAX_MESSAGE_SIZE = 256U;

// Baud rate for the debugging serial connection.
// If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable
constexpr uint32_t SERIAL_DEBUG_BAUD = 115200U;


// Initialize underlying client, used to establish a connection
WiFiClient wifiClient;
// Initialize ThingsBoard instance with the maximum needed buffer size
ThingsBoard tb(wifiClient, MAX_MESSAGE_SIZE);

// Attribute names for attribute request and attribute updates functionality

constexpr char BLINKING_INTERVAL_ATTR[] = "blinkingInterval";
constexpr char LED_MODE_ATTR[] = "ledMode";
constexpr char LED_STATE_ATTR[] = "ledState";

// Statuses for subscribing to rpc
bool subscribed = false;

// handle led state and mode changes
volatile bool attributesChanged = false;

// LED modes: 0 - continious state, 1 - blinking
volatile int ledMode = 0;

// Current led state
volatile bool ledState = false;

// Settings for interval in blinking mode
constexpr uint16_t BLINKING_INTERVAL_MS_MIN = 10U;
constexpr uint16_t BLINKING_INTERVAL_MS_MAX = 60000U;
volatile uint16_t blinkingInterval = 1000U;

uint32_t previousStateChange;

// For telemetry
constexpr int16_t telemetrySendInterval = 2000U;
uint32_t previousDataSend;

// List of shared attributes for subscribing to their updates
constexpr std::array<const char *, 2U> SHARED_ATTRIBUTES_LIST = {
  LED_STATE_ATTR,
  BLINKING_INTERVAL_ATTR
};

// List of client attributes for requesting them (Using to initialize device states)
constexpr std::array<const char *, 1U> CLIENT_ATTRIBUTES_LIST = {
  LED_MODE_ATTR
};

/// @brief Initalizes WiFi connection,
// will endlessly delay until a connection has been successfully established
void InitWiFi() {
  Serial.println("Connecting to AP ...");
  // Attempting to establish a connection to the given WiFi network
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    // Delay 500ms until a connection has been succesfully established
    delay(500);
    Serial.print(".");
  }
  Serial.println("Connected to AP");
}

/// @brief Reconnects the WiFi uses InitWiFi if the connection has been removed
/// @return Returns true as soon as a connection has been established again
const bool reconnect() {
  // Check to ensure we aren't connected yet
  const wl_status_t status = WiFi.status();
  if (status == WL_CONNECTED) {
    return true;
  }

  // If we aren't establish a new connection to the given WiFi network
  InitWiFi();
  return true;
}


/// @brief Processes function for RPC call "setLedMode"
/// RPC_Data is a JSON variant, that can be queried using operator[]
/// See https://arduinojson.org/v5/api/jsonvariant/subscript/ for more details
/// @param data Data containing the rpc data that was called and its current value
/// @return Response that should be sent to the cloud. Useful for getMethods
RPC_Response processSetLedMode(const RPC_Data &data) {
  Serial.println("Received the set led state RPC method");

  // Process data
  int new_mode = data;

  Serial.print("Mode to change: ");
  Serial.println(new_mode);

  if (new_mode != 0 && new_mode != 1) {
    return RPC_Response("error", "Unknown mode!");
  }

  ledMode = new_mode;

  attributesChanged = true;

  // Returning current mode
  return RPC_Response("newMode", (int)ledMode);
}


// Optional, keep subscribed shared attributes empty instead,
// and the callback will be called for every shared attribute changed on the device,
// instead of only the one that were entered instead
const std::array<RPC_Callback, 1U> callbacks = {
  RPC_Callback{ "setLedMode", processSetLedMode }
};


/// @brief Update callback that will be called as soon as one of the provided shared attributes changes value,
/// if none are provided we subscribe to any shared attribute change instead
/// @param data Data containing the shared attributes that were changed and their current value
void processSharedAttributes(const Shared_Attribute_Data &data) {
  for (auto it = data.begin(); it != data.end(); ++it) {
    if (strcmp(it->key().c_str(), BLINKING_INTERVAL_ATTR) == 0) {
      const uint16_t new_interval = it->value().as<uint16_t>();
      if (new_interval >= BLINKING_INTERVAL_MS_MIN && new_interval <= BLINKING_INTERVAL_MS_MAX) {
        blinkingInterval = new_interval;
        Serial.print("Updated blinking interval to: ");
        Serial.println(new_interval);
      }
    } else if(strcmp(it->key().c_str(), LED_STATE_ATTR) == 0) {
      ledState = it->value().as<bool>();
      digitalWrite(LED_BUILTIN, ledState ? HIGH : LOW);
      Serial.print("Updated state to: ");
      Serial.println(ledState);
    }
  }
  attributesChanged = true;
}

void processClientAttributes(const Shared_Attribute_Data &data) {
  for (auto it = data.begin(); it != data.end(); ++it) {
    if (strcmp(it->key().c_str(), LED_MODE_ATTR) == 0) {
      const uint16_t new_mode = it->value().as<uint16_t>();
      ledMode = new_mode;
    }
  }
}

const Shared_Attribute_Callback attributes_callback(SHARED_ATTRIBUTES_LIST.cbegin(), SHARED_ATTRIBUTES_LIST.cend(), &processSharedAttributes);
const Attribute_Request_Callback attribute_shared_request_callback(SHARED_ATTRIBUTES_LIST.cbegin(), SHARED_ATTRIBUTES_LIST.cend(), &processSharedAttributes);
const Attribute_Request_Callback attribute_client_request_callback(CLIENT_ATTRIBUTES_LIST.cbegin(), CLIENT_ATTRIBUTES_LIST.cend(), &processClientAttributes);

void setup() {
  // Initalize serial connection for debugging
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  delay(1000);
  InitWiFi();
}

void loop() {
//  delay(10);

  if (!reconnect()) {
    subscribed = false;
    return;
  }

  if (!tb.connected()) {
    subscribed = false;
    // Connect to the ThingsBoard
    Serial.print("Connecting to: ");
    Serial.print(THINGSBOARD_SERVER);
    Serial.print(" with token ");
    Serial.println(TOKEN);
    if (!tb.connect(THINGSBOARD_SERVER, TOKEN, THINGSBOARD_PORT)) {
      Serial.println("Failed to connect");
      return;
    }
    // Sending a MAC address as an attribute
    tb.sendAttributeString("macAddress", WiFi.macAddress().c_str());
  }

  if (!subscribed) {
    Serial.println("Subscribing for RPC...");
    // Perform a subscription. All consequent data processing will happen in
    // processSetLedState() and processSetLedMode() functions,
    // as denoted by callbacks array.
    if (!tb.RPC_Subscribe(callbacks.cbegin(), callbacks.cend())) {
      Serial.println("Failed to subscribe for RPC");
      return;
    }

    if (!tb.Shared_Attributes_Subscribe(attributes_callback)) {
      Serial.println("Failed to subscribe for shared attribute updates");
      return;
    }

    Serial.println("Subscribe done");
    subscribed = true;

    // Request current states of shared attributes
    if (!tb.Shared_Attributes_Request(attribute_shared_request_callback)) {
      Serial.println("Failed to request for shared attributes");
      return;
    }

    // Request current states of client attributes
    if (!tb.Client_Attributes_Request(attribute_client_request_callback)) {
      Serial.println("Failed to request for client attributes");
      return;
    }
  }

  if (attributesChanged) {
    attributesChanged = false;
    if (ledMode == 0) {
      previousStateChange = millis();
    }
    tb.sendTelemetryInt(LED_MODE_ATTR, ledMode);
    tb.sendTelemetryBool(LED_STATE_ATTR, ledState);
    tb.sendAttributeInt(LED_MODE_ATTR, ledMode);
    tb.sendAttributeBool(LED_STATE_ATTR, ledState);
  }

  if (ledMode == 1 && millis() - previousStateChange > blinkingInterval) {
    previousStateChange = millis();
    ledState = !ledState;
    digitalWrite(LED_BUILTIN, ledState);
    tb.sendTelemetryBool(LED_STATE_ATTR, ledState);
    tb.sendAttributeBool(LED_STATE_ATTR, ledState);
    if (LED_BUILTIN == 99) {
      Serial.print("LED state changed to: ");
      Serial.println(ledState);
    }
  }

  // Sending telemetry every telemetrySendInterval time
  if (millis() - previousDataSend > telemetrySendInterval) {
    previousDataSend = millis();
    tb.sendTelemetryInt("temperature", random(10, 20));
    tb.sendAttributeInt("rssi", WiFi.RSSI());
    tb.sendAttributeInt("channel", WiFi.channel());
    tb.sendAttributeString("bssid", WiFi.BSSIDstr().c_str());
    tb.sendAttributeString("localIp", WiFi.localIP().toString().c_str());
    tb.sendAttributeString("ssid", WiFi.SSID().c_str());
  }

  tb.loop();
}

در کد، جایگزین کردن نگهدارنده‌ها با SSID شبکه WiFi، رمزعبور و توکن دسترسی دستگاه ThingsBoard خود را انجام دهید.

متغیرهای لازم برای اتصال عبارتند از:

//جدول

...

constexpr char WIFI_SSID[] = "YOUR_WIFI_SSID";
constexpr char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";

constexpr char TOKEN[] = "YOUR_ACCESS_TOKEN";

constexpr char THINGSBOARD_SERVER[] = "demo.thingsboard.io";
constexpr uint16_t THINGSBOARD_PORT = 1883U;

constexpr uint32_t MAX_MESSAGE_SIZE = 256U;
constexpr uint32_t SERIAL_DEBUG_BAUD = 115200U;

...

قسمت ارسال داده (به طور پیش‌فرض، نمونه مقدار تصادفی برای کلید دما و برخی اطلاعات WiFi را ارسال می‌کند):

...
    tb.sendTelemetryInt("temperature", random(10, 20));
    tb.sendAttributeInt("rssi", WiFi.RSSI());
    tb.sendAttributeString("bssid", WiFi.BSSIDstr().c_str());
    tb.sendAttributeString("localIp", WiFi.localIP().toString().c_str());
    tb.sendAttributeString("ssid", WiFi.SSID().c_str());
    tb.sendAttributeInt("channel", WiFi.channel());
...

سپس کد را با فشار دادن دکمه “Upload” یا ترکیب صفحه کلید Ctrl+U بر روی دستگاه بارگذاری کنید.

//img

اگر نمی‌توانید کد را بارگذاری کنید و خطای “Property ‘upload.tool.serial’ is undefined” دریافت می‌کنید، می‌توانید مراحل زیر را انجام دهید:

  •  به “ابزارها” بروید > “برنامه‌نویس” و “Esptool” را به عنوان برنامه‌نویس انتخاب کنید.
  •  به “اسکچ” بروید > “بارگذاری با استفاده از برنامه‌نویس” را انتخاب کنید.

//img

بررسی داده‌ها در ThingsBoard

برای بررسی داده‌ها و امکان ارسال دستورها یا داده‌ها به دستگاه، ما باید داشبورد را ایجاد کنیم.

ابتدا فایل داشبورد بررسی و کنترل داده دستگاه را دانلود کنید.

برای اضافه کردن داشبورد به ThingsBoard، باید مراحل زیر را طی کنید:

  •  از طریق منوی اصلی در سمت چپ صفحه به بخش “داشبوردها” بروید.
  •  روی دکمه “+” در گوشه سمت راست صفحه کلیک کرده و “وارد کردن داشبورد” را انتخاب کنید.
  •  فایل dashboard.json خود را انتخاب کنید و دکمه وارد کردن را فشار دهید.
  •  حالا می‌توانید داشبورد وارد شده را در جدول مشاهده کنید.

//img

پس از وارد کردن، باید برای دستگاه خود یک نام مستعار انتخاب کنیم.
برای انجام این کار، باید روی آیکون قلم متعلق به موجودیت کلیک کنیم، سپس متغیرهای موجودیت را انتخاب کنیم و نام مستعار “دستگاه من” را انتخاب کرده و با فشار دادن آیکون قلم آن را برای ویرایش باز کنیم.
سپس یک دستگاه با نام “دستگاه من” را از لیست کشویی انتخاب کنید و نام مستعار موجودیت را ذخیره کنید، حالا باید قادر به مشاهده داده‌ها از دستگاه خود باشید.

برای بررسی داده‌ها از دستگاه خود، باید داشبورد وارد شده را باز کنید:

  •  با کلیک بر روی آن در جدول، داشبورد را باز کنید.
  •  نمای بررسی داده‌ها و کنترل دستگاه ما.
  •  ویژگی‌های دریافتی از دستگاه.
  •  اطلاعات دستگاه از سرور ThingsBoard.
  •  ویجتی برای مشاهده تاریخچه تغییرات حالت LED.
  •  ویجتی برای مشاهده تاریخچه دمای شبیه‌سازی شده ما.

//img

همگام‌سازی وضعیت دستگاه با استفاده از درخواست‌های مشترک و مشتری

برای دریافت وضعیت دستگاه از ThingsBoard در زمان بوت کردن، قابلیت مربوطه در کد وجود دارد.
قسمت‌های مسئول کد نمونه به شرح زیر است:

  • توابع بازخوانی ویژگی‌ها:
...
void processSharedAttributes(const Shared_Attribute_Data &data) {
  for (auto it = data.begin(); it != data.end(); ++it) {
    if (strcmp(it->key().c_str(), BLINKING_INTERVAL_ATTR) == 0) {
      const uint16_t new_interval = it->value().as<uint16_t>();
      if (new_interval >= BLINKING_INTERVAL_MS_MIN && new_interval <= BLINKING_INTERVAL_MS_MAX) {
        blinkingInterval = new_interval;
        Serial.print("Updated blinking interval to: ");
        Serial.println(new_interval);
      }
    } else if(strcmp(it->key().c_str(), LED_STATE_ATTR) == 0) {
      ledState = it->value().as<bool>();
      digitalWrite(LED_BUILTIN, ledState ? HIGH : LOW);
      Serial.print("Updated state to: ");
      Serial.println(ledState);
    }
  }
  attributesChanged = true;
}

void processClientAttributes(const Shared_Attribute_Data &data) {
  for (auto it = data.begin(); it != data.end(); ++it) {
    if (strcmp(it->key().c_str(), LED_MODE_ATTR) == 0) {
      const uint16_t new_mode = it->value().as<uint16_t>();
      ledMode = new_mode;
    }
  }
}
...
const Attribute_Request_Callback attribute_shared_request_callback(SHARED_ATTRIBUTES_LIST.cbegin(), SHARED_ATTRIBUTES_LIST.cend(), &processSharedAttributes);
const Attribute_Request_Callback attribute_client_request_callback(CLIENT_ATTRIBUTES_LIST.cbegin(), CLIENT_ATTRIBUTES_LIST.cend(), &processClientAttributes);
...

همانطور که مشاهده می‌کنید، دو تابع بازخوانی وجود دارد، تابع اول برای ویژگی‌های مشترک و تابع دوم برای ویژگی‌های مشتری است.
تابع اول پاسخی با فاصله‌ی چشمک زدن دریافت می‌کند تا دوره مناسب برای چشمک زدن را تنظیم کند.
تابع دوم مود و وضعیت LED را دریافت و آن‌ها را ذخیره و تنظیم می‌کند.
این قابلیت به ما اجازه می‌دهد تا وضعیت واقعی را پس از راه‌اندازی مجدد حفظ کنیم.

  • درخواست‌های ویژگی‌ها:
...
  // Request current states of shared attributes
  if (!tb.Shared_Attributes_Request(attribute_shared_request_callback)) {
    Serial.println("Failed to request for shared attributes");
    return;
  }

  // Request current states of client attributes
  if (!tb.Client_Attributes_Request(attribute_client_request_callback)) {
    Serial.println("Failed to request for client attributes");
    return;
  }
...

برای اینکه تابع‌های بازخوانی ما داده‌ها را دریافت کنند، باید یک درخواست به ThingsBoard ارسال کنیم.

کنترل دستگاه با استفاده از ویژگی‌های مشترک

همچنین می‌توانیم با استفاده از قابلیت به‌روزرسانی ویژگی مشترک، دوره چشمک زدن را تغییر دهیم.

  • برای تغییر دوره چشمک زدن، فقط کافی است مقدار را در داشبورد خود تغییر دهیم.
  • بعد از اعمال با فشار دادن علامت تیک، یک پیام تأیید را مشاهده خواهید کرد.

//img

برای تغییر وضعیت هنگامی که حالت چشمک زدن غیرفعال است، می‌توانیم از سوییچ در همان ویجت استفاده کنیم:

  • این کار فقط زمانی انجام می‌شود که حالت چشمک زدن غیرفعال است.

//img

برای دست‌یابی به این هدف، متغیر “blinkingInterval” در بخش‌های زیر از کد استفاده شده است:

  • تابع بازخوانی به‌روزرسانی ویژگی‌های مشترک:
...

void processSharedAttributes(const Shared_Attribute_Data &data) {
  for (auto it = data.begin(); it != data.end(); ++it) {
    if (strcmp(it->key().c_str(), BLINKING_INTERVAL_ATTR) == 0) {
      const uint16_t new_interval = it->value().as<uint16_t>();
      if (new_interval >= BLINKING_INTERVAL_MS_MIN && new_interval <= BLINKING_INTERVAL_MS_MAX) {
        blinkingInterval = new_interval;
        Serial.print("Updated blinking interval to: ");
        Serial.println(new_interval);
      }
    } else if(strcmp(it->key().c_str(), LED_STATE_ATTR) == 0) {
      ledState = it->value().as<bool>();
      digitalWrite(LED_BUILTIN, ledState ? HIGH : LOW);
      Serial.print("Updated state to: ");
      Serial.println(ledState);
    }
  }
  attributesChanged = true;
}

...
const Shared_Attribute_Callback attributes_callback(SHARED_ATTRIBUTES_LIST.cbegin(), SHARED_ATTRIBUTES_LIST.cend(), &processSharedAttributes);
...
  • دریافت اشتراک برای به‌روزرسانی ویژگی‌های مشترک:
...
    if (!tb.Shared_Attributes_Request(attribute_shared_request_callback)) {
      Serial.println("Failed to request for shared attributes");
      return;
    }
...
  • بخشی از کد برای چشمک زدن:
...

  if (ledMode == 1 && millis() - previousStateChange > blinkingInterval) {
    previousStateChange = millis();
    ledState = !ledState;
    digitalWrite(LED_BUILTIN, ledState);
    tb.sendTelemetryBool(LED_STATE_ATTR, ledState);
    tb.sendAttributeBool(LED_STATE_ATTR, ledState);
    if (LED_BUILTIN == 99) {
      Serial.print("LED state changed to: ");
      Serial.println(ledState);
    }
  }
...

شما می‌توانید منطق را تغییر دهید تا به اهداف خود دست یابید و پردازشی برای ویژگی‌های خود اضافه کنید.

کنترل دستگاه با استفاده از RPC

می‌توانید به طور دستی وضعیت LED و حالت بین روشنایی پیوسته و چشمک زدن را تغییر دهید. برای این کار، می‌توانید از بخش‌های زیر در داشبورد خود استفاده کنید:

  • تغییر وضعیت LED با استفاده از ویجت سوئیچ به روشنایی پیوسته.
  • تغییر وضعیت LED با استفاده از ویجت سوئیچ گرد به حالت چشمک زدن.

//img

لطفاً توجه داشته باشید که شما تنها می‌توانید وضعیت LED را تغییر دهید اگر حالت چشمک زدن غیرفعال باشد.

در نمونه کد، ما قابلیت بررسی دستورات RPC را داریم.
برای دسترسی به کنترل دستگاه، از بخش‌های زیر در کد استفاده کرده‌ایم:

  • تابع بازخوانی درخواست‌های RPC:
...

RPC_Response processSetLedMode(const RPC_Data &data) {
  Serial.println("Received the set led state RPC method");

  // Process data
  int new_mode = data;

  Serial.print("Mode to change: ");
  Serial.println(new_mode);

  if (new_mode != 0 && new_mode != 1) {
    return RPC_Response("error", "Unknown mode!");
  }

  ledMode = new_mode;

  attributesChanged = true;

  // Returning current mode
  return RPC_Response("newMode", (int)ledMode);
}

...

const std::array<RPC_Callback, 1U> callbacks = {
  RPC_Callback{ "setLedMode", processSetLedMode }
};

...
  • دریافت اشتراک برای درخواست‌های RPC:
...
    if (!tb.RPC_Subscribe(callbacks.cbegin(), callbacks.cend())) {
      Serial.println("Failed to subscribe for RPC");
      return;
    }
...

شما می‌توانید کد را تغییر دهید تا به اهداف خود برسید و پردازشی برای دستورات RPC خود اضافه کنید.

نتیجه‌گیری

با دانشی که در این راهنما شرح داده شده است، شما به راحتی می‌توانید WeMos D1 Mini خود را بر اساس ESP-12F ESP8266 متصل کنید و داده‌ها را به ThingsBoard ارسال کنید.

از مستندات پلتفرم برای یادگیری بیشتر درباره مفاهیم کلیدی و ویژگی‌ها استفاده کنید. به عنوان مثال، قوانین هشدار یا داشبوردها را پیکربندی کنید.

عناوین هر بخش