Last active
September 11, 2019 12:06
-
-
Save bonzini/04f9c41fedc5cf3e3d2c0ab843d5a7c9 to your computer and use it in GitHub Desktop.
NodeMCU script to control two relays via MQTT
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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