Grenton – plik OM.LUA

Jak już jakiś czas temu wspominałem, że zamierzam przyjrzeć się plikowi OM.LUA. Jest mi to potrzebne do dalszej pracy z Grentonem.

Konfiguracja CLU

Clu Grentona jest konfigurowane przez Object Managera, w którym użytkownik może wyklikać konfigurację. Następnie ta konfiguracja jest wysyłana na CLU za pomocą protokołu tftp. W skład konfiguracji wchodzą następujące pliki:

CONFIG.TXT – jest to plik w którym zapisane są klucze szyfrujące, wersja oprogramowania, ip CLU

OM.LUA – plik służący do konfiguracji modułów.

USER.LUA – plik w którym przechowywane są skrypty (funkcje) napisane przez użytkownika.

MAIN.LUA – jest to główny plik uruchamiany po włączeniu się CLU. Dołącza on konfigurację z plików USER, OM,

Plik MAIN.LUA wygląda następująco. Dodałem komentarze z prawej strony

collectgarbage("collect") 
require "user"                -- dołączenie skryptów użytkownika

collectgarbage("collect")
require "om"                  -- dołączenie konfiguracji modułów

collectgarbage("collect")    

function checkAlive()         -- nazwa jest trochę myląca. Funkcja ta zwraca "id" Clu, które jest skonfigurowane w pliku OM.LUA
    return "0d1cf150"       
end

SYSTEM.Init()                 -- inicjalizacja systemu. Prawdopodobnie, wywołanie tej metody wyzwala event OnInit. 

repeat
    SYSTEM.Loop()             -- główna pętla Clu.  
until 1==2

Co robi plik OM.LUA?

Przejdźmy do najważniejszego, czyli konfiguracji modułów. Konfiguracja ta jest zapisana w OM, ale przy wysyłce na CLU jest tłumaczona do LUA.

Plik zaczyna się od konfiguracji samego CLU:

CLU_0d1cf150 = OBJECT:new(0, 0xC0A802C8)
-- NAME_CLU DOM=CLU_0d1cf150

Obiekty modułów są tworzone za pomocą fabryki(?) o nazwie OBJECT. W nazwie zmiennej, do której przypisane jest CLU zaszyte jest ID modułu. Czyli CLU_0d1cf150  to szesnastkowy zapis: 220000592. Poniżej jest też komentarz w którym zapisana jest nazwa jaką przyznałem CLU, czyli DOM. Prawdopodobnie jest to potrzebne, gdy podłączamy się z OM pod istniejącą konfigurację i nie chcemy zmieniać nazw obiektów, które już zostały zdefiniowane. Metoda “new” przyjmuje dwa argumenty. Pierwszy – 0 (zero) to w tym przypadku ID urządzenia. Drugi argument to IP. Wartość jest zapisana w Hex. Aby odczytać IP należy przekonwertować tę liczbę do postaci dziesiętnej, a potem użyć funkcji z PHP long2ip.

0xC0A802C8(HEX) ->  3232236232(DEC) -> long2ip(3232236232) -> 192.168.2.200

Następnie zdefiniowane są moduły. W moim przypadku wpisy wyglądają następująco:

-- MODULES
mm_180001305 = OBJECT:new(2, 0x0aba9a19, 0x00) -- 180001305 00 10
mm_200003152 = OBJECT:new(2, 0x0bebce50, 0x01) -- 200003152 01 0b
mm_200003293 = OBJECT:new(2, 0x0bebcedd, 0x01) -- 200003293 01 0b
mm_460000424 = OBJECT:new(2, 0x1b6b0ca8, 0x08) -- 460000424 00 11
mm_113247182 = OBJECT:new(2, 0x06c003ce, 0xff) -- 113247182 28 01
mm_154160907 = OBJECT:new(2, 0x09304f0b, 0xff) -- 154160907 28 01

I tym razem użyta jest metoda OBJECT:new czyli ta sama co przy tworzeniu CLU. W tym przypadku przyjmuje trzy parametry a nie jak poprzednio dwa. W tym wypadku “2” może oznaczać, że są to moduły na szynę DIN. Wartości w drugim argumencie to ID moich modułów. Co do ostatniego argumentu nie jestem pewien. Wydaje mi się, że oznacza typ modułu.

0x00- digital in
0x01 – digital out
0x08 – analog out
0xFF – czujnik temperatury 1-wrie

Z prawej strony znajduje się komentarz, który powiela te informacje, ale typy (np. 10) zgadzają się ze słownikami zaszytymi w kodzie OM. Wygląda na to, że CLU ma własny słownik i OM ma własny.

Po skonfigurowaniu modułów można zacząć konfigurować poszczególne wejścia i wyjścia, które te moduły posiadają. Konfiguracja znów odbywa się za pomocą metody w new klasy OBJECT i wygląda następująco:

-- IO_MODULES
DIN_6650 = OBJECT:new(3, mm_180001305, 0)
-- NAME_IO x180001305_DIN1=DIN_6650
DIN_1277 = OBJECT:new(3, mm_180001305, 1)
-- NAME_IO x180001305_DIN2=DIN_1277
DIN_8304 = OBJECT:new(3, mm_180001305, 2)
-- NAME_IO x180001305_DIN3=DIN_8304
DIN_4380 = OBJECT:new(3, mm_180001305, 3)
-- NAME_IO x180001305_DIN4=DIN_4380
DIN_1066 = OBJECT:new(3, mm_180001305, 4)
-- NAME_IO x180001305_DIN5=DIN_1066
DIN_7578 = OBJECT:new(3, mm_180001305, 5)
-- NAME_IO x180001305_DIN6=DIN_7578
DIN_3284 = OBJECT:new(3, mm_180001305, 6)
-- NAME_IO x180001305_DIN7=DIN_3284
DIN_0388 = OBJECT:new(3, mm_180001305, 7)
-- NAME_IO x180001305_DIN8=DIN_0388

Rozszyfrowałem parametry następująco. Jest to konfiguracja 8 wejść digital in (od 0 do 7). Każde wyjście jest przypisane do globalnej zmiennej. O nazwach zaczynających się od prefiksu “DIN_”. Pierwszym parametrem jest 3, co prawdopodobnie oznacza, żeby używać fabryki obiektów klasy DigitalIn. Potem przekazana jest do obiektu modułu w ramach, którego pracuje dane wejście, a na koniec przypisane jest konkretne wejście (cyfry 0-7).

Podobnie wygląda konfiguracja DigitalOut:

DOUT_2485 = OBJECT:new(4, mm_200003152, 0)
-- NAME_IO x200003152_DOUT1=DOUT_2485
DOUT_6848 = OBJECT:new(4, mm_200003152, 1)
-- NAME_IO x200003152_DOUT2=DOUT_6848
DOUT_8565 = OBJECT:new(4, mm_200003152, 2)
-- NAME_IO x200003152_DOUT3=DOUT_8565
DOUT_4705 = OBJECT:new(4, mm_200003152, 3)

-- NAME_IO x200003152_DOUT4=DOUT_4705
DOUT_6710 = OBJECT:new(4, mm_200003293, 0)
-- NAME_IO x200003293_DOUT1=DOUT_6710
DOUT_3423 = OBJECT:new(4, mm_200003293, 1)
-- NAME_IO x200003293_DOUT2=DOUT_3423
DOUT_4513 = OBJECT:new(4, mm_200003293, 2)
-- NAME_IO x200003293_DOUT3=DOUT_4513
DOUT_4114 = OBJECT:new(4, mm_200003293, 3)

W sekcji powyżej widać konfigurację dwóch modułów DigitalIN: mm_200003152 oraz mm_200003293. Kolejną sekcja urządzeń będzie AnalogIn:

AnalogOUT_0042 = OBJECT:new(13, mm_460000424, 0)
-- NAME_IO x460000424_AnalogOUT1=AnalogOUT_0042
AnalogOUT_4654 = OBJECT:new(13, mm_460000424, 1)
-- NAME_IO x460000424_AnalogOUT2=AnalogOUT_4654
AnalogOUT_2371 = OBJECT:new(13, mm_460000424, 2)
-- NAME_IO x460000424_AnalogOUT3=AnalogOUT_2371
AnalogOUT_0007 = OBJECT:new(13, mm_460000424, 3)

-- NAME_IO x460000424_AnalogOUT4=AnalogOUT_0007
AnalogIN_3611 = OBJECT:new(12, mm_460000424, 0)
-- NAME_IO x460000424_AnalogIN1=AnalogIN_3611
AnalogIN_6008 = OBJECT:new(12, mm_460000424, 1)
-- NAME_IO x460000424_AnalogIN2=AnalogIN_6008
AnalogIN_7445 = OBJECT:new(12, mm_460000424, 2)
-- NAME_IO x460000424_AnalogIN3=AnalogIN_7445
AnalogIN_4221 = OBJECT:new(12, mm_460000424, 3)
-- NAME_IO x460000424_AnalogIN4=AnalogIN_4221

Tu też nie ma nic nowego. Moduł AnalogIN/OUT posiada 4 wejścia i wyjścia, których odzwierciedlenie widać w powyższej konfiguracji.

Na koniec zostały dwa czujniki temperatury podpięte pod 1-wire:

ONEW_SENSOR_7372 = OBJECT:new(23, mm_113247182, 0)
-- NAME_IO x113247182_ONEW_SENSOR1=ONEW_SENSOR_7372
ONEW_SENSOR_6304 = OBJECT:new(23, mm_154160907, 0)
-- NAME_IO x154160907_ONEW_SENSOR1=ONEW_SENSOR_6304

Nie jestem pewien skąd się wziął tak duży rozjazd pomiędzy ID tych czujników, tj: 113247182 a 154160907. Możliwe, że w termometrze jest zapisane to ID?

Kolejna sekcja to zdefiniowanie dwóch metod, które pozwalają na zapis zmiennych do globalnego scope w LUA.

function setVar(name, value)
    _G[name] = value
end

function getVar(name)
    return _G[name]
end

Funkcje zostały zdefiniowane, ale w pliku OM.LUA nie ma śladu ich użycia. Pewnie używane są przez kod wbudowany w CLU. Następna sekcja odpowiedzialna jest za eventy (zdarzenia).

function EventsFor_DIN_6650_0()
    light_switch(nil)
end
DIN_6650:add_event(0, EventsFor_DIN_6650_0)

W tej chwili mam zdefiniowany jeden event, który na zdarzenie OnChange (to jest to zero) włączy fukcję (skrypt) light_switch. Następnie funkcja ta zostaje dodana do konkretnego wejścia, w tym wypadku do DIN_6650. Metoda add_event posiada dwa argumenty. Pierwszy to numer zdarzenia. Prawdopodobnie przypisane są po kolei, ale tylko zgaduję. Prawdopodobnie słownik wygląda tak:
0 – OnChange
1 – OnSwitchOn
2 – OnSwitchOff
3 – OnShortPress
4 – OnLongPress
5 – OnHold
6 – OnClick

Przed ostatnią sekcją jest inicjalizacja wartości domyślnych dla modułów. Wygląda ona następująco (po prawej moje komentarze)

function OnInit()

    -- INIT_CLU_OBJECTS
    DIN_6650:set(1, 0)    -- moduł DigitalIN. 0 oznacza Intertion
    DIN_6650:set(2, 500)  -- 2 oznacza HoldDelay
    DIN_6650:set(3, 50)   -- 3 oznacza HoldInterwal
    DIN_1277:set(1, 0)
    DIN_1277:set(2, 500)
    DIN_1277:set(3, 50)
    DIN_8304:set(1, 0)
    DIN_8304:set(2, 500)
    DIN_8304:set(3, 50)
    DIN_4380:set(1, 0)
    DIN_4380:set(2, 500)
    DIN_4380:set(3, 50)
    DIN_1066:set(1, 0)
    DIN_1066:set(2, 500)
    DIN_1066:set(3, 50)
    DIN_7578:set(1, 0)
    DIN_7578:set(2, 500)
    DIN_7578:set(3, 50)
    DIN_3284:set(1, 0)
    DIN_3284:set(2, 500)
    DIN_3284:set(3, 50)
    DIN_0388:set(1, 0)
    DIN_0388:set(2, 500)
    DIN_0388:set(3, 50)

    DOUT_2485:set(0, 0)   -- czy dane wejście jest włączone czy wyłączone 
    DOUT_6848:set(0, 0)
    DOUT_8565:set(0, 0)
    DOUT_4705:set(0, 0)
    DOUT_6710:set(0, 0)
    DOUT_3423:set(0, 0)
    DOUT_4513:set(0, 0)
    DOUT_4114:set(0, 0)

    AnalogOUT_0042:set(0, 0)  -- analog in ma sporo parametrów: 
    AnalogOUT_0042:set(1, 0)  -- Value, Value%, Scale, 
    AnalogOUT_0042:set(2, 1)
    AnalogOUT_0042:set(3, 500) -- tego 500 nie ma w konfiguracji AnalogIn w OM. Możliwe, że jest to jakiś interwał. Np 500ms. 
    AnalogOUT_0042:set(4, 0)
    AnalogOUT_0042:set(5, 10)
    AnalogOUT_4654:set(0, 0)
    AnalogOUT_4654:set(1, 0)
    AnalogOUT_4654:set(2, 1)
    AnalogOUT_4654:set(3, 500)
    AnalogOUT_4654:set(4, 0)
    AnalogOUT_4654:set(5, 10)
    AnalogOUT_2371:set(0, 0)
    AnalogOUT_2371:set(1, 0)
    AnalogOUT_2371:set(2, 1)
    AnalogOUT_2371:set(3, 500)
    AnalogOUT_2371:set(4, 0)
    AnalogOUT_2371:set(5, 10)
    AnalogOUT_0007:set(0, 0)
    AnalogOUT_0007:set(1, 0)
    AnalogOUT_0007:set(2, 1)
    AnalogOUT_0007:set(3, 500)
    AnalogOUT_0007:set(4, 0)
    AnalogOUT_0007:set(5, 10)
    AnalogIN_3611:set(2, 1)
    AnalogIN_3611:set(3, 0)
    AnalogIN_3611:set(4, 0)
    AnalogIN_3611:set(5, 0)
    AnalogIN_3611:set(6, 10)
    AnalogIN_6008:set(2, 1)
    AnalogIN_6008:set(3, 0)
    AnalogIN_6008:set(4, 0)
    AnalogIN_6008:set(5, 0)
    AnalogIN_6008:set(6, 10)
    AnalogIN_7445:set(2, 1)
    AnalogIN_7445:set(3, 0)
    AnalogIN_7445:set(4, 0)
    AnalogIN_7445:set(5, 0)
    AnalogIN_7445:set(6, 10)
    AnalogIN_4221:set(2, 1)
    AnalogIN_4221:set(3, 0)
    AnalogIN_4221:set(4, 0)
    AnalogIN_4221:set(5, 0)
    AnalogIN_4221:set(6, 10)

    ONEW_SENSOR_7372:set(1, 0.5) -- Czujniki temperatury wpięte w 1-wire. 0.5 to Treshold
    ONEW_SENSOR_7372:set(2, 0)   -- minValue
    ONEW_SENSOR_7372:set(3, 100) -- maxValue
    ONEW_SENSOR_6304:set(1, 0.5)
    ONEW_SENSOR_6304:set(2, 0)
    ONEW_SENSOR_6304:set(3, 100)

end

Ostatnią sekcją jest przypisanie zdarzenia OnInit do CLU.

CLU_0d1cf150:add_event(0, OnInit)

Podsumowanie:

  • Konfigurację zaszytą w plikach dość łatwo zrozumieć.
  • Klasa OBJECT i metoda new mają bardzo dużo odpowiedzialności. Sterowane numerkami może powodować ból głowy.
  • Komentarze NAME_IO mogą się przydać przy pisaniu alternatywnego klienta.

Pozdrawiam,
T

Please follow and like us:

Leave a Reply

Your email address will not be published.