Witam wszystkich, mam taki temat. Integruję w OH3 pompę ciepła, inverter solarny, liczniki energii. Urządzenia te pracują wykorzystując MODBUS. Zainstalowałem gotowe bindings i nawet działają. Niestety nie obsługują one wszystkich rejestrów. W channels po prostu ich nie ma i nie ma do czego podpiąć link np. inwerter solarny ma dwa stringi DC i nie mogę czytać parametrów drugiego. W pompie ciepła znów czestotliwości pracy sprężarki nie da się czytać itp. Znam numery rejestrów przeliczniki itd. Najprościej byłoby wyciągnąć oryginalny zaszyty w OH3 binding zmodyfikować i zapisać pod nową nazwą. Jednak nie wydaje mi się to takie proste. Gdyby ktoś bardziej doświadczony coś podpowiedział byłbym wdzięczny.
Korzystasz z gotowych bindingów dedykowanych do tych urządzeń czy przez MODBUS?
W tym pierwszym przypadku można poprosić autora o wprowadzenie poprawek wyjaśniając na czym polega problem i podając link do dokumentacji urządzenia. Wykonanie tego samemu nie jest proste.
Najszybciej jednak będzie samemu odczytać potrzebne dane przez MODBUS binding.
Jego konfiguracja nie jest taka skomplikowana, choć na pierwszy rzut oka może wystraszyć. Podaj linka do dokumentacji urządzenia, postaram się pomóc.
Dziękuję @kamikac za ofertę pomocy. Inwerter solarny to 3-fazowy Fronius SYMO 4.5-3-M ma obsługę dwóch stringów. Wyposażony jest w standardzie w kartę Fronius Datamanager z WiFi, Ethernet, Modbus RTU i TCP. Do OH3 podłączyłem go przez WiFi korzystając z bindings: Fronius Bridge oraz Fronius Symo Inverter. Wszystko ładnie działa. W załączonym pliku screen z kanałów. Dokumentacja do urządzenia jest pod tym linikiem https://www.fronius.com/~/downloads/Solar%20Energy/Operating%20Instructions/42%2C0410%2C2049.pdf oraz w pliku zip www.fronius.com/QR-link/0006 wewnątrz zipa jest plik Inverter_Register_Map_Float_v1.0_with_SYMOHYBRID_MODEL_124.xlsx a w nim Arkusz o nazwie I160 MultiMPPT.
Chodzi mi o odczyt
Start Offset |
End Offset |
Size | RW | Function codes |
Name | Description | Type | Units | Scale Factor | Range of values |
20 | 20 | 1 | R | 0x03 | 1_DCA | DC Current | uint16 | A | DCA_SF | |
21 | 21 | 1 | R | 0x03 | 1_DCV | DC Voltage | uint16 | V | DCV_SF | |
22 | 22 | 1 | R | 0x03 | 1_DCW | DC Power | uint16 | W | DCW_SF | |
40 | 40 | 1 | R | 0x03 | 2_DCA | DC Current | uint16 | A | DCA_SF | Not supported if only one DC input. |
41 | 41 | 1 | R | 0x03 | 2_DCV | DC Voltage | uint16 | V | DCV_SF | Not supported if only one DC input. |
42 | 42 | 1 | R | 0x03 | 2_DCW | DC Power | uint16 | W | DCW_SF | Not supported if only one DC input. |
47 | 47 | 1 | R | 0x03 | 2_Tmp | Temperature | int16 | C | Not supported if only one DC input. |
Podobnie dodałbym odczyty prądów na poszczególne fazy (bo inverter 3-fazowy) jednak najbardziej mi zależy na odczycie oddzielnych stringów DC bo są to zestawy paneli różnych firm i o różnej wydajności.
@andry Przeglądając źródła bindingu Fronius widzę, że nie korzysta on z MODBUS tylko z HTTP ( https://github.com/openhab/openhab-addons/tree/main/bundles/org.openhab.binding.fronius). Czyta z następujących lokalizacji:
http://%IP%/solar_api/v1/GetInverterRealtimeData.cgi?Scope=Device&DeviceId=%DEVICEID%&DataCollection=CommonInverterData
http://%IP%/solar_api/v1/GetPowerFlowRealtimeData.fcgi
http://%IP%/solar_api/v1/GetMeterRealtimeData.cgi?Scope=Device&DeviceId=%DEVICEID%&DataCollection=MeterRealtimeData
Teraz widzę, że w instrukcji od bindingu jak byk jest napisane, że wykorzystuje solar_api froniusa, czyli dane są czytane przez HTTP w formacie JSON. Masz może jego specyfikację? Wtedy szybko przez HTTP binding dociągniemy pozostałe parametry.
Faktycznie masz rację, że to nie jest modbus bo nigdzie nie ma potrzeby podawania portu. W google znalazłem coś takiego Operating Instruction Fronius Solar API V1.pdf jak dla mnie jest to dość pogmatwane. Dotyczy nie tylko inwertera ale i mierników oraz sensorów froniusa, które się do niego podpina przez właśnie modbus RTU, a wtedy z niego można po HTTP czytać to wszystko. Po wstępnym przejrzeniu nie doszukałem się niestety tego czego potrzebuję czyli napięć i prądów MPPT dla dwóch stringów. Jednak to może być zaszyte w JSON poprostu w indeksach 1, 2,... co widać tam jest. Spróbuję najpierw node-redem to zassać zobaczyć co tam jest. Potem będę kolegę dopytywał jak to do OH3 podpiąć. Dzięki jeszcze raz za oświecenie z HTTP 🙂
@andry Tutaj znalazłem opis API: https://www.forum-fronius.pl/download/fronius-solar-api-v-1/
Szukając dalej zaczynam się zastanawiać:
A jakby zdefiniować drugi kanał powerinverter z indeksem 2, to może wyświetliłby dane dla drugiego stringu? Próbowałeś?
No niestety próbowałem indeks 2 i jest NULL. Więc to jakoś inaczej trzeba wyczytać. Najprościej jednak przez MODBUS TCP byłoby. Fronius ma go na porcie 502. Tam mam pewność, że osiągnę potrzebne mi informacje z drugiego stringu. Chciałbym jednak aby utworzony binding miał normalnie kanały, które normalnie potem linkuję w OH3. Wcześniej jak próbowałem zrobić to do licznika energii to w kanałach pojawiły się jakieś dziwne wielkości w ogóle wcześniej nie definiowane. Do samego modbusa trzeba było kilka thing. Najpierw Modbus Serial Slave potem Regular Poll a następnie do każdego rejestru Modbus Data. To jakoś to zabałaganione jest jak dla mnie. Powinno być jedno thing jako źródło informacji a w środku cała reszta. Może jednak OH3 ma jakąś inną taktykę.
To, że masz w OH kilka elementów jest naturalne, ponieważ każdy z nich definiuje inną funkcjonalność:
- slave - to połączenie
- poll - odczyt jednego lub więcej rejestrów danego typu
- data - mapowanie odczytanych rejestrów do kanałów
Można by zrobić tylko slave+data, natomiast wtedy odczyt każdego kanału to oddzielne zapytanie, które obciąża magistralę. Przy bardziej rozbudowanym sterowniku (lub PLC) może pojawić się ten problem z wydajnością.
Do istniejącego bindingu można dodawać nowe definicje rzeczy - pisząc kolejne rozszerzenia w Javie.
Zgadzam się z tym, że podejście openHAB żeby dla tak popularnego protokołu jak modbus pisać oddzielną integrację dla każdego urządzenia to droga donikąd. Myślę że przy odrobinie wysiłku dało by radę zrobić bardzo generyczne mapowanie XML -> thing aby ludzie średnio-techniczni mogli tworzyć definicje rzeczy a później je dodawać przez UI. W ten sposób praca jednej osoby z przepisaniem karty katalogowej może zostać wykorzystana wielokrotnie.
Wiem, że jest konfiguracja przez pliki tekstowe, ale to wciąż jest kopiuj-wklej. Przy większej ilości urządzeń tego samego typu nie da rady tego utrzymać. Jak ktoś ma w domu chociaż 4 regulatory pokojowe to przy przepisywaniu trzeciego się walnie. 😉 Nie mówiąc już o tym że pliczki *.things nie robią "discovery".
Ale to takie moje wolne przemyślenia.
Od pewnej ilości danych najłatwiej tym zarządzać w plikach.
Poniżej przykład odczytu 4 rejstrów wg dołączonej przez Ciebie dokumentacji
modbus.things:
Bridge modbus:tcp:fronius [ host="fronius.lan", connectMaxTries=1, reconnectAfterMillis=0, port=502, timeBetweenReconnectMillis=0, connectTimeoutMillis=10000, id=1, enableDiscovery=false ] {
Bridge poller ReadHoldingReg [ start=1, length=50, refresh=1500, type="holding" ] {
Thing data ID [ readStart="1", readValueType="uint16" ]
Thing data L [ readStart="2", readValueType="uint16" ]
Thing data DCA_SF [ readStart="3", readValueType="int16" ]
Thing data 2_DCEvt [ readStart="49", readValueType="int32" ]
}
modbus.items
Number Fronius_ID "Fronius ID [%d]" <text> { channel="modbus:data:fronius:ReadHoldingReg:ID:number", autoupdate="false" }
Number Fronius_L "Fronius L [%d]" <text> { channel="modbus:data:fronius:ReadHoldingReg:L:number", autoupdate="false" }
Number Fronius_DCA_SF "Fronius DCA_SF [%d]" <text> { channel="modbus:data:fronius:ReadHoldingReg:DCA_SF:number", autoupdate="false" }
Number Fronius_2_DCEvt "Fronius 2_DCEvt [%d]" <text> { channel="modbus:data:fronius:ReadHoldingReg:2_DCEvt:number", autoupdate="false" }
Pozostałe pola musisz sobie dopisać wg powyższego przykładu.
Dostrzegam tu jednak problem z wyświetlaniem wartości i potrzebne mogą być itemy pośredniczące i reguły, gdyż dla wielu pól w MODBUS w tym inwerterze są przeliczniki (typ sunssf w dokumentacji). Konkretnie wartość z takiego pola mówi o ile pól w prawo (wartości dodatnie) lub lewo (wartości ujemne) trzeba przesunąć przecinek, aby otrzymać wartość, która jest w polu mu towarzyszącym. Np DCA_SF jest wartością przelicznika dla prądu w polach 1_DCA i 2_DCA, czyli jeśli w polu 1_DCA mamy wartość 125, a w DCA_SF -1, to wartość prądu wyniesie 12,5A. Wydaje mi się, że ten problem nie występuje w dostępie po HTTP i łatwiej takiego JSONa obrobić w OH, niż kombinować z MODBUSem. Wybór należy do Ciebie.
@ldywicki Masz rację, ale można uporządkować dane wpisywane do plików za pomocą arkusza kalulacyjnego i reguł. Bez arkusza nie ogarnąłbym bindingu MODBUS z 245 thingsami.
Teraz dopisuję nazwę kolejnej zmiennej w odpowiednim "dziale", a arkusz generuje mi linijkę dla PLC i do modbus.things. Dzięki temu nie mam konfliktów adresów itp.
@andry Gotowy binding do urządzenia tworzy te kanały, które zostały zdefiniowane przez jego twórcę. Nie zawsze są one użyteczne dla każdego urządzenia, często czegoś brakuje. Jeśli sam robisz obsługę urządzenia korzystając z ogólnych bindingów jak MODBUS czy HTTP, to masz tylko te kanały, które zdefiniujesz, ale przeliczniki, obsługa wyjątków spada na Ciebie. Czasem trzeba uciec się do reguł, bo inaczej uzyskanie pewnych informacji nie jest możliwe.
Bez arkusza nie ogarnąłbym bindingu MODBUS z 245 thingsami.
Taką ilosć ogólnie trudno jest ogarnąć bez jakiegoś narzędzia. 😉 Powiedz mi tylko ile z tych 245 thingsów jest unikalne i jak wiele różnic jest między nimi. Czy to jest 5x slave + 80 pollerów + 160 elementów typu data czy inaczej?
Propozycja wyżej polega na tym żeby definiować "thing type" w XML a nie excelu tak by każdy, nawet bez excela to ogarnął. Dzięki temu będziesz mógł szybko udostępnić schemat rejestrów komuś innemu - bez konieczności ujawniania swojej pełnej konfiguracji.
Jedno urządzenie (PLC), 7 pollerów (każdy na inny obszar rejestrów), z róznym czasem odświeżania.
Dane są różne, z przelicznikiem (kilka różnych), bez przelicznika, odczyt i zapis do różnych rejestrów w ramach jednego thing, obsługa rolet w JS.
Dlatego w arkuszu mam kilka "działów".
Jedno urządzenie (PLC), 7 pollerów (każdy na inny obszar rejestrów), z róznym czasem odświeżania.
Tego typu urządzenie nie jest możliwe do opisania w postaci szablonu, ponieważ jego konfiguracja jest dynamiczna i zależna od podłączonych modułów wejść/wyjść czy nawet samego programu sterownika. Dla niektórych PLC - np. Wago w openHAB kiedyś była możliwość pobierania listy rejestrów przez wbudowany serwer FTP.
Przypadek, który wpisuje się w szablon XML to inwerter lub inny kontroler który ma raczej ustalone adresy rejestrów i ich funkcje.
@andry Czy ten binding nie rozwiązałby Twoich problemów z inwerterem?
https://www.openhab.org/addons/bindings/modbus.sunspec/
Jest to faktycznie binding który coś czyta z Froniusa. Niestety całkiem pechowo ten binding podobnie jak ten HTTP nie podaje parametrów DC dla dwóch MPPT. Pozostaje zrobić to na piechotę jak @kamikac proponowałeś. Dzięki za bardzo trafne podpowiedzi.