Playing with cheap IoT devices

Introduction

It is now possible to buy small WiFi enabled computers for less than a cup of coffee.  These devices have many uses thanks to their size and ability to run custom code.  This page will contain details of projects I undertake. All work is done on Linux (Ubuntu 17.10).  So far it focuses on BroadLink and Espressif ESP8266 based designs.  The goal is to use machine learning to optimise things in my flat, e.g. predicting what time I'll be home and setting the heating appropriately.

Hysen HY02B05H (BroadLink) thermostat/heating controller

This mains 16A thermostatic and timer switch is supposed to be an "end-user" product. It by far the most expensive I bought at £20.  However, it needed to be functional out-of-the-box and presentable and overall I consider it worth the cash.  It fits onto a standard single gang pattress box.  It looked fairly deep so I bought a 50mm box, but with hindsight suspect a slimmer (say 40mm) box would fit and look neater.  Inexplicably, the supplied plate screws are not the standard size!


Chinglish instructions with a link to both iOS and Android mobile applications are supplied. I used the Android app on an old phone to setup and test the device (old phone used because I noted that the app uses the phone's IMEI as an identifier, which I think presents an unnecessary vulnerability).  Before ordering I had already found python code, python-broadlink by Matthew Garrett, and intended to use that as the basis for experiments on Linux and eventually create a nice web interface.

The Python-Broadlink code can discover the device on the local network and authenticate it.  However, device specific features are not currently handled and so must be reverse engineered.  It should also be possible to load the BroadLink (closed source) binary library inside an emulated Android, however I have not explored this fully.  
Another issue with this device is that the output is switched mains (220v AC), whereas the boiler control logic is 24v DC.  As a temporary fix I have add a small Omron MY2N relay in a fire retardant box next to the boiler.  
These two frustrations prompted me to develop a home brew solution and this is partly reflected below.

ESP8266 Development Board (NodeMCU)

The ESP8266 is a small ARM-based SoC (system on a chip) with WiFi capability.  The cheapest practical option seems to be the ESP-01 module made by AI-Thinker and has its own section below.  However, this section focuses on my favourite incarnation, which costs is more expensive at £2.40 but has extra useful features like a built in USB-serial chip (QinHeng Electronics HL-340 for mine) for easy flashing, more IO pins and user button.  Basically it is better for quick experiments and the one I've found most fun!

NodeMCU firmware installation

The first job after receiving the board is to install some firmware.  I chose NodeMCU, an open source project to provide a Lua script based interactive firmware [github , documentation].  Due to all the extra options available it is best to use the NodeMCU build service to create a firmware image containing just what you want, rather than filling up the limited (4MB in my case) flash.  This will give you an up to date firmware image, e.g. nodemcu-1.5.4.1-final-7-modules-2017-11-21-20-30-42-float.bin. 
To flash the image using Linux you can use the python-based Espressif esptool, available either directly from github or from pip package esptool (i.e. do pip install esptool).  Of course, you need python installed to use this.  Then, assuming your USB cable is connected and the corresponding serial port created is /dev/ttyUSB0 do:
python /path/to/esptool.py -p /dev/ttyUSB0 write_flash -fm dio 0x00000 nodemcu-image.bin
If all goes well then 30s-1min later (depending on the size of your firmware) your device will be ready.

Lua script on NodeMCU

After the firmware has installed and you reset the device open a terminal program (like gtkterm) at baud 115200.  You can then play with the Lua examples.  For example, connect to an existing WiFi network with:
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","password")

Then you can start a simple webserver and test it with the browser on your PC:
  

AI-Thinker ESP-01 (ESP8266) module

This small module has all the essentials needed for a low powered WiFi device- an ESP8266, PCB antennae and flash memory chip.  It costs around £1.60 posted.  It does not have USB to serial adapter on the board so an external one is needed.  I have used a Prolific Technology, Inc. PL2303.  Note that the module needs 3.3v power not 5v.  It seems 5v tolerant for logic (but I am not liable if you melt yours using 5v signals!).
I am experimenting with a ready made "WiFi relay" that uses the AI-Thinker module.  It is made by "LC Tech" and shown below.  The whole thing cost around £3 and handily takes 5v power (stepped down to 3.3v for the ESP8266) so you can power it directly from the USB connection.
It is loaded with AI-Thinker firmware, which supports AT commands detailed here.  To connect it to an WiFi router, for example, you connect via serial (9600 baud for mine but apparently the default varies!) and issue:
AT+CWMODE=1
AT+RST
AT+CWJAP=<ssid>, <password>
Then start a TCP server on port 8080 and get the IP address:
AT+CIPMUX=1
AT+CIPSERVER=1,8080
AT+CIFSR
You can now connect to this IP address and issue commands.  For example, the LC Tech relay board can be controlled by netcat'ing the appropriate hex codes from the Ubuntu shell: 
# switch on
echo -e '\xA0\x01\x01\xA2'  | nc -q 1 192.168.0.37 8080
# switch off
echo -e '\xA0\x01\x00\xA1'  | nc -q 1 192.168.0.37 8080
(Long term it is more convenient to lookup the hostname and use that)
The problem with the AI-Thinker firmware is that it doesn't remember to start the TCP server when the chip gets reset.  This makes it rather inconvenient!  It would be possible to do a work around, but I decide to flash nodeMCU onto the AI-Thinker module as it seems more flexible.  I may also try the Arduino core firmware later.

NodeMCU running on AI-Thinker based relay board

The relay can be controlled from within nodeMCU/Lua by writing to the serial, like below.  Note that first it is necessary to switch the baud rate to 9600.
-- must switch to 9600 baud to control relay
uart.setup(0,9600,8,0,1)
-- switch on
uart.write( 0, 0xA0,0x01,0x01,0xA2)
-- switch off
uart.write( 0, 0xA0,0x01,0x00,0xA1)
The cool thing now is that this can easily be wrapped in a web interface so the relay can be controlled from a browser.  To do this I modified some code I found online- download the modified code here.  If you save it as init.lua on the module then it will run when the device powers up, so your web switch is ready to use without intervention!


ċ
nodeMCU-web-relay.lua
(1k)
Peter Windridge,
Nov 22, 2017, 3:31 PM
Comments