Witam
Minelo juz sporo czasu.... 🙂
Powyzszy problem opanowany dawno temu . Ale jak to w zyciu znalazlem sobie nowa zagwostke he he
postawilem w nowym miejscu malinke z openhabem V3 ma ona do roboty niewiele bo ma zczytywac 4 jednostki klimatyzacjii Gree
i to co z nich wyciagnie wysylac po modbusie na Fateka ( jeszcze nie ma bindingu na Fateka dla wersji 3 )
Kilkanascie rejestrow do zapisu i osobnych tyle samo do odczytu (rejestry R lub D -tabela modbus )
Wszystko zwizualizowane na HMI Weintek .
Problem polega na tym ,ze nie wiem jak sie do tego zabrac 🙂
Binding modbusa sciagniety , things-a juz mam ( on line )
Potrzebny mi przyklad co mam dac w itemach .... ktos czyms takim dysponuje ? ( tego co w objasnieniach bindingu pisza nie pojmuje )
Niech chodz jedno zatrybi a dalej juz jakos pojdzie 🙂
Moze szybciej bedzie jak po prostu ktos mialby chwilke i zajrzal w moje wypociny (nie ze jestem len ) ...... ?
Chcesz to po modbus wysłać do OH czy Fatek bo się zgubiłem.
Jak plc to możesz pchnąć od razu do HMI będziesz miał od zaraz prezentacje odczyt i zspis
Chialbym :
z OH pchnac info o stanie klimatyzatorow do Fateka (odczytane z bindingow GREE )
Z fateka wyciagnac stan kilku rejestrow do OH
A dalej wizualizacja na Panelu HMI , przeslanie do kolejnego Fateka w innej lokalizacji i tez wizualizacja - takie tam 🙂
Fateka i HMI to juz bez najmniejszego problemu ogarniam - przynajmniej to he he
@mario0658 Poniżej przykład dla wartości 16-bitowej. U mnie temperatury są po stronie PLC mnożone przez 10 i zapisywane w rejestrze dostępnym przez MODBUS. Po przemnożeniu przez 10 można je zapisać jako liczby całkowite (np 21,2 to będzie 212). Potem w bindingu zamieniam temperatury znów na liczby rzeczywiste dzieląc je przez 10, w drugą stronę analogicznie. Wykorzystuję przy tym JS transform. Oczywiście to nie jest konieczne, jeśli przesyła się liczby całkowite, wtedy można pominąć readTransform i writeTransform.
Things:
Bridge modbus:tcp:wago [ host="wago.lan", connectMaxTries=1, reconnectAfterMillis=0, port=502, timeBetweenReconnectMillis=0, connectTimeoutMillis=10000, id=1, enableDiscovery=false ] {
Bridge poller ReadHoldingReg [ start=12308, length=1, refresh=1500, type="holding" ] {
Thing data FDTempNastSalon [ readStart="12308", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="12308", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ]
}
Items:
Number GF_LivingRoom_Heating "Ogrzewanie komfort. [%.1f °C]" <setpoint> (gHeating_LivingRoom) ["Setpoint","Temperature"] { channel="modbus:data:wago:ReadHoldingPersistReg:FDTempNastSalon:number", autoupdate="false" }
Temp_int_to_float.js (transform)
(function(i) {
return parseFloat(i) / 10;
})(input)
Temp_float_to_int.js (transform)
(function(i) {
return Math.round(parseFloat(i, 10) * 10);
})(input)
Myślę, że załapiesz o co chodzi na podstawie powyższego przykładu.
Jesli chodzi o przeksztalcenia temperatur to ogarniam to
Mi chodzi o to jak dopisac wykonanie odcztu i zapisu danych rejestrow w OH 3
U mnie wyglada to tak Code :
UID: modbus:tcp:a94222f001
label: Fatek
thingTypeUID: modbus:tcp
configuration:
timeBetweenTransactionsMillis: 3000
connectMaxTries: 1
reconnectAfterMillis: 0
port: 502
timeBetweenReconnectMillis: 0
host: 192.168.0.25
connectTimeoutMillis: 10000
id: 1
enableDiscovery: false
I jesli probuje cos dopisac to odrazu wywala jakies bledy - taki czerwony X na poczatku kazdej dopisanej lini
Reasumujac : co dopisac aby odczytac powiedzmy 16 kolejnych rejestrow , oraz zapisac do innych 16 rejestrow 🙂
@mario0658 Nie wiem, jak to zrobić w UI, podałem Ci przykład z mojego konfigu, który działał pod OH2 i po dodaniu tagów działa w modelu semantycznym w OH3. Spróbuj zapisaś things w tekstowym, jak poniższy przykład. Items smożesz sobie potem zrobić w UI. Nie wiem, dokładnie co miałeś na myśli pisząc o zapisie 16 rejestrów i zapisie innych 16, więc poniższy przykład odczytuje 16 rejestró od adresu 16 i zapisuje te wartości do 16 rejestrów od adresu 32 (w przypadku zmiany ich wartości w OH. Nie da się wg mnie w OH (może się mylę) zrobić samego zapisu do rejestru bez odczytu czegokolwiek (może to być inny rejestr).
modbus.things:
Bridge modbus:tcp:wago [ host="wago.lan", connectMaxTries=1, reconnectAfterMillis=0, port=502, timeBetweenReconnectMillis=0, connectTimeoutMillis=10000, id=1, enableDiscovery=false ] {
Bridge poller ReadHoldingReg [ start=16, length=16, refresh=1500, type="holding" ] {
Thing data Data0 [ readStart="16", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="32", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data1 [ readStart="17", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="33", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data2 [ readStart="18", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="34", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data3 [ readStart="19", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="35", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data4 [ readStart="20", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="36", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data5 [ readStart="21", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="37", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data6 [ readStart="22", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="38", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data7 [ readStart="23", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="39", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data8 [ readStart="24", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="40", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data9 [ readStart="25", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="41", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data10 [ readStart="26", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="42", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data11 [ readStart="27", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="43", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data12 [ readStart="28", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="44", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data13 [ readStart="28", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="45", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data14 [ readStart="30", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="46", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ],
Thing data Data15 [ readStart="31", readValueType="int16", readTransform="JS(Temp_int_to_float.js)", writeStart="47", writeValueType="int16", writeType="holding", writeTransform="JS(Temp_float_to_int.js)" ]
}
Items będą w tej postaci:
Number Modbus_Data0 "Data 0 [%.1f]" <setpoint> ["Setpoint","Temperature"] { channel="modbus:data:wago:ReadHoldingReg:Data0:number", autoupdate="false" }
itd.
Data 0 jest odczytywane spod adresu 16, a z miany zapisywane są pod adres 32 itd.
Poprzednio wkradł się błąd, bo w things było ReadHoldingReg a w items ReadHoldingPersistReg.
Za mało podajesz informacji, żeby zrobić choć jedną linijkę dla konkretnej danej.
Generalnie struktura jest taka, że najpierw definiujesz bridge'a tcp czyli połaczenie do PLC. Potem jako jego podklasę definiujesz poller, gdzie określasz z jakiej puli adresów będziesz czytać i jaką funkcją. Jako jego podklasę definiujesz things (podając konkretny adres z podanej w pollerze puli, typ danej, transformaty i ewentualnie adres, do którego będzie zapisywana wartość w przypadku jej zmiany w OH), które później połączysz z items.
W tym nowym OH wszystko co widze mozna wpisac w zakladkach code
Mam binding modbusa zainstalowany , wpisalem tam co trzeba a wiec IP PLC (Fatek)
Binding go widzi i wyswietla status ON LINE.
I tu juz zaczyna sie problem ...
Na OH2 jakos sobie radze - edytuje wszystko recznie i dziala ( tam uzywam fatek binding )
Tu chcialbym z modbusem pokombinowac ...
@mario0658 Mnie się wydaje, że binding wchodzi w ONLINE, jak jest połączenie z portem urządzenia MODBUS. Dopiero potem są odpytywane rejestry/wejścia/wyjścia. Skoro ich nie zdefiniowałeś, to raczej samo ONLINE bindingu nic nie da.
Po chwili klikania:
Przejrzałem jak u mnie wygląda konfiguracja w UI po wgraniu modbus.things. I tak:
- To co podałeś z zakładki code w poście z 31 stycznia to jest dopiero pierwsza linijka z przykładów, które Ci podałem, czyli definicja bridge'a TCP (thingTypeUID: modbus:tcp), u mnie wygląda to tak:
UID: modbus:tcp:wago
label: Modbus TCP Slave
thingTypeUID: modbus:tcp
configuration:
connectMaxTries: 1
reconnectAfterMillis: 0
timeBetweenTransactionsMillis: 60
port: 502
timeBetweenReconnectMillis: 0
host: wago.lan
connectTimeoutMillis: 10000
id: 1
enableDiscovery: false
- Teraz trzeba zdefiniować poller - kolejny thing z MODBUS binding (thingTypeUID: modbus:poller), przykład kodu do UI poniżej:
UID: modbus:poller:wago:ReadHoldingReg
label: Regular Poll
thingTypeUID: modbus:poller
configuration:
start: 256
length: 60
refresh: 1500
maxTries: 3
cacheMillis: 50
type: holding
bridgeUID: modbus:tcp:wago
- Teraz definiujemy konkretną daną - kolejny thing z MODBUS binding (thingTypeUID: modbus:data), przykładowy kod do UI:
UID: modbus:data:wago:ReadHoldingReg:FDTempNastSalon
label: Modbus Data
thingTypeUID: modbus:data
configuration:
readValueType: int16
readTransform: JS(Temp_int_to_float.js)
writeType: holding
writeTransform: JS(Temp_float_to_int.js)
readStart: "12308"
updateUnchangedValuesEveryMillis: 1000
writeValueType: int16
writeMultipleEvenWithSingleRegisterOrCoil: false
writeMaxTries: 3
writeStart: "12308"
bridgeUID: modbus:poller:wago:ReadHoldingReg
Powyższe wpisy odpowiadają w 100% przykładowi .things z mojego posta z 31 stycznia.
A teraz przestań piętrzyć trudności, tylko melduj wykonanie 😉
Przeszedlem do OH 2.5 i w koncu sie udalo
co dziwne nie moge znalezc w bindingu Fateka .... czyzby wywalili go ?
Trza recznie go wrzucac ?
edit:
niestety nici z modbusa
testy robilem na swoim testowym fateku z ethernetem ( fatek protocol + modbus)
a docelowo mialo byc na fateku z innym ethernetem ....bez modbusa - tylko fatek protocol
Musze wiec wrocic do OH 2.5 i jakos wgrac mu fatek binding .....
Mam jeszcze jedno pytanko ....
Niestety Linuxem nie zajmowalem sie wczesniej , PLC hmi tak
Chcialbym w rules dodac formulke , ze jesli x otrzyma update ( np 16 °C) to wyslij to jako liczbe calkowita na Y
Chodzi mi tylko jak ma wygladac symbol tej konwersji
A jakaś dokumentacja do Fateka? W Wago w dokumentacji jest mapa rejestrów Modbus i wiadomo, które rejestry znajdują się pod jakim adresem, wtedy wiadomo, gdzie uderzać. Na pewno jest taki dokument dla Fateka.
Hej
ja się skupiłem na tych pdf'ach
https://www.esea.cz/support/fatek/FBs_Manual/Manual_1/instruction/Chapter_6.pdf
Nic tu nie znalazłem o MODBUSie w podanych publikacjach, ale 3 minuty z wujkiem google i mamy artykuł, gdzie jest mapa rejestrów:
https://www.multiprojekt.pl/fatek-modbus-slave/
Mapa jest, to w drogę.
Działa idealnie 😀
dziękuję
Edit
z tą drogą to jak u mnie w okolicy.... specjalne perforacje dla czujności kierowców się trafiają ;D
Bridge poller C "FatekPLC C poller" [ start=9701, length=4, refresh=1000, type="holding" ] { Thing data c1 "Parter kWh" [ readStart="9701", readValueType="uint32", writeStart="9701", writeValueType="uint32", writeType="holding" ] }
16bit-owe liczniki szyta bez problemu, a 32 już nie zamiast 76245 odczytuje 127199. Liczniki z których czytam to C200 i C201.
Możesz wytłumaczyć dlaczego? Co zrobiłem źle?
Tak na szybko, to nie wiem, wyglada dobrze, ja używałem u siebie int32. A próbowałeś zamiast uint32 użyć uint32_swap albo int32 albo int32_swap ?
dziwne, uint32_swap nie znam ale w 50% załatwiło problem
odczyt z plc
Bridge poller Licznik_PLC_Dom "FatekPLC C poller" [ start=9701, length=14, refresh=1000, type="holding" ] { Thing data c200 "Pracownia kWh" [ readStart="9701", readValueType="uint32_swap", writeStart="9701", writeValueType="uint32_swap", writeType="holding" ] Thing data c201 "Parter kWh" [ readStart="9702", readValueType="uint32_swap", writeStart="9702", writeValueType="uint32_swap", writeType="holding" ] } Bridge poller D_PLC_Dom "FatekPLC D poller" [ start=6200, length=4, refresh=1000, type="holding" ] { Thing data d200 "Pracownia kWh" [ readStart="6200", readValueType="uint32_swap", writeStart="6200", writeValueType="uint32_swap", writeType="holding" ] Thing data d201 "Parter kWh" [ readStart="6201", readValueType="uint32_swap", writeStart="6201", writeValueType="uint32_swap", writeType="holding" ] }
Wynik jest taki że dla parteru działa ok a dla pracowni pokazuje głupoty zwłaszcza że zużycie tam jest małe. C=78843, D=78 więc daleko od tego co wyświetla
a ty stany bezpośrednio z PLC
Może dlatego, że rejestr D jest 16-bitowy a odczytujesz go jako 32-bitowy, więc masz mix D200 i D201 ?
hehe też tak myślałem i przeleciałem od 8 do 32 bez efektu ale co ciekawej jak zrobię oddzielny odczyt c200 i c201 to działa.
Chyba tak już zostawię może binding modbusa się sypie od męczenia.
Czekam na OH4 dla QNAP wtedy odświeżę instalację wiązań i reszty.
Jeśli C200 ma adres 9701, to C201 musi mieć adres 9703. Modbus obsługuje rejestry 16-bitowe. Jak chcesz przekazać wartości 32-bitowe to używasz dwóch rejestrów 16-bitowych. Czyli C200 zajmuje adresy 9701 i 9702 a C201 adresy 9703 i 9704.
Spójrz na przestrzeń C200-C255 - to jest 56 rejestrów (32-bitowych), a odpowiadająca im pula adresów to 9701 do 9812 to jest 112 rejestrów (16-bitowych).
Natomiast na moje oko D bedzie uint16 lub int16.
No i kolejne zagadnienie (wiem, czepiam się): czy Ty te stany tylko odczytujesz z PLC czy także zapisujesz do PLC?