Zaprezentuję tu mały, przykładowy skrypt OpenBeken wyłączający urządzenie po danym czasie od włączenia. Czas oczekiwania będzie również konfigurowalny przez użytkownika, a cały mechanizm zostanie oskryptowany ręcznie, co daje użytkownikowi duże możliwości modyfikacji bez żadnych zmian w firmware.
Wykorzystane urządzenie
Do prezentacji użyłem gniazda LSPA9 sterowanego przez WiFi opartego na układzie BK7231:
Temat o gnieździe:
https://www.elektroda.com/rtvforum/topic3887748.html
Podstawy skryptowania
Skrypty tworzymy w systemie plików hostowanym na urządzeniu. Oto krótki tutorial:
Plik wykonywany na starcie to autoexec.bat, można w nim umieścić nasz program.
Dokumentacja znajduje się tutaj:
https://github.com/openshwprojects/OpenBK7231T_App/blob/main/docs/README.md
Dokumentacja komend ma osobną podstronę:
https://github.com/openshwprojects/OpenBK7231T_App/blob/main/docs/commands.md
W dokumentacji znajdują się też przykłady plików autoexec.bat:
https://github.com/openshwprojects/OpenBK7231T_App/blob/main/docs/autoexecExamples.md
Tworzymy własny skrypt
Najpierw zastanówmy się, co chcemy aby nasz skrypt oferował:
- czas opóźnienia do wyłączenia powinien być pokazany w polu tekstowym
- czas opóźnienia do wyłączenia powinien być pamiętamy po reboocie urządzenia
- bieżąca wartość czasu oczekiwania (gdy trwa odliczanie) powinna być pokazana jako timer, osobno od wartości "nastawionej"
- gdy użytkownik włącza urządzenie, to opracowany timer automatycznie się załącza i odlicza czas
Tutaj mała uwaga - jeśli ktoś by się uparł, to w OBK można by to zrobić jedną komendą, poprzez addRepeatingEvent, ale my chcemy rozbić to najbardziej jak się da na komendy by móc potem dowolnie je edytować.
Mając już koncept skryptu musimy postarać się bardziej rozbić go na części pierwsze, czyli:
- określić zmienne (w OBK kanały) jakich użyjemy - tu potrzebny będzie stan przekaźnika, bieżąca wartość czasu do wyłączenia oraz stała początkowa wartość do wyłączenia
- określić typy tych zmiennych w (w OBK typy kanałów) by móc je wyświetlać na panelu WWW, oto lista typów
- określić sposób odliczania czasu, tutaj, jako że to jest przykład, zdecydowałem się po prostu zmniejszać wartość kanału w prostej pętli
- określić sposób wykrycia zmiany stanu przekaźnika, tutaj użyłem zdarzenia zmiany AddChangeHandler
W oparciu o to można opracować gotowy skrypt. Oto mój przykładowy autoexec.bat;
// Used channels:
// Channel 1 - relay
// Channel 2 - current countdown value
// Channel 3 - constant time for countdown
// this will make channel 3 save in memory
setStartValue 3 -1
// if channel 3 is not set (default first case), set it to 15 seconds11
if $CH3==0 then setChannel 3 15
// display text field for channel 3 on www page
setChannelType 3 TextField
// set label
setChannelLabel 3 TurnOffTime
// display timer seconds (read only) for channel 2 on www page
setChannelType 2 TimerSeconds
// shorthand for setting channel 2 to value of channel 3
alias turn_off_after_time backlog setChannel 2 $CH3
// shorthand for clearing current timer value
alias on_turned_off setChannel 2 0
// shorthand to set relay off
alias turn_off_relay setChannel 1 0
// check used to turn off relay when countdown value reaches 0
alias do_check if $CH2==0 then turn_off_relay
// an update command; it decreases current countdown by 1 and checks for 0
alias do_tick backlog addChannel 2 -1; do_check
// event triggers for channel 1 changing to 0 and 1
addChangeHandler Channel1 == 1 turn_off_after_time
addChangeHandler Channel1 == 0 on_turned_off
// main loop - infinite
again:
if $CH2!=0 then do_tick
delay_s 1
goto again
Po restarcie urządzenia otrzymujemy zmodyfikowany panel:
Widać na panelu przycisk od przełącznika przekaźnika, bieżącą wartość odliczania oraz nastawę czasu odliczania.
W momencie załączenia przekaźnika rozpoczyna się odliczanie:
Wartość kanału 2 spada:
Po chwili dociera do 0 i przekaźnik się otwiera:
Skrypt jest odporny na wielokrotne włączanie i wyłączanie zasilania, nie ma możliwości popsucia tu tej logiki.
Dla miminalistów
Oczywiście cały przykład tutaj powstał po to, by też pokazać możliwości skryptowania. Jeśli ktoś nie chce pisać za dużo kodu, to również i taki skrypt da radę:
// This aliased command will turn off relay on CH1 after 10 seconds
// addRepeatingEvent [IntervalSeconds][RepeatsOr-1][CommandToRun]
alias turn_off_after_time addRepeatingEvent 10 1 setChannel 1 0
// this will run the turn off command every time that CH1 becomes 1
addChangeHandler Channel1 == 1 turn_off_after_time
Można go nawet skompresować:
addChangeHandler Channel1 == 1 addRepeatingEvent 10 1 setChannel 1 0
Tyle, że on nie oferuje możliwości podglądu i nastawiania czasów na panelu WWW i nie eksponuje ich dla MQTT.
Podsumowanie
Tak oskryptowane urządzenie może wykonywać różnego rodzaju automatyzacje zupełnie bez udziału chmury a nawet bez udziału Home Assistant. Co więcej, można nawet tak wykonywać automatyzacje na wielu urządzeniach, poprzez komendę SendGet, ale o tym innym razem. W razie wątpliwości polecam zajrzeć do naszej dokumentacji:
https://github.com/openshwprojects/OpenBK7231T_App/blob/main/docs/autoexecExamples.md
Oczywiście w razie pytań postaram się pomóc.
PS: Temat powstał w odpowiedzi na coraz częściej pojawiające się pytania o tego typu skrypty, m. in. tutaj i tutaj. Temat będzie też tłumaczony na język angielski.
Fajne? Ranking DIY Pomogłem? Kup mi kawę.