Hello, I have the SONOFF Basic R4 that I’m trying to control with my own C# application, but so far, I haven’t been successful in doing so.
I have a pump that is connected to the output of my switch through a contactor (I have a snubber on the coil terminals for protection) that I control to help supply water to my apartment when the pressure is really low. So far, everything is working well until it’s time to use the washing machine. I need to start the pump whenever the washing machine draws water (or it errors out), but it’s a hassle to do since it doesn’t draw water at fixed intervals for a fixed duration all the time, which makes creating a scene for this task rather difficult.
Previously, I created a small Arduino project using a water flow sensor to detect water flow and create visual and audible alerts, so I know the washing machine is drawing water and start the pump manually. I can use it now to start the pump using my R4, but I was thinking if I can automate the whole process with something like a NodeMCU board.
Before I ordered anything, I wanted to make sure I could control the R4 using a custom application (that gets its data from the NodeMCU). First, I tried a WebSocket connection (ws://R4-IP:8081), but I kept receiving error 400 at the handshake.
I managed to get the apiKey using NetCapture on my phone when I captured an HTTP request to the SONOFF. It looked like this:
The headers:
http://IP:8081/zeroconf/switches
POST /zeroconf/switches HTTP/1.1
accept: application/json
user-agent: eWeLink_Android/v5.21.1
cache-control: no-store
Content-Type: application/json;charset=UTF-8
Content-Length: 333
Host: IP:8081
Connection: Keep-Alive
Accept-Encoding: gzip
The request:
{
"sequence":"1763689250783",
"deviceid":"xxxxxxxxxx",
"selfApikey":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"iv":"MTU0NzgzMTgzNDgwNjQ5OQ==",
"encrypt":true,
"data":"GG/HPXHUD5HIlke1HBNkWEfP0OgkkNTwrPJp6b8i96C1A+jmqWdtxf5c7Thnv+OQPR/OAeHJsvVdR+g2bWZZNBX3hXDkThBssrDRLvJIrBZUYcRHrNakX0hwfdHRST3fPGgSBlEZ6OjatMPKhRLsS0lSRT9WO1KeyQ30HYk7owY="
}
I tried to replicate the same request by using the selfApikey to encrypt the payload, which I think should be like this:
{
"params": {
"switch": "on"
}
}
I stripped the dashes from the selfApikey to create an AES 256-bit key (while retaining them in the request variable), and encrypted the payload using the key and IV (after converting it back to a normal string from base64). Finally, I sent the request to the HTTP address, and I got an error code 500, BUT the request would return a “success” response from time to time that looks like this:
Success response: {"error":0,"sequence":"1763748541651","deviceid":"xxxxxxxxxx","encrypt":true}
However, nothing happens.
I created the sequence using:
DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()).ToString()
So, my question now is, am I doing something wrong, or is it just not possible this way? My last resort would be a premium subscription to use IFTTT paired with Adafruit IO.
Update 1: I managed to control my device using my computer by applying to be a dev, using the provided appID and appSecret to authenticate (freakin’ confusing) and control the device. I can’t make more than 50,000 requests a month, so no constant status updates every second. I settled for 1-minute status updates and status updates upon pressing the on/off button (it’ll detect the current status and reverse it).
It took me some time to replicate SONOFF’s button look lol.
I think I can use my tokens to communicate with the device using a Wi-Fi-equipped microcontroller board.

