
How to make friends OpenHAB and Arduino. Method # 3: MQTT
- Tutorial
This article shows another way the Arduino microcontroller interacts with a universal platform for integrating all home smart technology into a single openHAB control system . Articles on interactions using Serial and HTTP are already presented on Habré . For my new project, I chose MQTT , because I already tried the two previous methods and wanted to try something else.
Let's get started ...
MQTT is a protocol for exchanging messages between devices. It is assumed that there is one MQTT server (the so-called MQTT-broker) and client devices connected to it. Messages consist of a heading (topic) and the text of the message. Connecting to the server gives us two main possibilities: send messages and subscribe to topics of interest to us. At the same time, the tree-like structure of topics works. This is easier to show with an example. For sensors transmitting data from the bedroom, you can use the following headers:
Similarly for the kitchen:
Now, by subscribing to any of these topics, we will receive messages about the status of each specific sensor. But the protocol also allows you to subscribe to the entire branch at once. To receive data from all bedroom sensors in one subscription, you can subscribe to the topic
This structure is convenient for human understanding, but further use of MQTT has shown that it is much easier to use only two branches: one for updating the status of elements and the other for sending commands. But more on that later.
In my project I used Raspberry Pi model B + with Raspbian installed as a platform for openHAB and Arduino MEGA 2560 with Ethernet Shield w5100 installed on it . Also experimented with Arduino Yun - everything is the same, just use YunClient instead of EthernetClient.
We leave out the process of installing openHAB, since This is the subject of many articles. We proceed immediately to the installation of MQTT. Everything is simple here, open the console and install:
We reboot and check the operability (when I first installed mosquitto I didn’t want to start at system startup):
After reboot:
In response should receive:
Now you need to set binding for openHAB. To do this, we perform:
Or just copy the org.openhab.binding.mqtt-1.6.2.jar file (current version) to the folder / usr / share / openhab / addons /
Let's move on to setting up openHAB:
Here we add the following lines:
We also need two Item, responsible for turning on / off the light in the kitchen:
Do not forget to add them to the sitemap at any convenient place. Restart openHAB:
You can start experimenting! We connect from any device to the MQTT server and subscribe to the topic / myhome / #. Each time the status of any Item changes, we will receive a message in the topic of which the name Item will be indicated, and in the message text - its new status. This is enough for us, let's move on to programming the microcontroller.
The missing library can be downloaded here: https://github.com/knolleary/pubsubclient
That's all. I will comment only on the last piece of code. If the lighting is controlled directly through the microcontroller, it is necessary to transfer the new state to openHAB. This can be done immediately after a state change, or once a minute to transfer the state of all controlled loads.
In conclusion, I want to give a link to an amazing article that really helped me figure this out: “Uber Home Automation w / Arduino & Pi”
Let's get started ...
MQTT is a protocol for exchanging messages between devices. It is assumed that there is one MQTT server (the so-called MQTT-broker) and client devices connected to it. Messages consist of a heading (topic) and the text of the message. Connecting to the server gives us two main possibilities: send messages and subscribe to topics of interest to us. At the same time, the tree-like structure of topics works. This is easier to show with an example. For sensors transmitting data from the bedroom, you can use the following headers:
/myhome/bedroom/temperature
/myhome/bedroom/humidity
/myhome/bedroom/luminosity
Similarly for the kitchen:
/myhome/kitchen/temperature
Now, by subscribing to any of these topics, we will receive messages about the status of each specific sensor. But the protocol also allows you to subscribe to the entire branch at once. To receive data from all bedroom sensors in one subscription, you can subscribe to the topic
/myhome/bedroom/#
This structure is convenient for human understanding, but further use of MQTT has shown that it is much easier to use only two branches: one for updating the status of elements and the other for sending commands. But more on that later.
In my project I used Raspberry Pi model B + with Raspbian installed as a platform for openHAB and Arduino MEGA 2560 with Ethernet Shield w5100 installed on it . Also experimented with Arduino Yun - everything is the same, just use YunClient instead of EthernetClient.
We leave out the process of installing openHAB, since This is the subject of many articles. We proceed immediately to the installation of MQTT. Everything is simple here, open the console and install:
sudo apt-get install mosquitto
We reboot and check the operability (when I first installed mosquitto I didn’t want to start at system startup):
sudo shutdown -r now
After reboot:
sudo service mosquitto status
In response should receive:
[ ok ] mosquitto is running.
Now you need to set binding for openHAB. To do this, we perform:
sudo apt-get install openhab-addon-binding-mqtt
Or just copy the org.openhab.binding.mqtt-1.6.2.jar file (current version) to the folder / usr / share / openhab / addons /
Let's move on to setting up openHAB:
sudo nano /etc/openhab/configurations/openhab.cfg
Here we add the following lines:
mqtt:mybroker.url=tcp://localhost:1883
mqtt-eventbus:broker=mybroker
mqtt-eventbus:commandPublishTopic=/myhome/in/${item}
mqtt-eventbus:stateSubscribeTopic=/myhome/out/${item}
We also need two Item, responsible for turning on / off the light in the kitchen:
Switch Kitchen_light1 "Кухня. Свет 1"
Switch Kitchen_light2 "Кухня. Свет 2"
Do not forget to add them to the sitemap at any convenient place. Restart openHAB:
sudo service openhab restart
You can start experimenting! We connect from any device to the MQTT server and subscribe to the topic / myhome / #. Each time the status of any Item changes, we will receive a message in the topic of which the name Item will be indicated, and in the message text - its new status. This is enough for us, let's move on to programming the microcontroller.
The code should look something like this
#include // Ethernet shield
#include // Ethernet shield
#include // MQTT
#define light1_pin 25
#define light2_pin 27
byte mac[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0x12 };
byte server[] = { 192, 168, 1, 11 };
byte ip[] = { 192, 168, 1, 12 };
EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);
unsigned long lastMqtt = 0;
void callback(char* topic, byte* payload, unsigned int length) {
payload[length] = '\0';
Serial.print(topic);
Serial.print(" ");
String strTopic = String(topic);
String strPayload = String((char*)payload);
Serial.println(strPayload);
if (strTopic == "/myhome/in/Kitchen_light1") {
if (strPayload == "OFF") digitalWrite(light1_pin, LOW);
else if (strPayload == "ON") digitalWrite(light1_pin, HIGH);
}
else if (strTopic == "/myhome/in/Kitchen_light2") {
if (strPayload == "OFF") digitalWrite(light2_pin, LOW);
else if (strPayload == "ON") digitalWrite(light2_pin, HIGH);
}
}
void setup() {
Serial.begin(57600);
Serial.println("start");
pinMode(light1_pin, OUTPUT);
digitalWrite(light1_pin, LOW);
pinMode(light2_pin, OUTPUT);
digitalWrite(light2_pin, LOW);
Ethernet.begin(mac, ip);
if (client.connect("myhome-kitchen")) {
client.publish("/myhome/out/Kitchen_light1", "OFF");
client.publish("/myhome/out/Kitchen_light2", "OFF");
client.subscribe("/myhome/in/#");
}
}
void loop() {
if (lastMqtt > millis()) lastMqtt = 0;
client.loop();
// здесь какой-то другой код по уравлению светом, например, с кнопок или ещё как
if (millis() > (lastMqtt + 60000)) {
if (!client.connected()) {
if (client.connect("myhome-kitchen")) client.subscribe("/myhome/in/#");
}
if (client.connected()) {
if (digitalRead(light1_pin)) client.publish("/myhome/out/Kitchen_light1", "ON");
else client.publish("/myhome/out/Kitchen_light1", "OFF");
if (digitalRead(light2_pin)) client.publish("/myhome/out/Kitchen_light2", "ON");
else client.publish("/myhome/out/Kitchen_light2", "OFF");
}
lastMqtt = millis();
}
}
The missing library can be downloaded here: https://github.com/knolleary/pubsubclient
That's all. I will comment only on the last piece of code. If the lighting is controlled directly through the microcontroller, it is necessary to transfer the new state to openHAB. This can be done immediately after a state change, or once a minute to transfer the state of all controlled loads.
In conclusion, I want to give a link to an amazing article that really helped me figure this out: “Uber Home Automation w / Arduino & Pi”