SMART HOME SYSTÉMY
  • Smart Home
  • Cenová kalkulačka
  • Realizacie
  • Podpora
    • Servisný cenník
    • Blog
    • FAQ
    • Školenia
  • Kontakty
  • E-shop

Inteligentné riadenie osvetlenia

8/19/2015

Comments

 
Fibaro je systém, ktorý Vám umožňuje do detailu si prispôsobiť správanie Vášho inteligentného domu v určitých, opakujúcich sa podmienkach. Napríklad keď vojdete do izby, rozsvieti sa svetlo na 60%. Potom sú tu variácie, ktoré nám umožnia prispôsobiť toto nastavenie napríklad tak, že cez deň sa nesvieti, a keď klesnú namerané LUX pod určitú úroveň, tak sa svetlo zapne (vysvetlenie variácií: https://www.youtube.com/watch?v=vTu5T4MnUuA ). To je všetko super, avšak nie ideálne. Pre kompletné nastavenie systému môžete potrebovať 
Inteligentné osvetlenie
20 blokových scén. Tu prichádza ďalšia užitočná vlastnosť Fibara - LUA v spojení s komunitou ľudí, ktorí sa delia o svoje znalosti. Vďaka tejto kombinácií môžeme jednoduchým kopírovaním kódu (pokiaľ je voľne šíriteľný alebo máte povolenie) a drobnými úpravami získať pokročilé scény, ktoré nám ušetria hodne času. Nepotrebujete dokonca LUA jazyk ovládať, poznámky, ktoré v kóde nájdete, vás budu navigovať.
Dovoľte mi, aby som Vás previedol snáď najužitočnejším LUA kódom, ktorý je dostupný pre Fibaro systém. Taktiež by som týmto rád otvoril novú kategóriu nášho blogu s názvom "LUA pre vŠetkých" :)
Poďme na to...
Poďakovanie:
V prvom rade mi dovoľte uviezť veci na pravú mieru. Ako som spomínal pár riadkov vyššie, LUA kód môže (alebo mal by byť) použitý, len pokiaľ Vám autor dá povolenie, a to najmä v prípade komerčného použitia. Preto by som sa chcel poďakovať za povolenie a v neposlednom rade dlhé hodiny práce chalanom z "Control Living" (http://www.controlliving.com/) . O preklad celého kódu (vrátane debugov) sme sa Vám postarali my, vo www.HomeSystem.sk 

Hlavné výhody LUA kódu pre  inteligentné svietenie:

- 1 scéna pre ovládanie kompletného systému svietenia v miestnosti.
- Jednoduché nastavenie pre svetlá a ich intenzitu.
- Nastavte si ku každému svetlu čas, po uplynutí ktorého sa svetlo vypne (ak nie je zaznamenaný ďalší pohyb)
- Inteligentné svietenie zapne svetlo na požadovanú úroveň v závislosti od časti dňa, v ktorej práve ste
- Inteligentné svietenie zmení intenzitu svetla keď sa zmenia namerané LUXY alebo časť dňa
- Nadradené manuálne ovládanie - svetlá ostanú vypnuté, ak ich manuálne vypnete
- Použite vlastné variácie a scénu si jednoducho prispôsobte, ak už variácie máte vytvorené
- Podpora viacerých pohybových senzorov.

Variácie, na základe ktorých sa mení správanie osvetlenia:

Táto scéna pracuje s 3 variáciami. Tieto variácie si potrebujeme manuálne vytvoriť. Variácie si môžeme pomenovať podľa seba, avšak tieto mená aj ich hodnoty je potrebné potom prepísať aj v kóde. Takže pekne po poriadku. Variácie vytvárame tak, že v systéme Home Center 2 vojdeme do záložky "Panels" a v zozname nájdeme "Variable Panels". Tu si vytvoríme 3 preddefinované variácie (pozor, citlivé na veľké písmena) :

1 - "PresentState (alebo si to pomenujme Pritomnost) - Táto variácia bude mať 3 hodnoty - Away, Home, Holiday (Alebo Doma, Preč, Dovolenka)

2 - "SleepState" (alebo si to pomenujme Spanok) - Táto variácia bude mať 2 hodnoty - Awake, Sleeping (alebo Prebudený a Spánok)

3 - "TimeOfDay" - (Alebo si to pomenujme CasDna) - Najdôležitejšia variácia, má 5 hodnôt -
- Sleeping (Spanok)
- Morning (Rano)
- Day (Den)
- Evening (Popoludnie)
- Night (Noc)


Dobre, najťažšia časť je za nami. Ak sme si variácie vytvorili správne, vyzerá to nejako takto (pripadne s inými menami):
Picture
Skontrolujte si ešte raz, či ste niekde neurobili preklep! Keby to nebolo skutočne dôležité, neupozornil by som Vás na to. Jediné písmenko tu (napríklad Awale namiesto Awake) Vám môže priniesť hodiny skúmania, prečo veci nefungujú. Verte mi, vlastná skúsenosť :) Tiež by som rád povedal, že aj keď následujúci krok budeme robiť pre každú miestnosť osobitne, tieto variácie nám slúžia všeobecne, takže každá miestnosť z nich dokáže brať informáciu.

Úprava LUA kódu pre jednotlivé miestnosti:

Pre použitie tohto kódu chodťe do záložky "Scény" a pridajte novú LUA scénu (tu dáme zbohom majiteľom Home Center Lite so slovami - spomínal som Vám, že má svoje obmedzenia :) ). Túto scénu si pomenujme napríklad "Osvetlenie" a priraďme si ju do miestnosti (budeme mať v každej miestnosti jednu). Odškrtneme si tlačítko "Show this scenes in interfaces" (ak by Vás to zaujímalo, keď ho odškrtneme, scénu nebudeme vidieť cez mobil, čo v tomto prípade nepotrebujeme, nakoľko scéna beží sama). Prepneme sa do záložky "Advanced" a do okna, ktoré tam vidíme, skopírujeme následovný text. Tento text vložte od prvého riadku, takže ten, ktorý sa v okne nachádza, vymažte.

--[[
%% properties
60 value
62 value
63 value
%% globals
TimeOfDay
PresentState
--]]
 
--[[ Zmeňte hodnoty 60,63 a 63 vyššie - zadajte namiesto nich ID pohybových senzorov v miestnosti a 
 ID senzorov sily osvetlenia. Scéna na základe týchto senzorov
 a variácií automatický riadí osvetlenie
 
Nižšie zadajte svoje nastavenia svetiel a extra funkcií.
Tento kód bol vyvinutý spoločnosťou Control Living. Je voľne šíriteľný.
O preklad do slovenského jazyka sa postarala spoločnosť HomeSystem.sk
     Vetzia: 1.6.6
--]]
 
--------------------------------------------------------------------
-----------------------YOUR LIGHT SETTINGS--------------------------
 
motionSensorID    = {60};  -- Zadajte ID Vášho pohybového senzoru
LuxSensorID       = {62};  -- Zadajte ID senzoru na meranie osvetlenia
 
-- Zadajte meno Vašej Global variácie medzi úvodzovky. BEZ TÝCHTO VARIÁCIÍ SCÉNA NEFUNGUJE. Rozoznávajte veľké písmena!
sleepState   = "SleepState"; -- Názov variácie pre spánok
timeOfDay    = "TimeOfDay"; --Názov variácie pre čas dňa
presentState = "PresentState"; --Variácia pre stav prítomnosti.
 
--Zadajte hodnoty pre jednolivé variácie. Meňte zelené slová. To znamená, že variácia SleepState môže mať hodnoty Spánok, Prebudený...
sleepStateMapping   = {Sleeping="Sleeping", Awake="Awake"};
timeOfDayMapping    = {Morning="Morning", Day="Day", Evening="Evening", Night="Night"};
presentStateMapping = {Home="Home", Away="Away", Holiday="Holiday"};
 
-- Zadajte hodnoty LUXov, pod ktorými sa bude svetlo spúšťať je denotlivých fázach dňa.
-- Pokiaľ nechcete používať minimálne hodnoty, zadajte: 65535
minLuxMorning  = 100;
minLuxDay      = 300;
minLuxEvening  = 40;
minLuxNight    = 30;
 
--[[
 Teraz tá najdôležitejšia časť:
   Tu zadávate, ktoré svetlo, na ako dlho a s akou silou sa má spustiť.
   Pokiaľ nechcete v danej časovej variácií žiadné svetlo, nechajte prázdne zátvorky
   Pokiaľ nechcete vypínanie po určitom čase, zadajte len 2 parametra: {LightID, "VALUE"}
   Ak chcete vypínanie svetla po určitom čase, zadajte 3 parametre: {LightID, "VALUE", timeInSeconds }
   Pokiaľ chcete použiť svetlo s virtuálnym zariadením pre automatické svietenie (nie je súČasťou tohto kódu) zadajte 4 parametre: {LightID, "VALUE", "timeInSeconds", VirtualDeviceSliderID}  --]]
 
lightsSleeping = {{id=11, setValue="99", onTime=300},{id=35, setValue={R="10", G="30", B="29", W="1"}, onTime=90},{id=902, setValue="turnOn", onTime=300}};; -- Svetlá, ktoré sa spustia, keď je variácia SleepState na Sleepig... 
lightsMorning  = {{id=11, setValue="99", onTime=300},{id=35, setValue={R="10", G="30", B="29", W="1"}, onTime=90},{id=902, setValue="turnOn", onTime=300}};
lightsDay      = {{id=11, setValue="80", onTime=90},{id=35, setValue={R="10", G="30", B="29", W="1"}, onTime=90}};
lightsEvening  = {{id=11, setValue="60", onTime=300},{id=35, setValue={R="10", G="30", B="29", W="1"}, onTime=90},{id=902, setValue="turnOn", onTime=30}};
lightsNight    = {{id=11, setValue="45", onTime=30}, {id=35, setValue={R="10", G="30", B="29", W="1"}, onTime=90}};
--Pre použitie RGBW svetla setValue={R="255",G="255",B="255",W="255"}
--Manuálne nastavenie - Čas, počas ktorého sa svetlá nezapnú naspäť, pokiaľ ich vypnete vypínačom.
OverrideFor  = 90;
dimmDownTime = 10;
 
--------------------------------------------------------------------
-------------------------EXTRA VLASTNOSTI-----------------------------
 
extraMorningFunc = function()
  -- Ak máte extra kód, ktorý chcete v tejto scéne používať, zadajte ho tu.
  --Tento kód sa spustí vždy, ak je zaznamenaný pohyb
  -- napríklad filmoveOsvetlenie =  {{180, "10"},{181, "10"} };
  --potom napríklad pre použitie s XBMC zadajte: if (xbmc == "playing" ) then CallLightArray(filmoveOsvetlenie);
  ExtraDebug("Extra morning function called");
end
 
extraDayFunc = function()
  -- Priestor pre ďalší extra kód
  ExtraDebug("Extra day function called");
end
 
extraEveningFunc = function()
  -- Priestor pre ďalší extra kód
  ExtraDebug("Extra evening function called");
end
 
extraNightFunc = function()
  -- Priestor pre ďalší extra kód
  ExtraDebug("Extra night function called");
end
 
extraLightTriggerChecks = function()
--zadajte extra podmienku a vytiahnite z nej true alebo false
--Ak sa vráti False, svetlo sa nebude spúšťať
-- napríklad:  return ( (pcTurnedOff == true ) and (xbmc ~= "Empty") );
  -- pre fungovanie svetiel musí byť vrátená true
  return true;
end
 
extraOffChecks = function()
  --vráť true pre zapnutie osvetlenia
  return false;
end
 
--------------------------------------------------------------------
----------------------Pokročilé nastavenia--------------------------
local showStandardDebugInfo = true; -- Debug sa ukáže v bielej
local showExtraDebugInfo    = false; -- Debug sa ukáže v orandžovej
 
--------------------------------------------------------------------
--------------------------------------------------------------------
--                               NEMENTE KÓD NIŽŠIE               --
--------------------------------------------------------------------
--UPDATE FROM HERE
 
--private variables
startSource        = fibaro:getSourceTrigger();
keepLightsOn       = false;
timerRunning       = false;
previousLights     = nil;
version = "1.6.6";
 
SavedState = {
  homeStatus = "",
  sleepState = 0,
  timeOfDay  = "",
  lux        = 0,
  motion     = 0,
  startTime  = 0
}
 
CurrentState = {
  homeStatus  = "",
  sleepState  = "",
  timeOfDay   = "",
  lux         = 0,
  motionState = 0,
  currentLightArray = {}
}
 
RGBWDeviceType = { "com.fibaro.RGBW", "com.fibaro.colorController", "com.fibaro.FGRGBW441M"  }
BinaryDeviceType = { "com.fibaro.binarySwitch","com.fibaro.FGWP101", "turnOn"  }
DimmerDeviceType = { "com.fibaro.binarySwitch" }
 
function Debug( color, message )
  fibaro:debug(string.format('<%s >%s</%s>', "span", color, message, "span")); 
end
 
--Making sure that only one instance of the scene is running.
fibaro:sleep(50); --sleep to prevent all instances being killed.
if (fibaro:countScenes() > 1) then
  if (showExtraDebugInfo) then
    Debug( "grey", "Abort, Scene count = " .. fibaro:countScenes());
  end
  fibaro:abort();
end
 
--------------------------EXECUTION----------------------------------
 
function SetCurrentStatus()
  ExtraDebug("Aktualizuje stav variácií");
  CurrentState.homeStatus  = GetPresentState();
  CurrentState.timeOfDay   = GetTimeOfDay();
  CurrentState.sleepState  = GetSleepState();
  CurrentState.lux         = GetAverageLuxValue();
  CurrentState.motionState = GetCurrentMotionStatus();
end
 
function SaveCurrentStatus()
  ExtraDebug("Ukladám aktuálny stav variácií");
  SavedState.homeStatus = CurrentState.homeStatus;
  SavedState.timeOfDay  = CurrentState.timeOfDay;
  SavedState.sleepState = CurrentState.sleepState;
  SavedState.lux        = CurrentState.lux;
  SavedState.motion     = CurrentState.motionState;
end
 
function CheckStatusChanges()
  ExtraDebug("Overujem zmeny v statuse");
  if (CurrentState.homeStatus ~= SavedState.homeStatus ) or (CurrentState.timeOfDay ~= SavedState.timeOfDay ) then
    if (CurrentState.homeStatus ~= presentStateMapping.Home ) then
      TurnOffLights();
    else
      SceneTriggered()
    end;
  end
  SaveCurrentStatus();
    -- if we still have a motion then reset timer.
  if (CurrentState.motionState ~= 0 or extraOffChecks() ) then 
ExtraDebug( "Reštartujem časovač" );
    SavedState.startTime = os.time(); 
  end
  --any other case, we are not resetting the timer.
end
 
function LightsOff( lightArray )
  local stillLightsOn = 0;
  local currentTime = os.time();
  for i = 1,#lightArray do
    if ( lightArray[i].onTime ~= nil) then
 lightItem = lightArray[i];
 lightItem.OffMode = CheckManualOverrideItem( lightItem );
 --local 
 if ( lightItem.OffMode == "ManualOverride" ) then
     ExtraDebug("Manuálna zmena osvetlenia: [" .. lightItem.id .. "]" .. lightItem.name .. " aktívna, stav automatický nemením");
 goto continue;
 end
 --On till:
      local timeL = SavedState.startTime + (lightItem.onTime);
 local timeLeft =  timeL -  currentTime;
   if (timeLeft >= 0 ) then ExtraDebug("Zostávajúci čas pre: [" .. lightItem.id .. "]" .. lightItem.name .. ": " .. timeLeft .. " sekúnd" );   end
 if ( timeLeft < dimmDownTime ) then
        if ( lightItem.OffMode ~= "ManualOverride" ) then
lightItem.OffMode = "ByScene";
end
   if ( (timeLeft <= 0) and (lightItem.currentValue ~= 0) ) then
fibaro:call(lightItem.id, "turnOff");
StandardDebug("Vypínam svetlo: [" .. lightItem.id .. "]'" .. lightItem.name .."'");
        else
            if ( item.lightType == "com.fibaro.multilevelSwitch" ) then
 currentValueDiv = roundit(((lightItem.currentValue) / (dimmDownTime)), 0);
 currentValueNew = (lightItem.currentValue - currentValueDiv);
 if (currentValueNew <=0 ) then currentValueNew = 0; end
 fibaro:call(lightItem.id, "setValue", tostring(currentValueNew));
            end
stillLightsOn = stillLightsOn + 1;
end
      elseif (CheckLightToBeTurnedOnAgain(lightItem)) then
        ExtraDebug("Zapínam svetlo: " .. lightItem.id .. " naspäť");
        turnLightOn(lightItem);
lightItem.OffMode = "";
        stillLightsOn = stillLightsOn + 1;  
      else
   lightItem.OffMode = "NoOverride";
   stillLightsOn = stillLightsOn + 1;   
      end
    end
::continue::
  end
  return stillLightsOn;
end
 
function KeepLightsOnTimer()
  ExtraDebug("--------------- Časovač beží ---------------");
  ExtraDebug("Začínam s malým odskokom, aby svetla stále bežali");
  SavedState.startTime = os.time();
  SaveCurrentStatus();
  sleepTime = 1000;
  while ( keepLightsOn ) do
    ExtraDebug("--------------- Nový časovač začína ---------------");
    fibaro:sleep(sleepTime);
start_time = os.clock();
    SetCurrentStatus();
    currentLightArray = GetTimeOfDayLightArray();
    UpdateLightValues(currentLightArray);
    CheckStatusChanges();
    local stillLightsOn = 0;  
    stillLightsOn = LightsOff( currentLightArray );
    if (stillLightsOn == 0 ) then
 keepLightsOn = RunManualOverrideMode( currentLightArray );
    end
end_time = os.clock()
elapsed_time = (end_time - start_time) * 1000;
sleepTime = 1000 - elapsed_time;
  end
end
 
function CheckManualOverrideItem( currentItem ) 
  --ExtraDebug("Manual override check for: [" .. currentItem.id .. "]" .. currentItem.name);
  if (currentItem.currentValue == 0 and currentItem.OffMode ~= "ByScene" ) then
    ExtraDebug( "Manálna zmena svetla: [" .. currentItem.id .. "]" .. currentItem.name .. " aktívna" );
return "ManualOverride";
  elseif (currentItem.currentValue ~= 0 and currentItem.OffMode == "ManualOverride" ) then
ExtraDebug( "MAnuálna zmena svetla: [" .. currentItem.id .. "]" .. currentItem.name .. " zrušená" );
return "NoOverride";
  end
  return currentItem.OffMode; --returning current mode;
end
 
function RunManualOverrideMode( currentLightArray )
  OverrideForAll = CheckIfAllInOverrideMode(currentLightArray);
  if ( OverrideForAll ) then
    ExtraDebug("-----------------Manuálny mód---------------");
    OverrideTimer = os.time();
    while ( OverrideForAll and (OverrideTimer + OverrideFor ) - os.time() > 0 ) do
      ExtraDebug("Ešte stále v manuálnom móde na: " .. (OverrideTimer + OverrideFor ) - os.time() .. " seconds" );
      fibaro:sleep(1000);
 UpdateLightValues(currentLightArray);
 OverrideForAll = CheckIfAllInOverrideMode(currentLightArray);
 motion = GetCurrentMotionStatus();
 if ( motion ~= 0 ) then
   OverrideTimer = os.time();
 end
    end
else return false;
  end
 -- if  ( (OverrideTimer + OverrideFor ) - os.time() <= 0 ) then
  --time has end. So not continue to run lights loop 
 --   return false;
 -- end
  if (OverrideForAll) then
    return false; --run lights 
  else return true;
  end
end
 
function CheckIfAllInOverrideMode(currentLightArray)
  OverrideForAll = 0;
  for i = 1,#currentLightArray do
    if ( CheckManualOverrideItem(currentLightArray[i]) == "ManualOverride" ) then
      OverrideForAll = OverrideForAll +1;
    else
      return false;
    end
  end
  if (  OverrideForAll ~= 0 and OverrideForAll == #currentLightArray ) then
    return true;
  end
  return false;
end
 
function RunTimer()
if ( keepLightsOn and not timerRunning ) then
    ExtraDebug("Spúšťam časovač, ešte nebeží");
    timerRunning = true;
    KeepLightsOnTimer();
  else
ExtraDebug("Časovač beží, odpočítavam");
  end
end
 
function TurnOffLights()
     UpdateLightValues( GetTimeOfDayLightArray() );
     SetLightValues( GetTimeOfDayLightArray());
     CallLightArray( GetTimeOfDayLightArray(), "off" );
return;
end
 
----------------------Turn lights on functions------------------------
 
function CallLightArray( lightArray, turnOnOrOff )
  if (#lightArray == 0 ) then
    StandardDebug( "Žiadne svetla pre " .. CurrentState.timeOfDay );
    return;
  end
  if not ( CheckIfTable(lightArray, "lights" .. CurrentState.timeOfDay ) ) then return end
  for i = 1,#lightArray do
    if not ( CheckIfTable(lightArray[i], "lights" .. CurrentState.timeOfDay ) ) then break end
    lightItem = lightArray[i];
    if (turnOnOrOff == "on" ) then
      turnLightOn(lightItem);
      if (lightItem.onTime ~= nil) then keepLightsOn = true; end
    else
      if ( lightItem.currentValue ~= 0) then
        fibaro:call(lightItem.id, "turnOff"); 
        keepLightsOn = false;
        StandardDebug("Vypínam svetlá: [" .. lightItem.id .. "]'" .. lightItem.name .."'");
      end
    end
  end
  StandardDebug( "Svetla: " .. turnOnOrOff .. " v režíme " .. CurrentState.timeOfDay );
end
 
function turnLightOn( lightItem )
  if (lightItem.lightType == "com.fibaro.multilevelSwitch" ) then
    fibaro:call(lightItem.id, "setValue", tostring(lightItem.setValue));
    StandardDebug( "Nastavujem: [" .. lightItem.id .. "]'" .. lightItem.name .. "' na Hodnotu: " .. lightItem.setValue );
  elseif ( lightItem.lightType == "com.fibaro.RGBW" )then
    StandardDebug( "Zapínam: [" .. lightItem.id .. "]'" .. lightItem.name .. "' On"); 
    if ( lightItem.setValue.brg~= nil ) then
      fibaro:call(lightItem.id, "setBrightness", tostring(lightItem.setValue.brg));
    else
 local clrvalues =lightItem.setValue;
      fibaro:call(lightItem.id, "setColor", clrvalues.R,  clrvalues.G,  clrvalues.B,  clrvalues.W)
    end
  elseif (lightItem.lightType == "com.fibaro.binarySwitch") then
    fibaro:call(lightItem.id, "turnOn");
StandardDebug( "Zapínam: [" .. lightItem.id .. "]'" .. lightItem.name .. "' On"); 
  end
end
 
function CheckPreviousLights( NewLightArray )
  if ( previousLights ~= nil ) then
    for i = 1,#previousLights do
      local lightItem = previousLights[i];
      for i = 1,#NewLightArray do
        local lightItem1 = NewLightArray[i];
        inarray = false;
        if ( lightItem.id == lightItem1.id ) then
          inarray= true;
          break 
        end
      end
      if not ( inarray ) then fibaro:call(lightItem.id, "turnOff"); end
    end
  end
  previousLights = NewLightArray;
end
 
function LightperDayPart( minLux, lightArray )
  local newLuxValue = CurrentState.lux;
  if ( extraLightTriggerChecks() ) then
    if ( newLuxValue  >  minLux )  then
      StandardDebug( "V miestnosti je : " .. newLuxValue .. "luxov, čo je vyššie ako minimálna hodnota: " .. minLux .. " : nevykonávam žiadnú akcia");
    else
      StandardDebug("V miestnosti je : " .. newLuxValue .. " luxov, čo je nižšie ako minimálna hodnota: " .. minLux);
 SetLightValues(lightArray);
 CallLightArray( lightArray, "on" );
 CheckPreviousLights( lightArray );
    end
  else
    ExtraDebug("Spúšťač pre extra osvetlenie zaznamenal chybu, takže nevykonáva akciu");
  end
end
 
function SceneTriggered()
  if ( CurrentState.homeStatus ~= presentStateMapping.Home ) then
ExtraDebug("Stav prítomnosti - nikto nie je doma. Nevykonávam žiadnú akciu");
  elseif  ( CurrentState.sleepState == sleepStateMapping.Sleeping ) then
    LightperDayPart( 65535, lightsSleeping );
  elseif ( CurrentState.timeOfDay == timeOfDayMapping.Morning ) then
    extraMorningFunc();
    LightperDayPart( minLuxMorning, lightsMorning );
  elseif ( CurrentState.timeOfDay == timeOfDayMapping.Day ) then
    extraDayFunc();
LightperDayPart( minLuxDay, lightsDay );
  elseif ( CurrentState.timeOfDay == timeOfDayMapping.Evening ) then
    extraEveningFunc();
    LightperDayPart( minLuxEvening, lightsEvening );
  elseif ( CurrentState.timeOfDay == timeOfDayMapping.Night  ) then
    extraNightFunc();
    LightperDayPart( minLuxNight, lightsNight );
  else
ErrorDebug( "Bez svetla: " .. CurrentState.timeOfDay );
  end
  if (keepLightsOn == true) then
    RunTimer(); 
  end
end
 
function SceneTriggeredByLights( st )
  if (st == "off") then
    ExtraDebug( "svetlá vypnuté, spánok 4 sekundy" );
    fibaro:sleep(4000);
  elseif (st == "on") then
    ExtraDebug( "svetlá zapnuté, začínam odpočítavanie" );
fibaro:sleep(4000);
--TODO: add light to current array. 
--keepLightsOn = true;
--RunTimer();
end
end
 
------------------------STATUS functions------------------------------
 
function GetTimeOfDay()
  return LookupGlobal( timeOfDay, "TimeOfDay", "Day");
end
 
function GetSleepState()
  return LookupGlobal( sleepState, "sleepState", "Awake");
end
 
function GetPresentState()
  return LookupGlobal( presentState, "presentState", "Home");
end
 
function LookupGlobal( name, stateName, default )
  local ps = fibaro:getGlobalValue( name );
  if ( (ps ~= "") and (ps ~= nil ) ) then
    ExtraDebug("vrátené " .. stateName .. ": " .. ps );
    return ps;
  else 
    ErrorDebug( stateName .. " Variácia nenájdená");
    return default;
  end
end
 
function lightsStatus( id )
  --check if lights are already on.
  allLights = {lightsSleeping, lightsMorning, lightsDay, lightsEvening, lightsNight };
  for i = 1,#allLights do
    for iL = 1, #allLights[i] do 
 local lightItem =  allLights[i][iL];
      if ( lightItem.id == tonumber(id) ) then
        if   ( lightItem.currentValue == 0 ) then
          return "off";
        else
          return "on";
        end 
      end
    end
  end
  ErrorDebug("Stav svetiel neznámy");
  return "Unknown";  
end
 
function GetTimeOfDayLightArray()
 if ( CurrentState.sleepState == sleepStateMapping.Sleeping ) then
    return lightsSleeping;
  elseif ( CurrentState.timeOfDay == timeOfDayMapping.Morning ) then
    return lightsMorning;
  elseif ( CurrentState.timeOfDay == timeOfDayMapping.Day ) then
return lightsDay;
  elseif ( CurrentState.timeOfDay == timeOfDayMapping.Evening ) then
return lightsEvening;
  elseif ( CurrentState.timeOfDay == timeOfDayMapping.Night ) then
return lightsNight;
  end
end
 
function GetCurrentMotionStatus()
  local sensorbreached = 0;
  if (CheckIfTable(motionSensorID, "motionSensorID") ) then
    for i = 1,#motionSensorID do
      if ( tonumber(fibaro:getValue(motionSensorID[i], "value")) > 0 ) then
        sensorbreached = 1;
      end
    end
   else 
    --if not a table, just return the value of the containing ID
sensorbreached = tonumber(fibaro:getValue(motionSensorID, "value"))
  end
  return sensorbreached;
end
 
function GetAverageLuxValue()
  local luxAverage = 0;
  if (CheckIfTable(LuxSensorID, "LuxSensorID") ) then
    if (#LuxSensorID == 1) then 
      return tonumber(fibaro:getValue(LuxSensorID[1], "value"));
    end
    for i = 1,#LuxSensorID do 
      luxAverage = luxAverage + tonumber(fibaro:getValue(LuxSensorID[i], "value"));
    end
      luxAverage = roundit( (luxAverage / #LuxSensorID), 0 );
  else 
    --if not a table, just return the value of the containing ID
    luxAverage = tonumber(fibaro:getValue(LuxSensorID, "value"));
  end
  return luxAverage;
end
 
function UpdateLightValues( currentArray )
  for i = 1,#currentArray do
    item = currentArray[i];
newValue = fibaro:getValue(item.id, "value");
item.currentValue = tonumber(newValue) ~= nil and tonumber(newValue) or ( newValue == "true" and 1 or 0 );
    if ( item.lightType == "com.fibaro.RGBW" )then
         color = fibaro:getValue(item.id, "color");
         c = {R="0", G="0", B="0", W="0", brg="0" }
         c.R, c.G, c.B, c.W = color:match("([^,]+),([^,]+),([^,]+),([^,]+)");
         c.brg = fibaro:getValue(item.id, "brightness"); 
         item.currentValue = c;
       end
  end
end
 
function SetLightValues(currentArray)
  for i = 1,#currentArray do
    item = currentArray[i];
    item.name = tostring(fibaro:getName(item.id));
item.OffMode = "NoOverride";
if (item.name == nil) then item.name = "Unknown"; end
    item.lightType = GetDeviceType( item.id );
  end
end
 
function GetDeviceType(itemId)
  deviceType = fibaro:getType(item.id);
  if ( idIsInList(deviceType, RGBWDeviceType) ) then
      deviceType ="com.fibaro.RGBW";
  elseif ( idIsInList(deviceType, BinaryDeviceType) ) then
       deviceType = "com.fibaro.binarySwitch";
 --elseif ( idIsInList(deviceType, DimmerDeviceType ) then -- Not necessary.
  end
    return deviceType;
end
 
--------------------Helper functions--------------------------------
 
function CheckLightToBeTurnedOnAgain(lightItem)
 if not (lightItem.OffMode=="ByScene") then return; end
    
 if (lightItem.lightType == "com.fibaro.multilevelSwitch" ) then
   if (lightItem.currentValue) < tonumber(lightItem.setValue) then return true; end
 elseif( lightItem.lightType == "com.fibaro.RGBW" )then
   c = lightItem.currentValue;
   if (c.R == "0" and c.G == "0" and c.B == "0" and c.W == "0" ) then
     return true;
   end    
 elseif (lightItem.lightType == "com.fibaro.binarySwitch") then
   if (lightItem.setValue == "turnOn" and lightItem.currentValue == 0 ) then return true; end
  end
  return false;
end
 
function CheckIfTable( array, arrayname )
  local tableCheck = tostring( type( array ) ); 
  if ( tableCheck ~= "table" ) then
    ErrorDebug("Chýba časť variácie: '" .. arrayname .. "', prosím vložte extra časť: { } do: " .. array .. "."); 
return false;
  end
  return true;
end
 
function roundit(num, idp)
  local mult = 10^(idp or 0)
  return math.floor(num * mult + 0.5) / mult
end
 
function idIsInList( startSourceId, sensorList )
  for i = 1,#sensorList do
    if ( startSourceId == sensorList[i] ) then
      return true;
    end
  end
  return false;
end
 
--------------------Debugging Functions-----------------------------
 
function StandardDebug( debugMessage )
  if ( showStandardDebugInfo ) then
    Debug( "white", debugMessage);   
  end
end
 
function ExtraDebug( debugMessage )
  if ( showExtraDebugInfo ) then
    Debug( "orange", debugMessage);
  end
end
 
function ErrorDebug( debugMessage )
    Debug( "red", "Error: " .. debugMessage);
    Debug( "red", "");
end
 
function TestDebug(debugMessage )
   Debug( "blue", "Testing: " .. debugMessage );
end
 
----------------------START OF THE SCENE----------------------------
SetCurrentStatus();
StandardDebug("Status domu: " .. CurrentState.homeStatus );
StandardDebug("Stav pohybu: " .. ( CurrentState.motionState == 0 and "Nezaznamenaný" or "Pohyb zaznamenaný")); 
  
if (startSource["type"] == "property") then
  startSourceID = tonumber(startSource['deviceID']);
  triggerDebug  = "Spustené cez: " .. startSourceID;
  if ( idIsInList( startSourceID, motionSensorID ) ) then
    StandardDebug( triggerDebug .. " Pohybový senzor" );
    if ( CurrentState.motionState > 0 ) then
      SceneTriggered();
    end
  elseif ( idIsInList( startSourceID, LuxSensorID ) ) then
    StandardDebug( triggerDebug .. " Senzor LUXov" );
    ExtraDebug( "Hodnota Luxov sa zmenila na: " .. CurrentState.lux );
    if ( CurrentState.motionState > 0 ) then
      SceneTriggered();
    end
 -- elseif ( idIsInList( startSourceID, walkDirections ) ) then
    --StandardDebug( triggerDebug .. " Walk Direction sensor" );
    --walkDirection( startSourceID );
  else
    StandardDebug( triggerDebug .. " Vypínačom svetla" );
    st = lightsStatus( startSourceID );
    if (st == "Unknown") then
      ErrorDebug( "Naznámym spúšťačom" );
else
 SceneTriggeredByLights( st );
end
    -- Maybe we can change the light preset to make it more intelligent.
    -- Maybe we can change the Lux preset to make it more intelligent.
  end
elseif ( startSource["type"] == "global" ) then
  StandardDebug( "Spustené cez: " .. "global variable" );
  -- If home status away, we trigger so the current array will be turned off. If motion, turn them on.
  if (CurrentState.homeStatus ~= presentStateMapping.Home) then
    TurnOffLights();
  elseif (CurrentState.motionState > 0 ) then
    SceneTriggered();
  end
else 
  StandardDebug( "Scéna spustena: " .. startSource["type"] );
  --Just run the Light Code, not checking for motion. Probably triggered manually.
  if ( startSource["type"] == "other" ) then
    SceneTriggered();
  end
end
 
Debug( "green", "Smart Lights V" .. version .. " | by Control Living, Finished" );
fibaro:debug( "<a href=\"http://www.homesyste...roduktov.html\"target=\"blanc\">Potrebuješ stmievač alebo pohybový senzor? Klikni tu.</a>" );
fibaro:debug("                 ");
--Debug( "green","<img src=\"http://www.controlli...Mail-Logo.png\" width=\"179\" height=\"59\">");
Debug( "green", "-------------------------------------------------------" );
--fibaro:abort(); --otherwise scene will stay alive to long.
 
--UPDATE TILL HERE 

V riadku 3, 4 a 5 zmeňte hodnoty na ID vašich pohybových senzorov a senzoru sily osvetlenia (LUX). Tieto ID nájdete v nastaveniach jednotlivých senzorov. V našom prípade má pohybový senzor v miestnosti ID 60 a senzor sily osvetlenia má ID 63. Ak máte aj ďalší pohybový senzor, ktorý v miestnosti používate, zadajte ho.

Presunieme sa na riadky 24 a 25 kde zmeníme červené čísla na ID naších zariadení.

Picture
Riadky 28, 29 a 30 nám umožňujú zadať naše variácie. Ak sme pri zadávaní variácií v predchádzajúcom kroku použili anglické názvy, nemeníme ich. Ak sme sa rozhodli pre slovenské varianty (Spanok, CasDna, Pritomnost) tak zmeníme zelené slová na presne tie, ktoré sme si zadali. Opäť upozorňujem, dôležité je zadať ich úplne presne, sú citlivé na veľké a malé písmena!

Riadky 33, 34 a 35 platí to, čo pri variáciách. Pokiaľ ste použili anglické hodnoty variácií, nemusíme nič meniť. Pokiaľ ste sa rozhodli pre slovenské názvy, tu je miesto, kde ich zadáte. Stačí zmeniť zelené slová. Napríklad, ak ste sa rozhodli používať hodnotu "Rano", bude to vyzerať takto: "timeOfDayMapping    = {Morning="Rano", Day=..."

Riadky 39 - 42 nám dávajú možnosť nastaviť detailnejšie podmienky jednotlivých variácií. Pre vysvetlenie, ak zmeníme hodnotu pre MinLuxMorning zo 100 na 80, tak v prípade, že je variácia TimeOfDay na hodnote Morning tak sa svetlo spustí len v prípade, že v miestnosti je menej ako 80 LUXov. Je to jednoducho podmienka, aby sa nám nesvietilo napríklad ráno v prípade, že máme vytiahnuté žalúzie, ale aby sa svietilo v prípade, že žalúzie sú stiahnuté.

Riadky 52 až 56 sú tie najdôležitejšie a podľa všetkého sa k ním ešte vrátite. Tieto riadky nám určujú, ktoré svetlo sa spustí, na koľko percent, na ako dlho v prípade zvolenej variácie a v prípade splnenia podmienok pohybu a minimálnych LUXov. Hodnoty zadávate do riadku k jednotlivým "TimeOfDay" hodnotám.  Príklad:
lightsMorning  = {{id=11, setValue="99", onTime=300},{id=12, setValue={R="10", G="30", B="29", W="1"}, onTime=90},{id=13, setValue="turnOn", onTime=300}};
Tento záznam z riadku 53 hovorí o tom, že:
Ak je variácia nastavená na hodnotu "Morning" (alebo Den) a bol zaznamenaný pohyb a bola splnená podmienka s LUXami, tak sa zapne svetlo s ID 11 na 99% na dobu 300 sekúnd, ďalej sa spustí RGBW s ID 12 a nastavia sa hodnoty R=10, G=30, B=29 a W=1 na dobu 90 sekúnd a ešte sa nám zapne relátko ID 13 na dobu 300 sekúnd. Táto doba sa automatický predlžuje v prípade, že je opäť zaznamenaný pohyb. Takže vašou úlohou je zadať do každého z riadkov 52 až 56 správné ID svetiel a hodnoty, ktoré požadujete. Nie všade musia byť aktívne všetky svetlá, ak napríklad nechcete, aby Vám v noci svietila žiarovka, ale len RGBW pás, vymažte celú zátvorku so žiarovkou.

Riadky 59 a 60 - sú posledné riadky na zmenu. 59 nám hovorí o tom, že ak vypneme svetlo vypínačom, systém ho ani v prípade splnenia podmienok nezapne naspäť po dobu xx sekúnd. A hodnota v riadku 60 hovorí a rýchlosti stmievania osvetlenia. 

Ďalšie riadky odporúčam meniť len skúseným užívateľom, ktorí nájdu potrebné informácie v samotnej scéne. Scénu už len uložíme a máme hotové. Ak si chceme overiť funkčnosť, stlačíme "Štart" a scéna nám prebehne. Ak sme všetko urobili správne, mali by sa nám zobraziť všetky zistené informácie a aj výsledok. Tieto informácie sa zobrazujú vždy, keď je scéna spustená pohybom, zmenou variácií... Ak sa teda so svetlom deje niečo, čo nechceme, stačí sa pozrieť na tento záznam a uvidíme, prečo sa daná vec stala. Napríklad ak sa nezasvietilo osvetlenie keď bol zaznamenaný pohyb, pozrieme sa na záznam a môžeme uvidieť, že bolo nameraných viac LUXov ako je maximálna hodnota pre svietenie. Podľa toho si môžeme scénu nastaviť.

Ďalšia miestnosť:
Ako som spomínal na začiatku, scéna nám riadí osvetlenie v jednej miestnosti. Do ďalších miestnosti si vytvoríte scénu tým istým spôsobom, zmeníte ID zariadení a hodnoty. Samozrejme, prvá miestnosť je najzložitejšia, avšak každá ďalšia už pôjde ako po masle.

Nezabudnime na zmenu variácií:
Dôležitou vecou, ktorú samotná scéna nemôže riešiť, je zmena variácií. Pre správne fungovanie potrebujeme hlavne meniť variáciu TimeOfDay. Prečo to scéna nerieši? Pretože je to extrémne citlivé na prispôsobenia. Napríklad niekto si môže meniť fázu dňa zo spánku na ráno stlačením vypínača pri posteli, niekto chce, aby sa mu to stalo vždy ráno o 7. Niekto si to naopak želá vždy pri východe slnka...
Toto rozhodnutie je na každom, a preto je potrebné vytvoriť si scény, ktoré nám túto variáciu budú meniť. 
Tak pre príklad, ja používam zmenu variácie zo spánku na ráno v memente východu slnka, z rána na deň o 9:30, zo dňa na večer v momente západu slnka a z večera na noc keď dva krát stlačím vypínač v spálni. Ako príklad je tu scéna zmeny variácie na ráno:
Picture
Táto scéna je založená na Čase a dni v týždni, spustí sa každý deň pri východe slnka a jedinú vec, o ktorú sa stará je zmena variácie "TimeOfDay" na "Morning". Podobných scén si vytvoríme 5 (spúšťač bude podľa Vašej požiadavky). Tieto scény nám budú meniť variácie, ktoré fungujú spoločne pre celý dom, takže ich nepotrebujeme vytvárať pre každú miestnosť osobitne. 

Odporúčanie na záver:
Scéna pracuje so silou osvetlenia "LUX" ktoré sú pri základných nastaveniach pohybového senzora merané skôr sporadicky. Preto odporúčam, aby ste upravili nastavenia tohto merania. Aby ste tak urobili, vstúpte do nastavenia pohybového senzora, karta advanced (pokročilé) a zmeňte parametre 40 a 42 na nižšiu hodnotu. Napríklad parameter 40 na 50 LUXov a 42 na 240 sekúnd. Po tejto zmene prebuďte pohybový senzor (trojitým kliknutím) alebo nechajte parametre načítať neskôr (po nejakom čase sa uložia samé). Po tejto zmene bude meranie LUXov prebiehať častejšie a podľa mojich skúsenosti táto zmena nejak výrazne neovplyvňuje životnosť batérie.

Budem rád, ak nám napíšete svoje skúsenosti so scénou nižšie v komente alebo sa podelíte s vašimi vlastnými LUA scénami, ktoré zaradíme do tejto rubriky ako pokračovanie. 
Comments

    Categories

    All
    FIBARO
    Homey
    Ostatné SmartHome
    Recenzie

Smart cenová kalkulačka | Kontakty | Čo je Z-WAVE | Blog | Eshop

Picture
Picture
Picture
www.HomeSystem.sk je oficiálnym distribútorom a predajcom značiek: 
NodON reseller
Picture
Picture
Fibaro Slovensko
Picture
www.HomeSystem.sk je výhradným distribútorom týchto značiek:
Picture
Picture
Picture
Picture
HomeSystem vo svojom riešení používa aj produkty:
Picture
Picture
Picture
Global Cache iTach v spojení so systémom Fibaro
Danfoss termostatické hlavice LC13
Secure termostat Z-Wave
Vision siréna
Picture
Picture
Picture
Ocenenia na Slovensku, o ktoré sme sa zaslúžili:
Picture
  • Smart Home
  • Cenová kalkulačka
  • Realizacie
  • Podpora
    • Servisný cenník
    • Blog
    • FAQ
    • Školenia
  • Kontakty
  • E-shop