Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By ridge
#27133 A two week progress update for the openHab <=> mqtt <=> esp8266 project running on a Debian BeagleBone Black.

OpenHAB is stable. The learning curve is steep if you have little or no Java background. There are lots of examples.
No code changes at all required from the posted example.

MQTT: I was running the Mosquitto-3.1 Debian repo version and decided to upgrade to the Mosquitto-1.4.3 version.
The results seem to be worth it. I was getting 'half open' TCP communications sometimes on node startup with the old version. The new version has 2-way communications first time, every time so far...
I did an apt-get purge of the old mosquitto and used this for the new version install. I changed the version number as required. http://www.xappsoftware.com/wordpress/2014/10/27/installing-mosquitto-on-raspberry-pi/

PubSubClient library for the esp8266: My previous setup used the 3 year old knolleary/pubsubclient library. It worked, but the better choice these days is the lmroy/pubsubclient library. https://github.com/Imroy/pubsubclient

The new PubSubClient library only works with the newest versions of ESP8266/Arduino.
I had been holding off updating, but the mqtt pubsubclient left me no choice. I upgraded to Staging version Aug 10, 2015.

The code for the esp8266-12 on the yellow carrier board got an overhaul as well:

Code: Select all/*
 mqtt_openHAB_115_3

 Example program for esp8266-12 on the yellow carrier board.
 Used to interact over local intranet with a mosquitto v1.4.3 server. OpenHAB also running on server computer.
 
 Ver.3  Support mosquitto 1.4.3 and the @lmroy PubSubClient library for esp8266/arduino.
        Implement lmroy's wifi and mqtt initialization within the main loop method.
 Ver.2  Changed mqtt messaging structure to support multiple esp boards addressed by openHAB at different IP addresses
*/

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

ADC_MODE(ADC_TOUT);

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

IPAddress mqttServer( 192, 168, 1, 114 );//Hardcode of mosquitto server IP on local intranet connected computer.
byte IP[]         = { 192, 168, 1, 115 };//Hardcode for this esp8266 node
byte Netmask[]    = { 255, 255, 255, 0 };//Local router info
byte Gateway[]    = { 192, 168, 1, 1 };  //Local router info

WiFiClient   wifiClient;
PubSubClient mqttClient(mqttServer);

long millis_now;         // For non-blocking delay
long millis_prev;        // For non-blocking delay

long LEDredValue = 0;
long LEDgreenValue = 0;
long LEDblueValue = 0;

long lightsensor = 0;
long lightsensor_prev = 0;

int pir = 0;
int pir_flag = 0; 

//----------------------------------------------------------------------------
// Callback function
//----------------------------------------------------------------------------
void mqttCallback(const MQTT::Publish& pub) {
 
 String msgString = pub.payload_string();

 if (String(pub.topic()) == "openHAB/esp_115/RED") {
   LEDredValue = round(msgString.toInt() * 10.2);
   analogWrite(15,LEDredValue);
 }
 if (String(pub.topic()) == "openHAB/esp_115/GREEN") {
   LEDgreenValue = round(msgString.toInt() * 10.2);
   analogWrite(12,LEDgreenValue);
 }
 if (String(pub.topic()) == "openHAB/esp_115/BLUE") {
   LEDblueValue = round(msgString.toInt() * 10.2);
   analogWrite(13,LEDblueValue);
 }
 if (String(pub.topic()) == "openHAB/esp_115/led1") {
  if (msgString == "ON") digitalWrite( 2, 0 );  //red leds are inverted output
  else                   digitalWrite( 2, 1 ); 
 }
 if (String(pub.topic()) == "openHAB/esp_115/led2") {
  if (msgString == "ON") digitalWrite( 0, 0 );  //red leds are inverted output
  else                   digitalWrite( 0, 1 ); 
 }
 if (String(pub.topic()) == "openHAB/esp_115/led3") {
  if (msgString == "ON") digitalWrite( 4, 0 );  //red leds are inverted output
  else                   digitalWrite( 4, 1 ); 
 }
 if (String(pub.topic()) == "openHAB/esp_115/led4") {
  if (msgString == "ON") digitalWrite( 5, 0 );  //red leds are inverted output
  else                   digitalWrite( 5, 1 ); 
 }
 if (String(pub.topic()) == "openHAB/esp_115/led5") {
  if (msgString == "ON") digitalWrite( 14, 0 );  //red leds are inverted output
  else                   digitalWrite( 14, 1 ); 
 }
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void setup()
{
  // ESP-12 yellow carrier board GPIO assignments
  pinMode(A0, INPUT);  // analog light sensor input
  pinMode(2, OUTPUT);  // 00000X  discrete red led position
  pinMode(0, OUTPUT);  // 0000X0  discrete red led position
  pinMode(4, OUTPUT);  // 000X00  discrete red led position
  pinMode(5, OUTPUT);  // 00X000  discrete red led position
  pinMode(14,OUTPUT);  // 0X0000  discrete red led position
  pinMode(16,INPUT);   // PIR sensor
 
  pinMode(15,OUTPUT);  // RGB led red
  pinMode(12,OUTPUT);  // RGB led green
  pinMode(13,OUTPUT);  // RGB led blue
 
  // Initialize GPIO 'inverted' led outputs to off
  digitalWrite(2, 1);  // red leds are inverted output
  digitalWrite(0, 1);  // red leds are inverted output
  digitalWrite(4, 1);  // red leds are inverted output
  digitalWrite(5, 1);  // red leds are inverted output
  digitalWrite(14,1);  // red leds are inverted output
   
  digitalWrite(15,0);  // RGB led red not inverted
  digitalWrite(12,0);  // RGB led green not inverted
  digitalWrite(13,0);  // RGB led blue not inverted

  Serial.begin(115200);
  delay(10);
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void loop()
{
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println();
    Serial.print("WiFi connecting to ");
    Serial.print(ssid);
    Serial.println("...");
    yield();
    WiFi.begin(ssid, password);

    if (WiFi.waitForConnectResult() != WL_CONNECTED)
      return;
      Serial.println("WiFi connected.");
      WiFi.config(IPAddress(IP[0],IP[1],IP[2],IP[3] ), 
                  IPAddress(Gateway[0],Gateway[1],Gateway[2],Gateway[3] ),
                  IPAddress(Netmask[0],Netmask[1],Netmask[2],Netmask[3] ));
      WiFi.mode(WIFI_STA);   
      Serial.println("ESP8266 IP address: ");
      Serial.println(WiFi.localIP());
  }

  if (WiFi.status() == WL_CONNECTED) {
    if (!mqttClient.connected()){
      yield();
      if (mqttClient.connect("espClient_115")){
          mqttClient.publish("esp_115","Hello from esp8266 mqtt client");
          mqttClient.set_callback(mqttCallback);
          mqttClient.subscribe("openHAB/esp_115/#");
          Serial.println("Connected to mqtt server.");
      }
    }

    if (mqttClient.connected()){
     
      yield();
      mqttClient.loop(); // Keep mqtt connection open and allow callbacks to work

      pir = digitalRead(16);  // Read PIR
 
      if (pir == 1 && pir_flag == 0) {
        pir_flag = 1;
        mqttClient.publish("esp_115/pir_sensor", "1");
      }

      if (pir == 0 && pir_flag == 1) {
        pir_flag = 0;
        mqttClient.publish("esp_115/pir_sensor", "0");
      }
     
      millis_now = millis();
     
      if (millis_now > (millis_prev + 5000)){ 
        millis_prev = millis_now;
        lightsensor = analogRead(A0);

        if ((lightsensor > lightsensor_prev + 15) ||
            (lightsensor < lightsensor_prev - 15)){
          char sensor[8];
          lightsensor_prev = lightsensor;
          itoa(lightsensor,sensor,10);  // Integer to string
   
          mqttClient.publish("esp_115/light_sensor", sensor);
        }
      }
    }
  }
}




Somewhat (OK, very) surprisingly with so many changes at one time, everything is working nicely so far.
Time will tell how stable it really is. I now have five esp-12 nodes talking to the openHAB program through the mosquitto mqtt broker for a total of 45 digital I/O points and 5 analog inputs for pennies per point. Things are looking pretty good at the moment for affordable home automation!

I found this to be a good overview for learning the mqtt way: http://www.hivemq.com/mqtt-essentials-wrap-up/
User avatar
By ridge
#27767 Another update! :)

I have six nodes total running 24/7 on separate wall wart 5 volt cell phone chargers. I snip the ends off of the USB cords, find the ground and 5 volt wires with a multimeter and solder them where the battery pack wires were. Cheap and easy!

Multiple short power outages (summer lightning storms), and possibly interference from my microwave oven uncovered a failure mode I cannot duplicate. The esp8266 was still connected to the WiFi, but the mosquitto broker was dropping and reconnecting two of the six nodes over and over. A power cycle (unplug) of the two nodes cured the issue. I have not seen the issue again, but this code update should detect the issue and reset the nodes automatically.
I also added values in the 'last will and testament' fields for the mosquitto broker to let openHAB know when a node has become available or dropped off line.

All nodes have analog light sensors, pwm control of a RGB led, and multiple ON/OFF digital led's.
Three nodes have pir motion detection sensors.
Three nodes have high power white leds (about 3 watts) for automatic indoor night lighting.
One node has a high power RGB led that displays a different color for each pir that is activated.
All of the logic is performed in openHAB. The esp8266's all have essentially the same code.

After weeks of operation, I will call this setup stable.
The BeagleBone Black has not glitched at all.
OpenHAB is very stable. I often make errors when coding automation "rules" in openHAB. OpenHAB will throw an error for that rule and keep on running the rest of its software stack without a problem.
Mosquitto-1.4.3 has also not glitched at all.

Hopefully, this software update will let the esp8266 nodes recover from whatever the exact failure mode was that I observed.

Code: Select all/*
 mqtt_openHAB_115_5

 Example program for esp8266-12 on the yellow carrier board.
 Used to interact over local intranet with a mosquitto v1.4.3 server. OpenHAB also running on server computer.
 
 Ver. 5  Add full system reset if WiFi communications have become unstable. Add 5 min heartbeat.
 Ver. 4  Add last will and testament for openHAB notification of node health during MQTT initialization.
 Ver. 3  Support mosquitto 1.4.3 and the @lmroy PubSubClient library for esp8266/arduino.
         Implement lmroy's wifi and mqtt initialization within the main loop method.
 Ver. 2  Changed mqtt messaging structure to support multiple esp boards addressed by openHAB at different IP addresses
*/

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

ADC_MODE(ADC_TOUT);

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

IPAddress mqttServer( 192, 168, 1, 114 );//Hardcode of mosquitto server IP on local intranet connected computer.
byte IP[]         = { 192, 168, 1, 115 };//Hardcode for this esp8266 node
byte Netmask[]    = { 255, 255, 255, 0 };//Local router info
byte Gateway[]    = { 192, 168, 1, 1 };  //Local router info

WiFiClient   wifiClient;
PubSubClient mqttClient(mqttServer);

long millis_now;         // For non-blocking delay
long millis_prev1;       // For non-blocking delay
long millis_prev2;       // For non-blocking delay

long mqtt_connect_count = 0;

long LEDredValue = 0;
long LEDgreenValue = 0;
long LEDblueValue = 0;

long lightsensor = 0;
long lightsensor_prev = 0;

int pir = 0;
int pir_flag = 0; 

//----------------------------------------------------------------------------
// Callback function
//----------------------------------------------------------------------------
void mqttCallback(const MQTT::Publish& pub) {
 
 String msgString = pub.payload_string();

 if (String(pub.topic()) == "openHAB/esp_115/RED") {
   LEDredValue = round(msgString.toInt() * 10.2);
   analogWrite(15,LEDredValue);
 }
 if (String(pub.topic()) == "openHAB/esp_115/GREEN") {
   LEDgreenValue = round(msgString.toInt() * 10.2);
   analogWrite(12,LEDgreenValue);
 }
 if (String(pub.topic()) == "openHAB/esp_115/BLUE") {
   LEDblueValue = round(msgString.toInt() * 10.2);
   analogWrite(13,LEDblueValue);
 }
 if (String(pub.topic()) == "openHAB/esp_115/led1") {
  if (msgString == "ON") digitalWrite( 2, 0 );  //red leds are inverted output
  else                   digitalWrite( 2, 1 ); 
 }
 if (String(pub.topic()) == "openHAB/esp_115/led2") {
  if (msgString == "ON") digitalWrite( 0, 0 );  //red leds are inverted output
  else                   digitalWrite( 0, 1 ); 
 }
 if (String(pub.topic()) == "openHAB/esp_115/led3") {
  if (msgString == "ON") digitalWrite( 4, 0 );  //red leds are inverted output
  else                   digitalWrite( 4, 1 ); 
 }
 if (String(pub.topic()) == "openHAB/esp_115/led4") {
  if (msgString == "ON") digitalWrite( 5, 0 );  //red leds are inverted output
  else                   digitalWrite( 5, 1 ); 
 }
 if (String(pub.topic()) == "openHAB/esp_115/led5") {
  if (msgString == "ON") digitalWrite( 14, 0 );  //red leds are inverted output
  else                   digitalWrite( 14, 1 ); 
 }
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void setup()
{
  // ESP-12 yellow carrier board GPIO assignments
  pinMode(A0, INPUT);  // analog light sensor input
  pinMode(2, OUTPUT);  // 00000X  discrete red led position
  pinMode(0, OUTPUT);  // 0000X0  discrete red led position
  pinMode(4, OUTPUT);  // 000X00  discrete red led position
  pinMode(5, OUTPUT);  // 00X000  discrete red led position
  pinMode(14,OUTPUT);  // 0X0000  discrete red led position
  pinMode(16,INPUT);   // PIR sensor
 
  pinMode(15,OUTPUT);  // RGB led red
  pinMode(12,OUTPUT);  // RGB led green
  pinMode(13,OUTPUT);  // RGB led blue
 
  // Initialize GPIO 'inverted' led outputs to off
  digitalWrite(2, 1);  // red leds are inverted output
  digitalWrite(0, 1);  // red leds are inverted output
  digitalWrite(4, 1);  // red leds are inverted output
  digitalWrite(5, 1);  // red leds are inverted output
  digitalWrite(14,1);  // red leds are inverted output
   
  digitalWrite(15,0);  // RGB led red not inverted
  digitalWrite(12,0);  // RGB led green not inverted
  digitalWrite(13,0);  // RGB led blue not inverted

  Serial.begin(115200);
  delay(10);

  millis_prev1 = millis();
  millis_prev2 = millis();
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void loop()
{
  if (WiFi.status() != WL_CONNECTED) {
    Serial.println();
    Serial.print("WiFi connecting to ");
    Serial.print(ssid);
    Serial.println("...");
    yield();
    WiFi.begin(ssid, password);

    if (WiFi.waitForConnectResult() != WL_CONNECTED)
      return;
      Serial.println("WiFi connected.");
      WiFi.config(IPAddress(IP[0],IP[1],IP[2],IP[3] ), 
                  IPAddress(Gateway[0],Gateway[1],Gateway[2],Gateway[3] ),
                  IPAddress(Netmask[0],Netmask[1],Netmask[2],Netmask[3] ));
      WiFi.mode(WIFI_STA);   
      Serial.println("ESP8266 IP address: ");
      Serial.println(WiFi.localIP());
  }

  if (WiFi.status() == WL_CONNECTED) {
    if (!mqttClient.connected()){
      yield();
      //                    ( String id,      String willTopic,  uint8_t willQos, bool willRetain, String willMessage)
      if (mqttClient.connect("espClient_115","esp_115/available",0,               0,              "0")){
          mqttClient.publish("esp_115/available","1");
          mqttClient.set_callback(mqttCallback);
          mqttClient.subscribe("openHAB/esp_115/#");
          Serial.println("Connected to mqtt server.");
          mqtt_connect_count ++;
          if(mqtt_connect_count > 5){   //Something is out of sync somewhere... do a system reset.
            wifiClient.stop();
            wifiClient.flush();
            WiFi.mode(WIFI_OFF);
            WiFi.disconnect(1);
            yield();
            delay(5000);                // Give the router time to recognize disconnected node.
            ESP.restart();             
          }
       }
    }

    if (mqttClient.connected()){
     
      yield();
      mqttClient.loop(); // Keep mqtt connection open and allow callbacks to work

      pir = digitalRead(16);  // Read PIR
 
      if (pir == 1 && pir_flag == 0) {
        pir_flag = 1;
        mqttClient.publish("esp_115/pir_sensor", "1");
      }

      if (pir == 0 && pir_flag == 1) {
        pir_flag = 0;
        mqttClient.publish("esp_115/pir_sensor", "0");
      }
     
      millis_now = millis();
     
      if (millis_now > (millis_prev1 + 5000)){ 
        millis_prev1 = millis_now;
        lightsensor = analogRead(A0);

        if ((lightsensor > lightsensor_prev + 25) ||
            (lightsensor < lightsensor_prev - 25)){
          char sensor[8];
          lightsensor_prev = lightsensor;
          itoa(lightsensor,sensor,10);  // Integer to string
   
          mqttClient.publish("esp_115/light_sensor", sensor);
        }
      }
      if (millis_now > (millis_prev2 + 300000)){      //5 min
        millis_prev2 = millis_now;
        mqttClient.publish("esp_115/available","1");
      }
    }
  }
}



A 12 hour cable TV/internet outage during which the home automation system continued to function as normal reminded me why I like local hosting. ;)
User avatar
By ridge
#27969 So far, so good with the updated esp8266 code.

As an experiment, I installed PiDome home automation software on a Raspberry Pi to see if openHAB and PiDome could both use the same MQTT mosquitto broker running on the BeagleBone Black at the same time.
PiDome has a built-in MQTT broker, but also has a setting to allow communication as a client to an external broker.

The experiment worked fine. Both home automation systems had no problem using mosquitto at the same time.
The more I use MQTT, the less likely it seems I will ever need to use any other transport protocol for embedded device communications.

Vendor lock-in dependencies will not be happily tolerated by most early adopters these days. As a vendor neutral solution, MQTT in the IoT and home automation space will go a long way in allowing snap-in modules from both software and hardware suppliers.
User avatar
By Jram
#28559 I have to admit to having some trouble with this. I have Arduino 1.6.5 and the PubSubClient installed. The examples with PubSubClient compile fine.

Here is the error log:
Arduino: 1.6.5 (Windows 8.1), Board: "Generic ESP8266 Module, Serial, 80 MHz, 40MHz, DIO, 115200, 512K (64K SPIFFS)"

ESP_OpenHAB:30: error: no matching function for call to 'PubSubClient::PubSubClient(IPAddress&)'
ESP_OpenHAB.ino:30:35: note: candidates are:
In file included from ESP_OpenHAB.ino:16:0:
C:\Users\john\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:89:4: note: PubSubClient::PubSubClient(Client&, String, uint16_t)
PubSubClient(Client& c, String hostname, uint16_t port = 1883);
^
C:\Users\john\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:89:4: note: candidate expects 3 arguments, 1 provided
C:\Users\john\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:87:4: note: PubSubClient::PubSubClient(Client&, IPAddress&, uint16_t)
PubSubClient(Client& c, IPAddress &ip, uint16_t port = 1883);
^
C:\Users\john\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:87:4: note: candidate expects 3 arguments, 1 provided
C:\Users\john\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:84:4: note: PubSubClient::PubSubClient(Client&)
PubSubClient(Client& c);
^
C:\Users\john\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:84:4: note: no known conversion for argument 1 from 'IPAddress' to 'Client&'
C:\Users\john\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:20:7: note: PubSubClient::PubSubClient(const PubSubClient&)
class PubSubClient {
^
C:\Users\john\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:20:7: note: no known conversion for argument 1 from 'IPAddress' to 'const PubSubClient&'
C:\Users\john\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:20:7: note: PubSubClient::PubSubClient(PubSubClient&&)
C:\Users\john\Documents\Arduino\libraries\pubsubclient-master\src/PubSubClient.h:20:7: note: no known conversion for argument 1 from 'IPAddress' to 'PubSubClient&&'
no matching function for call to 'PubSubClient::PubSubClient(IPAddress&)'

Any hints gratefully received. Thx