Hi All
Noob here.
I made good progress in getting my MQTT working on OpenHAB on RPi3 and have a few ESP8266’s communicating and operating well.
I did however reach a stumbling block when it comes to the updating of my Switches in the GUI should the status of the item be changed from another external source (Node-RED etc.)
This ver simple example should explain what I am facing:
My MQtt Switch 2 Status will update perfectly when the device status changed, whether from using the “MQTT Switch 2” or external MQTT publisher but my switch status would only change when the item state has been changed within OpenHAB by clicking on it.
mqtt.items:
Switch mqttsw2 "MQTT Switch 2" (all,mqtt) {mqtt=">[broker:/ESP1/OUT-D5:command:ON:1],>[broker:/ESP1/OUT-D5:command:OFF:0],<[broker:/ESP1/confirmOUT-D5:state:default]"}
String mqttsw2s "MQtt Switch 2 Status [%s]" (all,mqtt) {mqtt="<[broker:/ESP1/confirmOUT-D5:state:default]"}
mqtt.sitemap:
sitemap mqtt label="MQTT-Test"
{
Frame label="MQTT"
{
Switch item=mqttsw2 label="MQTT Switch 2 (raw)"
Text item=mqttsw2s
}
}
This is the Arduino Code for this example ESP8266 that I am testing with:
//ItKindaWorks - Creative Commons 2016
//github.com/ItKindaWorks
//
//Requires PubSubClient found here: https://github.com/knolleary/pubsubclient
//
//ESP8266 Simple MQTT light controller
#include <PubSubClient.h>
#include <ESP8266WiFi.h>
//EDIT THESE LINES TO MATCH YOUR SETUP
#define MQTT_SERVER "192.168.0.123"
const char* ssid = "SSID";
const char* password = "******";
//LED on ESP8266 D5 GPIO14
const int lightPin14 = 14;
const int lightPin2 = 2;
char* lightTopic = "/ESP1/OUT-D5";
// Callback function header
void callback(char* topic, byte* payload, unsigned int length);
WiFiClient wifiClient;
PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);
void setup() {
//initialize the light as an output and set to LOW (off)
pinMode(lightPin14, OUTPUT);
digitalWrite(lightPin14, LOW);
//initialize the light as an output and set to LOW (off)
pinMode(lightPin2, OUTPUT);
digitalWrite(lightPin2, LOW);
//start the serial line for debugging
Serial.begin(115200);
delay(100);
//start wifi subsystem
WiFi.begin(ssid, password);
//attempt to connect to the WIFI network and then connect to the MQTT server
reconnect();
//wait a bit before starting the main loop
delay(2000);
}
void loop(){
//reconnect if connection is lost
if (!client.connected() && WiFi.status() == 3) {reconnect();}
//maintain MQTT connection
client.loop();
//MUST delay to allow ESP8266 WIFI functions to run
delay(10);
}
void callback(char* topic, byte* payload, unsigned int length) {
//convert topic to string to make it easier to work with
String topicStr = topic;
//Print out some debugging info
Serial.println("Callback update.");
Serial.print("Topic: ");
Serial.println(topicStr);
//turn the light on if the payload is '1' and publish to the MQTT server a confirmation message
if(payload[0] == '1'){
digitalWrite(lightPin14, HIGH);
client.publish("/ESP1/confirmOUT-D5", "Light On");
}
//turn the light off if the payload is '0' and publish to the MQTT server a confirmation message
else if (payload[0] == '0'){
digitalWrite(lightPin14, LOW);
client.publish("/ESP1/confirmOUT-D5", "Light Off");
}
}
void reconnect() {
//attempt to connect to the wifi if connection is lost
if(WiFi.status() != WL_CONNECTED){
//debug printing
Serial.print("Connecting to ");
Serial.println(ssid);
//loop while we wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
//print out some more debug once connected
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
//make sure we are connected to WIFI before attemping to reconnect to MQTT
if(WiFi.status() == WL_CONNECTED){
// Loop until we're reconnected to the MQTT server
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Generate client name based on MAC address and last 8 bits of microsecond counter
String clientName;
clientName += "esp8266-";
uint8_t mac[6];
WiFi.macAddress(mac);
clientName += macToStr(mac);
//if connected, subscribe to the topic(s) we want to be notified about
if (client.connect((char*) clientName.c_str())) {
Serial.print("\tMTQQ Connected");
client.subscribe(lightTopic);
}
//otherwise print failed for debugging
else{Serial.println("\tFailed."); abort();}
}
}
}
//generate unique name from MAC addr
String macToStr(const uint8_t* mac){
String result;
for (int i = 0; i < 6; ++i) {
result += String(mac[i], 16);
if (i < 5){
result += ':';
}
}
return result;
}
Any help would be greatly appreciated!