nwfnet.onmqtt["lamp"] = function(c,t,m) if t and m and t:find("^lamp/[^/]+/out") then dofile("lamp-remote.lc")(m) end end
-- TODO: messages to specific lamps? Multiple brokers?
-function lamp_announce(fn,g,r,b) mqc:publish(mqttBcastPfx,string.format("0 %s %x %x %x",fn,r,g,b),1,1) end
+function lamp_announce(fn,g,r,b) mqc:publish(mqttBcastPfx,string.format("0 %s %x %x %x ;",fn,r,g,b),1,1) end
-- mqtt setup
local mqtt_beat_cancel
--- GLOBAL: tq, remotefb, leddefault, doremotedraw, mqtt_revert, remotetmr, loaddrawfn
-
-local function ledrevert(ix)
- if ix < 3 then
- remotetmr:unregister()
- remotefb:fade(2) doremotedraw()
- tq:queue(500,function() ledrevert(ix+1) end)
- else leddefault(remotefb,0,16,16) end
- dodraw()
-end
+-- GLOBAL: tq, remotefb, doremotedraw, remotetmr, loaddrawfn, remotetqh
return function(msg)
- if mqtt_revert then tq:dequeue(mqtt_revert) end
+ if remotetqh then tq:dequeue(remotetqh) end
- local ix, _, d, m, r, g, b = msg:find("^(%d+)%s+(%w+)%s+(%x+)%s+(%x+)%s+(%x+)%s*$")
- if ix then
- g = tonumber(g,16); r = tonumber(r,16); b = tonumber(b,16)
+ local fifo = (require "fifo")()
+ local function fdq() if not fifo:dequeue(function(k) k() end) then remotetqh = nil end end
- remotetmr:unregister()
- loaddrawfn(m)(remotetmr,remotefb,g,r,b); doremotedraw()
+ local d,m,r,g,b
- -- if there's a duration set, register a timer to reset the display to the default
- local dn = tonumber(d)
- if dn and dn > 0 then tq:queue(math.min(dn,6870947),ledrevert,0) end
+ for d,m,r,g,b in msg:gmatch("(%d+)%s+(%w+)%s+(%x+)%s+(%x+)%s+(%x+)%s*;") do
+ g = tonumber(g,16); r = tonumber(r,16); b = tonumber(b,16); d = tonumber(d)
+ if d and d > 0 then
+ fifo:queue(function() remotetqh = tq:queue(d,fdq) end)
+ end
+ fifo:queue(function()
+ remotetmr:unregister()
+ loaddrawfn(m)(remotetmr,remotefb,g,r,b); doremotedraw()
+ remotetqh = tq:queue(1,fdq) -- run on callback to avoid stack problems
+ end)
end
-
+ fdq() -- start party
end