AN07 Periodický kalendář pro řízení výstupů v textové podobě Lua skriptem | Chytré zásuvky NETIO ovládané pomocí WiFi a LAN
Tagy: 
User library

Aplikační poznámka AN07 obsahuje Lua skript, který zapíná a vypíná jednotlivé výstupy zásuvek 110/230V podle záznamu v určitém čase. Tabulka stavů může mít desítky řádků, které se vykonávají v určité hodiny nebo dny v týdnu.

Můžeme Vám nějak pomoci?

NETIO 4x nativně obsahuje propracovaný grafický kalendář / Časovač (Funkce Scheduler), ten se ale nastavuje pro každý výstup zvlášť a pro kratší sekvence je nepraktický.
 

Lua skript AN07 je praktický pro textový zápis kdy a jak vyvolat akci na výstupu. Akce může být i hodnota 5 (neměň hodnotu výstupu). Hodnota 5 se hodí pro situace, kdy je výstup ovládán nějakým M2M protokolem nebo tlačítkem.

 

Skript spíná výstupy podle času

"1111,22:30:00,0001000"

Outputs,time,week-days

 

  • Outputs = Akce pro každý výstup O1 O2 O3 O4
  • Time = Čas provedení akce
  • WeekDays = Které dny v týdnu se má akce provést

 

 

Podporovaná zařízení: NETIO 4All, NETIO PowerPDU 4C, NETIO 4

 

Vytvoření pravidla (rule)

Pro vytvoření a spuštění Lua skriptu je nutné následující:

1) Ve webové administraci NETIO 4 v sekci Actions, přidejte pravidlo pomocí tlačítka Create Rule


 

2) Vyplňte následující parametry:

  • Enable rule: zaškrtnuto
  • Name: Lua scheduler (uživatelsky definovatelné)
  • Description: Lua script for switching outputs based on time (uživatelsky definovatelné)
  • Trigger: System started up
  • Schedule: Always

 

3) Do pole pro skript v jazyce Lua zkopírujte následující kód:

 
------------NETIO AN07------------

------------Section 1------------
-- Actions for all outputs (1-4), time and days
-- Format:
-- 4 x number with action (0 - turn off, 1 - turn on, 2 - short off, 3 short on, 4 - toggle, 5 - keep previous state), time (hours:minutes:seconds), day (Mo-Sun, 0 - not active in this day, 1 - active in this day)

-- Example – Toggle O1 and turn off other Outputs at 18:30 every day except Wednesday: "4000,18:30:00,1101111"

local states = {
"4444,16:14:00,1111111",
"1000,09:00:00,1111100",
"5515,22:33:44,0000011",
"0000,00:00:00,1000000"
}

local initialState = "0055" -- state to which outputs will be set after restart (0-5)

local shortTimeMs = 1000 -- time used for action 2 and 3 [milliseconds]
---------End of Section 1---------

local sortedStates = {}
local swapped = false


function checkFormat()
  for i=1,4 do
    local test = tonumber(initialState:sub(i,i))
    if test == nil or test>5 or test<0 then
      logf("Action in initialState for outlet %d is invalid!", i)        
      return false
    end
  end
  for i=1,#states do
    for j=1,4 do
      local test = tonumber(states[i]:sub(j,j))
      if test == nil or test>5 or test<0 then
        logf("Action in state %d for outlet %d is invalid!", i,j)        
        return false
      end
    end 
    if states[i]:sub(5,5) ~= "," or states[i]:sub(14,14) ~= "," then
      logf("Time or days in state %d are not separated by comma!", i)
      return false
    end
    local hours = tonumber(states[i]:sub(6,6))
    local minutes = tonumber(states[i]:sub(9,9))
    local seconds = tonumber(states[i]:sub(12,12))
    if hours == nil or hours > 2 or hours < 0 or 
      tonumber(states[i]:sub(7,7)) == nil or
      states[i]:sub(8,8) ~= ":" or 
      minutes == nil or minutes > 5 or minutes < 0 == nil or 
      tonumber(states[i]:sub(10,10)) == nil or 
      states[i]:sub(11,11) ~= ":" or 
      seconds == nil or seconds > 5 or seconds < 0 == nil or 
      tonumber(states[i]:sub(13,13)) == nil then
      logf("Time in state %d is invalid!",i)
      return false
    end
    for j=15,21 do
      local day = tonumber(states[i]:sub(j,j))
      if day == nil or (day ~= 0 and day ~= 1) then
        logf("Value for day %d in state %d is invalid", (j-14), i)        
        return false
      end
    end 
  end 
  log("FORMAT OK")
  return true
end

function loadStates()
  for i=1,#states do
    sortedStates[i] = {state,time}
    sortedStates[i].state = states[i]
    sortedStates[i].time = (3600*tonumber(states[i]:sub(6,7)) + 60*tonumber(states[i]:sub(9,10)) + tonumber(states[i]:sub(12,13)))
  end
end

function sortStates()
  for i=1,#states-1 do
    swapped = false
    for j=1, #states-1 do
      if sortedStates[j].time > sortedStates[j+1].time then
        local temp = sortedStates[j]
        sortedStates[j] = sortedStates[j+1]
        sortedStates[j+1] = temp
        swapped = true;
      end  
    end
    if not swapped then
      break
    end
  end
end

function startScheduler()
  -- Current time
  local stringTime = os.date("%X")
  local time = (3600*tonumber(stringTime:sub(1,2)) + 60*tonumber(stringTime:sub(4,5)) + tonumber(stringTime:sub(7,8)))
  local nextState = sortedStates[1].state
  local timeLeft = (86400-time+sortedStates[1].time)
  local stateIndex = 1
  for i=1,#sortedStates do
    if time < sortedStates[i].time then
      nextState = sortedStates[i].state
      timeLeft = (sortedStates[i].time - time)
      stateIndex = i
      break
    end
  end
  
  -- Delay between states must be at least 1s
  if timeLeft <= 0 then timeLeft = 1 end
  delay(timeLeft,function() scheduler(nextState,stateIndex) end)
end

function scheduler(currentState, stateIndex)
  if checkDay(currentState) then
    setOutputs(currentState:sub(1,4))
  end
  local nextIndex = stateIndex%#sortedStates + 1
  
  local currentTime = sortedStates[stateIndex].time
  local stringTime = os.date("%X")
  local realTime = (3600*tonumber(stringTime:sub(1,2)) + 60*tonumber(stringTime:sub(4,5)) + tonumber(stringTime:sub(7,8))) 
  if currentTime ~= realTime then
    currentTime = realTime 
  end

  local timeLeft = 0
  if nextIndex == 1 then
    timeLeft = (86400-currentTime+sortedStates[nextIndex].time)
  else
    timeLeft = sortedStates[nextIndex].time - currentTime
  end
    
  -- Delay between states must be at least 1s
  if timeLeft <= 0 then timeLeft = 1 end
  delay(timeLeft,function() scheduler(sortedStates[nextIndex].state,nextIndex) end)
end

function checkDay(state)
  local day = tonumber(os.date("%w"))
  -- os.date("%w") returns 0 for Sunday
  if day == 0 then day = 7 end
    if tonumber(state:sub(14+day,14+day)) == 1 then
      return true
    end
  return false
end

function setOutputs(state)
  for i=1,4 do
    value = tonumber(state:sub(i,i))
    if value == 0 then -- turn off
      devices.system.SetOut{output = i, value = false}
    elseif value == 1 then -- turn on
      devices.system.SetOut{output = i, value = true}
    elseif value == 2 then -- short off
      devices.system.SetOut{output = i, value = false}
      milliDelay(shortTimeMs,function() devices.system.SetOut{output=i,value=true} end)
    elseif value == 3 then -- short on
      devices.system.SetOut{output = i, value = true}
      milliDelay(shortTimeMs,function() devices.system.SetOut{output=i,value=false} end)   
    elseif value == 4 then -- toggle
      if devices.system["output" ..i.. "_state"] == 'on' then 
        devices.system.SetOut{output=i,value=false}
      else
        devices.system.SetOut{output=i, value=true}
      end
    elseif value == 5 then
      -- do nothing
    end
  end
end

function initiate()
  setOutputs(initialState)
end

log("Lua scheduler started")
checkFormat()
initiate()
loadStates()
sortStates()
startScheduler()

 

4) Tvorbu pravidla ukončete kliknutím na tlačítko Create Rule v dolní části obrazovky.

 

 

Nastavení proměnných

  • states
    • Proměnná pomocí které se nastavují akce, čas a dny. Jedná se o tabulku řetězců (strings). Každý řetězec je zodpovědný za akce v jednom konkrétním čase. Jednotlivé řetězce jsou uzavřeny do uvozovek a od sebe jsou odděleny čárkou.
    • Řetězec má následující formu "aaaa,hh:mm:ss,mtwtfss".
    • akce (aaaa)
      • První 4 symboly jsou vyhrazeny pro akce, které se vykonají s výstupy v zadaný čas.
      • První číslo je vyhrazeno pro první výstup, druhé číslo pro druhý výstup atd.
      • Čísla akcí odpovídají standardnímu číslování u zařízení NETIO
      • 0 - vypnutí výstupu
      • 1 - zapnutí výstupu
      • 2 - “short off” (nastaví výstup do hodnoty 0, čeká čas v proměnné shortTimeMs  a nastaví výstup do hodnoty 1)
      • 3 - “short on” (nastaví výstup do hodnoty 1, čeká čas v proměnné shortTimeMs  a nastaví výstup do hodnoty 0)
      • 4 - “toggle”, přepne stav výstupu na opačnou hodnotu (pokud byl zapnutý, pak ho vypne a naopak)
      • 5 - ponechání stavu beze změny
      • Příklad pro zapnutí výstupu 3 a vypnutí výstupů 1, 2 a ponechání stavu výstupu 4: 0015
    • čas  (hh:mm:ss)
      • Druhá část řetězce slouží k určení času ve který se má daná akce vykonat.
      • Skript používá čas ze zařízení NETIO (lze ho nastavit ve webové aplikaci v sekci Settings - Date/Time).
      • Čas se zadává ve formátu hodiny:minuty:sekundy
      • Hodiny musí být dvoumístné číslo (například 9 hodin je nutné zapsat jako 09:00:00) evropského formátu (5pm = 17:00:00).
      • Příklad pro nastavení času na 5:30 ráno: 05:30:00.
    • den (mtwtfss)
      • Vykonání akce je možné omezit na jednotlivé dny v týdnu
      • V této části řetězce je možné nastavit ve které dny se akce bude vykonávat.
      • Jednotlivé číslice odpovídají dnům v týdnu (pondělí - neděle).
      • Možné hodnoty jsou 0 a 1.
      • 0 - akce se v daný den nebude vykonávat.
      • 1 - akce se v daný bude vykonávat.
      • Příklad pro vykonávání akce pouze o víkendu: 0000011.
    • Jednotlivé části řetězce jsou od sebe odděleny čárkou a celý řetězec je uzavřen v uvozovkách.
    • Příklad pro přepnutí stavu všech výstupů vždy v 9:30 ráno každý pracovní den (pondělí - pátek): "4444,09:30:00,1111100".
    • Příklad pro vypnutí všech výstupů v 18:00 každý pátek: "0000,18:00:00,0000100".

 

  • initialState
    • V této proměnné jsou akce, které se vykonají s jednotlivými výstupy po restartu zařízení.
    • Jedná se o řetězec, musí být tedy uzavřen do uvozovek.
    • Řetězec má následující formu "aaaa". Za jednotlivá "a" je nutné vložit číslo akce, která se s daným výstupem vykoná.
    • Akce mají stejné hodnoty jako v proměnné states
    • Příklad pro vypnutí výstupů 1 a 2, ponechání původního stavu výstupů 3 a 4: local initialState = "0055"

 

  • shortTimeMs
    • Nastavuje dobu v milisekundách, za kterou se výstup zapne/vypne ve stavech 2 respektive 3
    • Minimální hodnota je 100ms.
    • Příklad pro změnu za 2 sekundy: shortTimeMs = 2000

 

Spuštění skriptu

Po nastavení všech parametrů a uložení skriptu je potřeba restartovat chytré zásuvky NETIO. Po opětovném naběhnutí systému se skript spustí a výstupy se nastaví do stavů určených proměnnou initialState.

 

FAQ:

1) Kolik jednotlivých akcí je možné pomocí tohoto skriptu vytvořit?

Počet akcí není omezen. Do proměnné states je možné vložit neomezený počet řetězců.
 

2) Co se stane s výstupem, pokud se jeho stav změní z jiného zdroje (například pomocí tlačítka na zařízení, z webu, jiným M2M protokolem nebo z mobilní aplikace?)

Skript se spustí v nastaveném čase a nastaví hodnoty výstupu podle tabulky. Má-li dojít k zapnutí výstupu, který už zapnutý je, nic se nezmění a výstup zůstane zapnutý.

Pro ponechání výstupu beze změny (ať už 0 nebo 1) lze použít Akci 5 (5 = neprováděj žádnou změnu stavu výstupu).

 

3) Co se stane při přechodu z letního na zimní čas?

Při přechodu času je možné že se nevykoná akce která je naplánovaná v čase přechodu. Následující akce se budou vykonávat již normálně.

 

4) Co když je zařízení vypnuté v čase, který je v tabulce uvedený?

Akce se v tom případě nevykoná. Po zapnutí napájení se NETIO zásuvky uvedou do stavu nastaveného v proměnné initialState v záhlaví Lua skriptu a pokračují podle aktuálního času. .

 

5) Musí být akce v tabulce seřazeny za sebou podle času?

Není to nutné, nicméně to doporučujeme kvůli přehlednosti.

 

6) Co když vložím dvě akce na stejný čas?

První se provede a druhá se provede o sekundu později.

 


 

Podporované verze FW:

3.0.0 a vyšší (Archiv firmware)

Více o Lua:

https://wiki.netio-products.com


 

 

Tato Aplikační poznámka může být použita v:

Smart power socket NETIO

 

NETIO 4

NETIO 4 je PDU modul čtyř zásuvek 230V/8A s připojením do počítačové sítě pomocí LAN a WiFi. Každou ze zásuvek lze individuláně vypnout/zapnout pomocí různých M2M API protokolů. NETIO 4 je unikátní produkt, který najde uplatnění v IT, průmyslu, chytrých domech, multimediálních instalacích atd. Všude, kde potřebujete zásuvky na 230V ovládané z mobilní aplikace, z nějakého programu (M2M API), z uživatelského skriptu (Lua), z funkcí časovač (Scheduler) a automatický restartér (IP WatchDog).

Více o NETIO 4

 

Smart power socket NETIO 4All

 

NETIO 4All

NETIO 4All je PDU modul čtyř elektrických zásuvek 230V/8A s měřením spotřeby na každé zásuvce, který lze připojit do počítačové sítě pomocí LAN a WiFi. Každou ze čtyř zásuvek lze individuálně vypnout/zapnout přes web nebo pomocí různých M2M API protokolů. Na každé zásuvce lze měřit její spotřebu elektřiny (A, W, kWh). Chytré zásuvky NETIO 4All jsou určeny pro aplikace vzdáleného měření a ovládání elektrických zásuvek.

Více o NETIO 4All

 
NETIO PowerPDU 4C is small PDU with power measurement and IEC-320 outputs

 

NETIO PowerPDU 4C

NETIO PowerPDU 4C je malé PDU (Power Distribution Unit) na 110/230V. Každý ze čtyř výstupů IEC-320 C13 lze ovládat samostatně (On / Off / Reset / přepni). Na každém výstupu jsou měřeny elektrické veličiny (A, W, kWh, TPF, V, Hz) s vysokou přesností. Zařízení obsahuje dva LAN porty pro připojení do sítě (vestavěný Ethernet switch). Každý výstup napájení podporuje ZCS (Zero Current Switching), to znamená šetrné ovládání připojených zařízení.

Více o NETIO PowerPDU 4C

 

Zeptejte se na cenu nebo technické parametry

Pro otestování zařízení použijte jméno/heslo demo/demo