How do Sonoff devices work?

A while ago Jan Almeroth have done excellent research on how Sonoff devices operate. Thanks to his (and many others’) work, projects like SonOTA are now possible. I’ll try to summarize the information in this article.

1. Overview

It appears that sonoffs areIoTgocompatible devices.IoTgo platform was created by Itead and aims to facilitate easier integration between IoT devices and Applications.It mainly consists of three parts:

  1. Devices ⇔ Server (left part) – devices connect to the server via HTTP/WebSocket, register and update their parameters. The server can send control commands using push notifications (via WebSocket);
  2. Apps ⇔ Server (right part) – IoTgo Apps use server gather information about devices (+their status) and control them;
  3. Web interface ⇔ Server (not shown) – used for device management;

IoTgo System Architecture

The server persists device/app information in a database and plays a mediation role between devices and apps.

The WebSocket communication channel between IoTgo server & devices can be virtually split into two parts:

1) Server side – responds to device’s requests. Currently it supports 4 methods:

  • register – registers a device to the system, saves details in a database and returns some configuration parameters
  • query – used by devices to query parameters like timers, switch state etc.
  • update – used by devices to send their actual state like switch state, sensor data etc.
  • date – used by devices to obtain the current date/time in ISO8601 format

2) Client side – receives remote commands from Apps via the IoTgo Server. As far as I know sonoffs support at least these two commands:

  • update – used by the server to set switch state (on/off) or set timers
  • upgrade – informs the device that updated firmware is available. The request contains download links. The device will download specified binaries and will perform auto update. This is the so called OTA.

It seems that Itead had extended the IoTgo platform with a device dispatch hook. They’ve added an intermediate server (let’s call it a Dispatch Server or DS) that redirects sonoffs to the actual IoTgo server. This gives them the opportunity to perform device load balancing based on geo-location.

So the initial configuration workflow looks like this:

1) eWeLink points the sonoff to a DS
2) sonoff connects to the DSvia HTTPS to obtain the address/port of IoTGO server
3) DS considers geo-location based on sonoff’s IP and returns address/port of regional IoTGOserver
4) sonoff establishes a WebSocket connection with the specifiedIoTGOserver where it registers itself

2. Detailed information

2.1 Initial configuration (pairing)

When you hold the button for more than 7 seconds the sonoff enters configuration mode:

1) Enters AP mode
2) Creates WiFi network ITEAD_10000xxxxx with password 12345678
3) Binds to 10.10.7.1
4) Enables DHCP
5) Enables a few HTTP endpoints:

  • http://10.10.7.1/device – a GET request will retrieve device’s information:

deviceid & apikey are pre-configured and unique to each sonoff

  • http://10.10.7.1/ap – a POST request with JSON payload will set the initial configuration:

A normal response will be:

The device will restart.

2.2 Receiving information about IoTGO server

The sonoff issues a POST request on https://SONOFF_SERVER_DS/dispatch/device with JSON payload:

Based on client’s IP the server will return the IP/Port of regional IoTGO server:

2.3 Device registration

The sonoff will try to establish a WebSocket connection (secured) the specified IoTGO server. Then it issues the register command:

IoTGO server registers the device and responds with some configuration parameters:

I supposehbInterval specifies the heartbeat interval. Some sonoff models report their presence but not all of them. I’ve played with different values but it haven’t changed anything.

According to IoTgo specifications device id should include a number representing device’s type.

01  –  “smart switch relay” (our device)
02  –  “smart light” (another product of the same company, which behaviors the same, for example Slamper)
03  –  “temperature and humidity sensor”

Sonoffs seem not to include that information (the id is always starting with 1)

2.4 Initial queries

Upon registration sonoffs will make a few additional requests:

1) Get current date/time

2) Report its parameters

If a sensor was connected to TH10/TH16 the sonoff will send separate update request, containing current temperature / humidity values:

Sonoff Dual has different notion for describing switches. It returns an array of switch-outlet pairs:

3) Query for timers

From this point on your sonoff is ready to serve requests.

3. Behavior

My observations show the following claims:

1) Most sonoff models will periodically report its presence via an update command:

I’m not sure if they strictly obey the hbInterval configuration parameter.

2) It seems that sensor’s data (TH models) is sent only in two cases: after registration and after a value (temp / humidity) have changed. The values are sent via separate update command:

I could not find a way to force the sonoff to report sensor’s values (via query command).

3) The sequence field contains current date/time in Unix epoch format

4) Sonoff Dual does not report its MAC address

4. Controlling sonoff devices

After successful registration the server can send the following commands:

1) update – used to set the switch on/off or to set a local timer

1.1) Controlling the switch

You have to specify parameter “switch” and its value: “on” or “off”:

The sonoff will respond with:

Observe thatsequence field contains the value from the initial request.

1.2) Setting up timers

Sonoffs support local timers i.e. they will be executed by sonoff itself and not commanded from IoTgo server. The Timer object format is:

To setup timer once, you should send type=”once” and at=time in ISO format. To setup repeat timer, send type=”repeat” and at=time in CRON format (e.g. “* * * * * *”).

Then you send it via update command:

where d.timers is array of timer objects.

Here is a real create timer request:

As you can see there are a few differences – I’ll try to test it when I get a moment.

2) upgrade

The server can tell the sonoff to upgrade itself (should be authorized in eWeLink by the user i.e. it is not automatic for now). The packet will be similar to:

This is the magic OTA (over-the-air) update. The device will download firmware images and will update itself. Interestingly sonoffs do not verify checksum nor server’s certificate. That allowed the community to perform custom firmware replacement via the original OTA mechanism – SonOTA. Unfortunately that have changed as of FW version 1.6.

In the next article I’ll show you how to trick your sonoffs to use a local IoTgo server.

Leave a Reply

Your email address will not be published. Required fields are marked *

*