RS485: Energia + Growatt + Eastron SDM630 Modbus V2

Powiesiłem plakat. Może pomoże.

image

:wink:

Tak na serio to terminatora nie ma. Może kiedyś podłączę. Póki co czekam do jutra i zobaczymy co będzie jak falownik wystartuje.

Przeanalizowałem to i myślę, że mój zapis jest poprawny. O tym który typ zostanie użyty mówi parametr input_type. Przybiera on holding/coil/discrete/input gdzie domyślnym parametrem jest holding.

Odnośnie integracji inwertera z licznikiem to nie tylko ograniczenie eksportu energii do sieci ale pełny monitoring na portalu, przykład z dzisiejszego dnia:

Licznik mam podłączony pod piny 7 i 8, jutro spróbuje podłączyć się pod piny 3 i 4 i przetestować czy odczytam dane.

1 polubienie

@arnie280
Wow, tego nie wiedziałem. Wykresy wyglądają naprawdę ładnie.

No to teraz mamy zagadkę. Czy licznik może być równolegle wpięty do sieci RS485 (piny 3,4) oraz do pinów 7,8 ?? Czyli czy mogę zmostkować pin 3 z 7 oraz 4 z 8. Hmmm? Jakie mogą być tego skutki? (podejrzewam, że żadne bo mimo wszystko to sieć RS485)

Jak napisałem integracja inwertera z licznikiem jest fajna ale działa tylko w godzinach pracy inwertera, teoretycznie jest sposób na przekazywanie danych z licznika do serwera growatt ale wymaga to zakupu dodatkowych urządzeń - pisałem na serwis growatt.
Próbowałem równolegle odczytywać licznik przez inwerter oraz HA (podłączyłem do pinów 7, 8 licznik oraz konwerter RS na USB) ale niestety skończyło się to odłączeniem licznika od inwertera a odczyt na HA pojawiał się i znikał.
Obawiam się, że licznik może działać tylko z jednym urządzeniem albo trzeba by zmusić do odczytu naprzemiennego.

Obstawiam, że przy zmostkowaniu pinów w sieci pojawią się dwa urządzenia MASTER. W sieci Modbus RTU może być jeden MASTER oraz do 247 urządzeń typu SLAVE.

Growatt wymaga aby licznik miał ustawiony adres 002 więc podejrzewam, że jest zaprogramowany aby być masterem :confused:

@arnie280 piny 7,8 są dedykowane do licznika. Myślę, że za ich pomocą nie odczytasz parametrów inwertera. Trzeba podłączyć się do 3 i 4.

W jaki sposób chcesz zmusić licznik do “odczytu naprzemiennego”?

Terminator V1.0 nie pomoże :yum:
Jest kilka sposobów rozwiązania tego problemu.
Podam na razie najłatwiejszy.
Podłączyć licznik do falownika do dedykowanych zacisków. Niech to on gada z licznikiem.
Skoro dane licznika również wysyła na portal to musi robić sobie kopie jego rejestrów w swojej mapie.
Przeglądałem rejestry i najbardziej “podpadające” są rej. od adresu 1044.
Do HA odczytywać potrzebne dane falownika i licznika tylko z falownika (zaciski 3,4?).
Wada - w nocy brak odczytów z licznika.
Drugi prosty, to zrezygnować ze statystyk licznika na portalu i połączyć to ta wspólnej magistrali.
Dane z licznika chyba do niczego nie są potrzebne falownikowi?
Pozostałe wymagałyby pisania własnej “integracji”, nie jest to trudne ale na razie pominę.

Podłączenie wszystkiego do jednej sieci RS485 powodowało jakieś błędy. Tak jak podejrzewałem, HA nie mógł poprawnie odpytywać SDM630 z tego względu, że w sieci pojawiły się dwa urządzenia typu MASTER.

Podłączenie SDM630 bezpośrednio do inwertera (piny 3,4) faktycznie w aplikacji oraz na server.growatt.com zaczęło pokazywać więcej danych. Minusem tego rozwiązania tak jak wspomniał @arnie280 jest to, że nie mamy podglądu na naszą sieć domową poza godzinami pracy inwertera.

Drogim rozwiązaniem jest zakup drugiego takiego licznika i wpięcie go szeregowo za/przed tym pierwszym. Jeden po RS485 bezpośrednio podpięty do inwertera (chyba tylko po to by mieć ładny wykres w apce growatta :smiley: ) a drugi normalnie do naszej domowej sieci RS485 z HA.

Podłączyłem się też bezpośrednio pod RS485 (jako jedyny MASTER) i zeskanowałem za pomocą CAS Modbus Skaner mojego Growatta:




Skupmy się na wartościach 51, 52, 52. To napięcia międzyfazowe.

Dokument z całą listą który odpowiada tym wartościom jest tutaj:

Niestety gdy ustawiłem HA aby odpytywał te wartości to cały czas encje wyświetlały status NIEDOSTĘPNY

############################

# Three phase grid voltage 0.1V Line voltage
- name: G10KTL3X Vac RS
  unit_of_measurement: V
  slave: 1
  address: 51
  input_type: input
  count: 2
  data_type: uint16
  precision: 1
  scale: 0.01
  scan_interval: 3
  device_class: voltage

# Three phase grid voltage 0.1V Line voltage
- name: G10KTL3X Vac ST
  unit_of_measurement: V
  slave: 1
  address: 52
  input_type: input
  count: 2
  data_type: uint16
  precision: 1
  scale: 0.01
  scan_interval: 4
  device_class: voltage

# Three phase grid voltage 0.1V Line voltage
- name: G10KTL3X Vac TR
  unit_of_measurement: V
  slave: 1
  # address: 30004
  address: 53
  input_type: input
  count: 2
  data_type: uint16
  precision: 1
  scale: 0.01
  scan_interval: 5
  device_class: voltage

###################################################

Macie jakieś pomysły dlaczego tak się dzieje? Z Windowsa za pomocą programu CAS odpytuję bez problemu. Natomiast HA tego nie ogarnia.

Może dlatego, że odczyt każdego rejestru to osobna sesja, a program odczytuje większymi paczkami?
RS się zapycha… i pora to zrobić w NR.
To by była furtka do utworzenia w NR fake slave licznika, z której falownik jako master pobierał dane dla portalu.
Dziś chinczyk jest a jutro go nie ma - odpuść sobie tą chmurę i tak zbierasz statystyki lokalnie.
Podłącz to po ludzku na jedną magistralę z jednym master na HA

@arnie280 , @bielen2k czytałem Wasze posty ale w pewnym momencie przestałem bo wymyślacie takie niestworzone rzeczy o Modbus (kolizje, dwa Mastery), że naprawdę nie da się :stuck_out_tongue:.
Gorąca prośba: proszę przeczytać dokładnie 3 razy artykuł https://ntronic.pl/jak-dziala-modbus/, potem 15 minut na zastanowienie się, jeszcze raz przeczytać to samo i mam nadzieję, że będzie lepiej.

A myślisz, że w NodeRED zaczarujesz Modbusa i będzie działać bo HA tego nie ogarnia :grin:. Nieważne w czym to zrobisz, z jakiego programu skorzystasz, wszystkie działają tak samo i w ten sam sposób komunikują się poprzez Modbus.

2 polubienia

@bielen2k jeszcze raz: już miałeś działający odczyt po Modbus danych z licznika SDM630, co teraz chciałeś zrobić? Dodać możliwość odczytania danych z Growatta, podpinając go do tej samej magistrali Modbus (podpinając go do tych samych dwóch kabelków z Modbus, które idą z konwertera USB->Modbus do licznika)?

Max długoć ramki Modubus RTU wynosi 256 bajtów, więc pomijając narzut na adres, kod, funkcji i CRC w jednej sesji możesz odczytać na raz 126 rejestrów i nie potrzeba tu żadnych czarów.
Więc takie cykanie rejestr po rejestrze w HA w osobnych sesjach jest nieporównywalnie wolniejsze.
Dołóż jeszcze do tego “siletn interval time” pomiędzy poszczególnymi query response.

Do przesłanie 126 rejestrów w sposób jak to robi HA potrzeba 2772 bajtów, w jednej sesji tylko 267.
Więc ustawiony scan_interval: 3 jest raczej nierealny, ale nie chce mi się już tego liczyć

W przyblizeniu tak, ale po pierwsze HA nie wyśle zapytania o tak dużą liczbę rejestrów bo w konfiguracji pliku yaml dla licznika i falownika powyżej koledzy powinni pytać o max 2 rejestry typu float32, jeżeli chces wysłać zapytanie o odczyt kilka rejestrów na raz to robi sie w Modbus tak:

i wszystko sie mieści w ramce :slight_smile:.
Po drugie w HA każdy sensor w konfiguracji Modbus to osobne wysłanie zapytania o odczyt.

Dzięki za link, przeczytam ten artykuł.

Tak i to działa super ekstra poprawnie (po wymianie konwertera z CH340 na FT232RL)

Dokładnie taką chce wykonać topologię.

odpytując inwerter za pomocą programu “CAS Modbus Scaner” nie ma tam odpowiedzi we float32 (screeny w wątkach wyżej).

W instrukcji mam natomiast zapis:

When controllers are setup to communicate on a Modbus network using RTU (Remote
Terminal Unit) mode, each 8–bit byte in a message contains two 4–bit hexadecimal
characters. Each message must be transmitted in a continuous stream

Czy to może być powodem tego, że HA nie potrafi odczytać tych danych? Może coś w mojej konfiguracji jest nie tak albo w jakiś sposób trzeba to przekonwertować?

zmień data_type: folat32

Zapytam tak: czy to co pisałem było do Ciebie? :grin:, nie więc proszę odpuść bo nie uruchomimy tego razem :stuck_out_tongue:.
BTW ja znalazłem float32 w screenach powyżej, jak mi udowodnisz, że nie ma tego to wysylam ci piwo.

Sam daje się prowadzać z nos… w dokumentacji adresy są kolejne 51,52,53 więc muszą być 16bit uint16, mnożnik 0.1

Na screenie jest :stuck_out_tongue: ale ten typ danych nie jest prawidłowy. Konwertując zapis szesnastkowy na uint/int wartość jest poprawna. Dla innych formatów już nie. Znalazłem w instrukcji że musi to być uint.

Więc muszę zaadresować kolejno 50,51,52 :sunglasses:
Typ danych dla napięć wystarczy uint16.
Dla jednostek energii (kWh) przyszłościowy będzie uint32.

Czy masz to podłączone dokładnie w ten sposób:

w praktyce wygląda to tak:

image

Jeżeli tak, to spróbujemy odczytać jedną wartość z falownika, najlepiej taką którą także możesz odczytać bezposrednio z falownika, będzie do porównania, może napięcie fazowe L1?

A, B mam mam dokładnie w taki sposób (oprócz uziemienia którego w poprzednim konwerterze nie było ale mimo to, SDM630 w miarę poprawnie przekazywał dane).

Poprawię swoje połączenia, dam konkretne zaciski a jak to nie pomoże to serwer przestawię 2 kondygnacje niżej. Od czasu do czasu HA wyświetla mi wartości z niektórych encji więc ze wszystkich czynności które wykonałem, zostało mi poprawienie okablowania. Dodatkowo podłączę też GND (nowy konwerter Waweshare na szczęście oprócz A i B ma też GND). Zrobię to jutro. Dziś mam inwerter Growatt spięty bezpośrednio z EASTRON SDM630. Chcę mieć jedną pełną dobę danych w chmurze by później w HA zrobić to ładniej i lepiej :sunglasses:

Edit:

SUKCES! :smiley: :grin: :sunglasses: :muscle: :fire: :zap: :sparkles: :tada:

Sytuacja wygląda następująco:

  • topologia RS485 jest ogólnie ok. Czekam tylko na rezystor 120 ohm 1% ale i bez niego komunikacja z urządzeniami jest prawidłowa.
  • podłączyłem dodatkowo parę skrętki do GND w konwerterze oraz w liczniku (nie mam pewności czy port nr. 13 w inwerterze to GND więc w nim mam podłączone tylko A oraz B - porty 3 i 4)
  • HA przez konwerter Waveshare jest podłączony do licznika Eastron SDM630 oraz inwetera Growatt MOD 10KTLX-3

Problem w HA polegał na typie danych. Inwerter zwraca go jako uint32 ale ciąg dotyczący napięcia międzyfazowego dawał mi wartość 272 437 297.0 zamiast ok 4196 (czyli 419,6 V)

Zdebugowałem komunikację i komunikacja w logach wyglądała następująco:

2022-01-19 09:34:46 DEBUG (SyncWorker_1) [pymodbus.transaction] Running transaction 84
2022-01-19 09:34:46 DEBUG (SyncWorker_1) [pymodbus.transaction] SEND: 0x1 0x4 0x0 0x33 0x0 0x2 0x81 0xc4
2022-01-19 09:34:46 DEBUG (SyncWorker_1) [pymodbus.framer.rtu_framer] Changing state to IDLE - Last Frame End - 1642581286.469352, Current Time stamp - 1642581286.502001
2022-01-19 09:34:46 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection] [139832151300608] Sending {"id": 2, "type": "event", "event": {"event_type": "state_changed", "data": {"entity_id": "sensor.g10ktl3x_vac_rs", "old_state": {"entity_id": "sensor.g10ktl3x_vac_rs", "state": "273027146.0", "attributes": {"unit_of_measurement": "V", "device_class": "voltage", "friendly_name": "G10KTL3X Vac RS"}, "last_changed": "2022-01-19T08:34:41.063418+00:00", "last_updated": "2022-01-19T08:34:41.063418+00:00", "context": {"id": "a4257b05f6e6ef6a32df403bf594403d", "parent_id": null, "user_id": null}}, "new_state": {"entity_id": "sensor.g10ktl3x_vac_rs", "state": "272961611.0", "attributes": {"unit_of_measurement": "V", "device_class": "voltage", "friendly_name": "G10KTL3X Vac RS"}, "last_changed": "2022-01-19T08:34:46.500895+00:00", "last_updated": "2022-01-19T08:34:46.500895+00:00", "context": {"id": "342a03fe2e8c6026846386f38d27937c", "parent_id": null, "user_id": null}}}, "origin": "LOCAL", "time_fired": "2022-01-19T08:34:46.500895+00:00", "context": {"id": "342a03fe2e8c6026846386f38d27937c", "parent_id": null, "user_id": null}}}
2022-01-19 09:34:46 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection] [139832151300608] Sending {"id": 7, "type": "event", "event": {"event_type": "state_changed", "data": {"entity_id": "sensor.g10ktl3x_vac_rs", "old_state": {"entity_id": "sensor.g10ktl3x_vac_rs", "state": "273027146.0", "attributes": {"unit_of_measurement": "V", "device_class": "voltage", "friendly_name": "G10KTL3X Vac RS"}, "last_changed": "2022-01-19T08:34:41.063418+00:00", "last_updated": "2022-01-19T08:34:41.063418+00:00", "context": {"id": "a4257b05f6e6ef6a32df403bf594403d", "parent_id": null, "user_id": null}}, "new_state": {"entity_id": "sensor.g10ktl3x_vac_rs", "state": "272961611.0", "attributes": {"unit_of_measurement": "V", "device_class": "voltage", "friendly_name": "G10KTL3X Vac RS"}, "last_changed": "2022-01-19T08:34:46.500895+00:00", "last_updated": "2022-01-19T08:34:46.500895+00:00", "context": {"id": "342a03fe2e8c6026846386f38d27937c", "parent_id": null, "user_id": null}}}, "origin": "LOCAL", "time_fired": "2022-01-19T08:34:46.500895+00:00", "context": {"id": "342a03fe2e8c6026846386f38d27937c", "parent_id": null, "user_id": null}}}
2022-01-19 09:34:46 DEBUG (SyncWorker_1) [pymodbus.transaction] Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2022-01-19 09:34:46 DEBUG (MainThread) [homeassistant.components.http.view] Serving /api/hassio_ingress/mvUUMqehXyHUNvbeqSY3cykWLqt5fwAltKntBPzYhgQ/ to 10.10.10.100 (auth: False)
2022-01-19 09:34:46 DEBUG (SyncWorker_1) [pymodbus.transaction] Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2022-01-19 09:34:46 DEBUG (SyncWorker_1) [pymodbus.transaction] RECV: 0x1 0x4 0x4 0x10 0x4b 0x10 0x49 0x43 0x64
2022-01-19 09:34:46 DEBUG (SyncWorker_1) [pymodbus.framer.rtu_framer] Getting Frame - 0x4 0x4 0x10 0x4b 0x10 0x49
2022-01-19 09:34:46 DEBUG (SyncWorker_1) [pymodbus.factory] Factory Response[ReadInputRegistersResponse: 4]
2022-01-19 09:34:46 DEBUG (SyncWorker_1) [pymodbus.framer.rtu_framer] Frame advanced, resetting header!!
2022-01-19 09:34:46 DEBUG (SyncWorker_1) [pymodbus.transaction] Adding transaction 1
2022-01-19 09:34:46 DEBUG (SyncWorker_1) [pymodbus.transaction] Getting transaction 1
2022-01-19 09:34:46 DEBUG (SyncWorker_1) [pymodbus.transaction] Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
2022-01-19 09:34:46 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=sensor.g10ktl3x_vac_st, old_state=<state sensor.g10ktl3x_vac_st=273289293.0; unit_of_measurement=V, device_class=voltage, friendly_name=G10KTL3X Vac ST @ 2022-01-19T09:34:41.142362+01:00>, new_state=<state sensor.g10ktl3x_vac_st=273354825.0; unit_of_measurement=V, device_class=voltage, friendly_name=G10KTL3X Vac ST @ 2022-01-19T09:34:46.582445+01:00>>
2022-01-19 09:34:46 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection] [139832423143696] Sending {"id": 2, "type": "event", "event": {"event_type": "state_changed", "data": {"entity_id": "sensor.g10ktl3x_vac_st", "old_state": {"entity_id": "sensor.g10ktl3x_vac_st", "state": "273289293.0", "attributes": {"unit_of_measurement": "V", "device_class": "voltage", "friendly_name": "G10KTL3X Vac ST"}, "last_changed": "2022-01-19T08:34:41.142362+00:00", "last_updated": "2022-01-19T08:34:41.142362+00:00", "context": {"id": "c22d699746a0425da2f3b8ad205049c1", "parent_id": null, "user_id": null}}, "new_state": {"entity_id": "sensor.g10ktl3x_vac_st", "state": "273354825.0", "attributes": {"unit_of_measurement": "V", "device_class": "voltage", "friendly_name": "G10KTL3X Vac ST"}, "last_changed": "2022-01-19T08:34:46.582445+00:00", "last_updated": "2022-01-19T08:34:46.582445+00:00", "context": {"id": "e92a1eab66bb6a355b577bc67b005285", "parent_id": null, "user_id": null}}}, "origin": "LOCAL", "time_fired": "2022-01-19T08:34:46.582445+00:00", "context": {"id": "e92a1eab66bb6a355b577bc67b005285", "parent_id": null, "user_id": null}}}
2022-01-19 09:34:46 DEBUG (SyncWorker_4) [pymodbus.transaction] Current transaction state - TRANSACTION_COMPLETE

Skupiłem się na odpowiedzi jaką HA otrzymywał:

RECV: 0x1 0x4 0x4 0x10 0x4b 0x10 0x49 0x43 0x64

W odpowiedzi w polu danych mam informajcę o przesłanych 4 bajtach zatem HA odczytywał mi 0x10 0x4b 0x10 0x49). Przeliczając to z systemu 16 na dziesiętny otrzymałem wartość 273 354 825. Natomiast biorąc tylko 2 bajty, czyli 0x10 0x4b i przeliczajac hex na dec mamy 4171 (czyli 417,1 V).

Mając taki trop doszedłem do tego, że należy w HA zmienić typ danych na “własny” czyli data_type: custom.

Oprócz tego ustawiłem count: 1 po to by był pobrany jeden rejestr oraz w typie danych określiłem strukturę na >1h. To znaczy, że miał być brany pod uwagę tylko jeden bajt.

Aby dane poprawnie się wyświetlały należało w pozostałych encjach dostosować tylko parametry precision oraz scale.

Przykładowa konfiguracja w HA:

# PV2 Energy total (low)
- name: G10KTL3X PV2 Energy total L
  unit_of_measurement: kWh
  slave: 1
  address: 66
  input_type: input
  count: 1
  data_type: uint16
  # Zmiana typu danych na poniższe również działa 
  # data_type: custom
  # structure: ">1h"
  precision: 1
  scale: 0.1
  scan_interval: 60
  device_class: energy

# Three phase grid voltage 0.1V Line voltage
- name: G10KTL3X Vac ST
  unit_of_measurement: V
  slave: 1
  # address: 30052
  address: 51
  input_type: input
  count: 1
  data_type: uint16
  # Zmiana typu danych na poniższe również działa 
  # data_type: custom
  # structure: ">1h"
  precision: 1
  scale: 0.1
  scan_interval: 15
  device_class: voltage

Dzięki wszystkim za zaangażowanie w temat i podesłanie (@macek) linku do konkretnego artykułu o modbusie.

Jeżeli gdzieś się pomyliłem w nazewnictwie to proszę poprawcie mnie. Uczyłem się tego dość dawno temu więc mogły zagnieździć się w moim poście jakieś bugi :wink:

edit: poprawiłem konfigurację zgodnie z wnioskami z postów poniżej

1 polubienie

@bielen2k
Super, mnie niestety się nie udało, mógłbyś udostępnić swoją konfigurację, nie dokończa wiem jak odczytać adresy poszczególnych parametrów.