Skip to content

Instantly share code, notes, and snippets.

@bonzini
Last active September 11, 2019 12:06
Show Gist options
  • Save bonzini/04f9c41fedc5cf3e3d2c0ab843d5a7c9 to your computer and use it in GitHub Desktop.
Save bonzini/04f9c41fedc5cf3e3d2c0ab843d5a7c9 to your computer and use it in GitHub Desktop.
NodeMCU script to control two relays via MQTT
connected = false
-- GPIO helpers
function blink_led(on, off, times, callback)
if times == 0 then
if type(callback) == "function" then
callback()
end
return
end
gpio.write(0, gpio.LOW)
gpio.mode(0, gpio.OUTPUT)
tmr.create():alarm(on, tmr.ALARM_SINGLE, function()
gpio.write(0, gpio.HIGH)
tmr.create():alarm(off, tmr.ALARM_SINGLE, function()
blink_led(on, off, times - 1, callback)
end)
end)
end
function toggle(pin)
blink_led(200, 200, 3)
gpio.write(pin, gpio.HIGH)
tmr.create():alarm(1000, tmr.ALARM_SINGLE, function()
gpio.write(pin, gpio.LOW)
end)
end
-- all the code is event driven, so each function calls the
-- next one through a callback
function startup()
if file.open("init.lua") == nil then
print("init.lua deleted or renamed")
else
print("Running")
file.close("init.lua")
main()
end
end
-- blink the LED until Wifi is connected, then do a rapid on-off sequence
-- runs asynchronously in the background until Wifi is connected
function blink()
blink_led(500, 500, 1, function()
if not connected then
blink()
else
blink_led(50, 50, 5)
end
end)
end
function main()
gpio.mode(0, gpio.INPUT)
if gpio.read(0) == 0 or file.open("eus_params.lua") == nil then
print("Starting enduser portal")
blink()
enduser_setup.start(connect_wifi,
function(err, str)
print("enduser_setup: Err #" .. err .. ": " .. str)
end
)
return
end
file.close("eus_params.lua")
blink()
connect_wifi()
end
function connect_wifi()
local p = {}
local x = dofile("eus_params.lua")
p.ssid = x["wifi_ssid"]
p.pwd = x["wifi_password"]
p.save = false
p.auto = false
wifi.setmode(wifi.STATION)
wifi.sta.config(p)
wifi.eventmon.register(wifi.eventmon.STA_DISCONNECTED, wifi_badstuff)
wifi.eventmon.register(wifi.eventmon.STA_DHCP_TIMEOUT, wifi_badstuff)
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, got_wifi)
wifi.sta.connect()
end
-- a reset the easiest way to clear all state :)
function wifi_badstuff()
print("Wifi disconnected, restarting")
node.restart()
end
function got_wifi()
if connected then
return
end
print("Connected to wifi")
connected = true
try_mqtt()
end
function try_mqtt()
m = mqtt.Client("entrata", 120)
m:lwt("/entrata/status", "offline", 1, 1)
m:on("message",
function(client, topic, data)
if topic == "/entrata/cancello" then toggle(1) end
if topic == "/entrata/garage" then toggle(2) end
end
)
m:on("offline", function(client)
tmr.create():alarm(1000, tmr.ALARM_SINGLE, try_mqtt)
end
)
-- add this: <input name=mqtt_broker type=text placeholder='MQTT broker IP address' />
-- to the default enduser_setup.html to customize the IP address for the MQTT broker
--
local x = dofile("eus_params.lua")
if not x["mqtt_broker"] then
x["mqtt_broker"] = "192.168.10.191"
end
m:connect(x["mqtt_broker"], 1883, false,
function(client)
print("Connected to MQTT")
client:subscribe("/entrata/cancello", 0)
client:subscribe("/entrata/garage", 0)
client:publish("/entrata/status", 'online', 1, 1)
end,
function(client, reason)
print("failed reason: " .. reason)
tmr.create():alarm(1000, tmr.ALARM_SINGLE, try_mqtt)
end
)
end
gpio.write(1, gpio.LOW)
gpio.write(2, gpio.LOW)
gpio.mode(1, gpio.OUTPUT)
gpio.mode(2, gpio.OUTPUT)
print("Startup will resume momentarily, you have 3 seconds to abort.")
print("Press USER button to enable the Wifi setup portal.")
print("Waiting...")
blink_led(50, 950, 4, startup)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment