This article shows another way to interact with the Arduino microcontroller with a universal platform for combining all the home-made "smart" technology into a single
openHAB control
system . On Habré already presented articles about the interaction using
Serial and
HTTP . For my new project, I chose
MQTT , because I have already tried the two previous methods and wanted to try something else.
Let's start ...
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 header (topic) and the text of the message. Connecting to the server gives us two main features: send messages and subscribe to topics of interest to us. At the same time the tree structure of topics works. It is easier to show by example. For sensors that transmit data from the bedroom, you can use the following headings:
/myhome/bedroom/temperature /myhome/bedroom/humidity /myhome/bedroom/luminosity
Similarly for the kitchen:
/myhome/kitchen/temperature
Now, 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 a single subscription, you can subscribe to a 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 the
Raspberry Pi model B + with
Raspbian installed as the platform for openHAB and
Arduino MEGA 2560 with
Ethernet Shield w5100 installed on it. Also experimented with Arduino Yun - all the same, just use YunClient instead of EthernetClient.
')
We leave behind the installation process openHAB, because Many articles are devoted to this. We proceed immediately to the installation of MQTT. Everything is simple here, open the console and install:
sudo apt-get install mosquitto
Reboot and check the operability (when I first installed, mosquitto did not want to start when the system was started):
sudo shutdown -r now
After reboot:
sudo service mosquitto status
In response, should receive:
[ ok ] mosquitto is running.
Now you need to set the binding for openHAB. To do this, perform:
sudo apt-get install openhab-addon-binding-mqtt
Or simply copy the file org.openhab.binding.mqtt-1.6.2.jar (current version) to the / usr / share / openhab / addons / folder
Let's go to openHAB setup:
sudo nano /etc/openhab/configurations/openhab.cfg
Here we add the following lines:
mqtt:mybroker.url=tcp:
We also need two Items that are responsible for turning on / off the lights in the kitchen:
Switch Kitchen_light1 ". 1" <light> Switch Kitchen_light2 ". 2" <light>
Do not forget to add them to the sitemap in 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 you change the status of any Item, we will receive a message, in the topic of which the name Item will be indicated, and in the text of the message - its new status. That's enough for us, let's move on to the programming of the microcontroller.
The code should look something like this. #include <SPI.h> // Ethernet shield #include <Ethernet.h> // Ethernet shield #include <PubSubClient.h> // 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 on only the last piece of code. If the lighting control takes place directly through the microcontroller, then it is necessary to transfer the new state to openHAB. This can be done immediately after the change of state, or once a minute you can transfer the state of all controlled loads.
In conclusion, I want to give a link to an amazing article that really helped me figure it all out:
“Uber Home Automation w / Arduino & Pi”