Home ESP8266/ESP32 ESP8266 DIY Smart Socket - SOFTWARE (3/3)

ESP8266 DIY Smart Socket – SOFTWARE (3/3)

Good things come to the ones who wait!

It took me longer than I assumed it would, mainly due to software issues, but once I modified the software to my needs, it was much easier to implement new features. ESP8266 DIY Smart Socket gains new options that go beyond the initial tutorial, and this video contains a short presentation as well as the full software guide.

ESP8266 DIY Smart Socket – SOFTWARE

The ESP8266 DIY Smart Socket has the following functionality right now:

  • Tasker (toggle, schedule, notifications)
  • Web UI (toggle, status, schedule)
  • Alexa (toggle)
  • Google Home (toggle)
  • NodeRED – (everything and more)

I mentioned before that ESP8266 DIY Smart Socket can be controlled with virtually anything that can send HTTP POST requests. These requests will control the toggle and the schedule of the smart plug.

ESP8266 DIY Smart Socket – ArduinoIDE

To communicate with the socket I’m using an MQTT server running on a Raspberry Pi. The same RPI handless pretty much all the communication between my devices. The protocol is fast, secure (tutorial has no passwords implemented) and it’s supported by ESP8266.

ESP8266 Arduino.ino code
#include 
#include 

// Wifi Connection
const char* ssid = "XXXXX";
const char* password = "XXXXXX";

// MQTT Server address
const char* mqtt_server = "192.168.XXX.XXX";  // ip of your server
const char* topic_internet = "esp/network";   // "online or offline" network status
const char* topic_status = "esp/relay";       // "1 or 0" to toggle socket
const char* topic_c_state = "esp/update";     //"offline"// current state "1 or 0" 
const char* topic_will = "esp/network";       // last will the same as "topic_internet"
const char* ESP_will = "offline";             //last will
const char* ESP_name = "XXXXX";               //Unique MQTT name for your ESP
int pin = 3;                                  //ESP pin RX is the GPIO3 

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup() {
  
  pinMode(3, OUTPUT);
  digitalWrite(3, 0);
//disabled serial after troubleshooting
  Serial.end();
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void setup_wifi() {

  delay(2);
  Serial.println();
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); } Serial.println(); if ((char)payload[0] == '1') { digitalWrite(pin, 1); client.publish(topic_c_state, "1"); } else { digitalWrite(pin, 0); client.publish(topic_c_state, "0"); } } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (client.connect(ESP_name, topic_will, 1, false, ESP_will)) { Serial.println("connected"); // Once connected, publish an announcement... client.publish(topic_internet, "online"); // ... and resubscribe client.subscribe(topic_status); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } void loop() { if (!client.connected()) { reconnect(); } client.loop(); long now = millis(); if (now - lastMsg > 10000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 75, "online", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish(topic_internet, msg);
  }
}

You can use the code as is, however, bear in mind that you have to modify it to your needs.

// Wifi Connection
const char* ssid = "XXXXX";
const char* password = "XXXXXX";

// MQTT Server address
const char* mqtt_server = "192.168.XXX.XXX";  // ip of your server
const char* topic_internet = "esp/network";   // "online or offline" network status
const char* topic_status = "esp/relay";       // "1 or 0" to toggle socket
const char* topic_c_state = "esp/update";     //"offline"// current state "1 or 0" 
const char* topic_will = "esp/network";       // last will the same as "topic_internet"
const char* ESP_will = "offline";             //last will
const char* ESP_name = "XXXXX";               //Unique MQTT name for your ESP
int pin = 3;                                  //ESP pin RX is the GPIO3 

I kept all the important values together, so you don’t have to jump through the code.

There are few things to note in the code:

void setup() {
 
 pinMode(3, OUTPUT);
 digitalWrite(3, 0);
//disabled serial after troubleshooting
 Serial.end();

I have used the RX pin GPIO03 (as per hardware tutorial) as OUTPUT, therefore disable the serial once you have done troubleshooting your ESP.

The callback function (function executed when MQTT message is received by ESP8266) updates the pin state and also publishes the current state value.

if ((char)payload[0] == '1') { 
 digitalWrite(pin, 1);
 client.publish(topic_c_state, "1"); 
 } 
 else {
 digitalWrite(pin, 0);
 client.publish(topic_c_state, "0");

This feedback is used for the web interface and to update Tasker variable.

The ESP will update the server every 10 sec with ‘online’ message. Additionally, the last will is posted when the ESP8266 DIY Smart Socket goes offline.

 if (client.connect(ESP_name, topic_will, 1, false, ESP_will)) {
 Serial.println("connected");
 // Once connected, publish an announcement...
 client.publish(topic_internet, "online");

The full code can be downloaded at the bottom of this article.

ESP8266 DIY Smart Socket – NodeRED

I know the flow looks scary! Fear not! You only need the whole flow if you are interested in schedules and interface. I will cover everything in this tutorial but you can pick the nodes that you are interested in.

Before we start, open the palette manager and install:

node-red-dashboard
node-red-contrib-bigtimer
node-red-contrib-alexa-home-skill (For Alexa)

These nodes are used in my NodeRED flow.

Online status

When the ESP8266 DIY Smart Socket is connected to the MQTT server it will update its status and update the Web UI. “online” is turned into green and “offline” into a red colour value for the text.

That text is a button node from the dashboard, and colour value is set to {{payload}}.

Current State

When ESP8266 writes a new pin value to control the relay, a new message is published to NodeRED. The message is a binary value (on/off) which is changed into the NO/OFF state and used in the Web UI text node.

Relay control

This is the main flow. The MQTT node will send 1 or 0  to enable and disable the socket. This can be issued with the Web UI node (blue ESP) which sends 1 or 0 based on the switch position. This node also notifies the Android phone via AutoRemote about the update. AR message “esp turnon/turnoff” is sent accordingly.

Another way of triggering the ESP8266 DIY Smart Socket is via Alexa. I talked about this node before. As payload (message sent by the node) is a boolean, we have to use a switch again to change it binary. Again, if the state has been changed, the Android phone is notified via AutoRemote.

Lastly, we have an HTTP POST node. We can connect any device (this is the Google Home endpoint) capable of sending POST requests. The request expected has:

{light: "1"} or {light: "0"}

value and it is posted to esp/relay directory. To use HTTP POST with Google Home, use IFTTT and Webhooks. I covered this type of set up here.

Default schedule

Bigtimer nodes are awesome. They come with some many options, that is just mind-blowing. If you are not interested in any schedule overrides, these are the only nodes you need. Select your default timers, and use the 1st output to trigger the MQTT node and Android AutoRemote notifications.

Schedule override

The WebUI and Tasker (or any device capable of HTTP POST) can override the default schedule. There are 2 POST requests – one for the time on and one for the time off.

esp/timeon {timeon: "12:20"}
esp/timeoff {timeoff: "12:20"}

Once again, the value has to be inserted into a payload via  function node:

msg.payload = msg.payload.timeon;
return msg;
AND
msg.payload = msg.payload.timeoff;
return msg;

Then a prefix is applied:

off_override {{payload}}
OR
on_override {{payload}}

as the bigtimer node requires a correct prefix to handle the input. To reset the values to the default, all you need to do is submit payload: “auto” or “default”. Each bigtimer node has to receive the input for time on and off to work properly. If you, like me, use multiple big timer nodes, they can be set to the same values without causing issues.

Web UI

The ESP8266 DIY Smart Socket comes with a Web UI now, where you can perform all the actions or check the status of your socket.

On the left, you see 2 button nodes, 2 text entry nodes, and a Reset button. Writing values into the input fields (delay1000) overwrites a text file. The value is picked up again once the button SET is pressed, and passed over to the template node (needs correct prefix as before). At the same time, the time entered into the web interface is passed over to the text interface on the right.

Reset button writes ‘auto’ to the file and sends the same message directly to the timer nodes and the text node.

Tasker

I set up Tasker to control the ESP8266 DIY Smart Socket and override the default schedule. Please note that I’m using the Near-Perfect Notification to handle my notifications.

Start with Set Server and set the %NodeServer with your IP (or DNS) and the port (default 1880). There are 2 profiles to handle everything.

ESP Smart Notification

TASKER PROFILE: ESP Smart Notification
Profile: ESP Smart Notification 
	Event: AutoRemote [ Configuration:esp ]
Enter: Socket Notifications
	A1: Variable Set [ Name:%ESPsocketValue To:0 Recurse Variables:Off Do Maths:Off Append:Off ] 
	If [ %armessage ~R .*turnon ]
	A2: AutoAppsHub SendCommand [ Configuration:Command: 
	NOTIFICATION=:=ESP Smart Socket=:=The light is ON=:=ESPsocket=:=#5481D4FA=:=2=:=espsocket=:=espsocket=:=Turn OFF=:=ESP TURNOFF 
	Timeout (Seconds):60 ] 
	If [ %armessage ~R .*turnon ]
	
	
	A3: AutoNotification Cancel [ Configuration:Id: ESPsocket Timeout (Seconds):0 ] 
		If [ %anmessage ~R .*turnoff | %armessage ~R .*turnoff ]
	A4: Variable Set [ Name:%ESPsocketValue To:1 Recurse Variables:Off Do Maths:Off Append:Off ] 
		If [ %armessage ~R .*turnoff ]
	A5: Perform Task [ Name:ESP Toggle Priority:%priority Parameter 1 (%par1):end 
		Parameter 2 (%par2): Return Value Variable: Stop:Off ] 
		If [ %anmessage ~R .*turnoff ]

Upon the arrival of an AutoRemote message, e a Notification is created. To do this I simply issue a string of text as an AutoApps command (using Near Perfect Notifications). The notification contains one button – which acts as a shutdown.In addition to that, each time my phone receives an update about the state of the socket %ESPsoketValue is set to the opposite value. I need this to issue a correct POST request later on.

If the ESP8266 DIY Smart Socket is turn on the message received by the POST node is:

on
https://autoremotejoaomgcd.appspot.com/sendmessage?key=YOURKEY&message=esp turnon
off
https://autoremotejoaomgcd.appspot.com/sendmessage?key=YOURKEY&message=esp turnoff

If the received message is ‘off’  the notification gets cancelled, variable %ESPsocketValue is set again.

If this action is triggered by AutoNotification (TURN OFF) button, Notification gets cancelled and the ESP Toggle task is triggered.

ESP Toggle

TASKER TASK: ESP Toggle
ESP Toggle 
	A1: AutoTools Dialog [ Configuration:Dialog Type: List
		Title: ESP Socket Menu
		Title Alignment: Left
		Icon: /storage/emulated/0/DCIM/Join/esp_socket.png
		List Type: Grid
		Text Size: 20
		Images: /ic_lightbulb_outline.png,/ic_alarm_plus-1.png
		Image Width: 100
		Dim Background: true
		Number Of Columns: 2
		Top Margin: 16
		Bottom Margin: 16
		Bottom Buttons Top Margin: 16
		Bottom Buttons Bottom Margin: 16
		Close On Select: true
		Separator: ,
		Command Variable: atcommand
		Cancelable: true
		Turn Screen On: true Timeout (Seconds):60 ] 
		If [ %par1 neq end ]
	A2: HTTP Post [ Server:Port:%NodeServer Path:esp/relay 
		Data / File:light=%ESPsocketValue Cookies: User Agent: 
		Timeout:10 Content Type: Output File: Trust Any Certificate:On ] 
		If [ %atposition eq 1 | %par1 ~ end ]
		
		
	A3: If [ %atposition eq 2 ]	
	

This is a stand alone task that can be triggered via Tasker shortcut from the home screen.

There is an option to toggle the light based on %ESPsocketValue or set an override timer using AutoTools time pickers. The dialog is protected by being triggered from the AutoNotification (TURN OFF button) via %par1 !~ end condition. This variable is issued when Perform Task action happens.

If I click on the bulb – the %atposition = 1 and HTTP POST is sent:

Server:Port:%NodeServer 
Path:esp/relay Data / File:light=%ESPsocketValue

Otherwise, two AutoTools dialogs are displayed. I can set the TIME ON and TIME OFF timers. As the HTTP requests are sent just after the time is picked, I don’t have to override both timers. All I have to check if variable %atdatetime1 has been set.

Conclusion

It’s fair to say, this is an interesting one. I didn’t anticipate the extended features but I’m glad I added it. The ESP8266 DIY Smart Socket has been serving me for over a month now, and I’m very pleased. I hope you picked new skills as well and learned something new!

Project Download

Download project files here. Bear in mind that Patreon supporters have early access to project files and videos.

PayPal

Nothing says "Thank you" better than keeping my coffee jar topped up!

Patreon

Support me on Patreon and get an early access to tutorial files and videos.

image/svg+xml

Bitcoin (BTC)

Use this QR to keep me caffeinated in style with crypto-currency

Smart Ideas with

Automate your space in with these ecosystems and integrate it with other automation services

Learn NodeRED

NodeRED for beginners: 1. Why do you need a NodeRED server?

0
To server or not to server? That's a very silly question!

Best Automation Projects

ESP8266 WIFI lights under $5

0
Your Sonoff device can't do this!

Free wireless doorbell (Amazon Dash button hack)

0
The most terrifying situation I can imagine* is missing a parcel

New Amazon Dash Buttons

0
You can teach new buttons old tricks!

ESP8266 ceiling light – demo

0
Testing the ESP8266 as a WIFI light controller

Try Tasker and Raspberry Pi for your home automation needs!

0
Raspberry Pi can help you with your Tasker profiles

Smart Home

Exciting changes in NodeRED 1.1.0

0
Exciting changes in NodeRED 1.1.0 - you can update your installation now and explore new features yourself.

Flashing Tasmota on 4CH R3 & 4CHPRO R3

0
Flashing Tasmota on 4CH R3 & 4CHPRO R3 takes only a couple of minutes and you can enjoy the custom firmware and NodeRED setup

Sonoff 4CH & 4CHPRO joins R3 revision

0
Everything you need to know about Sonoff 4CH & 4CHPRO and the new re

Better than Hue? Novostella smart bulb review

0
Novostella Smart Bulb packs vivid colours and 1300 lumens to keep the room as bright or as light as you need it to be

That’s the way I roll – Zemismart motorised blinds

0
Automate your windows with Zemismart motorized blinds. Add your roller blinds to your home automation.