summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2024-01-13 15:11:57 +0100
committerAki <please@ignore.pl>2024-01-13 15:40:18 +0100
commit4614f11a90fda9117f12f7435c163b90b974145e (patch)
tree704712c4e6c3b7b84d5b765c702245d230c1449e
parent6e430351816299521461739ce40af0493e358d8a (diff)
downloadnodemcu-wakeup-4614f11a90fda9117f12f7435c163b90b974145e.zip
nodemcu-wakeup-4614f11a90fda9117f12f7435c163b90b974145e.tar.gz
nodemcu-wakeup-4614f11a90fda9117f12f7435c163b90b974145e.tar.bz2
Wakeups can now be called arbitrary number of times
Most of the state has been refactored into wakeup module in attempt to reduce impact on the elua. Sendout timer closure still has two upvalues.
-rw-r--r--run.lua100
1 files changed, 62 insertions, 38 deletions
diff --git a/run.lua b/run.lua
index 3c22c30..67e3fdf 100644
--- a/run.lua
+++ b/run.lua
@@ -1,12 +1,11 @@
-local wol = {
+local wakeup = {
port = 9,
- timer = tmr.create(),
}
--- Reads configuration file at [[path]] and parses a pair of MAC and broadcast addresses from it. Builds a Wake-on-LAN
--- magic packet and saves it for later use with :worker(). Returns true if no errors were encountered, otherwise a nil.
-function wol:configure (path)
+function wakeup:configure (path)
local fd = file.open(path)
if not fd then
print("Config file not found", path)
@@ -29,53 +28,78 @@ function wol:configure (path)
end
---- Initializes and returns worker that implements :sendout(interval, times, callback) that attempts to wake up
---- designated host number of [[times]] each separated by [[interval]]. After all attempts [[callback]] is called.
-function wol:worker ()
+function wakeup:open ()
+ self.udp = net.createUDPSocket()
+end
+
+
+function wakeup:close ()
+ if self.udp then
+ self.udp:close()
+ end
+end
+
+
+--- Creates a new counter that has :up() method that returns true until it gets called N [[times]]. Then it returns only
+--- false.
+local
+function new_counter (times)
return {
- config = self,
- udp = net.createUDPSocket(),
- timer = tmr.create(),
count = 0,
- sendout = function (self, interval, times, cb)
- self.times = times
- return self.timer:alarm(interval, tmr.ALARM_SEMI, function (timer)
- self.count = self.count + 1
- if self.count <= self.times then
- print("Waking up", self.config.mac, self.config.addr)
- self.udp:send(self.config.port, self.config.addr, self.config.data)
- timer:start()
- else
- timer:unregister()
- cb()
- end
- end)
+ times = times,
+ up = function (self)
+ self.count = self.count + 1
+ return self.count <= self.times
end,
}
end
-wol.timer:register(1000, tmr.ALARM_SINGLE, function ()
- gpio.mode(4, gpio.OUTPUT)
- gpio.write(4, gpio.HIGH)
- if not wol:configure("wakeup.conf") then
+--- Begins to send Wake-on-LAN magic packets to the broadcast [[.addr]] for selected [[.mac]]. Packets are sent several
+--- [[times]] each separated by [[interval]]. Callback is called [[after]] all packets are sent.
+function wakeup:sendout (interval, times, after)
+ self:open()
+ local count = new_counter(times)
+ return tmr.create():alarm(interval, tmr.ALARM_SEMI, function (timer)
+ if count:up() then
+ print("Waking up", self.mac, self.addr)
+ self.udp:send(self.port, self.addr, self.data)
+ timer:start()
+ else
+ timer:unregister()
+ self:close()
+ after()
+ end
+ end)
+end
+
+
+--- Sets up Wake Up to run when wifi is connected and configured in a network. Runs callbacks [[before]] send-outs, and
+--- [[after]] they are done.
+function wakeup:setup (before, after)
+ if not self:configure("wakeup.conf") then
error("Could not configure wakeup")
end
- wifi.setmode(wifi.STATION, false)
-
wifi.eventmon.register(wifi.eventmon.STA_GOT_IP, function ()
- local waker = wol:worker()
- gpio.write(4, gpio.LOW)
- waker:sendout(500, 5, function ()
- wifi.setmode(wifi.NULLMODE, false)
- gpio.write(4, gpio.HIGH)
- end)
+ before()
+ self:sendout(500, 5, after)
end)
-
- wifi.sta.connect()
-end)
+end
return function ()
- wol.timer:start()
+ gpio.write(4, gpio.HIGH)
+ gpio.mode(4, gpio.OUTPUT)
+
+ tmr.create():alarm(1000, tmr.ALARM_SINGLE, function ()
+ wakeup:setup(
+ function () gpio.write(4, gpio.LOW) end,
+ function ()
+ wifi.setmode(wifi.NULLMODE, false)
+ gpio.write(4, gpio.HIGH)
+ end
+ )
+ wifi.setmode(wifi.STATION, false)
+ wifi.sta.connect()
+ end)
end