October 25, 2023

Flashing the Sonoff S31 with ESPHome

A friend of mine turned me on to Home Assistant which is a wonderful open source home automation platform. It's privacy forward (a hard requirement for me) and includes energy monitoring. It's got a neat event based system, lots of out of the box integrations and a large community of people making, hacking and helping. But what good is a home automation platform without hardware for home automations?

So one of the first things I got was a wifi outlet. The Sonoff s31. It includes an button, a relay, a current and voltage sensor, and an ESP based controller (Reports of an esp8266 or an esp8285). It connects to Sonoff's servers and has an app. I'm sure that's fine but lets replace it with something that works for us.

sonoff s31 looking surprised af

Update 2024-10-02: I can now also recommend the Sonoff S31 Lite ZB and the S40 Lite ZB which are great Zigbee outlets. I'm honestly unsure of the difference between the two beyond appearance and 1mm of size. They don't have current or voltage sensors and require you to have a Zigbee network in your home.

Overview

We're going to do the following;

  • Take the device apart and flash it with ESPHome
  • Connect it to Home Assistant

We want firmware that talks to our Home Assistant server and nobody else and ESPHome is just the ticket. It's a framework to manage many different kinds of ESP based devices and has support for many of Sonoff's devices including the S31. It's well supported and secure via the Noise Protocol which I find fascinating.

Home Assistant has a ESPHome add-on that makes it easy to manage and configure your devices. This part is nice and straightforward.

A warning about the hardware

You might notice that ESPHome shows the S31 has 3 GPIO pins in use leaving a few more unused. If you want to use them you do so at your own peril. This board is not split into high voltage and low voltage sections as a "non-isolated device". The current monitoring chip needs access to the mains which ties the digital ground to the AC neutral line, often known as "hot ground". This causes the GPIO have a high voltage differential outside of the unit so anything you attach should be considered as dangerous as a live wire. Be espicially careful of your computer, it should not be attached to the S31 when it is plugged in. It might just fry your USB/Serial adaptor but don't take the risk.

Hardware overview

The GPIO pins that are used are;

  • GPIO0 is the button (pulled high, reads 0 when pushed, 1 when not)
  • GPIO12 is the relay and red LED
  • GPIO13 is the green LED (inverted logic, set to 0 to turn on, 1 to turn off)

Connected via serial UART is a cse7766 a current and voltage sensing chip (Produced by "Chipsea" but I can't find info online in english language searches) this provides current voltage, amperage and power readings.

Disassembly and Flashing

To flash ESPHome onto the device we'll need to take it apart and connect to the serial pins on the circuit board. We'll connect these pins to a USB serial adaptor and use ESPHome's web interface to flash the device.

Tools you'll need:

Dear reader, do not have your device plugged in for any part of this operation. You don't need AC power to flash the device and you don't want AC power connected to your computer.

You'll start by pulling off the button. I can use my fingers but I've used a spacer and even a wrench (with some padding) to get leverage. The button is held on by a plastic clips.

sonoff s31 with button removed

Then you then slide the corners off the device.

sonoff s31 with corners sliding off

There are 3 screws to remove and then you can pull the top casing off exposing the circuit boards inside.

sonoff s31 with top casing removed

Note the pinout of the Sonoff's ESP chip.

sonoff s31 with pinout

Next you'll want to connect the USB Serial Adaptor power and Serial pins to the sonoff;

USB Serial Adaptor → Sonoff S31

  • USB GND → S31 GND
  • USB TX → S31 RX
  • USB RX → S31 TX
  • USB 3.3V → S31 VCC

sonoff s31 with test clips

Then hold the button (which connects GPIO0 to ground) and plug in the USB Serial adaptor to your computer. This will boot your device into flash mode. Once you see the blue light blink you can release the button. You can now flash the device with ESPHome.

The easiest way to do this is to navigate to https://web.esphome.io/ with google chrome or chromium or any browser with WebSerial support.

web.esphome.io screenshot

You'll need to select the USB device of your Serial Adaptor and let it flash your device. After flashing you need to reboot your S31 by unplugging it and plugging it back in. Then you can connect to it again and set your wifi credentials.

If it can't connect to your wifi it will boot into AP mode and broadcast it's own SSID. It is possible to connect to that and set WIFI credentials too.

Once it's on your network you can add it to Home Assistant.

Setup Home Assistant and Load Settings

To use the device you'll need to install the Home Assistant ESPHome Add-on which is straightforward. Then you will see a new ESPHome section in the sidebar.

esphome dashboard in home assistant

Then you should see your device appear for adoption. Click adopt and let it setup the device.

home assistant esphome add-on screenshot

Once adopted you'll need to add a configuration for the S31's hardware. You can use the following to add to the default configuration; Make sure to modify your existing logger section.

note In June 2024 Home Assistant changed how the ota configuration works. I've updated it here. note In October 2024 Home Assistant changed how the uart configuration to require parity settings.


# `ota` is part of the default config, no special configuration here
# Only calling it out because it changed and broke the configs for a lot of people.
ota:
  - platform: esphome

# Disable logging
logger:
  baud_rate: 0 # (UART logging interferes with cse7766)

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails, use your own ssid/password here
  ap:
    ssid: "Esphome-Web-XXXX"
    password: "XXXXXX"

captive_portal:
    
uart:
  rx_pin: RX
  baud_rate: 4800
  parity: EVEN # required since 2024-08

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: True
    name: "button"
    on_press:
      # Ensure the switch always operates the relay
      - switch.toggle: relay 
  - platform: status
    name: "status"

sensor:
  - platform: wifi_signal
    name: "wifi_signal"
    update_interval: 60s
  - platform: cse7766
    current:
      name: "current"
      accuracy_decimals: 1
    voltage:
      name: "voltage"
      accuracy_decimals: 1
    power:
      name: "power"
      accuracy_decimals: 1
      id: power
  - platform: integration
    name: "energy"
    sensor: power
    time_unit: h
    state_class: measurement
    unit_of_measurement: kWh
    filters:
      - multiply: 0.001
  - platform: total_daily_energy
    name: "Total Daily Energy"
    power_id: power

time:
  - platform: sntp
    id: the_time

switch:
  - platform: gpio
    name: "relay"
    pin: GPIO12
    id: relay
    restore_mode: ALWAYS_OFF # Modify this as it makes sense for your use case

status_led:
  pin: GPIO13

Click Save and then Install watch the firmware compile and load over the air to your plug. You can now put it back together and plug it in. In Home Assistant you should see the device appear and you can add it to your dashboard and setup automations. I use this device control a large light in my office. It turns on in the morning and off and the end of the work day but only on workdays. Additionally I have a switch that I can use to turn it on and off manually.

home assistant screenshot

Todo

No project is left without a healthy list of todos. Mine is just one, get this working better with the Home Assistant Energy Dashboard. The Total Daily Energy sensor works but it would be nice to have near realtime data.

References

Roborooter.com © 2024
Powered by ⚡️ and 🤖.