md
Sonoff, NodeMCU et Domoticz
2017-02-01

L'objectif est d'inclure un commutateur Sonoff de ITEAD utilisant le micrologiciel NodeMCU parmi les dispositifs contrôlés avec le logiciel de domotique Domoticz. C'est la suite logique de deux textes :

Il faut modifier le script, sonoff_01.lua de Michael Andresen (captain-slow.dk) qu'on avait installé. Voici la nouvelle version, nommée sonoff_02.lua.

-- Replacement NodeMCU firmware for ITEA Sonoff -- By Mikey (Michael Andresen) at captain-slow.dk -- URL: http://captain-slow.dk/2016/05/22/replacing-the-itead-sonoff-firmware/ -- Sonoff_02.lua -- Modified to use Sonoff in Domoticz. -- MQTT Client Gateway must be installed in Domoticz Hardware, and -- Publish Topic must be set to "out" which corresponds to Flat -- URL: http://sigmdel.ca/michel/ -- This file does not need to be edited -- user defined parameters are in config.lua ---------------------------------------------------------------- dofile('config.lua') deviceID = 'sonoff_'..DomoticzIdx topicToDomoticz = "domoticz/in" topicFromDomoticz = "domoticz/out" messageToDomoticz = '{ "idx" : %s, "nvalue" : %d }' -- Sonoff connections -- Function GPIO NodeMCU -- Button 0 3 -- Relay 12 6 -- Green LED 13 7 -- Spare (pin 5) 14 5 -- NodeMCU index of pin attached to the relay -- HIGH closes relay, LOW opens relay relayPin = 6 -- NodeMCU index of pin attached to button (with internal pullup enabled) -- Normally open = 0, closed = 1 buttonPin = 3 -- NodeMCU index of pin attached to green LED -- LOW drives LED ON, HIGH drives LED OFF mqttLed = 7 -- Timers -- 0 = WiFi status + mqtt connect -- 1 = MQTT offline -- 2 = Free -- 3 = Free -- 4 = Free -- 5 = MQTT activity -- 6 = Button debounce -- Setup WiFi wifi.setmode(wifi.STATION) wifi.sta.config (SSID, PSK) -- Pin which the relay is connected to gpio.mode(relayPin, gpio.OUTPUT) gpio.write(relayPin, gpio.LOW) -- Connected to switch with internal pullup enabled buttonDebounce = 250 gpio.mode(buttonPin, gpio.INPUT, gpio.PULLUP) -- MQTT led -- LOW drives LED ON, HIGH drives LED OFFp gpio.mode(mqttLed, gpio.OUTPUT) gpio.write(mqttLed, gpio.HIGH) -- Blink the green led to indicate MQTT activity 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 -- Setup and connect MQTT client 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) -- Pin to toggle the status buttondebounced = 0 gpio.trig(buttonPin, "down",function (level) if (buttondebounced == 0) then buttondebounced = 1 tmr.alarm(6, buttonDebounce, 0, function() buttondebounced = 0; end) --Change the state 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) -- Update status to MQTT 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 -- On publish message receive event m:on("message", function(conn, topic, data) --mqttAct() --print("Received:" .. topic .. ":" .. data) t = cjson.decode(data) --for k,v in pairs(t) do -- print(k,v) --end --print("idx: "..t["idx"]) --print("nvalue: "..t["nvalue"]) 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 -- do not call mqtt_update, this is from Domoticz - it is updated end end ) -- Subscribe to MQTT 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() -- run the subscription function end) end end)

Voici le fichier de configuration, config.lua, qui est invoqué au début de sonoff_02.lua. Ce fichier contient les seuls éléments devant être modifiés.

-- User defined parameters SSID = "yourWiFiSSid" PSK = "yourWiFiPassword" mqttBroker = "192.168.1.30" mqttUser = "" mqttPass = "" DomoticzIdx = "12"

Enfin voici le très court script init.lua qui est automatiquement exécuté quand le ESP8266 est mis sous tension ou lorsqu'il est remis à zéro.

dofile('sonoff_02.lua')
Il ne fait que lancer le script principal.

Initialement, on ne téléverse pas ce dernier fichier. On se contente de modifier les paramètres dans config.lua puis de téléverser les deux scripts et d'exécuter 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
On peut alors tester avec Domoticz que l'on peut contrôler le relai du Sonoff avec le logiciel de domotique et que ce dernier reflète l'état du commutateur lorsqu'on utilise l'interrupteur du Sonoff.

Lorsqu'on est satisfait des résultats avec le script sonoff_02.lua, on peut téléverser init.lua et puis redémarrer le commutateur Sonoff pour vérifier que tout fonctionne même après une remise sous tension.