Skip to content

Commit

Permalink
Refactored documentation, still a work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
Xose Pérez committed Nov 22, 2016
1 parent 9e96e0f commit 8154912
Show file tree
Hide file tree
Showing 17 changed files with 337 additions and 140 deletions.
171 changes: 31 additions & 140 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,163 +1,54 @@
# ESPurna

ESPurna ("spark" in Catalan) is a custom C firmware for ESP8266 based smart switches. It was originally developed with the **[ITead Sonoff][1]** in mind. This device has an ESP8266 on board with a 8Mbit flash memory chip, a mains to 3V3 transformer and a relay (GPIO12). It also features a button (GPIO0), an LED (GPIO13) and an unpopulated header you can use to reprogram it.
You can read about this board and firmware in [my blog][2].

![Sonoff board - front view](/images/pinout_front.jpg)

![Sonoff board - back view](/images/pinout_back.jpg)

## Hardware support

* [ITead Sonoff TH][1]
* [ITead Sonoff RF][8]
* [ITead Slampher][9]
* [ITead S20 Smart Socket][10]
* [ITead Sonoff POW][15]
* Tinkerman ESPurna board
ESPurna ("spark" in Catalan) is a custom C firmware for ESP8266 based smart switches. It was originally developed with the **[ITead Sonoff][1]** in mind.

## Features

* **WebServer for configuration** and simple relay toggle with basic authentication
* Communication between webserver and webclient via websockets with CSRF check
* **Asynchronous WebServer for configuration** and simple relay toggle with **basic authentication**
* Communication between webserver and webclient via **websockets** with secure ticket check
* **Flashing firmware Over-The-Air** (OTA)
* Up to **3 configurable WIFI networks**, connects to the strongest signal
* **MQTT support** with configurable host and topic
* Manual switch ON/OFF with button (single click the button)
* AP mode backup (double click the button)
* Manual reeset the board (long click the button)
* Visual status of the connection via the LED
* Support for **automatic over-the-air updates** through the [NoFUSS Library][6]
* **Alexa** integration (Amazon Echo or Dot) by emulating a Belkin WeMo switch
* Support for **automatic over-the-air updates** through the [NoFUSS Library][2]
* Support for **DHT22** sensors
* Support for the **HLW8012** power sensors present in the Sonoff POW
* Support for **current monitoring** through then [EmonLiteESP Library][7] using a non-intrusive current sensor (requires some hacking)
* Support for the **HLW8012** power sensor present in the Sonoff POW
* Support for **current monitoring** through the [EmonLiteESP Library][3] using a non-intrusive current sensor ([requires some hacking][4])
* Command line configuration

## Installing

### Build the web config site

Normally when you flash an ESP8266 you only flash the firmware, like for any other microcontroller. But the ESP8266 has plenty of room and normally it is split into different partitions. One such partition is used to store web files like a normal webserver. In the "Flash your board" section below you'll know how to flash this special partition, but first we will have to build it.

The build process read the HTML files, looks for the stylesheet and script files linked there, grabs them, merges them, minifies them and compresses them. Thus, a single HTML with N linked scripts and M linked CSS files is transformed in just 1 file (index.html.gz). This way the ESP8266 webserver can serve them really fast. Mind the ESP8266 is just a microcontroller, the webserver has a very limited capacity to hold concurrent requests, so few and lighter files are a must.

To build these files we are using **[Gulp][11]**, a build system built in [node.js][13]. So you will need node (and [npm][14], its package manager) first. [Read the documentation][12] on how to install them.

Once you have node and npm installed, go to the 'code' folder and install all the dependencies with:

```
npm install
```

It will take a minute or two. Then you are ready to build the webserver files with:

```
gulp
```

It will create a populate a 'data' folder with all the required files.

### Build the firmware

The project is ready to be build using [PlatformIO][3].
Please refer to their web page for instructions on how to install the builder.

PlatformIO will take care of some of the library dependencies, but not all the required libraries are available in the platform library manager. Some dependencies are thus checked out as submodules in GIT. So the normal initial checkout should be:

```
git clone git@bitbucket.org:xoseperez/espurna.git
git submodule init
git submodule update
```

On linux/max systems the libraries are soft linked to the code/lib folder and you are ready to go. Windows systems do not have this feature so you will have to copy them manually like this (ONLY WINDOWS):

```
cd espurna/code
copy vendor/emonliteesp/code/lib/EmonLiteESP lib/EmonLiteESP
copy vendor/nofuss/client/lib/NoFUSSClient lib/NoFUSSClient
copy vendor/RemoteSwitch-arduino-library lib/RemoteSwitch
```

The Embedis library is the only one required in all cases. The other three are optional at the moment and will only be linked if you set ENABLE_NOFUSS, ENABLE_EMON or ENABLE_RF in the defaults.h file.

Once you have all the code, you can check if it's working by:

```bash
> platformio run -e node-debug
```

If it compiles you are ready to flash the firmware.

### Flash your board

*This section only applies to the Sonoff Basic, but pretty much every other ESP8266-based hardware will be similar.*

The unpopulated header in the Sonoff has all the required pins. My board has a 5 pins header in-line with the button. They are (from the button outwards):

* 3V3
* RX
* TX
* GND
* GPIO14

Last one is not necessary. Mind it's a **3V3 device**, if connected to 5V you will probably fry it. Button is connected to GPIO0 on the ESP8266 chip, so to enter flash mode you have to hold the button pressed while powering on the board, then you can realease it again.

Wire your board and flash the firmware (with ```upload```) and the file system (with ```uploadfs```):

```bash
> platformio run --target upload -e node-debug
> platformio run --target uploadfs -e node-debug
```

You might notice than when you call "uploadfs" target it automatically builds the files (does a "gulp buildfs"). This is done by the hook defined in the extra_script parameter of each environment.

Once you have flashed it you can flash it again over-the-air using the ```ota``` environment:

```bash
> platformio run --target upload -e node-debug-ota
> platformio run --target uploadfs -e node-debug-ota
```

When using OTA environment it defaults to the IP address of the device in SoftAP mode. If you want to flash it when connected to your home network best way is to supply the IP of the device:

```bash
> platformio run --target upload -e node-debug-ota --upload-port 192.168.1.151
> platformio run --target uploadfs -e node-debug-ota --upload-port 192.168.1.151
```

You can also use the automatic OTA update feature. Check the [NoFUSS library][6] for more info.

Library dependencies are automatically managed via PlatformIO Library Manager or included via submodules and linked from the "lib" folder.

## Usage
## Index

On normal boot (i.e. button not pressed) it will execute the firmware. It configures the hardware (button, LED, relay), the SPIFFS memory access, the WIFI, the WebServer and MQTT connection.
* [Supported hardware](docs/Hardware.md)
* [Build and flash the firmware](docs/Firmware.md)
* [Build and flash the filesystem](docs/Filesystem.md)
* [Configuration](docs/Configuration.md)
* [Over-the-air updates](docs/OTA.md)
* [Sensors](docs/Sensors.md)
* [Troubleshooting](docs/Troubleshooting.md)

Obviously the default values for WIFI network and MQTT will probably not match your requirements. The device will start in Soft AP creating a WIFI SSID named "SONOFF_XXXXXX", where XXXXXX are the last 3 bytes of the radio MAC. Connect with phone, PC, laptop, whatever to that network, password is "fibonacci". Once connected
browse to 192.168.4.1. It will then present an authentication challenge. Default user and password are "admin" and "fibonacci" (again). Then you will be presented a configuration page where you will be able to define different configuration parameters, including changing the default password. The same password is used for the WIFI Access Point, for the web interface and for the OTA firmware upload.
## License

You can configure up to three WIFI networks. It will then try to connect to the configure WIFI networks in order of signal strength. If none of the 3 attempts succeed it will default to SoftAP mode again. Once connected it will try to connect the MQTT server. You can also switch to SoftAP mode by double click the on board button or reset the board long clicking it.
Copyright (C) 2016 by Xose Pérez (@xoseperez)

The device will publish the relay state to the given topic and it will subscribe to the same topic for remote switching. Don't worry, it avoids infinite loops.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

You can also use "{identifier}" as place holder in the topic. It will be translated to your device ID (same as the soft AP network it creates).
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

## Troubleshooting
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

After flashing the firmware via serial do a hard reset of the device (unplug & plug). There is an issue with the ESP.reset() method. Check [https://github.com/esp8266/Arduino/issues/1017][4] for more info.

[1]: https://www.itead.cc/sonoff-wifi-wireless-switch.html
[2]: http://tinkerman.cat/adding-rf-to-a-non-rf-itead-sonoff
[3]: http://www.platformio.org
[4]: https://github.com/esp8266/Arduino/issues/1017
[5]: https://github.com/esp8266/Arduino/pull/2251
[6]: https://bitbucket.org/xoseperez/nofuss
[7]: https://bitbucket.org/xoseperez
[8]: https://www.itead.cc/sonoff-rf.html
[9]: https://www.itead.cc/slampher-wifi-wireless-light-holder.html
[10]: https://www.itead.cc/smart-socket-eu.html
[11]: http://gulpjs.com/
[12]: https://docs.npmjs.com/getting-started/installing-node
[13]: https://nodejs.org/en/
[14]: https://www.npmjs.com/
[15]: https://www.itead.cc/sonoff-pow.html
[2]: https://bitbucket.org/xoseperez/nofuss
[3]: https://bitbucket.org/xoseperez/emonliteesp
[4]: http://tinkerman.cat/your-laundry-is-done/
21 changes: 21 additions & 0 deletions docs/Configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Configuration

*TODO*

## First boot

On normal boot (i.e. button not pressed) it will execute the firmware. It configures the hardware (button, LED, relay), the SPIFFS memory access, the WIFI, the WebServer and MQTT connection and whatever other enabled modules.

Obviously the default values for WIFI network and MQTT will probably not match your requirements. The device will start in Soft AP creating a WIFI SSID named "DEVICE_XXXXXX", where DEVICE will be an identifier of your device and XXXXXX are the last 3 bytes of the radio MAC. Connect with phone, PC, laptop, whatever to that network, password is "fibonacci". Once connected browse to 192.168.4.1. It will then present an **authentication challenge**. Default user and password are "admin" and "fibonacci" (again). Then you will be presented a configuration page where you will be able to define different configuration parameters, including changing the default password. The same password is used for the WIFI Access Point, for the web interface and for the OTA firmware upload.

## WiFi configuration

You can configure up to three WIFI networks. It will then try to connect to the configure WIFI networks in order of signal strength. If none of the 3 attempts succeed it will default to SoftAP mode again. You can also switch to SoftAP mode by double click the on-board button or reset the board long clicking it.

## MQTT

Once connected to an access point (so in station mode) the board will try to connect the MQTT server defined.

The device will publish the relay state to the given topic and it will subscribe to the same topic for remote switching. Don't worry, it avoids infinite loops.

You can also use "{identifier}" as place holder in the topic. It will be translated to your device ID (same as the soft AP network it creates).
77 changes: 77 additions & 0 deletions docs/Filesystem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Filesystem

## Introduction

Normally when you flash an ESP8266 you only flash the firmware, like for any other microcontroller. But the ESP8266 has plenty of room and normally it is split into different partitions. One such partition is used to store web files like a normal webserver.

Problem is that, even thou the ESP8266 is a very capable microcontroller it has its limitations and does not handle very well concurrent connections. This is specially true for the *default* webserver that comes with the Arduino Core for ESP8266.

On the other side, to provide a good user experience and work with a comfortable development environment you end up having different files: scripts, stylesheet files, images,... The browser will load the index.html file and quickly request for all those other files and the ESP8266 will easily struggle trying to serve them all.

So the trick here is to squeeze them all into one single compressed file just before uploading it. Luckily, we can do that automatically.

## Web interface build process

The build process reads the HTML files, looks for the stylesheet and script files linked there, grabs them, minifies them and includes them inline, in the same order they are loaded. The resulting single HTML file is then cleaned, further minified and compressed resulting in a single index.html.gz file. This way the ESP8266 webserver can serve it really fast.

To build this file we are using **[Gulp][1]**, a build system built in [node.js][2]. So you will need node (and [npm][3], its package manager) first. [Read the documentation][4] on how to install them.

Once you have node and npm installed, go to the 'code' folder and install all the dependencies with:

```
npm install
```

It will take a minute or two. Then you are ready to build the webserver files with:

```
gulp
```

It will create a populate a 'data' folder with all the required files.

## Images

Along with the HTML, CSS and JS files compressed into the index.html.gz file, the ESPurna firmware uses some images in its web interface. These are the favicon.ico file and a **sprite** for the iPhone style buttons in the interface. Again the idea is to use the minimum possible number of files.

## Flashing it

### Using PlatformIO

[PlatformIO][5] allows the developer to define hooks to be executed before or after certain actions. This is really cool since we can plug one such hook to the *uploadfs* target to automatically build the web interface before uploading it to the board.

This is done by specifying the script with the hook definitions in the *extra_script* option in the platformio.ini file. The script, written in python, binds the target file (spiffs.bin) to a method that executes the gulp command we have seen before.

```
#!/bin/python
from SCons.Script import DefaultEnvironment
env = DefaultEnvironment()
def before_build_spiffs(source, target, env):
env.Execute("gulp buildfs")
env.AddPreAction(".pioenvs/%s/spiffs.bin" % env['PIOENV'], before_build_spiffs)
```

The included platformio.ini file has all this already configured, so you don't have to worry about it. Just type:

```
pio run -t uploadfs -e sonoff
```

(or whatever other enviroment) and you are good to go.

### Using Arduino IDE

First you will have to manually build the data folder contents using gulp (see [instructions above](#web-interface-build-process)).

Then you will have to have the "[ESP8266 Sketch Data Upload][6]" utility installed. Check the instructions in the previous link. The data folder should be a subfolder of the code folder for the tool to find it. Then just execute it and it will upload the data folder contents to your board.


[1]: http://gulpjs.com/
[2]: https://nodejs.org/en/
[3]: https://www.npmjs.com/
[4]: https://docs.npmjs.com/getting-started/installing-node
[5]: http://www.platformio.org
[6]: https://github.com/esp8266/Arduino/blob/master/doc/filesystem.md#uploading-files-to-file-system
49 changes: 49 additions & 0 deletions docs/Firmware.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Firmware

## Build the firmware

The project is ready to be build using [PlatformIO][1].
Please refer to their web page for instructions on how to install the builder.

PlatformIO will take care of some of the library dependencies, but not all the required libraries are available in the platform library manager. Some dependencies are thus checked out as submodules in GIT. So the normal initial checkout should be:

```
git clone https://bitbucket.org/xoseperez/espurna.git
git submodule init
git submodule update
```

On linux/max systems the libraries are soft linked to the code/lib folder and you are ready to go. Windows systems do not have this feature so you will have to copy them manually like this (ONLY WINDOWS):

```
cd espurna/code
copy vendor/emonliteesp/code/lib/EmonLiteESP lib/EmonLiteESP
copy vendor/nofuss/client/lib/NoFUSSClient lib/NoFUSSClient
copy vendor/RemoteSwitch-arduino-library lib/RemoteSwitch
```

This libraries are optional at the moment and will only be linked if you set ENABLE_NOFUSS, ENABLE_EMON or ENABLE_RF from your build flag.

Once you have all the code, you can check if it's working by:

```bash
> pio run -e node-debug
```

If it compiles you are ready to flash the firmware.

## Flash your board

Wire your board (check the [Hardware page](Hardware.md)) and flash the firmware (with ```upload```):

```bash
> pio run -t upload -e sonoff
```

(or any other environment, depending on the board you are woring with).

Library dependencies are automatically managed via PlatformIO Library Manager or included via submodules and linked from the "lib" folder.

Once the firmware is uploaded next step is to upload the web interface. Check how to [build and flash the filesystem](Filesystem.md).

[1]: http://www.platformio.org
Loading

0 comments on commit 8154912

Please sign in to comment.