Kendali Lampu di ThingsBoard Dengan Remote Procedure Call
Kendali Lampu di ThingsBoard Dengan Remote Procedure Call
Pada tulisan ini diuraikan cara mengendalikan lampu secara wireless dengan ThingsBoard. Mikroprosesor yang dipakai adalah ESP32. Metode yang dipakai adalah RPC (Remote Procedure Call)
Berikut ini kode firmware untuk ESP32. Inspirasi kode dari “ESP32 Pico Kit GPIO Control and DHT22 sensor monitor using ThingBoard Arduino SDK“
Parameter yang perlu disesuaikan:
- WIFI_AP_NAME adalah nama access point
- WIFI_PASSWORD adalah password WiFi yang dipakai
- TOKEN adalah kode token dari perangkat. Diambil dari ThingsBoard
#include <WiFi.h> // WiFi control for ESP32
#include <ThingsBoard.h> // ThingsBoard SDK
// Helper macro to calculate array size
#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
// WiFi access point
#define WIFI_AP_NAME "WIFI_AP_NAME "
// WiFi password
#define WIFI_PASSWORD "WIFI_PASSWORD "
// See https://thingsboard.io/docs/getting-started-guides/helloworld/
// to understand how to obtain an access token
#define TOKEN "yd8R3K3GE61Drm7TtvgF"
// ThingsBoard server instance.
#define THINGSBOARD_SERVER "192.168.0.90"
#define ONBOARD_LED 22
// Baud rate for debug serial
#define SERIAL_DEBUG_BAUD 115200
// Initialize ThingsBoard client
WiFiClient espClient;
// Initialize ThingsBoard instance
ThingsBoard tb(espClient);
// the Wifi radio's status
int status = WL_IDLE_STATUS;
// Array with LEDs that should be controlled from ThingsBoard, one by one
uint8_t leds_control[] = { 12, 13, 27 };
// Main application loop delay
int quant = 20;
// Initial period of LED cycling.
int led_delay = 1000;
// Period of sending a temperature/humidity data.
int send_delay = 2000;
// Time passed after LED was turned ON, milliseconds.
int led_passed = 0;
// Time passed after temperature/humidity data was sent, milliseconds.
int send_passed = 0;
// Set to true if application is subscribed for the RPC messages.
bool subscribed = false;
// LED number that is currenlty ON.
//int current_led = 0;
// Processes function for RPC call "setGpioStatus"
// RPC_Data is a JSON variant, that can be queried using operator[]
// See https://arduinojson.org/v5/api/jsonvariant/subscript/ for more details
RPC_Response processSetGpioState(const RPC_Data &data)
{
Serial.println("Received the set GPIO RPC method");
int pin = data["pin"];
bool enabled = data["enabled"];
if (pin < COUNT_OF(leds_control)) {
Serial.print("Setting LED ");
Serial.print(pin);
Serial.print(" to state ");
Serial.println(enabled);
digitalWrite(leds_control[pin], enabled);
}
return RPC_Response(data["pin"], (bool)data["enabled"]);
}
// RPC handlers
RPC_Callback callbacks[] = {
{ "setGpioStatus", processSetGpioState },
};
// Setup an application
void setup() {
// Initialize serial for debugging
Serial.begin(SERIAL_DEBUG_BAUD);
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
InitWiFi();
for (size_t i = 0; i < COUNT_OF(leds_control); ++i) {
pinMode(leds_control[i], OUTPUT);
}
pinMode(ONBOARD_LED, OUTPUT); \
// LED check
digitalWrite(leds_control[0], HIGH);
delay(500);
digitalWrite(leds_control[1], HIGH);
delay(500);
digitalWrite(leds_control[2], HIGH);
delay(500);
digitalWrite(leds_control[0], LOW);
delay(500);
digitalWrite(leds_control[1], LOW);
delay(500);
digitalWrite(leds_control[2], LOW);
delay(500);
}
// Main application loop
void loop() {
delay(quant);
led_passed += quant;
send_passed += quant;
// Reconnect to WiFi, if needed
if (WiFi.status() != WL_CONNECTED) {
reconnect();
return;
}
// Reconnect to ThingsBoard, if needed
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)) {
Serial.println("Failed to connect");
return;
}
}
// Subscribe for RPC, if needed
if (!subscribed) {
Serial.println("Subscribing for RPC...");
// Perform a subscription. All consequent data processing will happen in
// callbacks as denoted by callbacks[] array.
if (!tb.RPC_Subscribe(callbacks, COUNT_OF(callbacks))) {
Serial.println("Failed to subscribe for RPC");
return;
}
Serial.println("Subscribe done");
subscribed = true;
}
if (send_passed > send_delay) {
send_passed = 0;
}
// Process messages
tb.loop();
static int blink_counter = 0;
if (blink_counter < 50) {
digitalWrite(ONBOARD_LED, LOW);
} else {
digitalWrite(ONBOARD_LED, HIGH);
}
blink_counter++;
if (blink_counter >= 100) {
blink_counter = 0;
}
}
void InitWiFi()
{
Serial.println("Connecting to AP ...");
// attempt to connect to WiFi network
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AP");
}
void reconnect() {
// Loop until we're reconnected
status = WiFi.status();
if ( status != WL_CONNECTED) {
WiFi.begin(WIFI_AP_NAME, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AP");
}
}
Berikut ini software PHP untuk mengendalikan LED dari Windows/Ubuntu
<?php
// kendali LED dengan REST API
// Create a new cURL resource
// Setup request to send json via POST
// login untuk mendapatkan JWT
$url = 'http://192.168.0.90:8080/api/auth/login';
$body_array = array();
$body_array["username"] = "tenant@thingsboard.org";
$body_array["password"] = "tenant";
$body = json_encode($body_array);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json', 'Accept: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
print_r($result);
$result_array = json_decode($result, true);
print_r($result_array);
$token = $result_array["token"];
printf("token %s\n", $result_array["token"]);
// sekarang kirim command pakai token
function SetGpio($led_index, $value, $token) {
$url = 'http://192.168.0.90:8080/api/rpc/twoway/e048cf90-cacc-11ec-84b1-a3192844351e';
$params = array();
$params["pin"] = $led_index;
$params["enabled"] = $value;
$body_array = array();
$body_array["method"] = "setGpioStatus";
$body_array["params"] = $params;
$body_array["persistent"] = false;
$body_array["timeout"] = 5000;
$body = json_encode($body_array);
$header = array();
$header[] = 'Content-Type:application/json';
$header[] = 'Accept: application/json';
$header[] = 'X-Authorization: Bearer ' . $token;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
print_r($result);
}
while (1) {
SetGpio(0, 1, $token);
usleep(50000);
SetGpio(0, 0, $token);
usleep(50000);
SetGpio(1, 1, $token);
usleep(50000);
SetGpio(1, 0, $token);
usleep(50000);
SetGpio(2, 1, $token);
usleep(50000);
SetGpio(2, 0, $token);
usleep(50000);
}