Control Home Appliances From Slack

Adding Outgoing Webhooks Integration to a Slack Channel

In the previous tutorial you have seen how you can configure a Slack channel to receive messages from external sources, such as an ESP8266 device. This is very handy for setting notifications that are triggered by various sensors, which we showed on the example of a motion sensor. Now we want to enable communication in the opposite direction, from Slack to the ESP8266. This will give us plenty opportunities and new ideas for development. I will show you one simple project I developed where I control home appliances with commands from Slack.

Same as before, you have to add an integration to the Slack channel you want to use for this purpose. If you don’t know how to do this, check the previous tutorial. This time we need the an integration that will allow us to send Slack messages to external addresses, such as our app in Bluemix. Search for the integration called Outgoing Webhooks.

Outgoing Webhooks integration

Choose channel, trigger word (optional) and URL. If you avoid trigger word, any messages sent to the specified channel will be sent to the specified URL(s). If you choose trigger word, only messages sent to the channel that start with the trigger word will be sent to the URL. URL has to start with the name of your Node-RED application, followed by the arbitrary path, for example: <appName>.mybluemix.net/slack.

Integration settings

In the above example, only messages sent to channel #sensors that start with the word @ESP8266 will be sent to the URL.

On the Bluemix side, we will use an HTTP node that will listen to incoming messages.

There is also a generated token that can be used for authentication. You can fill a few optional fields and click save settings. Your channel is now ready and you should see a notification about added integration.

Integration added

 

Node-RED Flow

Now we need to make an app that will accept messages from Slack and forward them to the ESP8266. Same as before, we will make it using Node-RED and it will be hosted on Bluemix (explained in the 3rd part).

The flow consists of an HTTP input node that listens to incoming messages from Slack, a function node that is used to the extract command string from the whole message string and IoT out node to send that command to the ESP8266.

Flow

In HTTP node you have to put the same path you have chosen while adding webhook integration to your channel (/slack in my case).

HTTP in node

A payload with various parameters is sent from Slack, with parameter text containing actual message content. Function node is used to extract text value and to remove trigger word, since we want to transfer command text only to the ESP8266. I have chosen that all messages I send from Slack have the following format @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

Upload the code for subscriptions to the ESP8266. Be sure that IoT node configuration corresponds to the subscribe topic (command type ‘test’ and format 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]);
  }
}

That’s it, you should see commands you send from Slack on the Serial monitor. There are plenty options how you can extend this system. You can attach and control from Slack motors, relays, lights etc. and build ‘Smart’ home quickly and cost-effectively.

 

Control Home Appliances with IR Signals

I have decided to connect an Arduino board with an infra-red diode to my ESP8266 device and control any home appliance that can be controlled by IR signals. ESP8266 receives commands from Slack and send them to the Arduino board over serial port (UART), which then sends appropriate signals to the IR diode. In order to work with IR protocol, you will have to add a great library by Ken Shirriff, called IRremote. Go to library manager and search for it, or add a zip file. On the github page you can see supported boards. I have used Arduino Mega board and I attached the IR diode to the pin 9 (you can’t use any pin for this purpose, check github page for more details). You have to put current limiting resistor to avoid damaging the board. You shouldn’t put too large resistor because you will reduce the range significantly (I have used 100 ohm and the range is around 4m). If you need longer range, you should consider option of driving the IR diode with a transistor. When placing the diode, be sure that the shorter lead is connected to the ground and longer to the pin 9 over the resistor. Whole circuit with Arduino board is quite simple. The yellow unconnected wire on the image is used for connection with the ESP8266. To transfer data from the ESP8266 to the Arduino over UART port, Tx pin of the ESP8266 has to be connected to the Rx pin of the Arduino. Also, don't forget to connnect the ground of the ESP8266 to the ground of the Arduino. 

Schematics for sending IR signals

Frequency of emitted IR waves should match frequency of an IR receiver of the appliance you want to control, but even if there is a small difference, communication should work properly.

Next thing you need to do is to reverse engineer a remote control of the appliance you want to control. You need to know which IR protocol is used by certain device and which data corresponds to each button of the remote control. To keep it simple, we will just use on and off commands. In order to do this, you will need to hook an IR receiver to the Arduino and upload a program that will do this work for you. I used TSOP 32128 receiver from this series. It has three pins, ground, power and data pin. Upload the IRrecvDumpV2 program from examples to the Arduino and connect the data pin of the receiver to the pin that is named in the code as recvPin.

Schematics for receiving IR signals

When you point the remote control and press any button, you should see readings on the serial monitor. Based on this, you know which protocol is used and which data is transferred when a certain button is pressed. These readings give you information which commands and which data to use to send commands with the Arduino. See IRsendDemo program to see how data is sent. It can happen that your IR remote control uses an unknown protocol which was the case with my air conditioner.

Serail monitor

Fortunately, this program prints whole data in raw format, which you can then send with sendRaw command, without need to care about specific protocol.

Raw data

I copied this raw data for on and off commands and everything worked perfectly. This is the code I uploaded to the 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);
     } 
   }   
}

It reads commands that come from the ESP8266 and based on them decides which signal to send to IR diode.

In the ESP8266 code, remove all serial print commands, except the one in the callback function, to avoid unnecessary data transfers. Second argument of the sendRaw function is used for data length and third for frequency of the signal in kHz.

Purpose of this part wasn’t to teach you about IR communication, but to show you an interesting application of the system we previously build. If you are interested more in IR communication, protocols and library, there are plenty of documentation available online.

That’s the end of this part. You have learnt how to transfer messages from Slack to the ESP8266. Also, you have seen an interesting application of this system where you can remotely control home appliances from Slack.

Lessons of this Series

Trending

Newsletter

Subscribe to our newsletter for good news, sent out every month.

Tags