Site icon Intermittent Technology

ESP8266 WiFi LED dimmer Part 6 of X: ESP8266 Domoticz Wall Switch

The next part I needed for my Domotica system was a way to have physical switches in my house which would run ‘virtual’ actions. Tonight I programmed the ESP LUA code to test this.

This series has been rebooted

Please take a look at the following post to visit the new rebooted series and index of all posts: https://blog.quindorian.org/2016/07/esp8266-lighting-revisit-and-history-of-quinled.html/


The Desired function

The software part of it was pretty easy to write. The hardware “end product” though has to be very small to fit into the normal wall sockets. It would be added behind a wall switch and contain an ESP8266 and a power supply all in the tiny box.

In the future I aim to design a special PCB combined with a very small power supply so it can easily fit inside a wall socket box.


The way I wanted this to work is that the switch only flips a virtual dummy switch inside of Domoticz and coupled to that, any other action can take place. That way, I can program the ESP8266 with the correct Domoticz switch IDX once and then when I wish to change the function, I can always do so from Domoticz and won’t need to change what’s running on the ESP8266 module.


In my case I used a ESP-12 in this case. I recently received this version and when I got it to work in my breadboard I used that setup. It doesn’t matter which ESP8266 module you wish to use yourself, just be sure to change the pin numbers accordingly.

 

How it works

My code is currently configured to use two GPIO pins of the ESP8266. If you wish to run multiple switches using a single ESP8266 you will need to use as many GPIO pins as you want switches.

The wiring of the switch is easy. In my case the switch had a negative/ground in and two outputs, which get switched. I wired the negative/ground to the switch input and wired the outputs to the GPIO pins on the ESP8266.


The way it’s setup is that the GPIO pins will be HIGH by default (The ESP8266 will pull it high internally) but when the negative/ground is switched on the circuit will be connected and so it will go LOW because now it’s connected to ground. That state change is what we are looking for. The pin will remain LOW until the switch is flipped again. Each position will keep it’s respective HIGH or LOW.


The code automatically detects when a switch was switched and when it’s still in the same state so that it won’t continuously hammer Domoticz. That does mean that when the action associated with the switch is run manually on the web interface of Domoticz, it could be that nothing happens.


Example: If you turn the switch on using the physical switch, but then turn it off using the Domoticz interface, the actions associated to this will be carried out, but the physical switch will remain in it’s position. When you then flip the switch, you will be switching it to off again, so nothing will happen. To turn the light on, you will have to flip the physical switch to on, and the connection actions will take place.

With that in mind, let’s continue!

 

ESP8266 code

This is version 0.2 of my test code, so don’t be too harsh. It’s working perfectly in my test setups though! Both switches are implemented in the code so make sure to change the pins, switch IDX, Domoticz IP, Wireless LAN, etc.

Currently the alarm loop is set to read the switch state every 0.1 of a second. This makes the reaction of the switch almost instant, but going through WiFi, then through Domoticz to another WiFi ESP8266 which then switches the light on has a little time delay. In my testing this delay was around 0.5 seconds or so, quite acceptable for my purpose.


Be sure to change the pins to your ESP layout!


update 2015-03-03

I updated the code so we now have variables for the most common settings and also added the code for connecting two separate switches. I also removed some logging so it won’t keep spamming the console with messages.


GPIOpin1 = 5
GPIOpin2 = 6
DomoticzIP = "10.10.128.14"
switchidx1 = 42
switchidx2 = 42
print "Vars set"

gpio.mode((GPIOpin1), gpio.INPUT, gpio.PULLUP)
gpio.mode((GPIOpin2), gpio.INPUT, gpio.PULLUP)
print "Pins set"

wifi.setmode(wifi.STATION)
wifi.sta.config("Q-LAN","yoloyoloyolo")
print "WiFi set"

print "Reading button states in loop"
tmr.alarm(0, 100, 1, function()
 if gpio.read(GPIOpin1) == 0 then
--  print ("Button 0 = On")
  if Switch0 == "On" then
--   print ("Switch already on")
   else
  Switch0 = "On"
   conn=net.createConnection(net.TCP, 0) 
   conn:on("receive", function(conn, payload) print(payload) end) 
   conn:connect(8080,(DomoticzIP)) 
   conn:send("GET /json.htm?type=command&param=switchlight&idx=" .. (switchidx1) .. "&switchcmd=On&level=0 HTTP/1.1rn") 
   conn:send("Host: " .. (DomoticzIP) .. "rn") 
   conn:send("Accept: */*rn") 
   conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)rn")
   conn:send("rn")
  print ("SWITCHED Switch0 ON")
  end
  else
--  print ("Button 0 = Off")
  if Switch0 == "Off" then
--   print ("Switch already Off")
   else
  Switch0 = "Off"
   conn=net.createConnection(net.TCP, 0) 
   conn:on("receive", function(conn, payload) print(payload) end) 
   conn:connect(8080,(DomoticzIP)) 
   conn:send("GET /json.htm?type=command&param=switchlight&idx=" .. (switchidx1) .. "&switchcmd=Off&level=0 HTTP/1.1rn") 
   conn:send("Host: " .. (DomoticzIP) .. "rn") 
   conn:send("Accept: */*rn") 
   conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)rn")
   conn:send("rn")
  print ("SWITCHED Switch0 OFF")
  end
end end )

tmr.alarm(2, 100, 1, function()
 if gpio.read(GPIOpin2) == 0 then
--  print ("Button 0 = On")
  if Switch1 == "On" then
--   print ("Switch already on")
   else
  Switch1 = "On"
   conn=net.createConnection(net.TCP, 0) 
   conn:on("receive", function(conn, payload) print(payload) end) 
   conn:connect(8080,(DomoticzIP)) 
   conn:send("GET /json.htm?type=command&param=switchlight&idx=" .. (switchidx2) .. "&switchcmd=On&level=0 HTTP/1.1rn") 
   conn:send("Host: " .. (DomoticzIP) .. "rn") 
   conn:send("Accept: */*rn") 
   conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)rn")
   conn:send("rn")
  print ("SWITCHED Switch1 ON")
  end
  else
--  print ("Button 0 = Off")
  if Switch1 == "Off" then
--   print ("Switch already Off")
   else
  Switch1 = "Off"
   conn=net.createConnection(net.TCP, 0) 
   conn:on("receive", function(conn, payload) print(payload) end) 
   conn:connect(8080,(DomoticzIP)) 
   conn:send("GET /json.htm?type=command&param=switchlight&idx=" .. (switchidx2) .. "&switchcmd=Off&level=0 HTTP/1.1rn") 
   conn:send("Host: " .. (DomoticzIP) .. "rn") 
   conn:send("Accept: */*rn") 
   conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)rn")
   conn:send("rn")
  print ("SWITCHED Switch1 OFF")
  end
end end )




 

 

Extra

A friendly comment-er suggested using a different method of reading the GPIO pins. I tried using this method (using interrupt based switching) but found it not reliable in my situation. From the 10 pushes I did it would not register one and it would actually reverse how the switch worked. So I am still using the above code right now.
 
Here is the code I tried:

wifi.setmode(wifi.STATION)
wifi.sta.config("Q-LAN","yoloyloyloyloylo")
print "WiFi set"

print "Reading button states in loop"
gpio.mode(5, gpio.INT, gpio.PULLUP)
gpio.trig(5, "both", function(level) 

if level == 1 then
--  print ("Button 0 = On")
  if Switch0 == "On" then
--   print ("Switch already on")
  else
   Switch0 = "On"
   conn=net.createConnection(net.TCP, 0) 
   conn:on("receive", function(conn, payload) print(payload) end) 
   conn:connect(8080,'10.10.128.14') 
   conn:send("GET /json.htm?type=command&param=switchlight&idx=42&switchcmd=On&level=0 HTTP/1.1rn") 
   conn:send("Host: 10.10.128.14rn") 
   conn:send("Accept: */*rn") 
   conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)rn")
   conn:send("rn")
  print ("SWITCHED IT ON")
  end
 elseif level == 0 then
--  print ("Button 0 = Off")
   if Switch0 == "Off" then
--    print ("Switch already Off")
   else
    Switch0 = "Off"
    conn=net.createConnection(net.TCP, 0) 
    conn:on("receive", function(conn, payload) print(payload) end) 
    conn:connect(8080,'10.10.128.14') 
    conn:send("GET /json.htm?type=command&param=switchlight&idx=42&switchcmd=Off&level=0 HTTP/1.1rn") 
    conn:send("Host: 10.10.128.14rn") 
    conn:send("Accept: */*rn") 
    conn:send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)rn")
    conn:send("rn")
   print ("SWITCHED IT OFF")
end end end )


 

Exit mobile version