1. Description

This project is an Open Source / Open Hardware minimal approach to build a Web Relay Board.

This Web Relay Board:

  • allows to connect 16 devices allowing to switch on/off Main Power

  • has temperature / humidity sensor

  • captures Téléinfo (France Electricity provider serial consumption data)

  • has REST API

  • has Web Socket API

Caution with 230v. Do not use high current.

The Web Relay board uses HTTP/REST API as interface.
Additionaly, simple Web UI is implemented on top of the REST API.

In practice, the Web Relay is used to manage electric heaters with data wire named fil pilote which is 230v at very low current. The heaters are ochestrated through Node-Red.

This project is part of a wider TiDhome Home Automation project.
Integration WebRelay and Teleinfo

HLA

Integration Teleinfo

grafana teleinfo

Above is an example of a dashboard created as part of Ti-Dhome project and using mostly Teleinfo data produces by the module in this repo, published to Node-Red through Web Sockets and inserted in Prometheus for Grafana use.

2. Specifications

  • 16 relays for 230v main current

  • Wifi

  • REST API

  • WebSockets

  • Reads EDF Téléinfo (France power consumption of the home as serial stream of data)

  • Reads room temperature and humidity

  • Simple web UI

Web Relays UI

3. PCB

PCB available at here

PCB Board ESP8266 WeMos

PCB was printed at DFRobot

4. Integration in Electric panel

Here is an integration of freshly solder PCB into electric panel:

Electric panel Web Relays

5. BOM

Here is list of items to purchase:

Table 1. BOM
Component Price Comment

SainSmart 16 relays

~ 12€

16 relays 12v with 5v data triggers

Wemos ESP8266 or ESP32 with (Wemos-clone pin layout)]

~ 4€

2x 74HC595

~ 0.2€

Shift Register IC DIP-16 Texas (sold by 20)

2x ULN2803

~ 0.12€

(sold by 20)

Optional (for Teleinfo and Temperature sensor

SFH6206

< 1€

Optocoupler for Teleinfo

4.7k resistor

For Teleinfo

HTU21D

< 4€

Temperature sensor

Total

~ 20€

6. API

REST API and websocket API are returning same JSON structure data.

Additionaly, websocket will periodically push changing info such as other user relay switch, Téléinfo and temperature.

Below is API description with examples:

6.1. GET /

Main HTML page display simple button and status:

Web Relays UI

6.2. GET /status

$ curl http://ioteleinfo.local/status | jq .

{
  "system": {
    "chip-model": "ESP32-D0WDQ6",
    "chip-revision": 1,
    "chip-cores": 2,
    "chip-bluetooth": "/BT/BLE",
    "chip-id": "ABCDEFGH",
    "heap": 256412,
    "flash-size": 4,
    "flash-type": "external",
    "time-iso": "2021-02-06T11:44:37Z"
  },
  "sensors": {
    "temperature": 13.12,
    "humidity": 62.5
  },
  "relays": [
    {
      "description": "Ch. Jeux",
      "id": 0,
      "value": 0
    },
    {
      "description": "Bureau",
      "id": 1,
      "value": 0
    },
    ...
    {
      "description": "Hall",
      "id": 15,
      "value": 0
    }
  ],
  "teleinfo": {
    "ADCO": 123456789,
    "OPTARIF": "HC..",
    "ISOUSC": 45,
    "HCHC": 32548297,
    "HCHP": 40260054,
    "PTEC": "HP..",
    "IINST": 5,
    "IMAX": 90,
    "PAPP": 1100,
    "HHPHC": "A",
    "MOTDETAT": 0
  },
  "message": "status"
}

6.3. GET /relays/set?id=X&value=Y

Specify id between 0 and 15:

$ curl -v http://ioteleinfo.local/relays/set?id=1&value=-1
{
   "id": 1, "value":0
}
value is 0, 1 or -1 to switch blindly

6.4. GET /test

Triggers a cycle on/off on each of the relays, with 500ms in between on/off.
Useful to test the websocket reaction of Web UI.

$ curl -v http://ioteleinfo.local/test

6.5. WebSocket

Example at index.html

Time events (from time to time)
{
    "system":{
        "time":"1615034255"
    }
}
Teleinfo events (when some field changes)
{
    "teleinfo":{
        "PAPP":"01140"
    }
}
Temperature events (from time to time)
{
    "sensors":{
        "temperature":13.2,
        "humidity":62.75
    }
}
Relays events (when a switch changes)
{
    "relays":[
        {"id":2,"value":1}
    ]
}

7. TODO

  • create 3D-printed plastic box

8. Iterations

8.1. 0 - Manual Setup ESP8266 board in Arduino IDE

Since this tutorial was written, I made available a Docker Arduino IDE

The development uses simple Arduino IDE with ESP8266 libs.

Follow this guide to setup ESP8266 board in Arduino IDE: https://github.com/esp8266/Arduino

8.1.1. Procedure

  • Import ESP Board into Arduino IDE

Import ESP Boards

  • Load the Libraries for ESP8266

Load ESP libraries

  • Load sample hello app into NodeMCU

In Arduino IDE, select proper board, example:
- Tools/Cards/NodeMCU 1.0 board
- CPU 160 MHz
- <correct USB device>

Create sketch such as the ESP8266 LED

void setup() {
  // initialize digital pin 2 as an output.
  pinMode(2, OUTPUT);
}


// the loop function runs over and over again forever
void loop() {
  digitalWrite(2, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);              // wait for a second
  digitalWrite(2, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);              // wait for a second
}

LED should blink as shown below:

NodeMCU Blink

  • Control a Wifi LED

    • Upload sketch found at ESP8266 LED WIFI with changing Wifi network settings

    • Open Serial Consoleon Arduino IDE

    • Ensure from logs that NodeMCU connected to local Wifi

    • Browse to IP address logged out

    • Click on button to switch led On and Off

NodeMCU Blink Wifi

8.2. 1 - Docker Setup ESP8266 board in Arduino IDE

  • check your tty device. e.g. /dev/ttyUSB2 and match it in Makefile

  • open the Arduino IDE with:

$ make arduino

8.3. 2 - Breadboard relay board

Breadboard video

Using Node MCU for Wifi, there are few remaining constraints:

  • GPIOs are 3.3v and we need 5v: ULN2803 to the rescue

    > ULN2803 is a Darlington array which can be used to translate from 3.3v digital outputs to 5v
  • Not enough GPIOs: 74HC595 to the rescue

    > This components enables use of 3 GPIOs to be used in serial protocol to handle in our case the 16 outputs requires for relay board

Photo (showing wired relay 8 to 15):

Breadboard NodeMCU

Fritzing picture:

Breadboard NodeMCU

8.3.1. Procedure

Few more details

74HC595

74HC595 pins

We will use 3 pins from Node MCU:

Table 2. wiring 74HC595
NodeMCU 74HC595 Comment

gpio13 (D7)

pin 14

data

gpio14 (D5)

pin 11

clock (both 74HC595)

gpio15 (D8)

pin 12

latch (both 74HC595)

Ground and 3.3v plugged obviously.
1st 74HC595 is connected to 2nd 74HC595 from pin 9 to pin 14.
We now have 16 I/Os through 3 ESP8266 pins!
ULN2803

ULN2803 pins

Table 3. wiring ULN2803
74HC595 ULN2803 Comment

8

9

Ground

5v (from power supply)

10

5v not the 3.3v here!

Q0 to Q7

1 to 8

Outputs

8.3.2. Resources

8.4. 3 - Relay board sketch

Now is time for a bit of coding.

8.4.1. How-To

Here is the first Basic sketch

Details of mathematics in next section.

Steps:

  • Uploaded from Arduino IDE

  • Open Arduino console

  • This should log the URL with IP address to connect to Wifi device

  • Connect using browser to see the table where you can switch on and off the relays

8.4.2. Mathematics

Binary computation

We have wired 16 outputs.

The outputs can be mapped to an integer from 0 to 65535.

In Arduino code, this means unsigned int

Let’s see what this means from Byte mathematics

unsigned int relayState = 0;

// state of each relay (switchId is relay number from 0 to 15):
boolean switchState = ((relayState >> switchId) & 1);

// Set relay to 0:
relayState &= ~(1 << relayNb);

// Set relat to 1:
relayState |= (1 << relayNb);
74HC595 - ShiftOut

The 74HC595 ShiftOut states that it is 8 bit and requires two steps operation to shift bits.

// Value is anything between 0 to 65535 representing 16 bits of data I/Os
void switchRelay(int value)
{
   // take the latchPin low:
   digitalWrite(latchPin, LOW);

   // shift out the highbyte
   shiftOut(dataPin, clockPin, MSBFIRST, (value >> 8));
   // shift out the lowbyte
   shiftOut(dataPin, clockPin, MSBFIRST, value);

   //take the latch pin high so the LEDs will light up:
   digitalWrite(latchPin, HIGH);
}

8.5. 4 - Relay board sketch

This iteration is about going deeper into the topic:

  • host static files such as images or CSS files

  • use the SPIFFS ~3MB flash storage

  • better HTML rendering

  • web sockets

8.5.1. Steps

Un coup dans le 'SPIFFS'

To leverage most of the 4MB disk from ESP8266, install plugin:

Usage is pretty simple:

  • create subfolder from sketch folder named 'data'

  • use Arduino IDE / Tools / ESP Sketch Data Upload

  • this takes very long as it uploads ~ 3MB (no matter what)

Sketch details

The sketch can be found under web-relay-advanced folder.

This is a basic sketch from SPIFFS example, with addition of relay web services.

SPIFFS is used only to load SVG images to be displayed on URL /index.htm.

8.6. 5 - ESP8266 - 12E

Switch from NodeMCU to ESP12.

This is aborted story, but it was interesting study! Instead ESP32 might be of better interest.

8.7. 6 - PCB based on NodeMCU WeMos

PCB sample details here

PCB Board ESP8266 WeMos

PCB was printed at DFRobot

8.7.1. PCB - Fritzing

PCB was done using fritzing, the lazy way.

Auto-routing did not work (as often) so all is routed manually.

See Fritzing

Fritzing project can be found here

8.8. 7 - WebSocket

Adding WebSocket code for Arduino and Web UI.

Also updated SPIFFS to LittleFS.

To test,
- open Web UI at http://iotrelays.local/
- *curl http://iotrelays.local/test

This initiate the rolling on/off test on each relay one by one.
The UI should move according to relay current state because it receives web socket events.

8.9. 8 - T/H and Teleinfo

Adding Sensors Temperature, Humidity and France Power (Teleinfo).

The board created in previous iterations supports a T/H sensor HTU21 and the components required for Teleinfo.

Examples:

Complete sources:

Wiring Teleinfo

Teleinfo

8.9.1. References

8.10. 9 - ESP 32

Switching to ESP32 with same form factor as Wemos D1 mini.

ESP 32 pins

Main differences with Wemos ESP8266:

  • Pins are slightly different, but can fit previously created PCB without soldering

  • ESP32 system info

  • Wifi and WebServer libs don’t allow same port WebSocket

  • SoftwareSerial is replaced with HardwareSerial

  • Web UI is enhanced to allow continuous update of power and temperature sensor

Complete sources:

8.11. 10 - Wiring the Heaters using Fil Pilote

This is high-level schema to wire the relays onto the heaters and perform on/off/low heat actions.

Fil Pilote wiring schema:

Fil Pilote

8.12. References

Other interesting links for more specific heater oriented board:

Integration with Node-RED