Dwaipayan Barman
Published © MIT

ESP8266 BASED HOME AUTOMATION WITH COMPLETE GUI

Easy to use GUI for ESP8266 based home automation project using HTML with Lua

IntermediateShowcase (no instructions)2 hours7,644
ESP8266 BASED HOME AUTOMATION WITH COMPLETE GUI

Things used in this project

Story

Read more

Schematics

esp8266 pin diagram

Code

conf.lua

Lua
print("Get available APs")
wifi.setmode(wifi.STATION)
wifi.sta.getap(function(t)
   available_aps = ""
   if t then
      for k,v in pairs(t) do
         ap = string.format("%-10s",k)
         ap = trim(ap)
         available_aps = available_aps .. "<option value='".. ap .."'>".. ap .."</option>"
      end
      setup_server(available_aps)
   end
end)

local unescape = function (s)
   s = string.gsub(s, "+", " ")
   s = string.gsub(s, "%%(%x%x)", function (h)
         return string.char(tonumber(h, 16))
      end)
   return s
end

function setup_server(aps)
   print("Setting up Wifi AP")
   wifi.setmode(wifi.SOFTAP)
  cfg = {}
   cfg.ssid = "ESP8266 HOME AUTOMATION";
   cfg.pwd  = "password"
   wifi.ap.config(cfg)     
  wifi.ap.setip({ip="192.168.1.1",netmask="255.255.255.0",gateway="192.168.1.1"})
   print("Setting up webserver")
   srv = nil
   srv=net.createServer(net.TCP)
   srv:listen(80,function(conn)
       conn:on("receive", function(client,request)
           local buf = ""
           local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");
           if(method == nil)then
               _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP")
           end
           local _GET = {}
           if (vars ~= nil)then
               for k, v in string.gmatch(vars, "(%w+)=([^%&]+)&*") do
                   _GET[k] = unescape(v)
               end
           end
             
           if (_GET.psw ~= nil and _GET.ap ~= nil and _GET.ipTCP ~= nil) then
              client:send("Saving data..")
              file.open("config.txt", "w+")
                file.writeline(_GET.ap)
                file.writeline(_GET.psw)
            file.writeline(_GET.ipTCP)
            file.writeline(_GET.nmsk)
            file.writeline(_GET.gty)
                 file.close()
                 --node.compile("config.lua")
                 --file.remove("config.lua")
                 client:send(buf)
                node.restart()
           end
   
            buf = "<html><body>"
            buf = buf .. "<br><h3 style = \"color: #fc970e; text-align: center; font-size: 40px; padding: 10px\">Configuration utility</h3>"
            buf = buf .. "<form style = \"border-radius: 20px; border:4px;text-align: center; border-style: solid; padding: 10px; border-color: #4eb0fd\" method='get' action='http://" .. wifi.ap.getip() .."'><br>"
            buf = buf .. "<d style = \"font-family: Arial; font-size: 30px; color: #4eb0fd\">Select access point: </d> <select name='ap'>" .. aps .. "</select><br><br>"          
            buf = buf .. "<d style = \"font-family: Arial; font-size: 30px; color: #4eb0fd\">Enter wifi password: </d> <input style = \" height: 20px; width: 200px; text-align: center;\" type='password' value = 'password' name='psw'></input><br><br>"
            buf = buf .. "<d style = \"font-family: Arial; font-size: 30px; color: #4eb0fd\">Server-IP: </d><input style = \" height: 20px; width: 200px; text-align: center;\" name='ipTCP' value='192.168.1.100'></input><br><br>"
            buf = buf .. "<d style = \"font-family: Arial; font-size: 30px; color: #4eb0fd\">Netmask : </d><input style = \" height: 20px; width: 200px; text-align: center;\" name='nmsk' value='255.255.255.0'></input><br><br>"
            buf = buf .. "<d style = \"font-family: Arial; font-size: 30px; color: #4eb0fd\">Gateway : </d><input style = \" height: 20px; width: 200px; text-align: center;\" name='gty' value='192.168.1.1'></input><br><br>"
            buf = buf .. "<button type='submit' style = \"font-size: 25px; border-color: #1ef59d; border-radius: 20px; background-color: #0dc2ee; color: #fbfcfc\">Save</button>"                   
            buf = buf .. "</form></body></html>"
           client:send(buf)
           client:close()
           collectgarbage()
       end)
   end)
   print("Please connect to: " .. wifi.ap.getip())
end

function trim(s)
  return (s:gsub("^%s*(.-)%s*$", "%1"))
end

server.lua

Lua
file.open("config.txt","r");
SSID = file.readline():gsub("%s+$", "");
PASS = file.readline():gsub("%s+$", "");
IP = file.readline():gsub("%s+$", "");
NETMSK = file.readline():gsub("%s+$", "");
GTY = file.readline():gsub("%s+$", "");
file.close();

wifi.setmode(wifi.STATION)
  cfg = {
      ip= IP,
      netmask= NETMSK,
      gateway= GTY
    }
  wifi.sta.setip(cfg)

  --Your router wifi network's SSID and password
  wifi.sta.config(SSID,PASS)
  --Automatically connect to network after disconnection
  wifi.sta.autoconnect(1)
  print ("\r\n")
  --Print network ip address on UART to confirm that network is connected
  print(wifi.sta.getip())
  --Create server and send html data, process request from html for relay on/off.
  srv=net.createServer(net.TCP)
  srv:listen(80,function(conn) --change port number if required. Provides flexibility when controlling through internet.
      conn:on("receive", function(client,request)
          local html_buffer = "";
          local html_buffer1 = "";
          local html_buffer2 = "";
          local html_buffer3 = "";
          local html_buffer4 = "";
          local html_buffer5 = "";
		
          local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");
          if(method == nil)then
              _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP");
          end
          local _GET = {}
          if (vars ~= nil)then
              for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do
                  _GET[k] = v
              end
          end

	  	html_buffer = html_buffer.."<!DOCTYPE html>";
      html_buffer = html_buffer.."<html>";
      html_buffer = html_buffer.."<title>DB's IOT Server</title>";
      html_buffer = html_buffer.."</head>";
      html_buffer = html_buffer.."<body style = \"color: #d8fafe\">";
      html_buffer = html_buffer.."<table align = \"center\" color = \"#aaaaff\" style = \"border-width: 4px; border-style: solid; border-color:  #4eb0fd; padding:18px ; border-radius:18px\">";
      html_buffer = html_buffer.."<thead>";
      html_buffer = html_buffer.."<title>IOT Server</title>";
      html_buffer = html_buffer.."<tr>";
      html_buffer = html_buffer.."<th colspan = \"2\" style = \"border-width:3px; border-color:   #fcd4fb; border-style: solid; border-radius:18px; font-size: 90px; font-family: Arial; padding: 12px; color:   #f09b19  \">IOT Server</th>";
      html_buffer = html_buffer.."</tr>";
      html_buffer = html_buffer.."<tr>";
      html_buffer = html_buffer.."<th style = \"background-color:  #e8fcfe ; padding: 6px; font-size: 42px; color: #4eb0fd; margin:20px\" >Relay 1</th>";
      html_buffer1 = html_buffer1.."<th style = \"background-color:  #e8fcfe ; padding: 6px; font-size: 42px; color: #4eb0fd; margin:20px\" >Relay 2</th>";
      html_buffer1 = html_buffer1.."</tr>";
      html_buffer1 = html_buffer1.."</thead>";
      html_buffer1 = html_buffer1.."<tbody style = \"background-color:  #d8fafe \">";
      html_buffer1 = html_buffer1.."<tr align = \"center\">";
      html_buffer1 = html_buffer1.."<td style = \"border: 2WHIRLPOOLpx\">";
      html_buffer1 = html_buffer1.."<a href=\"?pin=ON1\"><button style = \"color: #4eb0fd; width:110px; font-family:Arial; font-size: 45px; border-radius: 30px; margin:20px; padding:5px\">ON</button></a>";
      html_buffer1 = html_buffer1.."</td>";
      html_buffer1 = html_buffer1.."<td>";
      html_buffer1 = html_buffer1.."<a href=\"?pin=ON2\"><button style = \"color: #4eb0fd; width:110px; font-family:Arial; font-size: 45px; border-radius: 30px; margin:20px; padding:5px\">ON</button></a>";
      html_buffer1 = html_buffer1.."</td> ";
      html_buffer1 = html_buffer1.."</tr>";
      html_buffer1 = html_buffer1.."<tr align = \"center\">";
      html_buffer2 = html_buffer2.."<td>";
      html_buffer2 = html_buffer2.."<a href=\"?pin=OFF1\"><button style = \"color: #4eb0fd; width:110px; font-family:Arial; font-size: 45px; border-radius: 30px; margin:20px;padding:5px\">OFF</button></a>";
      html_buffer2 = html_buffer2.."</td>";
      html_buffer2 = html_buffer2.."<td>";
      html_buffer2 = html_buffer2.."<a href=\"?pin=OFF2\"><button style = \"color: #4eb0fd; width:110px; font-family:Arial; font-size: 45px; border-radius: 30px; margin:20px; padding:5px\">OFF</button></a>";
      html_buffer2 = html_buffer2.."</td>";
      html_buffer2 = html_buffer2.."</tr>";
      html_buffer2 = html_buffer2.."</tbody>";
      html_buffer2 = html_buffer2.."</table>";
      html_buffer2 = html_buffer2.."</body>";
      html_buffer2 = html_buffer2.."</html>";
          local _on,_off = "",""
          if(_GET.pin == "ON1")then
                gpio.write(Relay1, gpio.HIGH);
          elseif(_GET.pin == "OFF1")then
                gpio.write(Relay1, gpio.LOW);
          elseif(_GET.pin == "ON2")then
                gpio.write(Relay2, gpio.LOW);
          elseif(_GET.pin == "OFF2")then
                gpio.write(Relay2, gpio.HIGH);
          end
          --Buffer is sent in smaller chunks as due to limited memory ESP8266 cannot handle more than 1460 bytes of data.
	  	    client:send(html_buffer);
          client:send(html_buffer1);
          client:send(html_buffer2);
          client:close();
          collectgarbage();
      end)
  end)

HOME AUTOMATION USING ESP8266

Lua
Relay1 = 1
Relay2 = 4
Rst1 = 5
gpio.mode(Rst1, gpio.INPUT);
gpio.mode(Relay1, gpio.OUTPUT)
gpio.write(Relay1, gpio.LOW);
gpio.mode(Relay2, gpio.OUTPUT)
gpio.write(Relay2, gpio.HIGH);
if(gpio.read(Rst1) == 0)then
  print("Configuration mode")
  dofile("conf.lua");
else
  print("Server mode")
  dofile("server.lua");
end

Credits

Dwaipayan Barman

Dwaipayan Barman

2 projects • 9 followers

Comments