Alternative to Sonoff S20 EU Type F Smart Socket



Updated 28/03/2018:
The picture I’d originally posted had the wrong solder pad labelled as the Tx pin.
Many thanks to Michael Harwerth for pointing this out. The photo below is now correct.

I’ve been using Sonoff S20’s for a while, both at home in the UK and at our holiday home in Spain. The one thing I don’t like about them is their size and the position of the physical button.
I came across these on eBay recently and decided to order one and have a play with it:

They’re about 20% more expensive than the S20, and I’ve only been able to find them with the EU (Type F) style of fitting. They’re also a bit more difficult to make the electrical connections for flashing them the first time around, but they are considerably smaller than the S20 and the physical switch is in a better position in my opinion.
Here’s what they look like side by side:

The new sockets don’t seem to have a brand name. The info printed on the box calls it a “WiFi Smart Socket W-DE004” but they’re being sold on AliExpress under the names Rondaful and Xingg. Surprisingly, they are cheaper on eBay at the moment.
The instructions claim CE and RoHS compliance, but there are no compliance marks on the device itself, so you can draw your own conclusions from that.
The relay claims to be rated at 10A @ 250VAC, but I don’t think I’d want to put that much current through it (but the same also applies to the S20).
There is also a USB socket on the bottom which is said to provide 2.1A max @ 5V. This isn’t switched on and off by the relay, which makes sense if you want to use it for charging a phone etc.
There’s App that claims to have functionality including timers and Amazon Alexa, Google Home and IFTTT support, but I’ve not tried it.

When the Smart Socket arrived I was hoping that I’d be able to re-flash the firmware via the USB socket on the bottom, but no such luck, so I set about ripping it apart…
You have to remove a plastic cap which sits between the prongs, and I found that the easiest way to do this was to drill a hole in the middle of the cap and use a small screwdriver to lever it out. I’ve not bothered replacing mine, but you could patch-up the hole and refit it if you wanted.
Once removed, two screws are exposed:

When these are removed the front cover lifts off and the circuit board is exposed:

There’s another screw to remove which then allows the circuit board to be eased forwards enough to allow you to get to the small daughter-board that the ESP8266 sits on. Take note of how the switch button is located so you can refit it afterwards.

Unfortunately, the manufacturers haven’t made life easy when it comes to accessing the pins necessary to re-flash the firmware. There’s no 4-pin header and not even anywhere to solder your own in place. The Tx and GPIO 0 connections are fairly easy to access:

but the Rx connection is a bit trickier:

I chopped-up a couple of breadboard patch cables and soldered one end on to the Tx and Rx connections (don’t forget that you connect Tx to the Rx connection on your FTDI programmer and vice-versa).

Hopefully it goes without saying, but DO NOT CONNECT THE SMART SOCKET TO THE MAINS WHEN YOU’RE RE-FLASHING THE FIRMWARE. @marvin7 this means you too! :zap::zap::zap:

I powered the Smart Socket through the USB socket on the bottom, using a USB-A to USB-A Male-to-Male cable. If you don’t have one of these lying around then it’s easy to make one by cutting-up a couple of old USB cables.

To reprogram the device the GPIO 0 connection needs to be shorted to Ground when you apply the 5V power via the USB socket. Once the power has been applied the GPIO 0 to Ground connection can be removed. I used the metal casing of the USB socket as a convenient Ground connection point.
Powering the Smart Socket this way means you don’t have to use the power connection on your FTDI programmer. In theory you should connect the Ground wire from the FTDI to the Ground of the Smart Socket, but as both were connected directly to my PC via USB, I found this wasn’t necessary in my case.

Settings for re-flashing the device using the Arduino IDE with ESP8266 Core installed are documented in the code below. Once the device has been re-flashed and tested (don’t forget to remove and re-apply the USB power first, to power -cycle the ESP after re-flashing) you can de-solder the wires that you connected to Tx, Rx and GPIO 0 then re-assemble. It’s easier to get the button for the physical switch back in place if you hold the socket upside down then you’re refitting the main circuit board.

Using OTA to re-flash the firmware for future upgrades is obviously the way to go, as you wouldn’t want to be disassembling and re-soldering the connections unless you really have no choice.

The Smart Socket uses the following GPIO pins:
GPIO 14 Relay (Active High)
GPIO 13 Blue LED (Active Low)
GPIO 1 Physical Switch (Low when activated)

Because GPIO 1 is also the Tx pin on the ESP8266 it means that you can’t use the serial interface for debugging.

Here’s a simple Blynk sketch that incorporates OTA for future updates.
It’s designed to default to having the connected device switched off after a power outage, for safety reasons. If you want to sync with the previous state as held on the Blynk server instead then it’s a fairly simple modification for you to make.
I haven’t built-in any non-blocking code for the Wi-Fi/Blynk connection, so the physical switch won’t work if you can’t connect to the Blynk server. Once again, this is fairly easy to get around if you feel like tweaking the code.

// Blynk + OTA Code for "W-DE004 WIFI SMART SOCKET" by Pete Kniight

// Arduino IDE Upload Settings
// Board:            "Generic ESP8266 Module"
// Flash Mode:       "DOUT"
// Flash Size:       "1M (No SPIFFS)"
// Debug Port:       "Disabled"
// Debug Level:      "None"
// IwIP Variant:     "v1.4 Prebuilt"
// Reset Method:     "ck"                                                                                                                                
// Crystal Frequency "26 MHz"
// Flash Frequency:  "40 MHz"
// CPU Frequency:    "80MHz"
// Upload Speed:     "115200"

// Blynk App Project Setup:
// Add a Button widget connected to Virtual Pin V1
// Set button widget to Switch mode

// Notes:
// The wifi socket uses GPIO1 for the physical button. This is the hardware TX pin on the ESP8266, so SERIAL OUTPUT FOR DEBUGGING WILL NOT WORK !
// Please do not add Serial.begin() to this sketch !! 

#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Ticker.h>                  // Used to flash the LED in non-blocking mode

char auth[] = "xxxxxxxx";
char ssid[] = "xxxxxxxx"; 
char pass[] = "xxxxxxxx";
char OTAhost[] = "xxxxxxxx";

#define RELAY1    14                 // Wi-Fi Switch relay is connected to GPIO 14 (LOW(0)=0ff, HIGH(1)=On)
#define buttonPin  1                 // Wi-Fi Switch pushbutton is connected to GPIO 1 (LOW(0)=Pushed, HIGH(1)=Released)
#define BlueLED   13                 // Wi-Fi Switch Blue LED is connected to GPIO 13 (LOW(0)=0n, HIGH(1)=Off)

int RELAY1_State;                    // Used to track the current Relay state 
int reading = HIGH;                  // Used in the switch debounce routine
int buttonState=HIGH;                // The current button state is released (HIGH)
int lastButtonState = HIGH;          // The last button state is also relesed (HIGH) - Used in debounce routine
unsigned long lastDebounceTime = 0;  // The time in Millis that the output pin was toggled - Used in debounce routine
unsigned long debounceDelay = 20;    // The debounce delay; increase if you get multiple on/offs when the physical button is pressed

Ticker blueticker;                   // Create and instance of Ticker called blueticker
BlynkTimer timer;                    // Create and instance of BlynkTimer called timer

void setup()
  pinMode(RELAY1, OUTPUT);
  pinMode(BlueLED, OUTPUT); 
  pinMode(buttonPin, INPUT);  

  digitalWrite(RELAY1, LOW);                // Turn the Relay off  
  digitalWrite(BlueLED, HIGH);              // Turn the Blue LED off

  blueticker.attach(0.1, bluetick);         // start blueticker with 0.1 second flashes to indicate we're trying to connect to WiFi/Blynk
  Blynk.begin(auth, ssid, pass);
  while (Blynk.connect() == false) {}       // Dont proceed until we're connected to WiFi/Blynk
  blueticker.detach();                      // Stop the blueticker now we're connected
  digitalWrite(BlueLED, HIGH);              // Turn the Blue LED Off if it was previoulsy On

  Blynk.virtualWrite(V1, 0);                // If the App switch widget is On, turn it Off
  ArduinoOTA.onError([](ota_error_t error) { ESP.restart(); });

  timer.setInterval(10L, CheckButtonState); // Timer to check the physical button every 10ms

void loop()

BLYNK_WRITE(V1)                             // This code is triggered when the App button state changes
  int pinValue = param.asInt();             // Assign incoming value from pin V1 to a variable

  if (pinValue==1)                          // Do this if it was an On command from the Button widget in the App
    digitalWrite(RELAY1, HIGH);             // Turn the relay On
    RELAY1_State = HIGH;                    // Keep track of the relay state
    digitalWrite(BlueLED, LOW);             // Turn the LED On
  else                                      // Else do this if it was an Off command from the Button widget in the App
    digitalWrite(RELAY1, LOW);              // Turn the relay Off
    RELAY1_State = LOW;                     // Keep track of the relay state
    digitalWrite(BlueLED, HIGH);            // Turn the LED Off

void bluetick() // Non-blocking ticker for Blue LED
  //toggle state
  int state = digitalRead(BlueLED);         // get the current state of the BlueLED pin
  digitalWrite(BlueLED, !state);            // set pin to the opposite state

void CheckButtonState()
  reading = digitalRead(buttonPin);         // read the state of the physical switch
  if (reading != lastButtonState)
    lastDebounceTime = millis();            // Start the debounce timer

  if ((millis() - lastDebounceTime) > debounceDelay)
    if (reading != buttonState)             // We get here if the physical button has been in the same state for longer than the debounce delay
      buttonState = reading;

      if (buttonState == LOW)               // only toggle the power if the new button state is LOW (button pressed)
        RELAY1_State = !RELAY1_State;
        if (RELAY1_State==HIGH)             // The physical button press was an instruction to turn the power On
          digitalWrite(RELAY1, HIGH);       // Turn the relay On
          digitalWrite(BlueLED, LOW);       // Turn the LED On
          Blynk.virtualWrite(V1, 1);        // Turn the App button widget On                    
        else                                // The physical button press was an instruction to turn the power Off
          digitalWrite(RELAY1, RELAY1_State);  // Turn the relay Off
          digitalWrite(BlueLED, HIGH);         // Turn the LED Off
          Blynk.virtualWrite(V1, 0);           // Turn the App button widget Off 
  lastButtonState = reading;                // Update lastButtonState for use next time around the loop 

I should add that I don’t normally run Blynk code like this on my devices, I use MQTT and Node-Red to achieve my Blynk connectivity so this has just been bodged together as a quick and dirty example of how to use these Smart Sockets with Blynk. Any constructive criticism and improvements for the benefit of others are welcome, but the code isn’t something I’ll be spending any more time on.

I’ve been using one of these Smart Switches for a couple of weeks now (using my MQTT code) to switch a lamp on and off at scheduled times and it’s working just as well as the S20 that it replaced.
I like the smaller physical size and the fact that the cable doesn’t obstruct access to the physical switch. They look more discreet than the S20 when plugged-in to a wall socket and are easier to use with multi-way adapters as they don’t block the other sockets as badly as the S20.
I’d planned to buy more S20’s for our place in Spain, so I’ve ordered some more of these instead. I’m still hoping to find some with UK fittings as well, but I’ve not had any joy so far. If anyone comes-up with a source for the UK version then please let me know.


Sonoff TH10 'bricks' after flashing with basic Blynk script
My home automation projects built with MQTT and Node Red
Help with project
Remotely controlled Power Socket 250V/10A
Pulse water meter

You have my vote on this, do not flash sonoff’s while connected to mains, but… as long as there is separation from mains… :stuck_out_tongue_winking_eye:


I recently ordered another one of these smart sockets from eBay and the seller sent me a different type which
doesn’t have the USB socket on the bottom and the push switch is on the side rather than the top.

As the product wasn’t as advertised I received a refund, but the seller didn’t want to pay the return postage so I had a different type of smart socket to play with. Here are the details…

The model number is SA-P202A and you can find them on Aliexpress here:

Once again, I didn’t bother trying the dedicated app, instead I set about trying to figure out how to flash it with my own firmware.
Disassembly is very similar to the socket shown above, digging out the plastic cover between the mains pins reveals two screws and when these are removed the cover lifts off.
This version of the smart socket also uses a daughterboard module that contains the MCU, but the module is different to the one in the previous smart socket. In this case the MCU is an ESP8285, but I was only able to find that out because I found a data sheet for the module, which is here:

The easiest way to access the connections needed to flash the smart socket is to remove the whole circuit board from the bottom part of the housing and to do this the two screws that attach the board to the mains pins need to be removed. This needs a fairly slim Phillips/Pozidrive screwdriver and once the screws are removed there are a few very poor quality plastic clips that also hold the circuit board in position. On the one I had some of these clips were broken already, but they don’t really do much anyway and it’s easy to pop the board out.

The 4 connections needed to flash the board are all next to each other on the bottom of the daughterboard. The connections are 2mm pitch, but I found that it’s possible to solder a standard 0.1" 4-pin header on to them without too much difficulty.

A bit of work tracing the connections on the circuit board revealed that this smart switch uses different GPIOs for the LED, switch and relay, but because I had the data sheet for the module it was easy to figure these out.
I actually flashed it as an ESP8266 and it worked fine (I didn’t notice that it said in the data sheet that it was an ESP8285 until afterwards) but as far as I can gather the two MCU are effectively the same except that one has onboard memory and the other needs a separate memory chip.

I used the same code as above, but changed the pin definitions as follows:

#define RELAY1     12
#define buttonPin  13
#define BlueLED     5 

To put the device into flash mode, GPIO0 needs to be shorted to Ground when you apply the 3.3v power from the FTDI adapter. The location of the GPIO0 and Ground connections are easy to spot, but I’ve marked them on the photo below…


After I’d flashed the new code, which includes OTA routines, and tested that it was connecting to Wi-Fi I de-soldered the 4 pin header and re-assembled everything.
Although the LED and switch work fine when it’s being powered from the FTDI, the relay won’t work until the device is receiving mains power, so don’t worry about not hearing the relay clicking in and out at the initial testing stage. It seems that the the 5v feed for the relay is opto-isolated from the 3.3v supply for the ESP module, so reverse-powering the relay via a 3.3v supply won’t work.

Apart from the fact that these smart sockets don’t have the unswitched USB output, they are very similar to the original smart switch. I think the styling of the original one is nicer, and I prefer the push button to be on the top rather than the side, but otherwise there’s very little to choose between them.
It’s slightly easier to flash this style of socket, as the 4 pins are next to each other, but as this only needs to be done once it doesn’t really make much difference provided that you have reasonable soldering skills.



Which pins does the older S20 use? (left of the first picture)




Here is your link

Using With Sonoff S20


These are the GPIO pins for the S20:

GPIO 12 Relay (Active High)
GPIO 13 Green LED (Active Low)
GPIO 0 Physical Switch (Low when activated)

The Blue LED is connected to the relay, so is active whenever the relay is energised (HIGH).

As the physical button is connected to GPIO0, it can be used to put the S20 into flash mode.
Once again, the standard warning applies, don’t connect the S20 to the mains supply when you’re programming it using the FTDI connector!



Thanks for your help.



Excuse me. How do you debug your sketches, because you cannot use Serial.print?



You could use conventional serial debugging with the Sonoff S20, as that doesn’t use GPIO1 for the physical switch.

With the original switch I tested the software on a Wemos D1 Mini then used trial and error to find out which GPIO ports to use on the smart switch.



You could use conventional serial debugging with the Sonoff S20, as that doesn’t use GPIO1 for the physical switch.

With the original switch I tested the software on a Wemos D1 Mini then used trial and error to find out which GPIO ports to use on the smart switch.



Thanks, very nice.



I brought major improvements to this socket as the factory relay is crappy and the eeprom memory is too small!

Here is some code and photos for the UK version of this smart plug:

Any advices for improvements are welcome !


I’ve never had a problem with lack of memory on the Sonoff for OTA, but then I tend to run MQTT code rather than Blynk code.
I did buy some larger memory chips when I first bought some Sonoffs, but never had a need to fit them.
Some of the newer Sonoffs use ESP8285s, which have their memory onboard,so upgrading the memory chip isn’t an option.
Maybe streamlining the code so that it fits in 512mb and works with OTA would be a better overall approach.

I have to say that the relay upgrade looks a bit messy to me :wink:



Hello, Pete Knight!

For my Blynk code, upgrading the eeprom was the only way.

Also, the factory relay was completely useless. Any load(resistive or inductive) closer to an amp was causing it to get welded. Same thing for all of the 3 s20 I have.

This was the only way i found. It looks a bit messy. It is a bit messy to drill that hole accurately, but it’s compleetly safe. Especially because the main purpose of these plugs is to disable any device that can cause a fire when i leave the house.


Hi @rotarucosminleonard
according to data sheet

for the 5V 30A relay the coil resistance is 27 ohms and you need a current of 185 ma to maintain the relay well latched V*V/R= 0.93W
for the original 10A relay the coil resistance is 54 ohms and it need half the power.
Here I am asking if you checked that the power delivered by the sonoff SPS is enough for this relay and it will not heat up in summer and cause problems.


good point!
I did no measurements, but it should be in specs.
the relay is triggered by the 2n7002. it is rated for 210ma.
it is on the edge but it should be fine, the relay requires 185ma

this setup is in use for months and for now, nothing failed, but i will try to do some measurements for the power sources aswell.


on my Sonoff POW R2 the 16A relay is a HKE V6-S-DC5V

according to data sheet
HKE V6 Power Relay

the 5V 16A relay coil resistance is 125 ohms and you need only 200 mW or 40 mA to drive the relay.
also this relay is very small in size.
in your case
if every thing is working fine, OK keep it, but if something went wrong at least you know the reason.