Sonoff WiFi Switch – Custom firmware – esp8266 MQTT micro python

[toc]

Introduction

Got a few ITEAD Sonoff WiFi switches to automate my home. Why use the boring software, so I tried to hack the switches. This is a reference manual for me, but quite useful for anyone else if they want to use micropython, mqtt, web server and control the switches.

Required items

Flashing micropython

Make sure the FTDI cable is set to 3V which is very important. Then connect the cable as detailed in the table.

 

Programmer Sonoff (counting from the switch to bottom)
3V3 1
TX 2 (RX)
RX 3 (TX)
GND 4
5

The easiest way to flash the firmware is to use the nodemcu-flasher available. Unfortunately available only for windows. The micropython-flash image esp8266-20170108-v1.8.7.bin can be downloaded from the website. On the config tab add the image. Sometimes it helps to first flash a blank image to the WiFi switch.

 INTERNAL://BLANK

Installing MQTT

Install mosquitto, an open source MQTT broker. It is very easy to install, follow the installation instructions in the link or copy paste the following commands.


wget http://repo.mosquitto.org/debian/mosquitto-repo.gpg.key sudo
apt-key add mosquitto-repo.gpg.key
cd /etc/apt/sources.list.d/
sudo wget http://repo.mosquitto.org/debian/mosquitto-wheezy.list
sudo wget http://repo.mosquitto.org/debian/mosquitto-jessie.list
sudo apt-get update
sudo apt-get install mosquitto

view raw

install_mqtt.sh

hosted with ❤ by GitHub

Programming MQTT

MQTT service is started and running on the machine. I will deal with the basic programming initially. May be later, MQTT will be tightened up with security like auth, base64 encoded message etc.

there are few things to know first hand. That would be, the pins for the physical objects on the switch. There is a relay, led and a button. I want to use the button in case I m not connected to internet to be able to toggle the switch. Led is concealed inside the housing, so doesn’t matter. Relay is very important which will be switching the on off the device that is connect. This pin configuration is specific to micro python firmware. In LUA it might be different.

PIN 12-----------------replay

PIN 13-----------------LED

PIN 0------------Button


from umqtt.simple import MQTTClient
from machine import Pin
import ubinascii
import machine
import micropython
global switch_state
switch_state = True
CLIENT_ID = ubinascii.hexlify(machine.unique_id())
SERVER = 'localhost'
TOPIC = b"home/tv"
#– Pin which the relay is connected to
relayPin = 12
p6 = Pin(relayPin, Pin.OUT) # create output pin on GPIO6
#– Connected to switch with internal pullup enabled
# buttonPin = 0
# buttonDebounce = 0
# p3 = Pin(buttonPin, Pin.OUT) # create output pin on GPIO3
#– MQTT led
mqttLed=13
p13 = Pin(mqttLed, Pin.OUT) # create output pin on GPIO7
p13.low()
def sub_cb(topic,msg):
global switch_state
print((topic, msg))
if msg == b"on":
p13.value(0)
p6.value(1)
switch_state = 1
elif msg == b"off":
p13.value(1)
p6.value(0)
switch_state = 0
def main(server=SERVER):
c = MQTTClient(CLIENT_ID, server)
# Subscribed messages will be delivered to this callback
c.set_callback(sub_cb)
c.connect()
c.subscribe(TOPIC)
print("Connected to %s, subscribed to %s topic" % (server, TOPIC))
try:
while 1:
# micropython.mem_info()
c.wait_msg()
finally:
c.disconnect()
if __name__ == '__main__':
main()

Diving in to the code, there are only three parts that are done. One is the variable that is used around in all functions declared as global to keep the state known at all times. Then connect to mqtt and subscribe to a certain topic. Here I m controlling the switch for the TV system. The call back function will handle if the switch should be turned off or on. This means, just a if loop with toggling the pin 12 where the relay is connected and storing the current action in the global variable.

Securing MQTT:

coming soon

References

  1. http://micropython.org/webrepl/
  2. https://micropython.org
  3. http://captain-slow.dk/2016/05/22/replacing-the-itead-sonoff-firmware/
  4. https://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/pins.html
  5. https://home-assistant.io/blog/2016/08/31/esp8266-and-micropython-part2/
  6. https://github.com/micropython/micropython-lib/tree/master/umqtt.simple