ESP8266 và IOT (Part 9): Điều khiển thiết bị trong nhà bằng Slack

How-To-Make-Your-Home-A-Smart-Home

Thêm Outgoing Webhooks Integration vào một Slack Channel

Trong bài tutorial trước bạn đã biết cách để configure một Slack channel để nhận message từ nguồn ngoài, như ESP8266 device. Rất tiện cho việc tạo ra thông báo khi bị trigger từ các cảm biến khác nhau, như chúng ta đã làm ở ví dụ về cảm biến chuyển đông (ở bài trước). Bây giờ chúng ta kích hoạt (enable) kết nối trong chiều ngược lại, từ Slack đến ESP8266. Làm được điều này, rât nhiều ý tưởng có thể phát triển tương tự. Tôi sẽ chỉ cho bạn một project đơn giản tôi đã làm, đó là điều khiển các ứng dụng trong nhà với những lệnh (commands) từ Slack.

Giống như những bài trước, bạn phải add một integration vào Slack channel bạn muốn dùng. Nếu bạn chưa biết về nó, hãy quay lại xem lại bài tutorial trước. Lúc này chúng ta cần một integration cho phép chúng ta gửi Slack messages đến cái địa chỉ ngoài, ở đây là app của chúng ta trong Bluemix. Tìm integration tên Outgoing Webhooks.

Outgoing Webhooks integration
Outgoing Webhooks integration

Chọn channel, trigger word (tùy chọn) và URL. Nếu bạn không làm với trigger word, bất cứ message nào được gửi tới các channel xác định sẽ được gửi đến ULR(s) xác định. Nếu bạn chọn trigger word, chỉ message nào gửi đến channel được bắt đầu với trigger word sẽ được gửi đến URL. URL phải bắt đầu với tên của Node-RED application, theo bởi những path tùy biến, ví dụ:

<appName>.mybluemix.net/slack.

Integration settings
Integration settings

Trong ví dụ trên, chỉ message gửi đến channel #sensor được bắt đầu với từ @ESP8266 sẽ được gửi tới URL.

Bên phía Bluemix, chúng ta sẽ dùng một HTTP node để lắng nghe các message tới.

Cũng có token được tạo ra dùng để xác định danh (authentication). Bạn có thể điền một vài trường khác và click vào save setttings. Channel của bạn giờ đã sẵn sàng và bạn có thể xem một notification về việc thêm integration.

Integration added
Integration added

Node-RED Flow

Bây giờ chúng ta cần tạo ra một app để chấp nhận message từ Slack và chuyển tiếp chúng đến ESP8266. Giống như trước đây, bạn sẽ tạo nó bằng Node-RED và nó sẽ được host trên Bluemix (giải thích trong bài 3).

Flow chứa một HTTP input node lắng nghe message tới từ Slack, một function node được dùng để extract chuỗi command từ toàn bộ chuỗi message và IoT out node để gửi command đến ESP8266

Flow
Flow

Trong HTTP node bạn phải đặt chung path bạn đã chọn trong khi thêm webhook integration đến channel của bạn (của tôi là /slack).

HTTP in node
HTTP in node

Một payload với một những parameter khác nhau được gửi từ Slack, với parameter text được chứa trong nội dung của actual message. Function node được dùng để extract dữ liệu text và remove trigger word, vì chúng ta muốn chỉ truyền command text đến ESP8266. Tôi đã chọn tất cả các message tôi gửi từ Slack có theo chuẩn @ESP8266_<commandText>.

Function code:

var text = msg.payload.text;

msg.payload = text.substring(9, text.length);

return msg;

Configure IoT out node:

IBM out node
IBM out node

Upload code cho các subscription lên ESP8266. Chắc rằng thiết lập IoT node tương ứng với subscribe topic (command loại ‘test và định dạng String).

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char* ssid = "";
const char* password = "";

#define ORG "<yourOrganization>"
#define DEVICE_TYPE "ESP8266"
#define DEVICE_ID "<yourDeviceID>"
#define TOKEN "<yourToken>"

char server[] = ORG ".messaging.internetofthings.ibmcloud.com";
char topic[] = "iot-2/cmd/test/fmt/String";
char authMethod[] = "use-token-auth";
char token[] = TOKEN;
char clientId[] = "d:" ORG ":" DEVICE_TYPE ":" DEVICE_ID;

WiFiClient wifiClient;
PubSubClient client(server, 1883, callback, wifiClient);

void setup() {
  Serial.begin(115200);
  Serial.println();
  wifiConnect();
  mqttConnect();
}

void loop() {
  if (!client.loop()) {
    mqttConnect();
  }
}

void wifiConnect() {
  Serial.print("Connecting to "); Serial.print(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.print("nWiFi connected, IP address: "); Serial.println(WiFi.localIP());
}

void mqttConnect() {
  if (!client.connected()) {
    Serial.print("Reconnecting MQTT client to "); Serial.println(server);
    while (!client.connect(clientId, authMethod, token)) {
      Serial.print(".");
      delay(500);
    }
    initManagedDevice();
    Serial.println();
  }
}

void initManagedDevice() {
  if (client.subscribe(topic)) {
    Serial.println("subscribe to cmd OK");
  } else {
    Serial.println("subscribe to cmd FAILED");
  }
}

void callback(char* topic, byte* payload, unsigned int payloadLength) {
  Serial.print("callback invoked for topic: "); Serial.println(topic);

  for (int i = 0; i < payloadLength; i++) {
    Serial.print((char)payload[i]);
  }
}

Vậy đó, bạn có thể thấy các command bạn gửi từ Slack trên Serial monitor. Có rất nhiều option để bạn mở rộng hệ thống. Bạn có thể điều khiển từ Slack motor, relay, đèn… và build một ‘Smart’ home nhanh chóng hiệu quả.

Điều khiển Đồ gia dụng với IR Signals (hồng ngoại)

Tôi đã quyết định kết nối Arduino board có diode hồng ngoài với thiết bị ESP8266 và điều khiển bất cứ ứng thiết bị trong nhà có thể điều khiển bởi tín hiệu IR. ESP8266 nhận command từ Slack và gửi chúng đến Arduino board thông qua serial port (UART), sau đó gửi tín hiệu tương ứng đến diode IR. Để làm việc với IR protocol, bạn sẽ phải thêm một thư viện khá lớn của Ken Shirriff, gọi là Irremote. Vào library manager và tìm nó, hoặc add một zip file. Trên trang Github bạn có thể tìm thấy các board được hỗ trợ. Tôi dùng Arduino Mega board và tôi nối IR diode với chân 9 (bạn không thể sửa dụng bất cứ chân nào cho mục đích này, xem trên github để biết thêm chi tiết). Bạn phải đặt điện trở giới hạn dòng để tránh nguy hiểm cho board. Bạn không nên đặt điện trở quá lớn bởi vị nó sẽ giảm khoảng cách truyền tín hiệu (tôi dùng điện trở 100ohm và đạt khoảng cách khoảng 4m). Nếu bạn cần một khoảng cách xa hơn, bạn nên suy nghĩ về việc lái IR diode với transitor. Khi đặt diode, chắc rằng chân ngắn được nối với ground (đất) và chân dài với pin số 9 thông qua một điện trở. Toàn bộ mạch với Arduino board khá đơn giản. Dây vàng chưa được nối trong hình được dùng để kết nối với ESP8266. Để truyền dữ liệu từ ESP8266 đến Arduino thông qua UART port, chân Tx của ESP8266 phải được kết nối với chân Rx của Arduino. Đồng thời, đừng quên nối chung ground của ESP8266 với Arduino.

Schematics for sending IR signals
Schematics for sending IR signals

Tần số của sóng IR phát ra nên trùng với tần số của một IR receiver của các thiết bị bạn muốn điều khiển, nhưng thậm chí nếu có một khác biệt nhỏ, kết nối hoạt động tốt.

Điều tiếp theo bạn cần làm để reverse engineer (chỉnh sửa) một bộ điều khiển remote của các thiết bị bạn muốn điều khiển. Bạn cần biết IR protocol nào được dùng bởi các thiết bị đó và dữ liệu tương ứng cho mỗi nút của bộ điều khiển remote Để cho nó đơn giản, chúng ta chỉ sẽ dùng lệnh on và off. Để làm điều này, chúng ta sẽ cần hook một IR reciver vào Arduino và upload chương trình sẽ làm công việc này cho bạn. Tôi dùng TSOP 32128 receiver từ series này. Nó có 3 chân, ground, nguồn và chân dữ liệu. Upload chương trình IrrecvDumpV2 từ ví dụ của Arduino và kết nối chân dữ liệu của receiver với chân mà trong code tên là recvPin

Schematics for receiving IR signals
Schematics for receiving IR signals

Khi bạn hướng bộ điều khiển remote và nhấn bất cứ nút nào, bạn nên xem việc đọc dữ liệu trên serial monitor. Dựa trên điều này, bạn biết protocol nào được dùng và loại dữ liệu được truền khi một nút nhất định được nhấn. Việc đọc cho ta thông tin command nào và dữ liệu nào dùng để gửi command với Arduino. Xem chương trình IRsendDemo để biết làm cách nào dữ liệu được gửi. Nó có thể xảy ra bộ điều khiển IR remote dùng một giao thức nào đó (chưa biết) mà trong đây là trường hợp máy lạnh của tôi.

Serail monitor
Serail monitor

Thật may, chương trình in ra toàn bộ dữ liệu với dạng thô, bạn có thể gửi với sendRaw command, không cần quan tâm về protocol đặc biệt nào.

Raw data

Tôi đã copy dữ liệu thô này (raw data) cho lệnh on và off và mọi thứ hoạt động rất tốt. Đây là code tôi dùng để upload vào Arduino:

#include <IRremote.h>

IRsend irsend;

//put the data you obtained for your remote control
//unsigned int  irSignalOn[179] = { ...
//unsigned int  irSignalOff[179] = { ...

  
void setup() {

  Serial.begin(115200);

}

void loop() {
  
  String command = "";
  
  if(Serial.available()){
    delay(100);
    while(Serial.available() > 0){
      command += char(Serial.read());
    }

     if(command == "on"){
      irsend.sendRaw(irSignalOn, 179, 38);
      Serial.println(command);
     }
     else if(command == "off"){
      irsend.sendRaw(irSignalOff, 179, 38);
      Serial.println(command);
     } 
   }   
}

Nó đọc command đến từ ESP8266 và dựa trên chúng để quyết định tín hiệu để gửi đến IR diode.

Trong ESP8266 code, bỏ tất cả các lệnh serial print, ngoại trừ callback function, để tránh việc truyền dữ liệu không cần thiết. Đối số thứ 2 của sendRaw function là dùng để dữ liệu dài và thứ ba là cho tần số của tín hiệu trong kHz.

Mục đích của phần này không phải để dạy cho bạn về IR communication, nhưng để cho bạn thấy những ứng dụng thú vị của hệ thông chúng tôi build trước đây. Nếu bạn thích thú hơn về IR communication, protocol và thư viện, có rất nhiều tài liệu online.

Vậy là kết thúc của phần này. Bạn vừa học làm cách nào truyền nhận message từ Slack đến ESP8266. Đồng thòi bạn đã thấy những ứng dụng thú vị của hệ thống này khi bạn có thể điều khiển các thiết bị của nhà bạn từ xa bằng Slack.

Các bài cùng Series

(Part 1): Làm quen với ESP8266
(Part 2): ESP8266 với MQTT
(Part 3): Kết nối ESP8266 với IBM Bluemix
(Part 4): Dùng Cloudant DB trong IBM Bluemix để lưu trữ dữ liệu
(Part 5): Gửi Email và SMS thông báo khi bị trigger từ dữ liệu cảm biến
(Part 6): Hiển thị dữ liệu cảm biến với IBM Bluemix
(Part 7): Vị trí Devices trên Map
(Part 8): Nhận Motion Alarm Notifications trong Slack
(Part 9): Điều khiển thiết bị trong nhà bằng Slack

Tham khảo: Codingo

Comments

linhkienbachkhoa

Comments