--[[
%% autostart
--]]

--[[ Scena Lua do obslugi trybu 'Auto' urzadzenia wirtualnego (VD) dla Roller Shutter 2.
Scena wspomagająca  VD w trybie 'Auto'. Oblicza nowe polozenie Roller Shutter 2 w zaleznosci od
wartosci innego parametru np. jasnosci swiatla [Lux] lub temperatury w pokoju
   Designed by Lukasz Gawryjolek
   https://www.zFIBAROzaPanBrat.pl
]]

-- tu wpisz adresy swoich urzadzen
local virtualDeviceID = 568
local luxDeviceID = 470
local karniszDeviceID = 565



function f(x, x1, y1, x2, y2)
  --[[
  Linear function - funkcja liniowa na podstawie podanych dwoch punkutow p1(x1,y1), p2(x2,y2) oraz
 		dowolnej wartosci x, zwraca nowa warosc y.
  Input: p1(x1,y1), p2(x2,y2)
  Condition: x1 < x2
  Return {x, y, status} 
  Status constant tags: obliczone, ErrorCompareX1X2, ErrorCompareY1Y2, min Lux, max Lux
 
  --Designed by Lukasz Gawryjolek
  --For more details check https://zfibarozapanbrat.pl/
  --All rights reserved 2020
  ]]--
  
  
  
  local a = 0
  local b = -1
  
  local Dx = x2 - x1
  local Dy = y2 - y1
  local status = "obliczone"
  
  if Dx <= 0 then
    --not allowed
    status = "ErrorCompareX1X2"
    
  elseif Dy == 0 then
    --not allowedd
    status = "ErrorCompareY1Y2"
  else
  
    a = Dy / Dx
    b = y1 - a*x1  
    
    if x < x1 then
      x = x1
      status = "min Lux"
    end
    
    if x > x2 then
      x = x2
      status = "max Lux"
    end
  
   end
    
   return {x = x, y = a*x + b, status = status}

end

-----------------------------------------------------------
-- obliczenie nowego polozenia 0-100% dla Roller Shutter 2
function ustawNowePolozenie()
    
  --odczytanie biezacej wartosci parametru od ktorego bedzie wyliczone polozenie Roller Shutter 2 np. jasnosci w pokoju
  local lux = tonumber(fibaro:getValue(luxDeviceID, "value"))
  
  --tu okresl zachowanie sie funkcji (jaka ma byc wartosc otwarcia Roller Shutter dla parametru wejsciowego np. jasnosci)
  local x1 = 50 --lux min
  local x2 = 1000 --lux max
  local y1 = 100 -- % otwarcie dla x1
  local y2 = 0 --% otwarcie dla x2
  
  local polozenie = f(lux, x1, y1, x2, y2)
  local wyliczoneNowePolezenie = math.floor(polozenie.y)
  
  print(lux .. " Lux -> " .. wyliczoneNowePolezenie .. " %")
   
  local obecnePolozenie = tonumber(fibaro:getValue(karniszDeviceID, "value"))
  
  --sprawdzenie czy nowo obliczone polozenie jest rozne od obecnego
  --if wyliczoneNowePolezenie ~= obecnePolozenie then
  
  --lepiej sprawdzac czy nowe polozenie rozni sie więcej niz np. o 2 % 
  if math.abs(wyliczoneNowePolezenie - obecnePolozenie) > 2 then
   
    --wyslanie nowego polozenia do Roller Shutter 2
  	fibaro:call(karniszDeviceID, "setValue", wyliczoneNowePolezenie) 
  else
    print("Polozenie to samo, fizyczne przesuniecie nie jest potrzebne")
  end
  
  
end
  
  
-----------------------------------------
--odczyt trybu urzadzenia Virtual Device
function odczytajTryb() 
  
  --odczyt opisu dla etykiety w Virtual Device
  local trybPracy = fibaro:getValue(virtualDeviceID, "ui.TrybLabel.value")
  print("Tryb pracy: " .. trybPracy)
  
  if trybPracy == nil then 
    trybPracy =  ""
  end
  
  if trybPracy == "Auto" then
    ustawNowePolozenie()
  end
  
end


----------------------------------------------------------
-- funkcja wywolywana cyklicznie w pewnych odstepach czasu
function timeFunc()
  print("timeFunc wywolane w petli")
  
  --tylko jeden proces (1-na instancja) ma prawo wykonywac ta scene
  if fibaro:countScenes() > 1 then
    print("Only one time thread is allowed, killing current one.")
    fibaro:abort()
  end
  
  odczytajTryb() 
  
  setTimeout(timeFunc, 3 * 60 * 1000) --wywolywanie siebie samej ponownie za 3 minuty
  
end



--======================= Main Part ===============================

local sourceTrigger = fibaro:getSourceTrigger()
if (sourceTrigger["type"] == "autostart") then
  print("autostart")
  timeFunc()
  
elseif (sourceTrigger["type"] == "other") then
  print("manual restart - one time execution")
  odczytajTryb() 
  
end


