I got two sonoff wifi controlled switches to dabble with home automation.

Update: now moved to Sonoff-Tasmota, the latest version of Theo Arends’s firmware.  I had issues building it in Aduino, so have also switched to platform.io.  But the pre-build binary also works just fine for most applications.

These are some notes on use with MQTT when you have the ‘arendst‘ firmware on them.  I started as described in the wiki linked from the github page, building in my wifi AP name(s) and passwords(s) at compile time, then flashed the units using a 3.3v serial usb adaptor (make sure you supply enough 3.3v current).

I was controlling the switches primarily with wemo protocol, but wanted to be able to report their state.  To do this, I installed mosquitto on my RPi3 with ‘sudo apt-get mosquitto’.  This both installed and ran up mosquitto, and i was ready to roll.  Then, through the web interface of the arendst fimware, I renamed the devices to appropriate names (trevor and graham 🙂 ).

Note: Turns out that the MQTT ‘Client ID’ entry controls the wemo device name.

I also configured the MQTT server they would talk to.

The devices publish to ‘stat/<name>/POWER’ every time they change state, and to ‘tele/<name>/POWER’ regularly (values of ON and OFF).

Writing 0 or 1 to ‘cmnd/<name>/POWER will control the switch.

So to capture the states in  Node-Red, I subscribe to ‘stat/#’ and ‘tele/#’, then run some simple js code:

var state = global.get('state') || {};
var items = msg.topic.split('/');
if ((items[0] === 'stat') || (items[0] === 'tele')){
 if (items[2] === 'POWER'){
 state[items[1]] = msg.payload;
 node.warn(util.inspect(state));
 global.set('state', state);
 }
}

return msg;

which creates/populates a ‘state’ object in global with properties called the same as the device names, which contain the values received over MQTT.

The below flow embodies this, and also has a ui switch for my light called ‘trevor’:

sonoffflow

[{"id":"39b5710a.df73be","type":"mqtt in","z":"69f54fb.6c12cb","name":"","topic":"stat/#","qos":"2","broker":"336ce056.13623","x":91.8367919921875,"y":560.7986145019531,"wires":[["421e0eb4.baac5"]]},{"id":"3a4c6448.55022c","type":"debug","z":"69f54fb.6c12cb","name":"","active":true,"console":"false","complete":"false","x":480.8402557373047,"y":563.5347595214844,"wires":[]},{"id":"6970631b.c43acc","type":"debug","z":"69f54fb.6c12cb","name":"","active":true,"console":"false","complete":"false","x":480.8957977294922,"y":606.8889465332031,"wires":[]},{"id":"31e5ae3a.a84a82","type":"mqtt in","z":"69f54fb.6c12cb","name":"","topic":"tele/#","qos":"2","broker":"336ce056.13623","x":91.89227294921875,"y":606.1528625488281,"wires":[["6970631b.c43acc","421e0eb4.baac5"]]},{"id":"421e0eb4.baac5","type":"function","z":"69f54fb.6c12cb","name":"StoreStates","func":"var state = global.get('state') || {};\n\n//var topic = new String(msg.topic); \n\n//node.warn(util.inspect(topic));\n\nvar items = msg.topic.split('/');\n\nif ((items[0] === 'stat') || (items[0] === 'tele')){\n    if (items[2] === 'POWER'){\n        state[items[1]] = msg.payload;\n        node.warn(util.inspect(state));\n        global.set('state', state);\n    }\n}\n\nreturn msg;","outputs":1,"noerr":0,"x":280.8333282470703,"y":562.1250305175781,"wires":[["3a4c6448.55022c","e8346f72.cff36"]]},{"id":"c28a7abc.e2e5d8","type":"ui_switch","z":"69f54fb.6c12cb","name":"","label":"switch trevor","group":"c6aa22af.66ecc","order":0,"width":0,"height":0,"passthru":true,"topic":"cmnd/trevor/POWER","style":"","onvalue":"1","onvalueType":"str","onicon":"","oncolor":"","offvalue":"0","offvalueType":"str","officon":"","offcolor":"","x":714.8264007568359,"y":666.5000305175781,"wires":[["2094eca5.a389b4","fb8dbbb5.725268"]]},{"id":"2094eca5.a389b4","type":"mqtt out","z":"69f54fb.6c12cb","name":"","topic":"","qos":"1","retain":"","broker":"336ce056.13623","x":1080.8265228271484,"y":661.5035705566406,"wires":[]},{"id":"fb8dbbb5.725268","type":"debug","z":"69f54fb.6c12cb","name":"","active":true,"console":"false","complete":"false","x":1058.8299407958984,"y":724.0834045410156,"wires":[]},{"id":"e8346f72.cff36","type":"function","z":"69f54fb.6c12cb","name":"","func":"var items = msg.topic.split('/');\n\nif ((items[0] === 'stat') || (items[0] === 'tele')){\n    if (items[2] === 'POWER'){\n        if (items[1] === 'trevor'){\n            if (msg.payload === 'ON'){\n                return [{payload: '1'}];\n            } else {\n                return [{payload: '0'}];\n            }\n        }\n    }\n}\n\nreturn;","outputs":1,"noerr":0,"x":541.8333892822266,"y":664.3507385253906,"wires":[["c28a7abc.e2e5d8","3011f278.40e83e"]]},{"id":"3011f278.40e83e","type":"debug","z":"69f54fb.6c12cb","name":"","active":true,"console":"false","complete":"false","x":722.8402862548828,"y":618.0833435058594,"wires":[]},{"id":"336ce056.13623","type":"mqtt-broker","z":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"willTopic":"","willQos":"0","willPayload":"","birthTopic":"","birthQos":"0","birthPayload":""},{"id":"c6aa22af.66ecc","type":"ui_group","z":"","name":"Lights","tab":"8b5e7c3d.9e2ee","disp":true,"width":"6"},{"id":"8b5e7c3d.9e2ee","type":"ui_tab","z":"","name":"Home","icon":"dashboard"}]

I store the states so that I can ask Alexa about them using a custom skill (see Home Automation, Node-Red, Alexa, Sonoff).