Podporovaná zařízení: NETIO PowerPDU 4C
NETIO model 4C obsahuje sériový port RS-232 (3 piny).
V konfiguraci zařízení lze sériový port (sériová konzole) připojit na nastavený TCP/IP port nebo přesměrovat do Lua skriptu jak to používá dále popsaný skript.
Lua skript bude reagovat na přijatý řetězec po sériovém portu, odešle odpověď a sepne výstup.
Unikátní vlastností je možnost v Lua skriptu přes web rozhraní měnit textový řetězec a tím i protokol na sériovém portu.
Pro práci se se sériovým portem je nutné nastavení několika jeho parametrů (baud rate, block delimiter, handshake). Samotný skript pak pomocí základních funkcí načte přijatou zprávu ze sériového portu a podle jejího tvaru provede příslušnou akci a zašle zpět odpověď. Příklad příkazu pro zapnutí výstupu 1: port 1 1
V Lua skriptu AN18 jsou připraveny 2 uživatelsky definované zprávy, jejichž formát a obsah příkazu je uživatelsky definovatelný.
Nastavení sériového portu
Ve webové aplikaci v sekci M2M API Protocols rozklikněte Serial Console a zvolte možnost Use in actions (Lua scripts).
Block delimiter nastavuje znak, který uzavře poslanou zprávu a spustí Lua skript. Lze využít z nabízených znaků (CR+LF, CR, LF, NULL) nebo pomocí možnosti custom zvolit jakýkoli vámi vybraný znak.
Při použití možnosti custom je nutné požadovaný znak vložit v hexadecimálním tvaru (před znak je nutné vložit 0x) do pole vpravo.
Při využití se pole vyplní samo podle zvolených znaků (CR+LF má hexadecimální tvar “0xd” a “0xa”)
Speed nastavuje rychlost přenosu (Baud rate).
Nastavení potvrďte kliknutím na zelené tlačítko Safe Changes.
Po aktivaci sériového portu se vedle záložky objeví tmavě zelená tečka a status se změní na “Connected”.
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: Serial console to Lua (uživatelsky definovatelné)
- Description: Parse message from Serial console and respond (uživatelsky definovatelné)
- Trigger: Serial console has read line
- 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 shortTimeMs = 1000 -- "short" time for short on/off [ms] local definableQuestion1 = "^all%-off$" -- prepared customer string 1 local definableQuestion2 = "^all%-on$" -- prepared customer string 2 local endingString = "\r\n" -- symbol sent at the end of each answer (CR+LF in the default setting) ---------End of Section 1--------- ------------Section 2------------ -- Serial port - Telnet commands definition local portValue = "^port %d$" local portSet = "^port %d %d$"; local portListValue = "^port list$" local portListSet = "^port list %d%d%d%d$" ---------End of Section 2--------- local id = event.args.id -- internal variable, do not change local message = event.args.message -- internal variable, do not change logf("%s",message) local function short(output,state) devices.system.SetOut{output=output,value=state} end local function isBetween(number,lowLimit,highLimit) if number >= lowLimit and number <= highLimit then return true end return false end local function setOutput(output,action) if action == 0 then -- turn off devices.system.SetOut{output = output, value = false} elseif action == 1 then -- turn on devices.system.SetOut{output = output, value = true} elseif action == 2 then -- short off devices.system.SetOut{output = output, value = false} milliDelay(shortTimeMs,function() short(output,true) end) elseif action == 3 then -- short on devices.system.SetOut{output = output, value = true} milliDelay(shortTimeMs,function() short(output,false) end) elseif action == 4 then -- toggle if devices.system["output" ..output.. "_state"] == 'on' then devices.system.SetOut{output=output,value=false} else devices.system.SetOut{output=output, value=true} end elseif action == 5 then -- do nothing end end if string.match(message,portValue) then -- return output state local output = tonumber(message:sub(6,6)) if not isBetween(output,1,4) then devices.system.SerialWrite{id=id,message="501 INVALID PARAMETR" .. endingString} return end local answer = "250 0" if devices.system["output" ..output.. "_state"] == 'on' then answer = "250 1" end devices.system.SerialWrite{id=id,message=answer..endingString} elseif string.match(message,portSet) then -- set output local output = tonumber(message:sub(6,6)) local action = tonumber(message:sub(8,8)) if not isBetween(output,1,4) or not isBetween(action,0,5) then devices.system.SerialWrite{id=id,message="501 INVALID PARAMETR" .. endingString} return end setOutput(output,action) devices.system.SerialWrite{id=id,message="250 OK" .. endingString} elseif string.match(message,portListValue) then -- return output status local answer = "250 " for i=1,4 do if devices.system["output" ..i.. "_state"] == 'on' then answer = answer .. "1" else answer = answer .. "0" end end devices.system.SerialWrite{id=id,message=answer .. endingString} elseif string.match(message,portListSet) then -- set outputs local actions = {}; for i=1,4 do actions[i] = tonumber(message:sub(10+i,10+i)) if not isBetween(actions[i],0,5) then devices.system.SerialWrite{id=id,message="501 INVALID PARAMETR" .. endingString} return end end for i=1,4 do setOutput(i,actions[i]) end devices.system.SerialWrite{id=id,message="250 OK" .. endingString} elseif string.match(message,definableQuestion1) then -- command 1 start for i=1,4 do setOutput(i,0) end devices.system.SerialWrite{id=id,message="250 OK" .. endingString} -- command 1 end elseif string.match(message,definableQuestion2) then -- command 2 start for i=1,4 do setOutput(i,1) end devices.system.SerialWrite{id=id,message="250 OK" .. endingString} -- command 2 end else devices.system.SerialWrite{id=id,message="502 UNKNOWN COMMAND" .. endingString} logf("%s",message) end
Popis kódu
- Zpráva zaslaná po sériovém portu se načte do proměnné message pomocí příkazu local message = event.args.message
- V této zprávě se nachází vše, co bylo poslané po sériové lince bez znaku ukončující zprávu.
- Formát zprávy se porovná s předem nastavenými vzory, popřípadě s vzory vytvořenými uživatelem (viz níže) pomocí funkce string.match. V případě shody se přesune do dané sekce a vykoná zadanou akci.
Proměnné
- V kódu se vyskytují 2 proměnné, které je možné nastavit
-
shortTimeMs
- Nastavuje dobu v milisekundách, za kterou se výstup zapne/vypne ve stavech 2 respektive 3 (short off / short on)
- Minimální hodnota je 100ms.
- Příklad pro sepnutí na dobu 2 sekundy: shortTimeMs = 2000
-
endingString
- Nastavuje symbol, který bude ukončovat všechny odpovědi zaslané po sériové lince zpět.
- Výchozí hodnota jsou symboly CR+LF (v Lua jsou reprezentovány jako \r\n).
- Aby se celý skript choval jako solidní protokol, je nutné tento ukončující řetězec nastavit stejný, jako je řetězec, kterým se Lua skript spouští.
Seznam základních příkazů:
- Vzory pro tyto příkazy jsou v kódu v Section2 (proměnné portValue, portSet, portListValue, portListSet).
-
port <output> <action>
- Příkaz sloužící k ovládání jedné konkrétní zásuvky
- <output> nahraďte číslem zásuvky
- <action> nahraďte jedním z parametrů
- Pokud parametr <action> vynecháte, vypíše se stav zásuvky
-
Parametry:
- 0 - vypne zásuvku
- 1 - zapne zásuvku
- 2 - krátce vypne zásuvku (pokud byla zásuvky vypnutá, bude po provedení příkazu zapnutá)
- 3 - krátce zapne zásuvku (pokud byla zásuvky zapnutá, bude po provedení příkazu vypnutá)
- 4 - změní aktuální stav zásuvky
-
5 - ponechá zásuvku beze změny
- Příklad zapnutí zásuvky 1: port 1 1
- Příklad vypnutí zásuvky 3: port 3 0
-
port list [xxxx]
- Příkaz sloužící k ovládání všech zásuvek najednou
- Bez parametrů vypíše stav zásuvek
-
Seznam parametrů:
- 0 - vypne zásuvku
- 1 - zapne zásuvku
- 2 - krátce vypne zásuvku (pokud byla zásuvky vypnutá, bude po provedení příkazu zapnutá)
- 3 - krátce zapne zásuvku (pokud byla zásuvky zapnutá, bude po provedení příkazu vypnutá)
- 4 - změní aktuální stav zásuvky
-
5 - ponechá zásuvku beze změny
- Příklad zapnutí všech zásuvek: port list 1111
- Příklad zapnutí zásuvek 1,3, vypnutí zásuvky 4 a přepnutí stavu zásuvky 2: port list 1410
- Příklad zapnutí zásuvek 2,3 a zachování stavu zásuvek 1,4: port list 5115
- Poznámka: Je nutné nahradit všechny x v parametru, pokud nechcete, aby se stav zásuvky měnil, použijte jako parametr 5. Příkaz port list 10x1 nebude přijat.
Definice uživatelských příkazů po RS-232
Formát otázky (přijaté po RS-232)
- Pro vytváření vlastních vzorů otázek jsou připravené proměnné definableQuestion1 a definableQuestion2.
-
Vlastní vzor musí být umístěn do uvozovek a mezi znaky ^ a $. Tato konvence zajistí, že přijatá zpráva musí přesně odpovídat otázce.
- Příklad pro otázku all-on: definableQuestion = "^all%-on$"
-
Pokud se v otázce vyskytuje symbol, který slouží jako proměnná, je možné místo tohoto symbolu vložit zastupující symbol (. pro jakýkoli znak (char), %d specificky pro číslo).
- Příklad z přednastavených příkazů zjišťující stav zadaného výstupu port %d: portValue = "^port %d$"
- V otázce není možné ověřit o jaké číslo se jedná. Pokud chcete odpověď pouze pro konkrétní číslo, vložte ho klasicky do řetězce (definableQuestion1 = "^getState 1$"). Obsahuje-li otázka mezeru, zpráva ji musí obsahovat také.
- Při vytváření vlastních otázek je nutné dát si pozor na to, aby se vzory nepřekrývaly. Například "^port %d$" a "^port 1$". V tomto případě by se při poslání znaků port 1 vykonal příkaz, který je v kódu výše.
-
Tyto znaky jsou v Lua označovány jako “magické” a při jejich použití v otázce je nutné před ně vložit symbol %
- ( ) . % + - * ? [ ^ $
- Příklad pro otázku all-off : definableQuestion = "^all%-off$"
- Proces vytváření odpovědi je popsán níže.
Vytvoření odpovědi (odeslané po přijetí odpovědi)
- Pro obě připravené proměnné, je vyhrazen kus kódu, ve kterém se vykoná příslušná odpověď. Nacházejí se v dolní části kódu (viz obrázek).
- Na místo ukázkového kódu (sekce mezi komentáři) vložte váš kód s příslušnou akcí.
-
Pro jednoduší práci jsou naimplementovány pomocné funkce:
-
setOutput(output,action)
- Funkce sloužící k změně stavu výstupu (parametr output) podle zadané akce (parametr action).
- Parametr action může nabývat až 5 hodnot (viz popis příkazu port).
- Příklad pro přepnutí stavu výstupu 3: setOutput(3,4)
-
isBetween(number,lowLimit,highLimit)
- Funkce vrací true, pokud se první parametr (number) nachází mezi druhým a třetím parametrem (lowLimit a highLimit).
-
Příklady:
- isBetween(1,1,4) vrací true
- isBetween(0,1,4) vrací false
- Tato funkce se používá pro kontrolu vstupních parametrů.
-
setOutput(output,action)
-
Pro poslání zprávy po sériové lince zpět je možné využít funkci devices.system.SerialWrite{id=id,message="Your message" .. endingString}
- Na místo "Your message" je možné vložit string se zprávou (do uvozovek), popřípadě proměnnou (bez uvozovek).
- Pomocí .. endingString se na konec zprávy přidá ukončovací řetězec. Pokud nechte zprávu končit tímto řetězcem, lze tuto konstrukci smazat (včetně dvou teček).
- Pokud nechcete zaslat žádnou zprávu zpět, je nutné poslat alespoň ukončovací řetězec funkcí: devices.system.SerialWrite{id=id,message=endingString}
FAQ:
1) Můžu mít více vlastních otázek (commandů)?
Ano. Pro přidání vzoru stačí vytvořit proměnnou (např. definableMessage3), do které uložíte příslušný vzor. Do kódu je pak dále nutné přidat další podmínku do které budete moci napsat příslušnou akci. Nad poslední else vložte tuto podmínku: elseif string.match(message,definableMessage3) then
Pod tuto podmínku nyní můžete psát vaši akci. Pokud jste si zvolili jiný název proměnné, nezapomeňte ho změnit i v podmínce. Váš kód by měl nyní vypadat takto:
2) Nechci používat základní příkazy. Je možné je vypnout?
Stačí v kódu smazat příslušnou sekci pod funkcí setOutput. Kód by měl nyní vypadat takto
3) Proč je v ukázkovém příkladu ukončující řetězec “\r\n”?
V základním nastavení je jako řetězec, kterým se spouští CR+LF (viz Nastavení sériového portu). Je nutné, aby byl ukončující řetězec shodný s řetězcem, kterým se Lua skript spouští a v Lua je řetězec CR+LF reprezentován právě řetězcem “\r\n”.
4) Je možné získat data o naměřených hodnotách spotřeby?
Jelikož NETIO 4C neumí měřit hodnoty spotřeby, není možné zjistit spotřebu.
5) Dají se z Lua skriptu změnit parametry sériového portu?
Ne. Pouze v nastavení sériového portu.
Podporované verze FW:
3.1.0 a vyšší (Firmware archiv)
Více o Lua:
https://wiki.netio-products.com
Tato Aplikační poznámka může být použita v:
|
NETIO PowerPDU 4CNETIO 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í. |