'Inteligenty' dom ze sterownikiem PLC

 Language:
Szukanie zaawansowane  

Aktualności:

Powrót do strony głównej: www.edom-plc.pl

Autor Wątek: OpenHab2 - modbus - Wago?  (Przeczytany 2402 razy)

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
OpenHab2 - modbus - Wago?
« dnia: Października 05, 2020, 08:43:55 pm »

Witam,

Nadchodzi czas, żeby wizualizować automatykę domu. Przez ostatnie pół roku wszystko śmiga dobrze, ale narzazie tylko na przyciskach fizycznych w domu.

Po przeanalizowaniu różnych opcji wybrałem dla siebie Openhaba. Wydaje mi się, że dzięki niemu łatwiej będzie integrować systemy, które przez sterownik PLC nawet nie byłoby jak zintegrować.

WIem, że część z was korzysta też z tego oprogramowania i mam dość podstawowe pytanie dotyczące obsługi Latchingu (sterowania oswietleniem). Modbus działa, odczytuję i zapisuję zmienne, nawet udało się sterować oświetleniem, ale nie do końca działa to tak jak bym chciał.

Chodzi o to, że openhab wystawia sygnał "1" na "stałe" a nie impuls, który steruje PLC. Ogólnie wiem jak rozwiązać ten problem, ale chciałbym się podpytać, bo może ktoś ma mądrzejsze, lepsze rozwiązanie.

W openhabie chce oczywiście sterować pojedynczym "suwaczkiem", ale żeby to osiągnąć potrzebuję stworzyć regułę dla jednego Item, która będzie symulować wystawienie impulsów dla PLC po zmianie stanu drugiego Item, który będzie widoczny w wizualizacji (sitemap).

I teraz moje pytanie czy jest to jedyny sposób? Ogólnie chciałby, aby logika sterowania przekaźnikami były obsługiwana w całości po stronie wago, a openhab pełnił funkcję wizualziacji.

I na koniec jeszcze jedno pytanie. Openhab ponoc ma wago binding, ale u mnie go nie widać. Na stronie projektu przy wago binding widnieje opis v1, czy to znaczy, zę jest ono dostepne tylko dla wersji 1.x? Czym różni się wago binding od modbus binding, którego obecnie używam?


 
Zapisane

Simeone

  • Jr. Member
  • **
  • Wiadomości: 98
    • Zobacz profil
Odp: OpenHab2 - modbus - Wago?
« Odpowiedź #1 dnia: Października 06, 2020, 07:31:26 am »

Chodzi o to, że openhab wystawia sygnał "1" na "stałe" a nie impuls, który steruje PLC. Ogólnie wiem jak rozwiązać ten problem, ale chciałbym się podpytać, bo może ktoś ma mądrzejsze, lepsze rozwiązanie.

Korzystając z Node-reda napotkałem identyczny problem z wysyłaniem impulsów po Modbusie.
Rozwiązaniem jakie zastosowałem było dołożenia bloczka funkcyjnego poprzedzonego delay-em 100ms (jak na załączonym zrzucie). Działa to tak, że po naciśnięciu przycisku na wizualizacji, równolegle wysyłany jest impuls ustawiający rejestr modbusowy na 1 i startowany delay. Ten po upływie określonego czasu wysyła impuls aktywujący blok funkcyjny, który ustawia rejestr na 0.
Również nie jestem pewien, czy ten sposób jest najbardziej optymalny i szukam rozwiązania, które nie będzie wymagało dodawania do każdego przycisku tylu nadmiarowych bloczków.
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: OpenHab2 - modbus - Wago?
« Odpowiedź #2 dnia: Października 06, 2020, 05:46:47 pm »

no ja teraz impulsy generuje na sterowniku funkcją PT. Ogólnie nie widzę tego, aby powierzyć Rapsberry większą logikę domu. Kumpel namawia mnie na wykorzystanie w tym celu PHP w roli pośrednika między WAGO a Openhabem, ale to znowu kolejne komplikowanie sprawy. Aż się wierzyć nie chce, że na takim openhabie nie ma prostej obsługi na zasadzie "impulsów", a w zasadzie to chodzi o to, aby item mogło jednocześnie zapisywać i odczytywać modbusa, tak aby można było mieć informację o stanie światła przy wykorzystaniu włącznika na ścianie. Czy z tym problemem także sobie radziłeś w node red?
Zapisane

Simeone

  • Jr. Member
  • **
  • Wiadomości: 98
    • Zobacz profil
Odp: OpenHab2 - modbus - Wago?
« Odpowiedź #3 dnia: Października 07, 2020, 07:34:16 am »

no ja teraz impulsy generuje na sterowniku funkcją PT.

Chodzi o TP? On nie generuje impulsów, a raczej stabilizuje to co ma na wejściu. Więc tak czy inaczej trzeba mu zdefiniować źródło impulsów, którym u mnie jest z-OR-owane wejście fizyczne z wyłącznika oraz zmienna %MX, która ma przypisany adres MODBUS-owy. Zmieniając stan tej zmiennej z wizualizacji steruję działaniem bloczka TP. Problem jaki powstaje przy tym sposobie sterowania to właśnie omawiana konieczność wysyłania przy każdej akcji dwóch poleceń - najpierw ustawienia rejestru na 1 a później powrót na 0.

Ogólnie nie widzę tego, aby powierzyć Rapsberry większą logikę domu.

Nie ma mowy o powierzeniu innemu urządzeniu obsługi logiki - tą zajmuje się wyłącznie Wago. Jeśli jednak chcesz wizualizację i wygodny interfejs to musisz go postawić na zewnętrznym serwerze i tutaj takie wynalazki jak miniPC sprawdzą się doskonale.

Aż się wierzyć nie chce, że na takim openhabie nie ma prostej obsługi na zasadzie "impulsów", a w zasadzie to chodzi o to, aby item mogło jednocześnie zapisywać i odczytywać modbusa, tak aby można było mieć informację o stanie światła przy wykorzystaniu włącznika na ścianie. Czy z tym problemem także sobie radziłeś w node red?

Tak, chociaż cykliczne zapytania niezbędne do prawidłowego wyświetlania aktualnych statusów bardzo zmulają komputery o mniejszej wydajności, jak np. starsze RPi czy mojego BeagleBone'a, z którego byłem zmuszony zrezygnować.

Sam sposób implementacji widać na załączonym zrzucie:
1. Odczyt dziesięciu rejestrów Modbus poczynając od 512 (tyle mam kart wyjściowych)
2. Podgląd wartości poszczególnych rejestrów w formie tablicy WORDów (wartości od 0 do 65535 czyli 16 bitów bo tyle jest wyjść na każdej karcie)
3. Funkcja wyłuskująca interesujący bit (wyjście)
4. Bloki ustawiające na wyjściu właściwości takie jak kolor czy tekst w zależności od stanu wejścia
5. Przycisk
6. Zapis rejestru odpowiadającego zmiennej sterującej dany obwód
7. Bloczek delay
8. Funkcja wymuszająca zmianę stanu rejestru na 0 po upływie czasu "delay"
Zapisane

vakul

  • Full Member
  • ***
  • Wiadomości: 149
    • Zobacz profil
Odp: OpenHab2 - modbus - Wago?
« Odpowiedź #4 dnia: Października 08, 2020, 09:00:41 pm »

Na własne potrzeby napisałem funkcję sterującą przekaźnikami światła. Sterowanie osobnymi zmiennymi z przycisku ściennego (in) lub z wizualizacji (in_visu). Przycisk ścienny wciśnięty jeden raz włącza lampę A, długie przytrzymanie lampy A+B, jeszcze dłuższe A+B+C. Kliknięcie wyłącza to co jest aktualnie włączone. Działanie jest bardzo intuicyjne. Jeżeli działa już A+B i wciśniemy przycisk na odpowiednio długi czas to zapali się A+B+C bez wyłączania tego co już działa. Bloczki z oscata nie miały takich funkcjonalności, stąd pisałem własny.

Osobna zmienna z wizualizacji/openhaba przyjmuje wartości 0-3 i ustawia odpowiedni stan na wyjściach 0,A,A+B lub A+B+C. Zmienna nie jest zerowana. Zmienna wyjściowa (out_visu) przekazuje do openhaba bieżącą wartość włączonego oświetlenia (0-3).

Z openhaba wysyłam konkretną wartość tego co co chcę włączyć, np. wartość 2, co oznacza obie żarówki/lampy włączone (nie mam żadnych ściemniaczy). Bloczek dba o to, żeby odpowiednio wysterować wyjścia (poniżej np: O90_LIGHT_SALON1). Zmienne pisane wielkimi literami to moje fizyczne wejścia/wyjścia sterownika).

Nie korzystam z modbusa tylko ze zmiennych dodanych do wizualizacji i własnego pośrednika w postaci skryptu PHP, który korzysta z READAPI (tak to się chyba nazywało). Rozwiązanie sprawdza się wyśmienicie od ponad 2 lat.

Istotą tego rozwiązania jest to, że nie ma potrzeby wysyłania "impulsów" do sterownika.

W załączniku zrzut ekranu openhaba z telefonu.

W openhabie wygląda to tak:

items:
Number Wago_oh_light_switch_dol_salon "oh_light_switch_dol_salon" <light> {autoupdate="true", http=">[1:POST:http://127.0.0.1/wago/wago_set-var.php?var=SWIATLA.oh_light_switch_dol_salon&val=1] >[2:POST:http://127.0.0.1/wago/wago_set-var.php?var=SWIATLA.oh_light_switch_dol_salon&val=2] >[3:POST:http://127.0.0.1/wago/wago_set-var.php?var=SWIATLA.oh_light_switch_dol_salon&val=3] >[0:POST:http://127.0.0.1/wago/wago_set-var.php?var=SWIATLA.oh_light_switch_dol_salon&val=0] <[WagoHttpBinding:500:JSONPATH($['SWIATLA.oh_light_switch_dol_salon'])]" }

sitemap:
Switch item=Wago_oh_light_switch_dol_salon label="Salon" icon="lightbulb" mappings=[0="WYŁ", 1="20%", 2="60%", 3="100%"] 

Definicja funkcji sterującej światłem (codesys):

FUNCTION_BLOCK LightSwitch
VAR_INPUT
in : BOOL;
in_visu: BYTE;
all_off : BOOL;
in_lamp1 : BOOL;
in_lamp1_ext_status : BOOL;
END_VAR
VAR_OUTPUT
lamp1 : BOOL;
lamp2 : BOOL;
lamp3 : BOOL;
out_visu : BYTE;
is_on : BOOL;
END_VAR
VAR_INPUT CONSTANT
T_short : TIME := t#450ms;
T_long : TIME := t#1100ms;
END_VAR
VAR
short : BOOL;
medium : BOOL;
long : BOOL;
tx : TIME;
tn: TIME;
edge : BOOL;
current_press : BOOL;
in_lamp1_trig, in_lamp2_trig, in_lamp3_trig, all_off_trig : R_TRIG;
END_VAR


tx := DWORD_TO_TIME(T_PLC_MS());
all_off_trig (CLK := all_off);
IF (in_lamp1_ext_status = TRUE) THEN
lamp1 := in_lamp1;
END_IF;

(* pojawil sie nowy stan z wizualizacji *)
IF (in_visu <> out_visu ) THEN
        CASE in_visu OF
0:
lamp1 := lamp2 := lamp3 := FALSE;
1:
lamp1 := TRUE;
lamp2 := lamp3 := FALSE;
2:
lamp1 := lamp2 := TRUE;
lamp3 := FALSE;
3:
lamp1 := lamp2 := lamp3 := TRUE;
END_CASE;
out_visu := in_visu;
END_IF;

IF (all_off_trig.Q) THEN
lamp1 := FALSE;
lamp2 := FALSE;
lamp3 := FALSE;
END_IF;
all_off := FALSE;

short := FALSE;
medium := FALSE;
long := FALSE;

IF in AND NOT edge THEN
(* przycisk wcisniety - start *)
edge := TRUE;
tn := tx;
IF (NOT lamp1) THEN
lamp1 := TRUE;
current_press := TRUE;
END_IF
ELSIF in AND edge THEN
(* przycisk przytrzymany - trwa *)

IF tx - tn >= t_short AND  tx - tn <= t_long THEN
lamp2 :=  TRUE;
ELSIF tx - tn > t_long THEN
lamp3 := TRUE;
END_IF;

ELSIF NOT in AND edge THEN
(* przycisk zwolniony - koniec*)
edge := FALSE;
tn := tx - tn;
IF tn < t_short THEN
short := TRUE;
ELSIF tn > t_long THEN
long := TRUE;
ELSE
medium := TRUE;
END_IF;

IF short AND NOT current_press THEN
lamp1 := FALSE;
lamp2 := FALSE;
lamp3 := FALSE;
END_IF;
ELSE
(* nic sie nie dzieje *)
current_press := FALSE;
END_IF;

(* informacja zwrotna dla wizualizacji *)
IF (lamp1 AND lamp2 AND lamp3) THEN out_visu := 3;
ELSIF (lamp1 AND lamp2) THEN out_visu := 2;
ELSIF (lamp1) THEN out_visu := 1;
ELSE
out_visu := 0;
END_IF;

IF (out_visu>0) THEN
is_on := TRUE;
ELSE
is_on := FALSE;
END_IF;


Wykorzystanie funkcji:
Salon_LightSwitch : LightSwitch; (* lampy gorne w salonie *)

Salon_LightSwitch (in := IN005_SW015_X OR IN096_SW089_X, in_visu := oh_light_switch_dol_salon);

O86_LIGHT_SALON_KINKIETY := Salon_LightSwitch.lamp1;
O90_LIGHT_SALON1 := Salon_LightSwitch.lamp2;
O91_LIGHT_SALON2 := Salon_LightSwitch.lamp3;

oh_light_switch_dol_salon := Salon_LightSwitch.out_visu;
Zapisane

Simeone

  • Jr. Member
  • **
  • Wiadomości: 98
    • Zobacz profil
Odp: OpenHab2 - modbus - Wago?
« Odpowiedź #5 dnia: Października 09, 2020, 08:15:42 am »

Na własne potrzeby napisałem funkcję sterującą przekaźnikami światła.

Super  :D dzięki za udostępnienie kodu. Jakbyś jeszcze dorzucił ten skrypt PHP, który pośredniczy w wymianie danych to byłby już komplet  ;)

Wywalenie Modbus-a z procesu wymiany danych wizualizacji ze sterownikiem to byłoby duże udoskonalenie. Aktualnie sprawdzam komunikację po zmiennych sieciowych ale chętnie przetestuję też Twoje rozwiązanie.

W jaki sposób odświeżasz aktualne statusy wyjść? Jest do tego osobno wywoływany skrypt, czy jeden wago_set-var.php załatwia ruch w obie strony? Jaka jest częstotliwość wywoływania tego skryptu?
Zapisane

kempa007

  • Jr. Member
  • **
  • Wiadomości: 92
    • Zobacz profil
Odp: OpenHab2 - modbus - Wago?
« Odpowiedź #6 dnia: Października 09, 2020, 03:13:38 pm »

Ja  ogólnie robie pewne postępy, ale nie do końca działa to jak chcę. Openhab ma opcję czytania i pisania w jednym Item, ale cały czas mam problem, gdy zacznę korzystać z przełącznika na ścianie. Normalnie przełącznik OH działa elegancko po modbusie załącza i wyłącza światło, ale gdy wcisnę przycisk na ścianie, w OH muszę dwa razy kliknąć, żeby zmienić stan oświetlenia. Gdy znowu kliknę przycisk na ścianie wszystko wraca do normalności. Wygląda to tak jakby OH pamiętał swój stan i fakt odczytania stanu oświetlenia z drugiego rejestru reprezentującego stan wyjścia w sterowniku w ogóle go nie interesował. Mimo iż pstrykanie światłem z przełącznika w ścianie ładnie zmienia stan switcha w OH. Trochę brakuje mi już pomysłów. Na razie testuje wszystko, korzystam tylko z Paper UI.
Zapisane

vakul

  • Full Member
  • ***
  • Wiadomości: 149
    • Zobacz profil
Odp: OpenHab2 - modbus - Wago?
« Odpowiedź #7 dnia: Października 09, 2020, 05:49:09 pm »

Openhab jest wyjątkowo toporny w debuggowaniu. Pisanie kodu to wyzwanie. W miarę możliwości wyrzucam logikę poza openhaba i obrabiam zmienne w PHP korzystając z API. Na dość wczesnym etapie poddałem się z pisaniem kodu w OH i doszedłem do autorskiego rozwiązania jak poniżej.

Robię to dodając "rule" w OH, który wywołuje skrypt PHP na tym samym raspberry:

rule "Item updated DOOR"
when
Item Wago_DoorLockState changed from 1 to 9 or
Item Wago_DoorLockState changed from 9 to 1
then
// external PHP script to parse the rule
executeCommandLine("/usr/bin/php /var/www/html/openhab/rule_item_changed.php FRONT_DOOR")
end

po stronie PHP wywołuję skrypt "rule_item_changed.php" w tym przypadku z parametrem FRONT_DOOR (poniżej fragment kodu). Ten skrypt z kolei obsługuje bazę danych MySQL, pushovera i wiele innych trudnych w obsłudze, z poziomu OpenHaba, spraw. W ten sposób "daję znać" do PHP, że coś się dzieje i tam już pobieram z OpenHaba zmienne, obrabiam wartości i zapisuję z powrotem do OH.

<?php
include 
'inc.dbconn.php';
include 'inc.openhab.php';
include 'inc.pushover.php';
dbConnect();

$updated_item = @$argv[1];

if (isset ($_GET['item'])) $updated_item $_GET['item'];

if ($updated_item == 'FRONT_DOOR')
{
if (openhab_GetState('Wago_DoorLockState') == 9)
{
sendPushover ('DOM''Drzwi zamknięte');
save_event ('DRZWI_WEJSCIOWE''zamknięte');
}

if (openhab_GetState('Wago_DoorLockState') == 1)
{
sendPushover ('DOM''Drzwi otwarte');
save_event ('DRZWI_WEJSCIOWE''otwarte');
}

}


Tutaj treść pliku "inc.openhab.php", który służy do obsługi API openhaba.

<?php
function 
doPostRequest($item$data)
{
$url "http://127.0.0.1:8080/rest/items/" $item;

$options = array(
'http' => array(
    'header'  => "Content-type: text/plain\r\n",
    'method'  => 'POST',
    'content' => (string)$data
),
);

$context  stream_context_create($options);
$result file_get_contents($urlfalse$context);

return $result;
}

function openhab_SendCommand($item$data$onlyIfValueHasChanged FALSE)
{
$execute TRUE;
$result '';

if ($onlyIfValueHasChanged)
{
$currentValue openhab_GetState($item);
if ($currentValue == $data$execute FALSE;
}

if ($execute)
{
$url "http://127.0.0.1:8080/rest/items/" $item;

$options = array(
'http' => array(
    'header'  => "Content-type: text/plain\r\n",
    'method'  => 'POST',
    'content' => (string)$data
),
);

$context  stream_context_create($options);
$result file_get_contents($urlfalse$context);
}
return $result;
}

function openhab_GetState($item)
{
$url "http://127.0.0.1:8080/rest/items/"$item."/state";

$result file_get_contents($url);

return $result;
}

function openhab_SetState($item$data)
{
$url "http://127.0.0.1:8080/rest/items/"$item."/state";

$options = array(
'http' => array(
    'header'  => "Content-type: text/plain\r\n",
    'method'  => 'PUT',
    'content' => (string)$data
),
);

$context  stream_context_create($options);
$result file_get_contents($urlfalse$context);

return $result;
}?>

 

Jeżeli masz podstawy PHP, to takie podejście dużo ułatwia, bo masz dostęp do wszystkich narzędzi i metod jakie są dostępne dla PHP bez ograniczeń OpenHaba. Możesz wtedy wysyłać maile, SMSy, powiadomienia push, pisać do/z plików, bazy danych czy co tam sobie wymyślisz. Żadnych limitów.

Co do problemu, o którym pisze kempa007, to proponuję zacząć od podejrzenia logów OH (na żywo) pod adresem http://openhabianpi:9001/ lub wywołanie konsoli Karaf (szukaj w google). Tam z kolei zobaczyć jakie wpisy pojawiają się w trakcie zmiany stanów włącznika z OH i Wago. To z pewnością dużo wyjaśni.

I jeszcze uwaga do OH, jeśli ma to działać stabilnie to Raspberry Pi nie może działać jedynie z karty SD. Trzeba to postawić na dysku SSD podłączonym przez USB (na allegro są takie 16GB za około 40zł). Raspberry PI w wersji 3 (jeśli dobrze pamiętam) może już startować z USB zamiast z SD bez żadnych dodatków. Przedziwne rzeczy dzieją się z OH, kiedy zaczyna szwankować karta SD.

Simeone - napiszę osobny wątek odnośnie READAPI, tylko potrzebuję chwilę żeby do tego usiąść.
Zapisane