Re: Scen aktiverad på tid i lua
Posted: 29 Sep 2018, 11:41
local wind_km_h = ( tonumber(api.get('/weather')['Wind'])) ??? funkar det?
Code: Select all
--[[
%% properties
%% events
5 CentralSceneEvent
%% globals
--]]
--[[
-- EventRunnerLight. Single scene instance framework
-- Copyright 2018 Jan Gabrielsson. All Rights Reserved.
-- Email: jan@gabrielsson.com
--]]
_version = "1.1"
osTime = os.time
osDate = os.date
_debugFlags = { post=false,invoke=false,triggers=false,dailys=false,timers=false,rule=false,fibaro=true,fibaroGet=false }
if dofile then dofile("EventRunnerDebug.lua") end -- Support for running off-line on PC/Mac
---- Single scene instance, all fibaro triggers call main(sourceTrigger) ------------
function printf(...) fibaro:debug(string.format(...)) end
-- Table how much to open scheds depending on time and month, other time values are interpolated
SouthValue = {
Jan = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Feb = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Mar = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Apr = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
May = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Jun = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Jul = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Aug = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Sep = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",99}},
Oct = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Nov = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Dec = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
}
WestValue = {
Jan = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Feb = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Mar = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Apr = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
May = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Jun = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Jul = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Aug = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Sep = {{"09:00",99},{"10:00",99},{"11:00",99},{"11:30",99},{"12:30",99},{"13:00",99},{"14:00",85},{"15:00",60},{"17:00",45},{"18:00",99},{"19:00",99},{"20:00",99}},
Oct = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Nov = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
Dec = {{"09:00",80},{"10:00",65},{"11:00",50},{"11:30",33},{"12:30",50},{"13:00",65},{"14:00",80},{"15:00",100}},
}
local houseSheds = {
--South
{name="Matsal",start="09:00",stop="18:00",id=491,tab=SouthValue}, --Matsal
{name="Kök syd",start="09:00",stop="18:00",id=485,tab=SouthValue}, --Kök syd
{name="Sveas Rum",start="09:00",stop="18:00",id=497,tab=SouthValue}, --Sveas Rum
{name="Augusts Rum",start="09:00",stop="18:00",id=500,tab=SouthValue}, --Augusts Rum
--West
{name="Vardagsrum Nere",start="09:00",stop="18:00",id=488,tab=WestValue}, --Matsal
{name="Bibliotek",start="09:00",stop="18:00",id=482,tab=WestValue}, --Kök syd
{name="Lekrum Väst",start="09:00",stop="18:00",id=506,tab=WestValue}, --Vardagsrum Uppe
--Vardagsrum Uppe
{name="Vardagsrum Uppe",start="09:00",stop="18:00",id=503,tab=WestValue} --Vardagsrum Uppe
}
function shedsValue(time,shed) -- Calculates how much sheds should be open given time and month
local mt,stop,start = shed.tab[osDate("%b")]
for _,t in ipairs(mt) do if t[1] <= time then start = t else break end end
start = start or mt[1][1] -- lowest/equal before time or the first value
for _,t in ipairs(mt) do if t[1] >= time then stop = t break end end
stop = stop or mt[#mt][1] -- highest/equal after time or the last value
if time < mt[1][1] or time>mt[#mt][1] then return 0 end -- Time outside min & max returns 0
local x1,y1,x2,y2 = toTime(start[1]),start[2],toTime(stop[1]),stop[2]
return x1==x2 and y1 or math.floor((y2-y1)/(x2-x1)*(toTime(time)-x1)+y1+0.5) -- linear extrapolation for times not in table
end
local keepShedsClosed = false
local goodWeather = {[30]=true,[36]=true,[34]=true,[32]=true,[28]=true} -- conditions when sheds should be open
local maxWind = 25.0
function main(sourceTrigger)
local event = sourceTrigger
if event.type=='schedule' then
local shed = event.shed
local value = shedsValue(osDate("%H:%M"),shed)
local name,id = event.shed.name,event.shed.id
if not keepShedsClosed then
printf("Setting %s with id %s to value %s",name,id,value)
fibaro:call(id,"setValue",value)
else
printf("Keeping %s with id %s closed",name,id)
end
if osDate("%H:%M") > shed.stop then time = "n/"..shed.start else time = "+/00:30" end
printf("Scheduling %s for %s",name,osDate("%X",toTime(time)))
post(event,time)
end
-- setUp initial posts of daily events
if event.type == 'autostart' or event.type == 'other' then
local now,time = osDate("%H:%M")
for _,shed in ipairs(houseSheds) do
time = "t/"..osDate("%H:%M:%S")
if now <= shed.start or now > shed.stop then time = "n/"..shed.start end
printf("Scheduling %s for %s",shed.name,osDate("%X",toTime(time)))
post({type='schedule', shed=shed},time)
end
post({type='checkWeather'}) -- and also start checking weather every 2 minutes
end
if event.type=='checkWeather' then
local weather = api.get("/weather")
local wind = weather.Wind
local wcode = weather.ConditionCode
if wind <= maxWind and goodWeather[wcode] then -- good weather, keep sheds open
post({type='closeSheds', close=false}) -- open sheds
else
post({type='closeSheds', close=true}) -- close sheds
end
post(event,"+/00:02") -- check weather every other minute
end
if event.type == 'closeSheds' and event.close and not keepShedsClosed then -- close all Sheds
keepShedsClosed = true
for _,shed in ipairs(houseSheds) do
fibaro:call(shed.id,"setValue",0)
end
elseif event.type == 'closeSheds' and (not event.close) and keepShedsClosed then -- restore all sheds
local now = osDate("%H:%M") -- open sheds again
keepShedsClosed = false
for _,shed in ipairs(houseSheds) do
fibaro:call(shed.id,"setValue",shedsValue(now,shed))
end
end
if event.type=='event' and event.event.data.deviceId==5 then -- Toggle sheds at keypress (any)
post({type='sheds', close=(not keepShedsClosed)})
end
end -- main()
------------------------ Framework, do not change ---------------------------
-- Spawned scene instances post triggers back to starting scene instance ----
local _trigger = fibaro:getSourceTrigger()
local _type, _source = _trigger.type, _trigger
local _MAILBOX = "MAILBOX"..__fibaroSceneId
if _type == 'other' and fibaro:args() then
_trigger,_type = fibaro:args()[1],'remote'
end
function _midnight() t=osDate("*t"); t.min,t.hour,t.sec=0,0,0; return osTime(t) end
function hm2sec(hmstr)
local sun,offs = hmstr:match("^(%a+)([+-]?%d*)")
if sun and (sun == 'sunset' or sun == 'sunrise') then
hmstr,offs = fibaro:getValue(1,sun.."Hour"), tonumber(offs) or 0
end
local h,m,s = hmstr:match("(%d+):(%d+):?(%d*)")
return h*3600+m*60+(tonumber(s) or 0)+(offs or 0)*60
end
function toTime(time)
if type(time) == 'number' then return time end
local p = time:sub(1,2)
if p == '+/' then return hm2sec(time:sub(3))+osTime() -- Plus now
elseif p == 'n/' then
local t1 = _midnight()+hm2sec(time:sub(3))-osTime() -- Next
return (t1 > 0 and t1 or t1+24*60*60)+osTime()
elseif p == 't/' then return _midnight()+hm2sec(time:sub(3)) -- Today
else return hm2sec(time) end
end
function post(event, time) return setTimeout(function() main(event) end,((time and toTime(time)-osTime()) or 0)*1000) end
function cancel(ref) if ref then clearTimeout(ref) end return nil end
function postRemote(sceneID,event) event._from=__fibaroSceneId; fibaro:startScene(sceneID,{json.encode(event)}) end
---------- Producer(s) - Handing over incoming triggers to consumer --------------------
if ({property=true,global=true,event=true,remote=true})[_type] then
local event = type(_trigger) ~= 'string' and json.encode(_trigger) or _trigger
local ticket = string.format('<@>%s%s',tostring(_source),event)
repeat
while(fibaro:getGlobal(_MAILBOX) ~= "") do fibaro:sleep(100) end -- try again in 100ms
fibaro:setGlobal(_MAILBOX,ticket) -- try to acquire lock
until fibaro:getGlobal(_MAILBOX) == ticket -- got lock
fibaro:setGlobal(_MAILBOX,event) -- write msg
fibaro:abort() -- and exit
end
---------- Consumer - Handing over incoming triggers to main() --------------------
local function _poll()
local l = fibaro:getGlobal(_MAILBOX)
if l and l ~= "" and l:sub(1,3) ~= '<@>' then -- Something in the mailbox
fibaro:setGlobal(_MAILBOX,"") -- clear mailbox
post(json.decode(l)) -- and "post" it to our "main()" in new "thread"
end
setTimeout(_poll,250) -- check every 250ms
end
---------- Startup --------------------
if _type == 'autostart' or _type == 'other' then
printf("Starting EventRunnerLite demo")
if not _OFFLINE then
if not string.find(json.encode((api.get("/globalVariables/"))),"\"".._MAILBOX.."\"") then
api.post("/globalVariables/",{name=_MAILBOX})
end
fibaro:setGlobal(_MAILBOX,"")
_poll() -- start polling mailbox
main(_trigger)
else
collectgarbage("collect") GC=collectgarbage("count")
_System.runOffline(function() main(_trigger) end)
end
end