nwfnet = require "nwfnet"
mqc, mqcu = dofile("nwfmqtt.lc").mkclient("nwfmqtt.conf")
-mqcCan = false
-
-- rtcfifo conditional init
if rtcfifo.ready() == 0 then rtcfifo.prepare() end
--- timers
-tq = (dofile "tq.lc")(tmr.create())
-
-- setup peripherals
ow.setup(owpin)
i2c.setup(0,2,3,i2c.SLOW)
-- hook registry, MQTT connection management
-local mqtt_beat_cancel
-local mqtt_reconn_poller
-local function mqtt_reconn()
- mqtt_reconn_poller = tq:queue(30000,mqtt_reconn)
+local mqtt_reconn_timer
+local function mqtt_reconn(_t)
mqc:close(); dofile("nwfmqtt.lc").connect(mqc,"nwfmqtt.conf")
end
+local function mqtt_conn()
+ mqtt_reconn_timer = tmr.create()
+ mqtt_reconn(mqtt_reconn_timer)
+ mqtt_reconn_timer:alarm(30000,tmr.ALARM_AUTO,mqtt_reconn)
+end
+
+local mqtt_beat_cron
nwfnet.onnet["init"] = function(e,c)
if e == "mqttdscn" and c == mqc then
- if mqtt_beat_cancel then mqtt_beat_cancel(); mqtt_beat_cancel = nil end
- if not mqtt_reconn_poller then mqtt_reconn() end
- mqcCan = false
+ if mqtt_beat_cron then mqtt_beat_cron:unschedule(); mqtt_beat_cron = nil end
+ if not mqtt_reconn_timer then mqtt_conn() end
elseif e == "mqttconn" and c == mqc then
- if mqtt_reconn_poller then tq:dequeue(mqtt_reconn_poller); mqtt_reconn_poller = nil end
- if not mqtt_beat_cancel then mqtt_beat_cancel = dofile("nwfmqtt.lc").heartbeat(mqc,mqttHeartTopic,tq,mqttHeartTick) end
+ if mqtt_reconn_timer then
+ mqtt_reconn_timer:unregister()
+ mqtt_reconn_timer = nil
+ end
+ mqc:lwt(mqttHeartTopic,"dead",1,1)
+ mqtt_beat_cron = cron.schedule("*/5 * * * *",function(e) mqc:publish(mqttHeartTopic,"beat",1,1) end)
mqc:publish(mqttHeartTopic,"alive",1,1)
mqc:subscribe(mqttTargTopic,1)
mqc:subscribe(mqttModeTopic,1)
mqc:subscribe(mqttFanTopic ,1)
- mqcCan = true
elseif e == "wstagoip" then
- if not mqtt_reconn_poller then mqtt_reconn() end
+ if not mqtt_reconn_timer then mqtt_conn() end
end
end
-- data logging
function logdata(v,e,n)
local t = rtctime.get()
- if mqcCan then mqc:publish(mqttPubRoot..n,sjson.encode({ ['t']=t, ['v']=v, ['e']=e }),1,1) end
+ if mqtt_reconn_timer == nil then mqc:publish(mqttPubRoot..n,sjson.encode({ ['t']=t, ['v']=v, ['e']=e }),1,1) end
if v then rtcfifo.put(t,v,e,n) end
end
-- state
local driving = false -- are we driving?
-local fanOffDelayTQ = nil -- a tq object for nixing the fan
+local fanOffDelayTMR = nil -- a timer for nixing the fan
local vdenom = 0 -- window votes elapsed
local vnum = 0 -- window votes accumulated
local verr = 0 -- errors during voting window
return v -- XXX debug
end
+local function stopFan()
+ -- if we aren't forcing the fan on, schedule it to be turned off later
+ if not tcfan and fanOffDelayTMR == nil then
+ tcfan = true
+ fanOffDelayTMR = tmr.create()
+ fanOffDelayTMR:alarm(tcFOffDly,tmr.ALARM_SINGLE,function()
+ fanOffDelayTMR = nil
+ tcfan = false
+ doRelays()
+ end)
+ end
+end
+
nwfnet.onmqtt["th"] = function(c,t,m)
if not m then return end
if t == mqttTargTopic then
- driving = false; resetTempAcc()
+ if driving then stopFan() end
+ resetTempAcc()
tctarget = tonumber(m) or tctarget
+ -- don't stop driving now, let the poller logic handle that
elseif t == mqttModeTopic then
- driving = false; resetTempAcc()
- tcmode = m
+ if driving then stopFan() end
+ driving = false -- stop driving now, since the mode differs!
+ resetTempAcc()
+ tcmode = m
elseif t == mqttFanTopic then
- nextFan = (m == "on" or m == "1")
+ nextFan = (m == "on" or m == "1")
- if fanOffDelayTQ == nil then
+ if fanOffDelayTMR == nil then
-- we aren't about to automate the fan off, so go ahead and let the
-- setting have immediate effect
tcfan = nextFan
else
-- we are about to turn off the fan anyway; is that what we should do?
if nextFan then -- no, keep the fan on
- tq:dequeue(fanOffDelayTQ)
- fanOffDelayTQ = nil
+ fanOffDelayTMR:unregister()
+ fanOffDelayTMR = nil
tcfan = nextFan
- -- else let the callback turn it off for us
+ -- else let the callback turn it off for us
end
end
else return -- not for us?
local function startDrive()
driving = true
-- nix any future fan-off we might have had scheduled
- if fanOffDelayTQ ~= nil then tq:dequeue(fanOffDelayTQ); fanOffDelayTQ = nil end
+ if fanOffDelayTMR ~= nil then fanOffDelayTMR:unregister(); fanOffDelayTMR = nil end
end
local function stopDrive()
driving = false
- -- if we aren't forcing the fan on, schedule it to be turned off later
- if not tcfan and fanOffDelayTQ == nil then
- tcfan = true
- fanOffDelayTQ = tq:queue(tcFOffDly, function()
- fanOffDelayTQ = nil
- tcfan = false
- doRelays()
- end)
- end
+ stopFan()
end
local function therm_res(t)
local r = doRelays()
-- XXX debug
- if mqcCan then
+ if mqtt_reconn_timer == nil then
mqc:publish(mqttPubRoot.."zz",
sjson.encode({ ['m']=m, ['r']=r, ['h']=node.heap(),
- ['f']=tempAccFan, ['ftq']=(fanOffDelayTQ ~= nil),
+ ['f']=tempAccFan, ['ft']=(fanOffDelayTMR ~= nil),
['c']=vdenom, ['v']=vnum, ['e']=verr }),
1,1)
end
end
local function thermpoller()
- dofile("ow-ds18b20.lc")(tq, owpin, owtherm, 0,
+ dofile("ow-ds18b20.lc")(owpin, owtherm, 0,
function(r)
therm_res(r)
- therm_poll_cancel = tq:queue(tcPollIval,thermpoller)
+ tmr.create():alarm(tcPollIval,tmr.ALARM_SINGLE,thermpoller)
end)
end