Saturday, February 7, 2015

ESP8266 and OpenHAB (Part 2)

ESP8266 and OpenHAB (Part 2)

Improving MQTT Auto-connect 

In the last blog one of the issues I mentioned was the LUA code being 'finicky' about reconnects, I made some updates based on code I found on www.esp8266.com to address this as well as move some of the configurable aspects to variables.

Updated mqtt.lua


 --Init  
 DeviceID="Light_FF_Bath_Ceiling"  
 Broker="192.168.0.32"  
 --GPIO0 is connected to switch with internal pullup enabled  
 gpio.mode(3,gpio.INPUT,gpio.PULLUP)  
 --GPIO2 is connected to LED via resistor, initially off  
 gpio.mode(4,gpio.OUTPUT)  
 gpio.write(4,gpio.LOW)  
 m = mqtt.Client("ESP8266", 180, "user", "password")  
 m:lwt("/lwt", "ESP8266", 0, 0)  
 m:on("offline", function(con)   
    print ("Mqtt Reconnecting...")   
    tmr.alarm(1, 10000, 0, function()  
      m:connect(Broker, 1883, 0, function(conn)   
        print("Mqtt Connected to:" .. Broker)  
        mqtt_sub() --run the subscription function  
      end)  
    end)  
 end)  
 gpio.trig(3, "down",function (level)  
    local PinValue=gpio.read(4)  
    --Change the state  
    if (PinValue==1) then  
      --The read resets the output to 0, put it back  
      gpio.write(4,0)  
      print("Light was on, turn off")    
      m:publish("/openHAB/in/" .. DeviceID .. "/state","OFF",0,0)  
    else  
      gpio.write(4,1)  
      print("Light was off, turn on")    
      m:publish("/openHAB/in/" .. DeviceID .. "/state","ON",0,0)  
     end  
 end)  
 -- on publish message receive event  
 m:on("message", function(conn, topic, data)   
    print("Recieved:" .. topic .. ":" .. data)   
      if (data=="ON") then  
      print("Enabling LED")   
      gpio.write(4,gpio.HIGH)  
      m:publish("/openHAB/in/" .. DeviceID .. "/state","ON",0,0)  
    elseif (data=="OFF") then  
      print("Disabling LED")   
      gpio.write(4,gpio.LOW)  
      m:publish("/openHAB/in/" .. DeviceID .. "/state","OFF",0,0)  
    else  
      print("Invalid - Ignoring")   
    end   
 end)  
 function mqtt_sub()  
    m:subscribe("home/openHAB/out/" .. DeviceID .. "/command",0, function(conn)   
      print("Mqtt Subscribed to OpenHAB feed for device " .. DeviceID)  
    end)  
 end  
 tmr.alarm(0, 1000, 1, function()  
  if wifi.sta.status() == 5 and wifi.sta.getip() ~= nil then  
    tmr.stop(0)  
    m:connect(Broker, 1883, 0, function(conn)   
      print("Mqtt Connected to:" .. Broker)  
      mqtt_sub() --run the subscription function  
    end)  
  end  
 end)  

Improving the feedback of the OpenHAB item graphic


Another issue I had mentioned was my concern that the state of the switch changed in OpenHAB independent of whether the ESP8266 actually processed the request and made the update. One way to improve this is to disable the autoupdate property of the switch item. This will wait until the ESP8266 responds before updating the graphic indicating the light is on or off (unfortunately the toggle switch still changes). So the light bulb picture on the left doesn't change until the ESP publishes the state update but the toggle graphic on the right still updates immediately. So if your broker is off the switch shows on but the light shows off

For reference here is a screenshot when working








To fix this, open the items file that defines the switch
C:\openhab\configurations\items\demo.items

Find the entry for the Light_FF_Bath_Ceiling and add {autoupdate="false"} to the end as so:

 Switch Light_FF_Bath_Ceiling           "Ceiling"           (FF_Bath, Lights)     {autoupdate="false"}  

I find you need to refreh the browser before it works correctly


Open Issues

At this point the basics work pretty well, some major open issues though as far as resiliency:

  • The LUA mqtt code will crash if it tries to send or receive more than one message at the same time. This can happen if the button is pressed at the same time as the every 3 minute status update occurs.
  • Not very resilient to wifi outage (LUA Panic crash)
  • Rebooting the module sometimes doesn't start the code correctly
  • The bootloader outputs to GPIO2 upon boot so you will see the light flicker on reboot.


7 comments:

  1. Is it possible that you showed the configuration openhab.
    I mean specifically the section mtqq:lwt.
    Because it does not work for me.

    Please.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. The first issue happens because NodeMCU try to publish a topic without checking the one earlier finish publishing or not. You will not have this problem with NodeMCU ver 0.9.6.

    GPIO2 outputs some debug information @ boot. That's why you see the blinking LED. No way around this other than avoiding this pin for GPIO purposes.

    ReplyDelete
  4. The first issue happens because NodeMCU try to publish a topic without checking the one earlier finish publishing or not. You will not have this problem with NodeMCU ver 0.9.6.

    GPIO2 outputs some debug information @ boot. That's why you see the blinking LED. No way around this other than avoiding this pin for GPIO purposes.

    ReplyDelete
  5. The first issue happens because NodeMCU try to publish a topic without checking the one earlier finish publishing or not. You will not have this problem with NodeMCU ver 0.9.6.

    GPIO2 outputs serial debug output @ boot. That's why you see the blinking LED. No way around this other than using another pin.

    ReplyDelete
  6. dump lua and look into C using the the Arduino ESP8266 core framework. You use either the Arduino IDE or platformio inside of atom. I prefer the latter.

    ReplyDelete