Scen aktiverad på tid i lua

Erik
Medlem
Posts: 65
Joined: 10 Jan 2016, 18:46
8

hur aktiverar jag scenen på tid?
--[[
%% properties
%% events
%% globals
--]]
local currentDate = os.date("*t");
if string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) == "09:00"
then

--Matsal
fibaro:call(491, "setValue", "80")
--Kök syd
fibaro:call(485, "setValue", "80")
--Vardagsrum Uppe
fibaro:call(503, "setValue", "80")
--Sveas Rum
fibaro:call(497, "setValue", "80")
--Augusts Rum
fibaro:call(500, "setValue", "80")
end
alexndr
Medlem
Posts: 420
Joined: 14 Jul 2016, 14:38
7

Scenen har ingen trigger och måste startas manuellt första gången eller markeras att den skall starta automatiskt.
Den körs dock bara en gång så det krävs att du lägger in en loop i koden också.
Bästa sättet i detta fall vore att göra en funktion av det du vill göra. Anropa funktionen en gång i början av koden och därefter samma funktion med setTimeout- funktionen i slutet av funktionen (det vill säga, den kommer anropa sig själv).
I ditt fall bör det räcka med att anropa en gång i minuten.
Att använda setTimeout är att föredra jämfört med en annan typ av loop med en ”sleep” eftersom det sägs att setTimeout är mindre prestandakrävande.
jang
Medlem
Posts: 388
Joined: 05 Jan 2014, 00:44
10
Location: Stockholm

Typ såhär (starta manuellt eller klicka i "Run scene: Automatic")
Lätt att lägga till andra tider och andra funktioner...

Code: Select all

--[[
%% properties
%% events
%% globals
%% autostart
--]]

if fibaro:countScenes() > 1 then fibaro:abort() end
fibaro:debug("Starting")

function totime(time)
  local t,h,m,s = os.date("*t"),time:match("(%d+):(%d+):?(%d*)")
  t.hour,t.min,t.sec = h,m,tonumber(s) or 0
  local t1,t2 = os.time(t),os.time()
  return (t1 > t2 and t1 or t1+24*60*60)-t2
end

function daily(t,d,fun)
  local time = totime(t)
  fibaro:debug(string.format("Scheduling %s for %s",d,os.date("%c",os.time()+time)))
  setTimeout(function() fun(); daily(t,d,fun) end,time*1000)
end

daily("09:00","Matsal",function() fibaro:call(491, "setValue", "80") end) --Matsal
daily("09:00","Kök syd",function() fibaro:call(485, "setValue", "80") end) --Kök syd
daily("09:00","Vardagsrum Uppe",function() fibaro:call(503, "setValue", "80") end) --Vardagsrum Uppe
daily("09:00","Sveas Rum",function() fibaro:call(497, "setValue", "80") end) --Sveas Rum
daily("09:00","Augusts Rum",function() fibaro:call(500, "setValue", "80") end) --Augusts Rum
Erik
Medlem
Posts: 65
Joined: 10 Jan 2016, 18:46
8

Tack det där var ju en superduper grymmescen för allt som ska tidsstyras.
det jag egentligen försöker göra är en scen för mina markiser i sydlig riktning.
eftersom de pekar rakt åt söder behöver de bara rullas ut till:
80% öppet klockan 09
65% öppet klockan 10
50% öppet klockan 11
33% öppet klockan 1130
50% öppet klockan 1230
65% öppet klockan 13
80% öppet klockan 14
100% öppet klockan 15
Det funkar ju väldigt bra att göra med din scen, men jag tänkte bygga på med lite om och and satser. Tanken är ju att om det regnar, snöar eller
blåser storm att de ska stanna inne.

har du några bra förslag hur man får ut direkt solljus eller tips på en bra vädercentral, så är jag idelöra
Erik
Medlem
Posts: 65
Joined: 10 Jan 2016, 18:46
8

jag hade även tänkt bygga på med currentDate.month, eftersom solen står olika högt
jang
Medlem
Posts: 388
Joined: 05 Jan 2014, 00:44
10
Location: Stockholm

Ok, jag har ingen markis så det här är otestad kod.
För att få veta hur mycket markisen ska vara ute beroende på tid och månad används en tabell. Antar att det finns formler...
Att stänga markisen vid regn snö etc är knepigare. Fibaro har "weather" triggers men jag vet inte hur ofta dessa uppdateras - antar att man vill stänga en markis så fort det börjar regna... bäst är nog en regnmätare eller liknande. Dessutom bör man kanske ha en ljussensor för att få en känsla för hur ljust det i realiteten är.
Här har jag kodat en rutin som pollar Yahoo väder varannan minut för att kolla vädret (vet inte hur ofta Yahoo updaterar sig?).

Code: Select all

--[[
%% properties
%% events
%% globals
%% autostart
--]]

if fibaro:countScenes() > 1 then fibaro:abort() end
fibaro:debug("Starting")

function printf(...) fibaro:debug(string.format(...)) end

function totime(time)
  local t,h,m,s = os.date("*t"),time:match("(%d+):(%d+):?(%d*)")
  t.hour,t.min,t.sec = h,m,tonumber(s) or 0
  local t1,t2 = os.time(t),os.time()
  return (t1 > t2 and t1 or t1+24*60*60)-t2
end

function daily(t,d,fun)
  local time = totime(t)
  printf("Scheduling %s for %s",d,os.date("%c",os.time()+time))
  setTimeout(function() fun(t); daily(t,d,fun) end,time*1000)
end

daily("09:00","Matsal",function() fibaro:call(491, "setValue", "80") end) --Matsal
daily("09:00","Kök syd",function() fibaro:call(485, "setValue", "80") end) --Kök syd
daily("09:00","Vardagsrum Uppe",function() fibaro:call(503, "setValue", "80") end) --Vardagsrum Uppe
daily("09:00","Sveas Rum",function() fibaro:call(497, "setValue", "80") end) --Sveas Rum
daily("09:00","Augusts Rum",function() fibaro:call(500, "setValue", "80") end) --Augusts Rum

-- Table how much to open scheds depending on time and month, other time values are interpolated
openValue = {
  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",100}},
  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}},
}

function markisValue(time) -- Interpolates how much a sched should be open given time and month
  local mt,stop,start = openValue[os.date("%b")]
  for _,t in ipairs(mt) do if t[1] <= time then start = t else break end end
  start = start or mt[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] -- highest/equal after time or the last value
  if time < mt[1] or time>mt[#mt] 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

markisFlag = true        -- false if should stay closed (rain, snow etc)
function setMarkis(time)
  local val = markisFlag and markisValue(time)  or 0
  printf("Setting sched value to %s",val)
  fibaro:call(markisID,"setValue",val) -- Close if markisFlag == false
end

-- Schedule times to adjust
for _,t in ipairs({"09:00","10:00","11:00","11:30","12:30","13:00","14:00","15:00"}) do daily(t,"Markis",setMarkis) end 

local weatherStat = { -- Yahoo weather states
  [0]="tornado",
  [1]="tropical storm",
  [2]="hurricane",
  [3]="severe thunderstorms",
  [4]="thunderstorms",
  [5]="mixed rain and snow",
  [6]="mixed rain and sleet",
  [7]="mixed snow and sleet",
  [8]="freezing drizzle",
  [9]="drizzle",
  [10]="freezing rain",
  [11]="showers",
  [12]="showers",
  [13]="snow flurries",
  [14]="light snow showers",
  [15]="blowing snow",
  [16]="snow",
  [17]="hail",
  [18]="sleet",
  [19]="dust",
  [20]="foggy",
  [21]="haze",
  [22]="smoky",
  [23]="blustery",
  [24]="windy",
  [25]="cold",
  [26]="cloudy",
  [27]="mostly cloudy (night)",
  [28]="mostly cloudy (day)",
  [29]="partly cloudy (night)",
  [30]="partly cloudy (day)",
  [31]="clear (night)",
  [32]="sunny",
  [33]="fair (night)",
  [34]="fair (day)",
  [35]="mixed rain and hail",
  [36]="hot",
  [37]="isolated thunderstorms",
  [38]="scattered thunderstorms",
  [39]="scattered thunderstorms",
  [40]="scattered showers",
  [41]="heavy snow",
  [42]="scattered snow showers",
  [43]="heavy snow",
  [44]="partly cloudy",
  [45]="thundershowers",
  [46]="snow showers",
  [47]="isolated thundershowers",
  [3200]="not available"
}

local sunnyWeather = {[30]=true,[36]=true,[34]=true,[32]=true,[28]=true}  -- conditions when sheds should be open
-- sets markisFlag depending on weather condition (true=open, false=closed)
-- and calls setMarkis to adjust sched.
function weatherChanged(code)
  printf("new weather is %s",weatherStat[code])
  markisFlag = sunnyWeather[code] == true
  setMarkis(os.date("%H:%M")) 
end

-- Continously polls Yahoo weather
function pollForWeather(pollInterval) -- interval in seconds
  local info = api.get("/settings/location")
  local lat,long = math.floor(10.0*info.latitude+0.5)/10.0,math.floor(10.0*info.longitude+0.5)/10.0
  local query = 'select * from weather.forecast where woeid in (SELECT woeid FROM geo.places WHERE text="('..lat..','..long..')") '..'and u="c"'  
  local url = "https://query.yahooapis.com/v1/public/yql?q=" .. urlencode(query)
  local headers = { ["Accept"] = 'application/json', ["Cache-Control"] = 'no-cache'}
  local http = net.HTTPClient()
  local wcode = nil
  local function poll()
    http:request(url, {
        options={headers = headers,method ='GET',timeout =5000}, 
        success = function(resp)
          if resp.status == 200 then
            ok, msg = pcall(
              function()
                local data = json.decode(resp.data)
                --printf("%s",data.query.results.channel.description)
                local code = tonumber(data.query.results.channel.item.forecast[1].code)                 
                --printf("Weather is %s",weatherStat[code])
                if code ~= wcode then wcode=code; weatherChanged(wcode) end
              end
            )
          else
            printf("Server returned an error. Will retry. Error: %s",resp.status)
          end
          setTimeout(poll,pollInterval*1000)
        end,
        error = function() setTimeout(poll,pollInterval*1000) end
      })
  end
  poll()
end

pollForWeather(2*60) -- poll every other minute
Erik
Medlem
Posts: 65
Joined: 10 Jan 2016, 18:46
8

Men shit va cool du är!
Hur hyr man in dig jang?

Nedan är hela min kod som jag försökt få till. inte fått ordning på något av snö eller regn, jag hade avsikten att köpa in en bra vädermätare med vind, LUX och nederbörd. Jag har en Aeotech multi sensor 5 utomhus men den mäter bara upp till 1000lux. typ dag/natt.
Den där koden för väder hänger jag inte alls med i. Ska finula lite med din matris, med den kan man ju faktiskt räkna ut övriga månader, eftersom endast solens höjd över horisonten förändras.

………………………………………………….
--[[
%% properties
%% events
%% globals
%% autostart
--]]

local currentDate = os.date("*t");

if fibaro:countScenes() > 1 then fibaro:abort() end
fibaro:debug("Starting")

if ((string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) >= "23:01")
and (string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) <= "08:59"))
then
end


function totime(time)
local t,h,m,s = os.date("*t"),time:match("(%d+):(%d+):?(%d*)")
t.hour,t.min,t.sec = h,m,tonumber(s) or 0
local t1,t2 = os.time(t),os.time()
return (t1 > t2 and t1 or t1+24*60*60)-t2
end

function daily(t,d,fun)
local time = totime(t)
fibaro:debug(string.format("Scheduling %s for %s",d,os.date("%c",os.time()+time)))
setTimeout(function() fun(); daily(t,d,fun) end,time*1000)
end



if ((string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) >= "09:00")
and (string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) <= "09:59"))
then

--Syd
fibaro:call(485, "setValue", "80") --Kök syd
fibaro:call(491, "setValue", "80") --Matsal
fibaro:call(497, "setValue", "80") --Sveas Rum
fibaro:call(500, "setValue", "80") --Augusts Rum
--Väst
fibaro:call(503, "setValue", "75") --Vardagsrum uppe
fibaro:call(488, "setValue", "99") --Vardagsrum Nere
fibaro:call(482, "setValue", "99") --Bibliotet
fibaro:call(506, "setValue", "99") --Lekrum
end

if ((string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) >= "10:00")
and (string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) <= "10:59"))
then

--Syd
fibaro:call(485, "setValue", "60") --Kök syd
fibaro:call(491, "setValue", "60") --Matsal
fibaro:call(497, "setValue", "60") --Sveas Rum
fibaro:call(500, "setValue", "60") --Augusts Rum
--Väst
fibaro:call(503, "setValue", "75") --Vardagsrum uppe
fibaro:call(488, "setValue", "99") --Vardagsrum Nere
fibaro:call(482, "setValue", "99") --Bibliotet
fibaro:call(506, "setValue", "99") --Lekrum
end

if ((string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) >= "11:00")
and (string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) <= "12:59"))
then

--Syd
fibaro:call(485, "setValue", "33") --Kök syd
fibaro:call(491, "setValue", "33") --Matsal
fibaro:call(497, "setValue", "33") --Sveas Rum
fibaro:call(500, "setValue", "33") --Augusts Rum
--Väst
fibaro:call(503, "setValue", "75") --Vardagsrum uppe
fibaro:call(488, "setValue", "99") --Vardagsrum Nere
fibaro:call(482, "setValue", "99") --Bibliotet
fibaro:call(506, "setValue", "99") --Lekrum
end

if ((string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) >= "13:00")
and (string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) <= "13:59"))
then

--Syd
fibaro:call(485, "setValue", "60") --Kök syd
fibaro:call(491, "setValue", "60") --Matsal
fibaro:call(497, "setValue", "60") --Sveas Rum
fibaro:call(500, "setValue", "60") --Augusts Rum
--Väst
fibaro:call(503, "setValue", "75") --Vardagsrum uppe
fibaro:call(488, "setValue", "99") --Vardagsrum Nere
fibaro:call(482, "setValue", "99") --Bibliotet
fibaro:call(506, "setValue", "99") --Lekrum
end

if ((string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) >= "14:00")
and (string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) <= "14:59"))
then

--Syd
fibaro:call(485, "setValue", "80") --Kök syd
fibaro:call(491, "setValue", "80") --Matsal
fibaro:call(497, "setValue", "80") --Sveas Rum
fibaro:call(500, "setValue", "80") --Augusts Rum
--Väst
fibaro:call(503, "setValue", "75") --Vardagsrum uppe
fibaro:call(488, "setValue", "85") --Vardagsrum Nere
fibaro:call(482, "setValue", "85") --Bibliotet
fibaro:call(506, "setValue", "85") --Lekrum
end

if ((string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) >= "15:00")
and (string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) <= "15:59"))
then

--Syd
fibaro:call(485, "setValue", "99") --Kök syd
fibaro:call(491, "setValue", "99") --Matsal
fibaro:call(497, "setValue", "99") --Sveas Rum
fibaro:call(500, "setValue", "99") --Augusts Rum
--Väst
fibaro:call(503, "setValue", "75") --Vardagsrum uppe
fibaro:call(488, "setValue", "70") --Vardagsrum Nere
fibaro:call(482, "setValue", "70") --Bibliotet
fibaro:call(506, "setValue", "70") --Lekrum
end

if ((string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) >= "16:00")
and (string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) <= "16:59"))
then

--Syd
fibaro:call(485, "setValue", "99") --Kök syd
fibaro:call(491, "setValue", "99") --Matsal
fibaro:call(497, "setValue", "99") --Sveas Rum
fibaro:call(500, "setValue", "99") --Augusts Rum
--Väst
fibaro:call(503, "setValue", "75") --Vardagsrum uppe
fibaro:call(488, "setValue", "55") --Vardagsrum Nere
fibaro:call(482, "setValue", "55") --Bibliotet
fibaro:call(506, "setValue", "55") --Lekrum
end

if ((string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) >= "17:00")
and (string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) <= "17:59"))
then

--Syd
fibaro:call(485, "setValue", "99") --Kök syd
fibaro:call(491, "setValue", "99") --Matsal
fibaro:call(497, "setValue", "99") --Sveas Rum
fibaro:call(500, "setValue", "99") --Augusts Rum
--Väst
fibaro:call(503, "setValue", "75") --Vardagsrum uppe
fibaro:call(488, "setValue", "40") --Vardagsrum Nere
fibaro:call(482, "setValue", "40") --Bibliotet
fibaro:call(506, "setValue", "40") --Lekrum
end

if ((string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) >= "15:00")
and (string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) <= "15:59"))
then

--Syd
fibaro:call(485, "setValue", "99") --Kök syd
fibaro:call(491, "setValue", "99") --Matsal
fibaro:call(497, "setValue", "99") --Sveas Rum
fibaro:call(500, "setValue", "99") --Augusts Rum
--Väst
fibaro:call(503, "setValue", "75") --Vardagsrum uppe
fibaro:call(488, "setValue", "99") --Vardagsrum Nere
fibaro:call(482, "setValue", "99") --Bibliotet
fibaro:call(506, "setValue", "99") --Lekrum
end

if (string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min) == "22:00")
then
fibaro:call(503, "setValue", "99") --Vardagsrum uppe
end
Erik
Medlem
Posts: 65
Joined: 10 Jan 2016, 18:46
8

Hej Jang.
Har jag fel om jag tänker så här?
En scen per vädersträck.
ser det rätt ut i september?

--[[
%% properties
%% events
%% globals
%% autostart
--]]

if fibaro:countScenes() > 1 then fibaro:abort() end
fibaro:debug("Starting")

function printf(...) fibaro:debug(string.format(...)) end

function totime(time)
local t,h,m,s = os.date("*t"),time:match("(%d+):(%d+):?(%d*)")
t.hour,t.min,t.sec = h,m,tonumber(s) or 0
local t1,t2 = os.time(t),os.time()
return (t1 > t2 and t1 or t1+24*60*60)-t2
end

function daily(t,d,fun)
local time = totime(t)
printf("Scheduling %s for %s",d,os.date("%c",os.time()+time))
setTimeout(function() fun(t); daily(t,d,fun) end,time*1000)
end
--South
daily("09:00","Matsal",function() fibaro:call(491, "setValue", "80") end) --Matsal
daily("09:00","Kök syd",function() fibaro:call(485, "setValue", "80") end) --Kök syd
daily("09:00","Sveas Rum",function() fibaro:call(497, "setValue", "80") end) --Sveas Rum
daily("09:00","Augusts Rum",function() fibaro:call(500, "setValue", "80") end) --Augusts Rum

--West
daily("09:00","Vardagsrum Nere",function() fibaro:call(488, "setValue", "99") end) --Matsal
daily("09:00","Bibliotek",function() fibaro:call(482, "setValue", "99") end) --Kök syd
daily("09:00","Lekrum Väst",function() fibaro:call(506, "setValue", "99") end) --Vardagsrum Uppe

--Vardagsrum Uppe
daily("09:00","Vardagsrum Uppe",function() fibaro:call(503, "setValue", "75") end) --Vardagsrum Uppe



-- 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}},
}

function SouthMValue(time) -- Interpolates how much a sched should be open given time and month
local mt,stop,start = SouthValue[os.date("%b")]
for _,t in ipairs(mt) do if t[1] <= time then start = t else break end end
start = start or mt[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] -- highest/equal after time or the last value
if time < mt[1] or time>mt[#mt] 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

function WestMValue(time) -- Interpolates how much a sched should be open given time and month
local mt,stop,start = WestValue[os.date("%b")]
for _,t in ipairs(mt) do if t[1] <= time then start = t else break end end
start = start or mt[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] -- highest/equal after time or the last value
if time < mt[1] or time>mt[#mt] 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

markisFlag = true -- false if should stay closed (rain, snow etc)
function setMarkis(time)
local val = markisFlag and SouthMValue(time) or 0
printf("Setting sched value to %s",val)
fibaro:call(markisID,"setValue",val) -- Close if markisFlag == false
end

markisFlag = true -- false if should stay closed (rain, snow etc)
function setMarkis(time)
local val = markisFlag and WestMValue(time) or 0
printf("Setting sched value to %s",val)
fibaro:call(markisID,"setValue",val) -- Close if markisFlag == false
end


-- Schedule times to adjust
for _,t in ipairs({"09:00","10:00","11:00","11:30","12:30","13:00","14:00","15:00"}) do daily(t,"Markis",setMarkis) end

local weatherStat = { -- Yahoo weather states
[0]="tornado",
[1]="tropical storm",
[2]="hurricane",
[3]="severe thunderstorms",
[4]="thunderstorms",
[5]="mixed rain and snow",
[6]="mixed rain and sleet",
[7]="mixed snow and sleet",
[8]="freezing drizzle",
[9]="drizzle",
[10]="freezing rain",
[11]="showers",
[12]="showers",
[13]="snow flurries",
[14]="light snow showers",
[15]="blowing snow",
[16]="snow",
[17]="hail",
[18]="sleet",
[19]="dust",
[20]="foggy",
[21]="haze",
[22]="smoky",
[23]="blustery",
[24]="windy",
[25]="cold",
[26]="cloudy",
[27]="mostly cloudy (night)",
[28]="mostly cloudy (day)",
[29]="partly cloudy (night)",
[30]="partly cloudy (day)",
[31]="clear (night)",
[32]="sunny",
[33]="fair (night)",
[34]="fair (day)",
[35]="mixed rain and hail",
[36]="hot",
[37]="isolated thunderstorms",
[38]="scattered thunderstorms",
[39]="scattered thunderstorms",
[40]="scattered showers",
[41]="heavy snow",
[42]="scattered snow showers",
[43]="heavy snow",
[44]="partly cloudy",
[45]="thundershowers",
[46]="snow showers",
[47]="isolated thundershowers",
[3200]="not available"
}

local sunnyWeather = {[30]=true,[36]=true,[34]=true,[32]=true,[28]=true} -- conditions when sheds should be open
-- sets markisFlag depending on weather condition (true=open, false=closed)
-- and calls setMarkis to adjust sched.
function weatherChanged(code)
printf("new weather is %s",weatherStat

Code: Select all

)
  markisFlag = sunnyWeather[code] == true
  setMarkis(os.date("%H:%M")) 
end

-- Continously polls Yahoo weather
function pollForWeather(pollInterval) -- interval in seconds
  local info = api.get("/settings/location")
  local lat,long = math.floor(10.0*info.latitude+0.5)/10.0,math.floor(10.0*info.longitude+0.5)/10.0
  local query = 'select * from weather.forecast where woeid in (SELECT woeid FROM geo.places WHERE text="('..lat..','..long..')") '..'and u="c"'  
  local url = "https://query.yahooapis.com/v1/public/yql?q=" .. urlencode(query)
  local headers = { ["Accept"] = 'application/json', ["Cache-Control"] = 'no-cache'}
  local http = net.HTTPClient()
  local wcode = nil
  local function poll()
    http:request(url, {
        options={headers = headers,method ='GET',timeout =5000}, 
        success = function(resp)
          if resp.status == 200 then
            ok, msg = pcall(
              function()
                local data = json.decode(resp.data)
                --printf("%s",data.query.results.channel.description)
                local code = tonumber(data.query.results.channel.item.forecast[1].code)                 
                --printf("Weather is %s",weatherStat[code])
                if code ~= wcode then wcode=code; weatherChanged(wcode) end
              end
            )
          else
            printf("Server returned an error. Will retry. Error: %s",resp.status)
          end
          setTimeout(poll,pollInterval*1000)
        end,
        error = function() setTimeout(poll,pollInterval*1000) end
      })
  end
  poll()
end

pollForWeather(2*60) -- poll every other minute
Erik
Medlem
Posts: 65
Joined: 10 Jan 2016, 18:46
8

Jang teoretiskt sätt behöver du ju ingen markis. Kan du få 2 lampor att dimma till nivåerna i matrisen så är det ju samma sak.
Jag får det inte att fungera just nu, men jag vet inte vilken av mina 5 scener som arbetar. Jag måste nog bygga någon form av labb.
jang
Medlem
Posts: 388
Joined: 05 Jan 2014, 00:44
10
Location: Stockholm

Erik wrote: 10 Sep 2018, 14:03 Jang teoretiskt sätt behöver du ju ingen markis. Kan du få 2 lampor att dimma till nivåerna i matrisen så är det ju samma sak.
Jag får det inte att fungera just nu, men jag vet inte vilken av mina 5 scener som arbetar. Jag måste nog bygga någon form av labb.
Well, många markiser och många väderstreck gör det lite komplicerat. Den 'day' funktion jag kodat var en simpel scheduling av återkommande daghändelser. I ditt fall vill du justera markiserna många ggr per dag och olika antal tillfällen och då passar modellen inte så bra...
Jag har kodat om det i ett framwork som jag använder för min egen kodning. Lite dokumentation finns här men lite Lua förståelse krävs.<https://forum.fibaro.com/topic/31180-tu ... ent-model/>
Prova den här och se om den scheduler rätt markis på rätt tid (enl. tabellen), den är lätt att utöka med väder och andra event senare.
Edit:fixade en bug då jag klistrade in fel version

Code: Select all

--[[
%% properties
%% events
%% globals
--]]

--[[
-- EventRunnerLight. Single scene instance framework
-- Copyright 2018 Jan Gabrielsson. All Rights Reserved.
-- Email: jan@gabrielsson.com
--]]

_version = "1.0" 
osTime = os.time
osDate = os.date
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",deviceID=491,tab=SouthValue}, --Matsal
  {name="Kök syd",deviceID=485,tab=SouthValue}, --Kök syd
  {name="Sveas Rum",deviceID=497,tab=SouthValue}, --Sveas Rum
  {name="Augusts Rum",deviceID=500,tab=SouthValue}, --Augusts Rum

--West
  {name="Vardagsrum Nere",deviceID=488,tab=WestValue}, --Matsal
  {name="Bibliotek",deviceID=482,tab=WestValue}, --Kök syd
  {name="Lekrum Väst",deviceID=506,tab=WestValue}, --Vardagsrum Uppe

--Vardagsrum Uppe
  {name="Vardagsrum Uppe",deviceID=503,tab=WestValue} --Vardagsrum Uppe
}

function markisValue(time,tab) -- Calculates how much a sched should be open given time and month
  local mt,stop,start = tab
  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

function main(sourceTrigger)
  local event = sourceTrigger

  if event.type == 'midnight' then
    for _,shed in ipairs(houseSheds) do 
      post({type='schedule',doc=shed.name,deviceID=shed.deviceID,tab=shed.tab[osDate("%b")],ptr=1})
    end
    post({type='midnight'},"n/00:00") -- do it again next midnight
  end

  if event.type=='schedule' then
    if event.ptr > #event.tab then return end -- No more times today
    local time = event.tab[event.ptr]
    if time[1] < osDate("%H:%M") then event.ptr=event.ptr+1 post(event) return end -- Try next
    return end
    printf("%s:Scheduling %s for %s to value %s",osDate("%X"),event.doc,time[1],time[2])
    event.ptr = event.ptr+1
    post({type='adjustShed',shed=event},"t/"..time[1])
  end

  if event.type=='adjustShed' then
    local doc,id,value = event.shed.doc, event.shed.deviceID,markisValue(osDate("%H:%M"),event.shed.tab)
    printf("%s:Setting %s with id %s to value %s",osDate("%X"),doc,id,value)
    fibaro:call(id,"setValue",value)
    post(event.shed)
  end

  -- setUp initial posts of daily events
  if event.type == 'autostart' or event.type == 'other' then 
    post({type='midnight'}) --schedule 
  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)) -- 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
  elseif p == 't/' then return  _midnight()+hm2sec(time:sub(3))-osTime()  -- Today
  else return hm2sec(time) end
end

function post(event, time) return setTimeout(function() main(event) end,(toTime(time 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
Erik
Medlem
Posts: 65
Joined: 10 Jan 2016, 18:46
8

Jag har startat den. klockan 09 vet vi säkert om det funkar.
Kanske finns det lättare sätt att uppnå den optimala markisstyrningen.
Principen är ju enkel.
ett hus har 4 väderstreck solen följer ett solbanediagram tämligen exakt.
om sol ute och ej risk för regn, snö eller storm så ska markiser rullas ut till ett max värde och sedan rullas in igen

Maxvärdet bör nås beroende på väderstreck,månad och tid på dygnet.
kanske skulle man kunna mata motorn med variabel spännig och på så vis få den att rulla ut sig i konstant hastighet.
men det kräver ju hårdvara.
Lösningen mjukvarumässigt borde koden innehålla ett Solbanediagram och kod för att rulla ut sig i 5-10 intervall/dag till ett valt max läge.
Min sydsida är 33% ganska optimalt om det inte blir över +30c. I så fall kanske man vill stänga helt för värmen.
detta är den optimala inmatningen
Min sydsida
Enheter =491,485,497,500
Markis väderstreck=183
Max läge=33%
Antal intervall upp-ner-upp =10
Temperatur för markisstängning (Maxläge =100%) >30c

Följer man ett solbanediagram ser man att solen börjar stråla in ca 09:00
Värst klockan 12:00
och slutar ca 15:00

Min västsida
Enheter=488,502,586
Markis väderstreck=273
Max läge=33%
Antal intervall upp-ner-upp =10
Temperatur för markisstängning (Maxläge =100%) >30c

Följer man ett solbanediagram ser man att solen börjar stråla in ca 14:00
Värst klockan 17:30
och slutar ca 21:00
Grannen åt väst har en hög häck, så i september går den ner bakom den klockan 18. dvs solen står då 10grader över horisonten.
10grader upp borde solen även vara klockan 18:30 1 Maj om jag fattat rätt, dock 285 grader.

https://www.smhi.se/kunskapsbanken/mete ... am-1.31981
https://www.smhi.se/polopoly_fs/1.32183 ... gendSo.png

kanske finns det snabbare kod än matrisen.
man kanske kan sätta ett utgångsvärde och öka det, förutom när det regnar snöar eller blåser.
jang
Medlem
Posts: 388
Joined: 05 Jan 2014, 00:44
10
Location: Stockholm

Tabeller är snabba...
Ett problem är att tabellen båda gav värden för tider samt var de tider då markiserna skulle justeras.
Om man bara har tider och värden i tabellen så kan man ha få värden i tabellen och andra värden interpoleras (linjärt i det här fallet)
ex. {{"07:00",10},{"11:00",90},{"12:00",100},{"13:00",90},{"20:00",10}}
Mellan 7-20 får vi en kantig böjd kurva... (tider utanför ger 0)
En mer avancerad shedsValue funktion kan göra ngt mer avancerat med värdena.
Sedan kör vi en loop som justerar markiserna till de värden mellan t.ex 09:00 och 18:00 varje 30min.

Jag håller med att det framework jag använder är lite onödigt komplicera för det här men fördelen kommer om man blandar in andra event.
Koden jag inkluderat nu lyssnar på 'CentralSceneEvents' från en t.ex fibaro keyfob och flippar en variabel 'shedsClosed' som stänger eller öppnar alla markiser (Det börjar regna eller snöa och man trycker på kontrollen). När man öppnar så återställs de till rätt värde för tiden på dagen.
Här skulle man kunna integrera bra/dåligt väder event som och stänger öppnar markiserna (koden i första exemplet).
Den andra fördelen med detta framework är att det går att köra off-line på en PC/Mac för att debugga och 'köra tiden fortare' - din lab-miljö?. Beskrivning hur finns här https://github.com/jangabrielsson/Event ... wiki/Setup men i det här exemplet används 'EventRunnerLite.lua' istället.

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.0" 
osTime = os.time
osDate = os.date
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 interpolation for times not in table
end

local shedsClosed = false

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 shedsClosed 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,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/"..now
      if now <= shed.start or now > shed.stop then time = "t/"..shed.start end
      printf("Scheduling %s for %s",shed.name,time)
      post({type='schedule', shed=shed},time)
    end
  end

  if event.type=='event' then  -- Toggle sheds if event from a keyFob or similar
    shedsClosed = not shedsClosed
    if shedsClosed then
      printf("Closing sheds")
      for _,shed in ipairs(houseSheds) do
        fibaro:call(shed.id,"setValue",0)
      end      
    else
      local now = osDate("%H:%M")  -- open sheds again
      printf("Opening sheds")
      for _,shed in ipairs(houseSheds) do
        fibaro:call(shed.id,"setValue",shedsValue(now,shed))
      end
    end
  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)) -- 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
  elseif p == 't/' then return  _midnight()+hm2sec(time:sub(3))-osTime()  -- Today
  else return hm2sec(time) end
end

function post(event, time) return setTimeout(function() main(event) end,(toTime(time 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
Erik
Medlem
Posts: 65
Joined: 10 Jan 2016, 18:46
8

gårdagens 1.0 funkar. Dagens har jag inte prövat :)
Erik
Medlem
Posts: 65
Joined: 10 Jan 2016, 18:46
8

Så här tänker jag nu.
--[[
%% properties
%% events
%% globals
## autostart
--]]

local MarkisGroup1 == 491,485,497,500
local MarkisGroup2 == 488,502,586
local MarkisGroup2 == 503
local MarkisMax == 33
local MarkisClose == 0
local MarkisSteps == 10
local MarkisTemp >= 30

Mer kommer när jag hinner
jang
Medlem
Posts: 388
Joined: 05 Jan 2014, 00:44
10
Location: Stockholm

Under tiden postar jag en version som stänger markiserna vid dåligt väder (när det rapporteras av Yahoo, vet inte hur ofta, men vi pollar varannan minut)
Går också att stänga/öppna markisen med en fjärrkontroll som skickat CentralSceneEvent

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.0" 
osTime = os.time
osDate = os.date
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 shedsClosed = false

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 shedsClosed 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
  end

  if event.type=='event' and event.event.data.deviceId==5 then -- Toggle sheds at keypress (any)
    post({type='sheds', state=(not shedsClosed)}) 
  end

  if event.type=='sheds' then
    if shedsClosed == event.state then return end
    shedsClosed = event.state
    if shedsClosed then
      printf("Closing sheds")
      for _,shed in ipairs(houseSheds) do
        fibaro:call(shed.id,"setValue",0)
      end      
    else
      local now = osDate("%H:%M")  -- open sheds again
      printf("Opening sheds")
      for _,shed in ipairs(houseSheds) do
        fibaro:call(shed.id,"setValue",shedsValue(now,shed))
      end
    end
  end

  local weatherStat = { -- Yahoo weather states
    [0]="tornado",[1]="tropical storm",[2]="hurricane",[3]="severe thunderstorms",[4]="thunderstorms",
    [5]="mixed rain and snow",[6]="mixed rain and sleet",[7]="mixed snow and sleet",[8]="freezing drizzle",
    [9]="drizzle",[10]="freezing rain",[11]="showers",[12]="showers",[13]="snow flurries",[14]="light snow showers",
    [15]="blowing snow",[16]="snow",[17]="hail",[18]="sleet",[19]="dust",[20]="foggy",[21]="haze",[22]="smoky",
    [23]="blustery",[24]="windy",[25]="cold",[26]="cloudy",[27]="mostly cloudy (night)",[28]="mostly cloudy (day)",
    [29]="partly cloudy (night)",[30]="partly cloudy (day)",[31]="clear (night)",[32]="sunny",[33]="fair (night)",
    [34]="fair (day)",[35]="mixed rain and hail",[36]="hot",[37]="isolated thunderstorms",[38]="scattered thunderstorms",
    [39]="scattered thunderstorms",[40]="scattered showers",[41]="heavy snow",[42]="scattered snow showers",[43]="heavy snow",
    [44]="partly cloudy",[45]="thundershowers",[46]="snow showers",[47]="isolated thundershowers",[3200]="not available"
  }

  local goodWeather = {[30]=true,[36]=true,[34]=true,[32]=true,[28]=true}  -- conditions when sheds should be open

-- Continously polls Yahoo weather
  function pollForWeather(pollInterval) -- interval in seconds
    local info = api.get("/settings/location")
    local lat,long = math.floor(10.0*info.latitude+0.5)/10.0,math.floor(10.0*info.longitude+0.5)/10.0
    local query = 'select * from weather.forecast where woeid in (SELECT woeid FROM geo.places WHERE text="('..lat..','..long..')") '..'and u="c"'  
    local url = "https://query.yahooapis.com/v1/public/yql?q=" .. urlencode(query)
    local headers = { ["Accept"] = 'application/json', ["Cache-Control"] = 'no-cache'}
    local http = net.HTTPClient()
    local wcode = nil
    local function poll()
      http:request(url, {
          options={headers = headers,method ='GET',timeout =5000}, 
          success = function(resp)
            if resp.status == 200 then
              ok, msg = pcall(
                function()
                  local data = json.decode(resp.data)
                  --printf("%s",data.query.results.channel.description)
                  local code = tonumber(data.query.results.channel.item.forecast[1].code)                 
                  if code ~= wcode then 
                    printf("Weather is %s",weatherStat[code])
                    wcode=code; post({type='sheds',state=not goodWeather[wcode]}) 
                  end
                end
              )
            else
              printf("Server returned an error. Will retry. Error: %s",resp.status)
            end
            setTimeout(poll,pollInterval*1000)
          end,
          error = function() setTimeout(poll,pollInterval*1000) end
        })
    end
    poll()
  end

  pollForWeather(2*60) -- poll every other minute
  
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
Erik
Medlem
Posts: 65
Joined: 10 Jan 2016, 18:46
8

Den verkar vädret funka, förutom att den stänger markiserna, dvs fullt utrullad. Den borde öppna markiserna. fullt inrullad :)
jang
Medlem
Posts: 388
Joined: 05 Jan 2014, 00:44
10
Location: Stockholm

Är 100 stängt? Isåfall får du ändra i shedsClosed rutinen.
Erik
Medlem
Posts: 65
Joined: 10 Jan 2016, 18:46
8

100% är öppen
Erik
Medlem
Posts: 65
Joined: 10 Jan 2016, 18:46
8

Hej igen Jan jag har börjat titta lite på din kod men saknar ett maxvärde för vind. Hur kan man lägga in det?
jang
Medlem
Posts: 388
Joined: 05 Jan 2014, 00:44
10
Location: Stockholm

Ja, Yahoo weather hjälper inte med vind. Du behöver någon form av vindmätare.
Om du har en z-wave vindmätare med deviceID=77 som returnerar <50 om det är lugnt och >50 om det blåser för mycket (har ingen aning hur riktiga mätare rapporterar).
I princip kan man isåfall lägga till det här till scenen, som stänger på samma sätt som dåligt väder..

Code: Select all

  if event.type=='property' and event.deviceID==77 then
     if fibaro:getValue(77,"value") > "50" then
        post({type='sheds',state=true}) -- windy, close sheds
     else 
       post({type='sheds',state=false}) -- calm, open sheds
     end
 end
 
men jag inser att man inte vill öppna markiserna om det slutar blåsa men det är dåligt väder. Dessutom behöver man någon form av trögheten i systemet så att man inte öppnar direkt det slutar blåsa. Har du en vindmätare?
Post Reply