Sonoff Basic R3 – DIY Switch via HTTP POST of JSON

The latest firmware of the Sonoff BasicR3 Wifi Switch now allows the device to be controlled through the DIY mode built into its firmware (v3.6.0) without any re-flashing with Tasmota firmware or fooling about with jumpers. The only obvious limitation for some people is that the “eWeLink” app and DIY access cannot both be used together; the switch is either in DIY mode or app-control mode. This is not an issue for me as I have no requirement for remote control from outside my LAN and don’t intend to use the app at all. In any case it would not be hard to either use a general purpose HTTP “shortcuts” app (e.g. HTTP Shortcuts!) for control from a phone from my LAN, or to write/run my own web app of a Raspberry Pi. I begin to digress… the point of this post is to make some notes for myself in a way which someone else might find useful (and adding some extra helpful comments). Much of what follows can be found on the web, but there are some holes, and I didn’t find the documentation quick and easy in parts.

Getting into DIY Mode

The key is to get the device into what the Sonoff User Manual calls “Compatible Pairing Mode”. The push button is used in two stages, with long (5s) holds, first to get the LED signalling “..-” and then again to get continuous rapid flashing.

The switch is now acting as a WiFi access point with SSID (name) of “ITEAD-{device_id}”, where device_id will be something like “100136da83”. Connect to this network using the network security key 12345678 and then visit http://10.10.7.1 to access a web page which allows you to enter your own WiFi SSID and password. After a short while, the Sonoff device will have closed its access point and connected to your local network. It is now in DIY mode, and will stay this way when its power supply is disconnected and reconnected. The LED will signal “..”. You can still use the eWeLink app to add the switch to its device list, but this cancels the DIY mode. Also: once in DIY mode, you cannot access http://10.10.7.1, no matter how many times you force the device into making “ITEAD-{device_id}” available. The exception to this is if you power the switch up so it cannot connect to your local network. In which case, the device will eventually (20s) give up trying to connect and become eligible to be forced into Compatible Pairing Mode again.

Finding the Device on the Network

This is not as simple as it might be; it would have been neater if the http://10.10.7.1 web page reported its network name before disappearing. This is a bit messy.

Option 1 is to look at the client list in your router admin web interface. This is likely to require the “advanced” option. In my case, my modem-router does provide a client list, but rather confusingly the client name which is reported, and the MAC address have no obvious connection with the device_id revealed above. The client name is like “ESP_80DD76”, which is the standard way an ESP8266 (etc) chip reports its name, which takes the last 3 bytes of the MAC address prefixed by “ESP_”. If you can see something like this, you’ve found the IP address and can progress to the “Control the Switch” section, below, although you will have to trust that the default port is used (I see no reason why it would not be).

Option 2 is to use an mDNS browser. The essence of mDNS is a service which links device names to IP addresses and other info. MS Windows doesn’t seem to have an easy way to do this, but if you also run a Raspberry Pi it is not hard. Mac users can use Bonjour, there are Android Apps, and linux users (of course) can do as follows anyway. The service/tool for the Pi is Avahi. This should already be up and running, which can be confirmed using “service avahi-daemon status”. The mDNS browser requires the avahi-utils package, which was not on my Pi, but installed with “sudo apt-get install avahi-utils”. The simple command is not “avahi-browse –all –resolve”, which will reveal that the mDNS name is of the form “eWeLink_{device_id}.local”. The port entry will report which TCP port should be used to connect to the device, which should be the default of 8081. The txt entry reveals the device state if in DIY mode, or a base-64 string of gobbledy-gook if in eWeLink app mode.

Option 2a is an Android App. I tried one called Service Browser, but there are other mDNS browsers

Option 3 is to take advantage of the observation that the mDNS name is of the form “eWeLink_{device_id}.local”. This is fine so long as your method of controlling the switch can work with mDNS names, which Postman cannot (at present).

Caveat: there is no guarantee that your router will assign the same IP address. In my case, I operate a router which allows “address reservation”, so that several IoT devices I have get known IP addresses. Unless your router has this feature, beyond tinkering, you will have to resort to using mDNS-aware software. If writing your own in Python, it looks like the “zeroconf” package is suitable for dealing with mDNS names and not worrying about reliable IP addresses.

Control the Switch

I use Postman for manual testing, and Python for anything automated.

The documentation for interacting with the device is fairly good, and can be found at https://sonoff.tech/sonoff-diy-developer-documentation-basicr3-rfr3-mini-http-api/. This includes info on how to perform an OTA (“over the air”) firmware update, control how the device behaves when its power is restored (allowing you to choose whether it starts up off, on, or in its previous state), and to change the WiFI SSID and password which the device connects to, but I’m content with the info, on, off, and pulse options.

Note that all messages to the device are HTTP (not HTTPS) POST operations, with a JSON body (payload). Although the documentation includes “deviceid” in the JSON, this is completely redundant and can be omitted.

Summary:

Operation URL JSON Body
Info http://{{ip_addr}}:{{port}}/zeroconf/info
{
 "data": {}
}
On http://{{ip_addr}}:{{port}}/zeroconf/switch
{
  "data": { 
    "switch": "on" 
  }
}
Off http://{{ip_addr}}:{{port}}/zeroconf/switch
{
  "data": { 
    "switch": "off" 
  }
}
Pulse http://{{ip_addr}}:{{port}}/zeroconf/pulse
{ 
  "data": { 
    "pulse": "on", 
    "pulseWidth": 2000
  }
}

Pulse changes the behaviour of “On” operations; if Pulse is on then an “On” operation will only last for pulseWidth milliseconds, after which the device will turn off again. The maximum duration is 1 hour. The JSON payload for Pulse can omit the “pulseWidth” to enable/disable the feature, but it is not possible to change the pulse duration by only specifying “pulseWidth”.

Leave a Reply

Your email address will not be published.