Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- WiFi IoT Signaleer 1.0 for ESP8266/nodeMCU - See http://imgur.com/sNi8Ou6
- -- (c) 2016 Chris Burri @ NISTON Engineering Works
- -- http://niston.wordpress.com
- -- HTTP Polling Version:
- -- Periodically retrieves a status URL and updates connected lamps & beeper accordingly.
- -- Status page must serve string in the format: "ID=SIGNLR;R=0;Y=0;G=1;S=0" where
- -- R=Red Lamp, Y=Yellow Lamp, G=Green Lamp, S=Beeper and
- -- 0=Off, 1=On, 2=Blink, 3=Blink_Reversed (see Signal definitions below for explanation of "reversed")
- -- ID=SIGNLR is the Protocol's Magic String. It must preclude everything else and match with what's in the magicID variable.
- -- Signaleer configuration
- httpURL = "https://my.server.com/signaleer.aspx"; -- status page URL
- wlanSSID = "wlanSSID"; -- WiFi network name
- wlanPwd = "wlanPassword"; -- WiFi network password
- pollInterval = 90; -- HTTP polling run interval (polling for status update) in seconds
- pollMaxRetries = 5; -- maximum http.get() retries during poll run before aborting
- pollRetryDelay = 5; -- delay in seconds between failure and rescheduled poll
- beepMaxDuration = 15; -- maximum audible alert duration in seconds
- -- Code Below --
- -- Update protocol related
- magicID = "ID=SIGNLR"; -- magic string
- -- Timer definitions (7 IDs available form 0...6).
- timerBlink = 0; -- Main/Blinker procedure timer
- timerPoll = 1; -- HTTP poll procedure timer
- timerRescheduler = 2; -- HTTP failed poll reschedule timer
- timerResetBeeper = 3; -- Beep limiter timer
- -- GPIO pin definitions
- pinBeeper = 1; -- beeper GPIO pin
- pinLampRed = 2; -- red lamp GPIO pin
- pinLampYellow = 6; -- yellow lamp GPIO pin
- pinLampGreen = 7; -- green lamp GPIO pin
- -- Signal definitions
- SIG_OFF = "0"; -- signal off
- SIG_ON = "1"; -- signal on
- SIG_BLINK = "2"; -- signal alternating (2Hz)
- SIG_BLINK_REV = "3"; -- signal alternating (2Hz reversed: on when blink is off, off when blink is on)
- -- signal image variables
- signalRed = SIG_OFF; -- red signal lamp
- signalYellow = SIG_OFF; -- yellow signal lamp
- signalGreen = SIG_OFF; -- green signal lamp
- signalBeeper = SIG_OFF; -- piezo beeper
- -- State variables
- intervalBlink = 500; -- milliseconds between run/blinker state change intervals - do NOT configure this
- stringLastStatus = nil; -- last obtained status string; nil when no update
- blinkState = 0; -- blinker status; alternates between 0 and 1 at 2Hz (intervalBlink=500ms)
- pollFails = 0; -- count of subsequently failed HTTP polls. reset to zero after pollMaxRetries
- flagBeeptimeExceeded = 0; -- Beep duration limiter: set to 1 if beeper is to be silenced
- signalBeeperPrevious = 0; -- previous beeper state, used to detect state transitions
- -- Initialize GPIO ports
- function InitGPIO()
- gpio.mode(pinBeeper,gpio.OUTPUT);
- gpio.mode(pinLampRed,gpio.OUTPUT);
- gpio.mode(pinLampYellow, gpio.OUTPUT);
- gpio.mode(pinLampGreen, gpio.OUTPUT);
- gpio.write(pinBeeper, 0);
- gpio.write(pinLampRed, 0);
- gpio.write(pinLampYellow, 0);
- gpio.write(pinLampGreen, 0);
- end
- -- WiFi STA_GOTIP callback
- function WifiConnected(previousState)
- ip, nm, gw = wifi.sta.getip();
- print("WiFi connected (DHCP). IPAddr=" .. ip .. " Netmask=" .. nm .. " Gateway=" .. gw);
- ExecutePoll(); -- poll immediately when connected
- end
- -- Wifi STA_WRONGPWD callback
- function WifiWrongPwd()
- print("WiFi connection failed: Invalid Password.");
- end
- -- Wifi STA_CONNECTING callback
- function WifiConnecting()
- ssid, password, bssid_set, bssid = wifi.sta.getconfig();
- print("WiFi connecting to " .. ssid .. " (" .. bssid .. ")...");
- end
- -- Wifi STA_FAIL callback
- function WifiConnectionFail()
- print("WiFi connection failed: Connection Failure.");
- end
- -- WiFi Setup
- function SetupWiFi()
- wifi.sta.eventMonStop();
- wifi.sta.autoconnect(0);
- wifi.setmode(wifi.STATION);
- wifi.setphymode(wifi.PHYMODE_N);
- wifi.sta.sethostname("Signaleer");
- wifi.sta.config(wlanSSID, wlanPwd, 0);
- wifi.sleeptype(wifi.NONE_SLEEP);
- wifi.sta.eventMonReg(wifi.STA_GOTIP, function(previous_State) WifiConnected(previous_State) end);
- wifi.sta.eventMonReg(wifi.STA_WRONGPWD, function() WifiWrongPwd() end);
- wifi.sta.eventMonReg(wifi.STA_CONNECTING, function() WifiConnecting() end);
- wifi.sta.eventMonReg(wifi.STA_FAIL, function() WifiConnectionFail() end);
- wifi.sta.eventMonStart(200);
- wifi.sta.connect();
- wifi.sta.autoconnect(1);
- end
- -- test all actors (lamp & beeper test)
- function TestActors()
- ClearActors();
- Beep(500);
- tmr.delay(1000000);
- tmr.wdclr();
- gpio.write(pinLampRed, 1);
- Beep(75);
- tmr.delay(1000000);
- tmr.wdclr();
- gpio.write(pinLampYellow, 1);
- Beep(75);
- tmr.delay(1000000);
- tmr.wdclr();
- gpio.write(pinLampGreen, 1);
- Beep(75);
- tmr.delay(1000000);
- tmr.wdclr();
- ClearActors();
- tmr.delay(1000000);
- tmr.wdclr();
- end
- -- stop all actors
- function ClearActors()
- gpio.write(pinBeeper, 0);
- gpio.write(pinLampRed, 0);
- gpio.write(pinLampYellow, 0);
- gpio.write(pinLampGreen, 0);
- end
- -- hard beep for duration milliseconds
- function Beep(duration)
- duration = duration or 500;
- gpio.write(pinBeeper, 1);
- tmr.delay(duration * 1000);
- gpio.write(pinBeeper, 0);
- end
- -- signal image "WAITING FOR IP": red/yellow alternating blink
- function SignalWaitIP()
- signalRed = SIG_BLINK;
- signalYellow = SIG_BLINK_REV;
- signalGreen = SIG_OFF;
- signalBeeper = SIG_OFF;
- UpdateSignaleer();
- end
- -- signal image "WAITING FOR UPDATE": red/yellow+green alternating blink
- function SignalWaitUpdate()
- signalRed = SIG_BLINK;
- signalYellow = SIG_BLINK_REV;
- signalGreen = SIG_BLINK_REV;
- signalBeeper = SIG_OFF;
- UpdateSignaleer();
- end
- -- signal image "GENERAL ERROR": red/beeper alternating blink
- function SignalErrorStatus()
- signalRed = SIG_BLINK;
- signalYellow = SIG_OFF;
- signalGreen = SIG_OFF;
- signalBeeper = SIG_BLINK_REV;
- UpdateSignaleer();
- end
- -- fetch status URL from HTTP server
- function ExecutePoll()
- print("Polling " .. httpURL .. " for update...");
- http.get(httpURL, nil, function(code, data)
- if (code == 200) then
- -- reset poll fail count
- pollFails = 0;
- -- parse the received data
- if ParseStatusString(data) == 0 then
- print("OK: " .. stringLastStatus);
- else
- print("FAIL: Protocol error (Magic not found).");
- end
- else
- pollFails = pollFails + 1;
- if pollFails < pollMaxRetries then
- -- schedule retry
- print("FAIL (Code " .. code .. "): Scheduling retry #" .. pollFails .. "...");
- tmr.alarm(timerRescheduler, (pollRetryDelay * 1000), tmr.ALARM_SINGLE, function()
- -- execute rescheduled Poll
- ExecutePoll();
- end)
- else
- -- give up
- print("FAIL (Code " .. code .. "): Update failed.");
- stringLastStatus = 'ERROR';
- pollFails = 0;
- end
- end
- end)
- end
- -- parse status string from HTTP server
- function ParseStatusString(statusString)
- -- statusString must start with protocol magic string
- if string.find(statusString, magicID) == 1 then
- -- parse status String (thanks to RyanE@Freenode)
- for kv in (statusString .. ";"):gfind("(.-);") do local _,_,k,v = kv:find("(.+)=(.+)")
- if (k == "R") then signalRed = v end
- if (k == "Y") then signalYellow = v end
- if (k == "G") then signalGreen = v end
- if (k == "S") then signalBeeper = v end
- end
- stringLastStatus = statusString;
- return 0;
- else
- -- magic ID not present : Communications error, probably wrong protocol/URL
- stringLastStatus = "ERROR";
- return -1;
- end
- end
- -- update signaleer with current signal image & implement beep duration limiter
- function UpdateSignaleer()
- -- upate lamps
- UpdatePin(pinLampRed, signalRed);
- UpdatePin(pinLampYellow, signalYellow);
- UpdatePin(pinLampGreen, signalGreen);
- -- detect state transition: beeper disabled->enabled - arm beep limiter
- if signalBeeperPrevious == SIG_OFF and signalBeeper ~= SIG_OFF then
- -- spin up one-shot timer
- tmr.alarm(timerResetBeeper, (beepMaxDuration * 1000), tmr.ALARM_SINGLE, function()
- -- trigger beep limiter: set flag after beepMaxDuration
- flagBeeptimeExceeded = 1;
- --print("Beeper maximum alert duration exceeded; limiter triggered.");
- end)
- end
- -- detect state transition: beeper enabled->disabled - reset beep limiter
- if signalBeeperPrevious ~= SIG_OFF and signalBeeper == SIG_OFF then
- -- reset & disarm beep limiter
- flagBeeptimeExceeded = 0;
- tmr.stop(timerResetBeeper);
- tmr.unregister(timerResetBeeper);
- end
- signalBeeperPrevious = signalBeeper;
- -- check if beep time exceeded
- if flagBeeptimeExceeded == 0 then
- -- no, update beeper according to status string
- UpdatePin(pinBeeper, signalBeeper);
- else
- -- yes, always silence beeper
- UpdatePin(pinBeeper, SIG_OFF);
- end
- end
- -- update GPIO pin with signal value
- function UpdatePin(pinNumber, Value)
- if Value == SIG_OFF then
- gpio.write(pinNumber, 0);
- elseif Value == SIG_ON then
- gpio.write(pinNumber, 1);
- elseif Value == SIG_BLINK then
- gpio.write(pinNumber, blinkState);
- elseif Value == SIG_BLINK_REV then
- gpio.write(pinNumber, 1 - blinkState);
- end
- end
- -- string splitter function [sourced from stackoverflow]
- function SplitString(pString, pPattern)
- local Table = {} -- NOTE: use {n = 0} in Lua-5.0
- local fpat = "(.-)" .. pPattern
- local last_end = 1
- local s, e, cap = pString:find(fpat, 1)
- while s do
- if s ~= 1 or cap ~= "" then
- table.insert(Table,cap)
- end
- last_end = e+1
- s, e, cap = pString:find(fpat, last_end)
- end
- if last_end <= #pString then
- cap = pString:sub(last_end)
- table.insert(Table, cap)
- end
- return Table
- end
- -- main program
- print("");
- print("");
- print("WiFi IoT Signaleer - (c) 2016 Chris Burri @ NISTON Engineering Works");
- print("See http://niston.wordpress.com");
- print("");
- -- initialize GPIO
- InitGPIO();
- -- Power On Self Test
- print ("Lamps & Beeper Test...");
- TestActors();
- -- Setup and connect WiFi
- SetupWiFi();
- -- setup main "loop" timer
- tmr.alarm(timerBlink, intervalBlink, 1, function()
- -- toggle blinker state
- blinkState = 1 - blinkState;
- -- update light signal & beeper status
- if wifi.sta.getip() == nil then
- -- waiting for IP: blink red/yellow alternating
- SignalWaitIP();
- elseif stringLastStatus == nil then
- -- first status update: blink red/yellow&green alternating
- SignalWaitUpdate();
- elseif stringLastStatus == 'ERROR' then
- -- ERROR: blink red
- SignalErrorStatus();
- else
- -- OK; Update signaleer according to signal image variables
- UpdateSignaleer();
- end
- end)
- -- setup HTTP polling timer
- tmr.alarm(timerPoll, pollInterval * 1000, 1, function()
- if wifi.sta.getip() ~= nil then
- ExecutePoll();
- end
- end)
- -- ## END OF CODE ##
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement