diff --git a/http/garage_door.html b/http/garage_door.html new file mode 100644 index 0000000..879d325 --- /dev/null +++ b/http/garage_door.html @@ -0,0 +1,32 @@ + + + Garage control + + + +
+ +

Door 1

+ +
+ + + + + +
+ +

Door 2

+ +
+ + + + + +
+ +
+ + + diff --git a/http/garage_door.lua b/http/garage_door.lua new file mode 100644 index 0000000..a24958a --- /dev/null +++ b/http/garage_door.lua @@ -0,0 +1,153 @@ +-- garage_door_open.lua +-- Part of nodemcu-httpserver, example. +-- Author: Marcos Kirsch + +--[[ + This example assumed you have a Wemos D1 Pro to control a two-door garage. + For each garage door, a Wemos relay shield is used to simulate a button (connect relay in + parallel with the actual physical button) and a reed switch is used in order to know + whether a door is currently open or closed (install switch so that it is in the closed + position when your garage door is closed). + + You can configure which GPIO pins you use for each function by modifying variable + pinConfig below. +]]-- + +local function pushTheButton(connection, pinConfig) + -- push the button! + gpio.write(pinConfig["controlPin"], gpio.HIGH) + gpio.mode(pinConfig["controlPin"], gpio.OUTPUT, gpio.FLOAT) + tmr.delay(300000) -- in microseconds + gpio.mode(pinConfig["controlPin"], gpio.INPUT, gpio.FLOAT) + gpio.write(pinConfig["controlPin"], gpio.LOW) +end + + +local function readDoorStatus(pinConfig) + -- When the garage door is closed, the reed relay closes, grounding the pin and causing us to read low (0). + -- When the garage door is open, the reed relay is open, so due to pullup we read high (1). + gpio.write(pinConfig["statusPin"], gpio.HIGH) + gpio.mode(pinConfig["statusPin"], gpio.INPUT, gpio.PULLUP) + if gpio.read(pinConfig["statusPin"]) == 1 then return 'open' else return 'closed' end +end + + +local function sendResponse(connection, httpCode, errorCode, action, pinConfig, message) + + -- Handle nil inputs + if action == nil then action = '' end + if pinConfig == nil then + pinConfig = {} + pinConfig["door"] = 0 + pinConfig["controlPin"] = 0 + pinConfig["statusPin"] = 0 + end + if message == nil then message = '' end + + connection:send("HTTP/1.0 "..httpCode.." OK\r\nContent-Type: application/json\r\nCache-Control: private, no-store\r\n\r\n") + connection:send('{"error":'..errorCode..', "door":'..pinConfig["door"]..', "controlPin":'..pinConfig["controlPin"]..', "statusPin":'..pinConfig["statusPin"]..', "action":"'..action..'", "message":"'..message..'"}') +end + + +local function sendStatus(connection, pinConfig) + connection:send("HTTP/1.0 200 OK\r\nContent-Type: application/json\r\nCache-Control: private, no-store\r\n\r\n") + connection:send('{"error":0, "door":'..pinConfig["door"]..', "controlPin":'..pinConfig["controlPin"]..', "statusPin":'..pinConfig["statusPin"]..', "action":"status"'..', "status":"'..readDoorStatus(pinConfig)..'"}') +end + + +local function openDoor(connection, pinConfig) + -- errors if door is already open. + local doorStatus = readDoorStatus(pinConfig) + if doorStatus == 'open' then + return false + else + pushTheButton(connection, pinConfig) + return true + end +end + + +local function closeDoor(connection, pinConfig) + -- errors if door is already closed. + local doorStatus = readDoorStatus(pinConfig) + if doorStatus == 'closed' then + return false + else + pushTheButton(connection, pinConfig) + return true + end +end + + +return function (connection, req, args) + + -- The values for pinConfig depend on how your Wemo D1 mini Pro is wired. + -- Adjust as needed. + pinConfig = {} + pinConfig["1"] = {} + pinConfig["1"]["door"] = 1 + pinConfig["1"]["controlPin"] = 2 + pinConfig["1"]["statusPin"] = 5 + pinConfig["2"] = {} + pinConfig["2"]["door"] = 2 + pinConfig["2"]["controlPin"] = 1 + pinConfig["2"]["statusPin"] = 6 + + -- Make this work with both GET and POST methods. + -- In the POST case, we need to extract the arguments. + print("method is " .. req.method) + if req.method == "POST" then + local rd = req.getRequestData() + for name, value in pairs(rd) do + args[name] = value + end + end + + -- validate door input + + if args.door == nil then + sendResponse(connection, 400, -1, args.action, pinConfig[args.door], "No door specified") + return + end + + if pinConfig[args.door] == nil then + sendResponse(connection, 400, -2, args.action, pinConfig[args.door], "Bad door specified") + return + end + + -- perform action + + if args.action == "open" then + if(openDoor(connection, pinConfig[args.door])) then + sendResponse(connection, 200, 0, args.action, pinConfig[args.door], "Door opened") + else + sendResponse(connection, 400, -3, args.action, pinConfig[args.door], "Door is already open") + end + return + end + + if args.action == "close" then + if(closeDoor(connection, pinConfig[args.door])) then + sendResponse(connection, 200, 0, args.action, pinConfig[args.door], "Door closed") + else + sendResponse(connection, 400, -4, args.action, pinConfig[args.door], "Door is already closed") + end + return + end + + if args.action == "toggle" then + pushTheButton(connection, pinConfig[args.door]) + sendResponse(connection, 200, 0, args.action, pinConfig[args.door], "Pushed the button") + return + end + + if args.action == "status" then + sendStatus(connection, pinConfig[args.door]) + return + end + + -- everything else is error + + sendResponse(connection, 400, -5, args.action, pinConfig[args.door], "Bad action") + +end diff --git a/http/garage_door_opener.css b/http/garage_door_control.css similarity index 100% rename from http/garage_door_opener.css rename to http/garage_door_control.css diff --git a/http/garage_door_opener.html b/http/garage_door_control.html similarity index 91% rename from http/garage_door_opener.html rename to http/garage_door_control.html index cc67ca2..74ea20a 100644 --- a/http/garage_door_opener.html +++ b/http/garage_door_control.html @@ -1,7 +1,7 @@ - + Garage Remote @@ -11,7 +11,7 @@ function pushTheButton(door) { - var url = "/garage_door_opener.lua?door=" + door; + var url = "/garage_door.lua?action=toggle&door=" + door; xmlHttp = new XMLHttpRequest(); xmlHttp.onreadystatechange = processRequest; diff --git a/http/garage_door_opener.lua b/http/garage_door_opener.lua deleted file mode 100644 index 74e59c7..0000000 --- a/http/garage_door_opener.lua +++ /dev/null @@ -1,31 +0,0 @@ --- garage_door_opener.lua --- Part of nodemcu-httpserver, example. --- Author: Marcos Kirsch - -local function pushTheButton(connection, pin) - - -- push the button! - -- The hardware in this case is a Wemos D1 Pro with two relay shields. - -- The first relay is controlled with D1. - -- The second one was modified to be controlled with D2. - gpio.write(pin, gpio.HIGH) - gpio.mode(pin, gpio.OUTPUT, gpio.FLOAT) - tmr.delay(300000) -- in microseconds - gpio.mode(pin, gpio.INPUT, gpio.FLOAT) - gpio.write(pin, gpio.LOW) - - -- Send back JSON response. - connection:send("HTTP/1.0 200 OK\r\nContent-Type: application/json\r\nCache-Control: private, no-store\r\n\r\n") - connection:send('{"error":0, "message":"OK"}') - -end - -return function (connection, req, args) - print('Garage door button was pressed!', args.door) - if args.door == "1" then pushTheButton(connection, 1) - elseif args.door == "2" then pushTheButton(connection, 2) - else - connection:send("HTTP/1.0 400 OK\r\nContent-Type: application/json\r\nCache-Control: private, no-store\r\n\r\n") - connection:send('{"error":-1, "message":"Bad door"}') - end -end diff --git a/http/index.html b/http/index.html index 30df7bc..4170487 100644 --- a/http/index.html +++ b/http/index.html @@ -27,7 +27,7 @@
  • Zipped: Same exact file as served above. Server is smart enough to treat the .gz extension correctly (static but gzipped)
  • Arguments: Parses arguments passed in the URL and prints them. (Lua)
  • Post: A form that uses POST method. Displays different content based on HTTP method. (Lua)
  • -
  • Garage door opener: Control GPIO lines via the server. (Lua)
  • +
  • Garage door opener: Control GPIO lines via the server. Or try this simpler and nicer UI. (Lua)
  • NodeMCU info: Shows some basic NodeMCU(Lua)
  • List all server files: Displays a list of all the server files. (Lua)
  • Upload: Update, remove, list files on the server. Beware security implications. By ATAMAH.
  • diff --git a/httpserver-conf.lua b/httpserver-conf.lua index 85ab358..5218523 100644 --- a/httpserver-conf.lua +++ b/httpserver-conf.lua @@ -9,7 +9,7 @@ local auth = {} -- Set to true if you want to enable. auth.enabled = false -- Displayed in the login dialog users see before authenticating. -auth.realm = "nodemcu-httpserver" +auth.realm = "nodemcu" -- Add users and passwords to this table. Do not leave this unchanged if you enable authentication! auth.users = {user1 = "password1", user2 = "password2", user3 = "password3"} diff --git a/init.lua b/init.lua index e6b8837..3d53c79 100644 --- a/init.lua +++ b/init.lua @@ -4,7 +4,7 @@ local wifiConfig = {} -- Possible modes: wifi.STATION : station: join a WiFi network -- wifi.SOFTAP : access point: create a WiFi network --- wifi.wifi.STATIONAP: both station and access point +-- wifi.STATIONAP : both station and access point wifiConfig.mode = wifi.STATION if (wifiConfig.mode == wifi.SOFTAP) or (wifiConfig.mode == wifi.STATIONAP) then