* Slots 0 - 9 are used by the RTC itself
* Slots 10 - 20 are used by the RTC fifo for metadata
-* Slots 21 - 31 are unused
+* Slot 22 used by thermostat itself and holds
+ * bits 0-7 : target value
+ * bits 8-9 : operating mode
+ * bit 10 : fan drive
+* Slots 23 - 31 are unused
* Slots 32 - 128 are used by the RTC fifo for its journal
-- modules
nwfnet = require "nwfnet"
mqc, mqcu = dofile("nwfmqtt.lc").mkclient("nwfmqtt.conf")
-
--- rtcfifo conditional init
-if rtcfifo.ready() == 0 then rtcfifo.prepare() end
-
mqc:lwt(mqttHeartTopic,"dead",1,1)
-- setup peripherals
function logdata(v,e,n)
local t = rtctime.get()
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
+ if rtcfifo.ready() and v then rtcfifo.put(t,v,e,n) end
end
-- go online
local tcVWin = 10 -- longest sliding sampling window
local tcFOffDly = 180000 -- run the fan after turning of H/AC
--- remote configuration (set by MQTT)
+-- remote configuration (set by MQTT or rtcmem, below)
local tctarget = 55
local tcmode = "off" -- "off" "cool" "heat" "emht"
local tcfan = false -- should we keep the fan on?
+local function storeconfig()
+ local v
+ -- are you kidding?
+ if tctarget < 0 then v = 0
+ elseif tctarget > 255 then v = 255
+ else v = tctarget
+ end
+
+ if tcmode == "cool" then v = bit.bor(v, 0x00000100)
+ elseif tcmode == "heat" then v = bit.bor(v, 0x00000200)
+ elseif tcmode == "emht" then v = bit.bor(v, 0x00000300)
+ end
+
+ if tcfan then v = bit.bor(v, 0x00000400) end
+
+ rtcmem.write32(21, v)
+end
+
+-- rtcfifo conditional init
+if rtcfifo.ready() == 0 then
+ rtcfifo.prepare()
+ storeconfig()
+else
+ -- the rtc is good to go, so we must have valid configuration
+ -- in rtcmem. Fetch and decode.
+ local w = rtcmem.read32(21)
+ tctarget = bit.band(w, 0x000000FF)
+ tcfan = not (0 == bit.band(w, 0x00000400))
+ local m = bit.arshift(bit.band(w, 0x00000300),8)
+ tcmode = ({ "off", "cool", "heat", "emht" })[m+1]
+end
+
-- state
local driving = false -- are we driving?
local fanOffDelayTMR = nil -- a timer for nixing the fan
else return -- not for us?
end
+ storeconfig()
doRelays()
end