AN08 Cyklický semafor v Lua podle tabulky | NETIO products: Networked power sockets
Tagy: 
User library

Příklad AN08 přepíná Lua skriptem stavy On/Off výstupů zásuvek 230V podle tabulky. Vzorová tabulka má 8 stavů a každý stav trvá nastavenou dobu (minimálně jednu sekundu). Tento příklad lze použít jako cyklující „semafor “. 

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

 

Podporovaná zařízení: 

NETIO 4All, NETIO 4C, NETIO 4

 

Lua skript v této aplikační poznámce obsahuje v záhlaví uživatelem nadefinovanou tabulku 8 stavů, periodicky ovládají zapnutí/vypnutí čtyř výstupů zásuvek 230V (110/230V IEC-320 pro NETIO 4C). Každý z 8. stavů trvá nastavitelný čas (páté číslo, oddělené čárkou), kdy výstupy setrvají v nastavených hodnotách.
Počet stavů (řádků tabulky) lze rozšířit na víc než 8.


Hodnota výstupu může být 0/1, ale také 2/3 nebo 4, případně 5.

Hodnoty 0 až 5 pro jednotlivé výstupy používá firma NETIO products ve všech M2M API.

0 = Vypnutí výstupu  (Off)

1 = Zapnutí výstupu (On)

2 = Vypnutí výstupu na krátkou dobu (short Off)

3 = Zapnutí výstupu na krátkou dobu (short On)

4 = Přepnutí výstupu z jednoho stavu do druhého (toggle)

5 = Ponechání stavu výstupu (no change)

 

Stavy 2/3 slouží pro vytvoření pulsu na výstupu o definované délce. Lze tak například vytvořit stav, který trvá 5 sekund, ale jeden výstup se zapne pouze na 2 sekundy (state2 v příkladu).

Stav 5 je užitečný, pokud potřebujete výstup ovládat například tlačítkem na zařízení, nebo z jiného zdroje (mobilní aplikace, web rozhraní). Při použití hodnoty 5 zůstane výstup beze změny.

 

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:

 

  • Enabled: zaškrtnuto
  • Name: Traffic lights (uživatelsky definovatelné)
  • Description: Cyclic switching of the outputs (uživatelsky definovatelné)
  • Trigger: System started up
  • Schedule: libovolný (v této konfiguraci nemá vliv na funkci)

 

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

 

------------Section 1------------
local states = {"0000,1", --state1
                "3001,5", --state2
                "0010,1", --state3
                "1011,1", --state4
                "1100,1", --state5
                "0101,1", --state6
                "0110,1", --state7
                "0111,1"} --state8

local shortTimeMs = 1000 -- time used in states 2 and 3
---------End of Section 1---------

local currentState = 1 -- internal variable, do not change
local value -- internal variable
local time -- internal variable

local function checkFormat()
  for i=1,#states do
    local time = tonumber(states[i]:sub(6))
    if time == nil or time<-1 then
      logf("Time in state %d is invalid!",i)
      return false
    end
    local comma = states[i]:sub(5,5)
    if comma ~= "," then
      logf("Time in state %d is not separated by comma!", i)
      return false
    end
    for j=1,4 do
      local test = tonumber(states[i]:sub(j,j))
      if test == nil or test>5 or test<0 then
        logf("Value in state %d for outlet %d is invalid!", i,j)        
        return false
      end 
    end  
  end  
  return true
end

local function trafficLights()
  --logf("Current state: %d",currentState)
  time = tonumber(states[currentState]:sub(6))
  for i=1,4 do
    value = tonumber(states[currentState]: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() short(i,true) end)
    elseif value == 3 then -- short on
      devices.system.SetOut{output = i, value = true}
      milliDelay(shortTimeMs,function() short(i,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
  currentState = (currentState%#states) + 1
  delay(time,function() trafficLights() end)
end

local function short(outlet,state)
  devices.system.SetOut{output=outlet,value=state}
end

if checkFormat() then
  trafficLights()
end

 

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

 

 

Princip

 

  • Skript nejprve pomocí funkce checkFormat zkontroluje, jestli jsou stavy správně naformátované.
  • Do proměnné time uloží čas, za který se výstupy přepnou do dalšího stavu.
  • Ve smyčce postupně pro všechny výstupy nastaví jejich hodnotu podle zvolené hodnoty (0 - vypnout, 1 - zapnout, 2 - “short off”, 3 - “short on”, 4 - toggle, 5 - nic). Pro hodnoty 2 a 3 využívá k přepnutí funkci short.
  • Po nastavení výstupů nastaví proměnnou currentState na další stav a zavolá funkci trafficLights s patřičným zpožděním.

 

Nastavení proměnných

 

  • states
    • Proměnná obsahuje řetězce, z nichž každý odpovídá jednomu stavu. Před prvním a za posledním stavem musejí být složené uvozovky. Jednotlivé stavy jsou odděleny čárkou.
    • Formáty řetězců:
      • Řetězec má tvar “abcd,e” jednotlivá písmena znamenají:
        • a - hodnota výstupu 1
        • b - hodnota výstupu 2
        • c - hodnota výstupu 3
        • d - hodnota výstupu 4
        • e - čas, po který bude daný stav trvat (v sekundách)
      • Řetězec je typu string, musí být celý v uvozovkách
      • Příklad: “1205,25”
    • Stavy
      • 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

 

  • 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

 

Příklad: Postupné sepnutí a vypnutí všech výstupů, každý stav trvá 30 sekund (celkem 240 sekund - 4 minuty).

 

 

Ve stavu 1 se vypnou všechny výstupy. Za 30 sekund se semafor dostane do stavu 1 a zapne se výstup 4. Postupně se odzadu po 30 sekundách zapínají všechny výstupy až do stavu 5, kdy jsou všechny zapnuté. Poté se opět po 30 sekundách od výstupu 4 začnou vypínat. Ze stavu 8, kdy je zapnutý pouze výstup 1, přejde semafor opět do stavu 1 a celý cyklus se opakuje.

Ve stavu 8 je na jednom místě použit stav výstupu 5. Kdyby se v průběhu předchozího stavu změnil stav výstupu, nedojde k jeho vypnutí. Nechová se tedy stejně, jako kdyby tam byla 0.

 

Časté chyby

  • Špatné formátování
    • "0000" - není udán čas
    • "0000.30" - mezi stavy a časem musí být čárka (,)
    • "0006,30" - hodnota stavu musí být 0-5
    • "000x,30" - pokud nechcete stav zásuvky měnit, použijte hodnotu 5
    •  0000,30  - chybí uvozovky

 

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 script spustí a výstupy se začnou nastavovat podle tabulky. Pokud se skript nespustí zkontrolujte nastavení.

 

FAQ:

 

1) Je možné mít jiný počet stavů než je 8?

Ano, do proměnné states můžete vložit kolik stavů budete chtít. Nezapomeňte ale na správné formátování. Před prvním a posledním stavem musí být složené uvozovky a jednotlivé stavy musí být odděleny čárkou, viz obrázky.

Ukázky pro 4 a 10 stavů:

 

 

 

2) Je nějaká maximální doba, po kterou může daný stav trvat?

Není, ale pro dlouhé časové intervaly (řádově hodiny) doporučujeme použít funkci Scheduler.

 

3) Chtěl bych, aby se mi cyklus neopakoval do nekonečna, ale jenom několikrát, lze to udělat?

Ano, je ale potřeba většího zásahu do kódu. Je nutné vytvořit si vlastní proměnnou, která bude počítat počet stavů a tu porovnávat s vámi zvolenou hranicí.

 

4) Jak můžu běžící skript vypnout?

Nejprve musíte v nastavení skriptu vypnou zaškrtnutí políčka Enabled  a uložit nastavení. Potom je třeba restartovat NETIO.

 

5) Chtěl bych pomocí semaforu ovládat jenom 3 výstupy, je to možné?

Ano, pro výstupy, které nechcete ovládat,  nastavte všechny hodnoty na 5.

 

6) Pokud je následující hodnota výstupu nastavena na 5 a já ho mezitím změním například z mobilní aplikace, ovlivní běžící Lua skript jeho hodnotu?

Ne, stav 5 ponechá současný stav výstupu. Nezáleží na tom, jak se do daného stavu dostal.

 

7) Jak mám nastavit dobu trvání stavů 2 a 3 na 0.4 sekundy?

Proměnná shortTimeMs nastavuje dobu trvání stavu 2 a 3 v milisekundách. Stačí ji tedy nastavit takto: shortTimeMs = 400.

 

8) Můžu si do logu zapisovat, v jaké stavu se momentálně semafor nachází?

Ano, stačí odkomentovat (smazat pomlčky) řádek

--logf("Current state: %d",currentState) ve funkci trafficLights.

 

9) Je možné skript na chvíli zastavit a pak ho pustit znovu?

Ne, skript běží nepřetržitě a pozastavit ho není možné. Funkci, která by toto umožňovala plánujeme vydat v dalších verzích firmwaru.

 


Podporované verze FW:

3.0.0 a vyšší

 


Klíčová slova

Cyklické spínání zásuvek, semafor, spínání podle tabulky, práce s řetězci v Lua 

 

Zeptejte se na cenu nebo technické parametry

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