An adaptive smart plug

Wanted to have a smart plug that is able switch on the mains power during the – let’s say – 4 hours of lowest electricity cost of the day. The reason for this is the fact that the electricity prices may vary a lot during the day:

Why not use the cheapest way to heat up the summer house, the swimming pool or charge the car, the e-bike, the notebook and the mobile phone.

At the time of writing there are great open source communities working with smart home devices, like ESPhome and Tasmota , but I wanted a stand alone smart plug solution , that reads the local electricity prices and turn on the smart plug accordingly. That is, without the need of a local home server.

The calculation of the electricity prices here in Denmark mostly depends on the el spot price on hourly basis and the socalled nettarif, that is fixed in 3 months intervals.

At the time of writing the danish el spot prices can be read via an API. Here is a json table example from Nov. 15 2023 with the price area DK1 and the electricity provider N1 : Api response . The el spot price query URL definition in this case can be found here: query dataset .

The danish nettarif prices depends on the electricity transport provider, the region, time of day and the defined summer/winter periods. I am using the nettarif prices from the N1 electricity provider at this site: N1 nettarif . The nettarif pricing has no API and need to be hard coded, checked and eventually changed every 3 months.

I added the hourly el spot price for the price area DK1 and the nettarif prices for el provider N1 using a serverside PHP script. Querying the PHP script returns this response: Elpriserne . Around 13:00 and until 00:00 the price calculation for the next day is shown as well. The reason for this is the fact, that the el spot prices for the next day are available around 13:00 . See the figure above.

To make it easy for the embedded https client to find the lowest price periods, I made another PHP script. Querying the PHP script returns a CSV formatted with this response: price_indexes. The script makes a prioritized indexed price table based on the available electricity prices.

Below is an example of hourly price indexes calculated from the sum of the el spot price area DK1 and nettarif N1 with index 1 for the lowest price and 24 as the highest indexes:

Time: 20:29 2023-11-25,6,4,3,2,1,5,7,10,15,14,12,11,9,8,13,16,18,22,23,24,21,19,20,17,10,8,5,3,1,2,4,7,11,16,15,13,12,9,14,19,20,23,24,22,21,18,17,6
The string holds the prioritized price indexes for today and tomorrow, 2×24 hours of price indexes.
Tomorrow price indexes of 0 indicate that the nextday indexes will be ready around 13:00.

The client software connects to the internet a wifi router to get the electricity price index table. To develop the client side I used the Arduino IDE as the software platform along with the ESP8266 01S module plus a suitable USB programmer. The relay module shown can be used to switch on the mains supply.  WARNING: adding mains supply is dangerous.!!

The client must: 1. connect to the internet a wifi router. – 2. request the “price indexes of the day string” from the https server. – 3. find the lowest price periods. – 4. activate the output according to the low price periods. – 5. do the time keeping during missing wifi periods. The client program ( early beta version ! ) is to be seen here: Adaptive_client_SW . This software version finds and uses the hours during the day with the lowest electricity prices to turn ON the relay. A guide on flashing via the Arduino IDE is here: Ardu_flashing

Actually, the ESP8266 module forms the basis of many smart plug units. The hacker-friendly Sonoff S26 smart plug uses the ESP8266EX with 1MB of flash memory and is easily opened to install the client software from above !.:

The Sonoff S26 pin layout for LEDs and the mains relay is shown below and must be taken into consideration in the client software when defining the I/O pins.

To flash a new Arduino based firmware version Over The Air via wifi, called OTA, there is a nice set of libraries you can use. The concept is described here: Ardu_8266_OTA  . In this actual case the code overhead is 3%. The flash code size went from 35% flash usage to 38%, still ok to let the OTA software use another 38% for the firmware download !.

Following the concept to add libraries and initialization, I just needed to insert a few lines in the loop() function:

// if wifi: look for an OTA update
  if ((WiFi.status() == WL_CONNECTED)) {
 – – –
To set the low price hours with an active smart plug output, I used a small webserver for look for a http url issued from a client web browser (PC , mobile phone) on the wifi network. The url is the IP of the smart plug with a port number set at compile time, here 8000.
The number of low el price hours ( at the time of writing, up to 18 hours per day ) for the smart plug to turn on can be selected via the web page. The selected value for the number of hours is saved in the internal flash of the smart plug:

To set up the wifi network ssid and password, press the on/off button for 2 seconds. Change your mobil phone network to “Smart plug setup”, goto and insert the ssid og password of your local wifi network.

In your wifi network router admin page you will find the DHCP allocated IP address of the smart plug. In the router, it is a good idea to make a static DCHP definition for the smart plug IP address.

Technical info: The root certificate of the price index server at changes every 3 months, so the smart plug certificate header file must be replaced accordingly, and the source recompiled.!

The complete ESP8266 source is found here: Adaptive_smart_plug

Made the same modification with a Denver SHP-310U power strip as described above:

It works the same way but with the hours of the lowest el prices to be set for each mains outlet. The internal 5V DC charger for USB jacks are originally connected to the mains , but has been rewired to work with the mains outlet closest to the USB jacks. Inside the housing a Tuya TYWE3S module is found:

The Tuya TYWE3S module holds an ESP8285 CPU , a newer, compatible and faster version of the ESP8266 used with the Sonoff S26 smart plug.

On the rear side of the module the GPIO0 pin is found. Thi GPIO0 pin is connected to GND before the USB-3V3 UART converter is plugged into the PC for flashing. The wires from the converter is soldered in place:

The embedded webpage was changed to handle the 3 power strip outlets. In the case the wifi is turned off before midnight, the option to postpone the output scheduling to the next day was added:

The Arduino source is found here: Denver_power_strip_source