February 1st, 2017
The objective is to add an ITEAD Sonoff WiFi switch with NodeMCU firmware to
the list of devices controlled with the home automation software
Domoticz. This is the logical conclusion of two
previous blogs:
The Michael Andresen (captain-slow.dk) script, sonoff_01.lua
, previously uploaded to the
switch has to be replaced. Here is the modified version, called
sonoff_02.lua
.
dofile('config.lua')
deviceID = 'sonoff_'..DomoticzIdx
topicToDomoticz = "domoticz/in"
topicFromDomoticz = "domoticz/out"
messageToDomoticz = '{ "idx" : %s, "nvalue" : %d }'
relayPin = 6
buttonPin = 3
mqttLed = 7
wifi.setmode(wifi.STATION)
wifi.sta.config (SSID, PSK)
gpio.mode(relayPin, gpio.OUTPUT)
gpio.write(relayPin, gpio.LOW)
buttonDebounce = 250
gpio.mode(buttonPin, gpio.INPUT, gpio.PULLUP)
gpio.mode(mqttLed, gpio.OUTPUT)
gpio.write(mqttLed, gpio.HIGH)
function mqttAct()
if (gpio.read(mqttLed) == 1) then gpio.write(mqttLed, gpio.HIGH) end
gpio.write(mqttLed, gpio.LOW)
tmr.alarm(5, 50, 0, function() gpio.write(mqttLed, gpio.HIGH) end)
end
m = mqtt.Client(deviceID, 180, mqttUser, mqttPass)
m:lwt("/lwt", deviceID, 0, 0)
m:on("offline", function(con)
ip = wifi.sta.getip()
print ("MQTT reconnecting to " .. mqttBroker .. " from " .. ip)
tmr.alarm(1, 10000, 0, function()
node.restart();
end)
end)
buttondebounced = 0
gpio.trig(buttonPin, "down",function (level)
if (buttondebounced == 0) then
buttondebounced = 1
tmr.alarm(6, buttonDebounce, 0, function() buttondebounced = 0; end)
if (gpio.read(relayPin) == 1) then
gpio.write(relayPin, gpio.LOW)
print("Was on, turning off")
else
gpio.write(relayPin, gpio.HIGH)
print("Was off, turning on")
end
mqttAct()
mqtt_update()
end
end)
function mqtt_update()
if (gpio.read(relayPin) == 0) then
n = 0
else
n = 1
end
msg = string.format(messageToDomoticz, DomoticzIdx, n)
print(topicToDomoticz..msg)
m:publish(topicToDomoticz, msg, 0, 0)
end
m:on("message",
function(conn, topic, data)
t = cjson.decode(data)
if tostring(t["idx"]) == DomoticzIdx then
nval = t["nvalue"]
if nval == nil then
nval = 0
end
print(topicFromDomoticz..'{ "idx" : '..DomoticzIdx..', "nvalue" : '..nval..' }')
mqttAct()
if (nval==1) then
print("Turning relay ON")
gpio.write(relayPin, gpio.HIGH)
elseif (nval==0) then
print("Turning realy OFF")
gpio.write(relayPin, gpio.LOW)
else
print("Invalid nvalue: "..nval)
end
end
end
)
function mqtt_sub()
mqttAct()
m:subscribe(topicFromDomoticz, 0, function(conn)
print("MQTT subscribed to ".. topicFromDomoticz)
end)
end
tmr.alarm(0, 1000, 1, function()
if wifi.sta.status() == 5 and wifi.sta.getip() ~= nil then
tmr.stop(0)
m:connect(mqttBroker, 1883, 0, function(conn)
gpio.write(mqttLed, gpio.HIGH)
print("MQTT connected to:" .. mqttBroker)
mqtt_sub()
end)
end
end)
Here is the configuration script
config.lua
which is called at the
very start of sonoff_02.lua
. This file contains the only elements
that need to be changed to take care of the local context.
SSID = "yourWiFiSSid"
PSK = "yourWiFiPassword"
mqttBroker = "192.168.1.30"
mqttUser = ""
mqttPass = ""
DomoticzIdx = "12"
The very short Lua script init.lua
is automatically executed whenever the ESP8266 is powered up or reset.
dofile('sonoff_02.lua')
All it does is call on the main script.
Initially, do not upload this last script. Instead modify the parameters in
config.lua
and upload it. Then upload and execute
sonoff_02.lua
.
michel@hp:~/Documents/test$ nodemcu-uploader upload init.lua
michel@hp:~/Documents/test$ nodemcu-uploader upload sonoff_02.lua
michel@hp:~/Documents/test$ nodemcu-uploader exec sonoff_02.lua
Test with
Domoticz that it can control the relay of the
Sonoff and use the tactile switch on the Sonoff to test that the state of the
virtual switch in
Domoticz is correctly updated as the
relay is toggled manually.
When satisfied with the results, upload init.lua
. Then cycle the
Sonoff power off and on and check that the switch still works correctly.