Integracja pompy ciepła JNOD (klon Sprsun) z HA modbus rs-485

Witam,

zakupiłem w sierpniu tego roku pompę ciepła monoblok na czynniku r290 firmy JNOD. Model JME120HC, jednofazowy, wersja split - coś jak Sprsun dlatego myślę że to jego chiński klon. Sprężarka GMCC :sob:

Pompa wygląda typowo - jednostka wewnętrzna (nie wiem dlaczego mam tylko zdjęcie od tyłu) :

  • jednostka zewnętrzna:

W komplecie nie było urządzenia Elfin-EW11 do łączności i sterowania :thinking:
Sterownik/wyświetlacz łączy się bezprzewodowo z siecią wi-fi i sam przesyła dane do jakiegoś chińskiego serwera.

Następnie udostępniona jest aplikacja Tuya smart na telefon do sterowania pompą w bardzo podstawowym zakresie. Możliwy jest jedynie wybór trybu pracy oraz ustawienie temperatury w układzie co i osobno cwu.

Po uruchomieniu wszystkiego urządzenie działa bezproblemowo. Koniec wstępu i tu przechodzimy do sedna :grinning:

Z racji tego iż nie ma oryginalnie urządzenia Elfin-EW11 a nie chciałem go już dokupywać bo nie mam pewności czy na 100% będzie działał postanowiłem spróbować innej integracji z HA:

  • podłączenie przewodowe dwużłowe z płyty głównej jednostki zewnętrznej - płyta główna chyba firmy ELECHICO model CC902

do wolnego wyjścia A i B (tam w oryginalnych pompach Sprsun jest wpięty Elfin-EW11)

  • doprowadzenie tych dwóch przewodów do jednostki wewnętrznej - i tak idzie masę innych przewodów między jednostką zewnętrzną a wewnętrzną :grinning:
  • wejście do konwertera TTL na rs-485
  • wyjście sygnałów rs-485 do esp32 - znalazłem w sieci taki schemat

  • wykorzystanie mapy adresów z postu użytkownika Blackscreener - link

To tyle - w efekcie w HA pojawiają się encje:

Moje pytanie do innych użytkowników pomp ciepła Sprsun lub JNOD (tych to chyba niewielu jest :stuck_out_tongue: ) - czy też takie bzdurne encje macie ?
Niektóre pozycje rozwijalne z konfiguracji mogę rzeczywiście wybrać i przekłada się to na ustawienia w sterowniku/wyświetlaczu. Widać że integracja w jakimś zakresie działa. Inne encje od początku były zupełnie puste.
W jaki sposób na przykład wykorzystać encję sensor.jnod_output_symbol_1 która ma stan High or low fan speed: 0-low 1-high,
Bez sensu. Wiem, że sam to powpisywałem/skopiowałem do kodu esphome w esp32.
Czy ktoś ma to ogarnięte ? Nie mam precyzyjnej mapy rejestrów - posługiwałem się kodem .yaml do esp 32 znalezionym w internetach link - tak na marginesie także autorstwa użytkownika Blackscreener - mam nadzieję, że nie przyjdzie tu i mi nie nawrzuca :hushed:

1 polubienie

To tylko kontrolka w jakim trybie jest wentylator.

W końcu znalazł się tester. W tej wersji zmienilem sposób na sterowanie pompą, bo miałem sygnały że coś jest nie halo. I tak dużo działa, ja tego nie testowałem bo pompa czeka na montaż.

@rzyraafa wrzuć Twojego yamla. Nie musisz dodawać failure symbol bitowo, bo zrobiłem to w komponencie text sensor.

W encji grzanie co i grzanie cwu prawdopodobnie miałem zły typ rejestru. Teraz powinno być ok:

- platform: modbus_controller
  modbus_controller_id: sprsun_pc
  name: Grzanie CWU
  id: hotwater_demand
  #entity_category: diagnostic
  device_class: heat
  register_type: holding
  address: 0x0003
  bitmask: 0x01

- platform: modbus_controller
  modbus_controller_id: sprsun_pc
  name: Grzanie CO
  id: heating_demand
  #entity_category: diagnostic
  device_class: heat
  register_type: holding
  address: 0x0003
  bitmask: 0x02

Fajnie gdybyś przetestował działanie selecta “Heat pump on/off switch”. Czyli rejestr PARAMETER MARKER DEFINITION. Select:

  - platform: modbus_controller
    use_write_multiple: true
    modbus_controller_id: sprsun_pc
    name: "Heat pump on/off switch"
    id: on_off
    address: 0x0032
    value_type: U_WORD
    optionsmap:
      "OFF": 0
      "ON": 1
    lambda: |-
      //ESP_LOGE("main","Modbus Number incoming value = %d",x);
      //ESP_LOGE("main","Modbus eval value = %d",(x & 0x0001));
      if ((x & 0x0001) == 0)
        return  std::string("OFF");
      if ((x & 0x0001) == 1)
        return  std::string("ON");
      return {};
    write_lambda: |-
      //ESP_LOGE("main","Modbus write gets = %d",value);
      uint16_t unmodified =  id(parameter_marker_definition_raw).state;
      //ESP_LOGE("main","Modbus write unmodified = %d", unmodified);
      uint16_t modified = ((unmodified & ~0x0001) | value);
      //ESP_LOGE("main","Modbus write to write = %d", modified);
      return modified;

sensor:

  - platform: modbus_controller
    modbus_controller_id: sprsun_pc
    id: parameter_marker_definition_raw
    register_type: holding
    address: 0x0032
    value_type: U_WORD

sprsun-logger-v2(3).yaml (234,5 KB)

Failure symbol masz puste, bo nie masz błędów.

Dzięki wielkie za pomoc. Twój yaml ma ponad 7 tysięcy nowych linii :scream: Wrzuciłem wczoraj wieczorem za szybko, po wstępnej edycji ale po kilku minutach działania powiesił się esp32. Były jakieś błędy. Po chwili znów sie połączył i działał.
Teraz staram się podejśc bardziej bez emocji, ale pewnie zabierze mi to trochę czasu.
Po tym co widzę w Twoim yaml to mamy trochę odmienne konfiguracje - ja nie mam w ogóle do tego esp32 podpiętych żadnych termometrów (dallas), ani przekaźników, ani urządzeń do pomiaru ilości zużytej energii. Ten moduł esp32 jedynie odpowiada za komunikację po modbus z pc. Wykorzystane jedynie GPIO16 i 17.
Trochę inaczej mam przeliczniki ciśnienia sprężania i rozprężania - bez lambdy, po prostu zwykłe mnożenie. Wcześniej miałem dziwne wyniki.
W encji grzanie co i grzanie cwu miałeś raczej dobry typ rejestru.
Włącznik “Heat pump on/off switch" się pojawił

Mojego yaml załączam, jnod.yaml (33,6 KB)
ale to tylko kawałek Twojego kodu. Jeszcze dużo trzeba żeby go dopieścić.
Będę metodą kolejnych przybliżeń meldował jak idzie.

Dlatego najlepiej sprawdzać te wszystkie dane z wyświetlaczem. Ten select on/off faktycznie włącza/wyłącza pompę i poprawnie odwzorowuje jej stan?
Grzanie co i grzanie cwu masz raz read, a raz holding - który typ działa? Zmienną device_class możesz z tych encji usunąć.

BTW. Masz do tej pompy jakiegoś pdfa ze schematem płyty głównej?

Tak, potwierdzam on/off działa poprawnie w obie strony - po zmianie na sterowniku/wyświetlaczu zmienia się jego status w HA i odwrotnie.
Grzanie co i grzanie cwu raz read, a raz holding - nie zwróciłem uwagi, rzeczywiście :exploding_head: - działa poprawnie tylko grzanie cwu czyli holding.
Nie mam problemów z rozłączaniem modułu - to o czym pisałem wcześniej - działa cały czas ok, jest połączony z wi-fi i działa poprawnie.
Schemat załączam - był na wewnętrznej stronie górnej pokrywy

Dzięki.
Faktycznie musi być holding:

Terminal pump to pompa obiegowa za buforem? Masz jakąś instrukcję do tej pompy?

Nie wiem co to za pompa, nie mam fizycznie bufora - zasilanie z pc od razu na podłogówkę i grzejniki. Gdzie ją znalazłeś ?
W ogóle jaką wartość encji powinien zwracać ten fragment kodu ?

- platform: modbus_controller
    modbus_controller_id: jnod_pc
    name: ${friendly_name} Output symbol 1
    id: output_symbol_1
    register_type: holding
    address: 0x0004
    response_size: 2
    raw_encode: HEXBYTES
    #bitmask: 0
    lambda: |-
       std::string z = "";
       int idx = item->offset+1;
       if ((data[idx] & 0x0001) != 0) z += "Compressor, ";
       if ((data[idx] & 0x0002) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0004) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0008) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0010) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0020) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0040) != 0) z += "4-way valve, ";
       if ((data[idx] & 0x0080) != 0) z += "High or low fan speed: 0-low 1-high, ";
   
       if(z.length() > 0){
         z.pop_back();
       }
       return {z};

Podczas normalnej pracy ma on wartość

Compressor, Invalid, High or low fan speed: 0-low 1-high,

Czy taka wartość niejednoznaczna do czegoś może posłużyć w ogóle ?
Pomijam fakt, że w yaml od Ciebie wpis występuje 5 razy a w .pdf z rejestrem pojawia się 4 razy. Nie wiem czy to ma jakies znaczenie.
Mam instrukcję ale tam niewiele jest link

W Twoim schemacie masz te drugą pompę obiegową. Z tym wentylatorem to poprawię ten kod. Jeśli chodzi o invalid, to zapewne jest to któryś z przekaźników który nie jest rozpisany w instrukcji i rozpisce rejestrów modbus. Jak chcesz, to wywal to z kodu. Nie ufam tej rozpisce, dlatego zostawiłem te bity z invalid. Być może uda się rozszyfrować do czego służą niewykorzystane przekaźniki.

No zwątpiłem teraz co z tą pompą - jestem pewien że w jednostce zewnętrznej jej nie ma - dość dokładnie przyglądałem się temu co jest w środku - sprężarka, parownik, skraplacz w postaci wymiennika płytowego, zawór, czujniki i raczej tyle:

Listwa przyłączeniowa jednostki zewnętrznej:

Masz rację że na schemacie jest coś takiego

Ale na listwie przyłączeniowej jednostki wewnętrznej jest tylko ta jedna jedyna pompa sterowana sygnałem PWM połączona do zacisków 4 i N. F i 7 to sygnał PWM. To jest połączenie przewodami między jednostką zewnętrzną/wewnętrzną.

I w schemacie z instrukcji też nie ma żadnej pompy w jednostce zewnętrznej:

Upieram się że jej tam nie ma :grinning:

Chodzi tylko o to, że jest możliwość podpięcia kolejnej pompy obiegowej.

  - platform: modbus_controller
    modbus_controller_id: sprsun_pc
    name: ${friendly_name} Output symbol 1
    id: output_symbol_1
    register_type: holding
    address: 0x0004
    response_size: 2
    raw_encode: HEXBYTES
    #bitmask: 0
    lambda: |-
       std::string z = "";
       int idx = item->offset+1;
       if ((data[idx] & 0x0001) != 0) z += "Compressor, ";
       if ((data[idx] & 0x0002) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0004) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0008) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0010) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0020) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0040) != 0) z += "4-way valve, ";
       if ((data[idx] & 0x0080) == 0) z += "Low fan speed, ";
       if ((data[idx] & 0x0080) == 128) z += "High fan speed, ";
   
       if(z.length() > 0){
         z.pop_back();
       }
       return {z};

Sprawdź czy działa ten fragment z fan speed.

Chyba jednak nie - podczas grzania cwu encja sensor.jnod_output_symbol_1 ma wartość:

Compressor, Invalid, High fan speed,

sensor.jnod_output_symbol_2 ma wartość:

Chasis heater, Three-way valve,

sensor.jnod_output_symbol_3 ma wartość:

A/C PUMP, Assistant solenoid valve, Pump,

a sensor.jnod_working_status_mark ma wartość:

Hot water demand, With or without heating,

W międzyczasie, gdy nie jest grzane ani cwu ani co sensor.jnod_output_symbol_1 ma wartość:

High fan speed,

sensor.jnod_output_symbol_2 ma wartość:

Chasis heater,

sensor.jnod_output_symbol_3 ma wartość:

A/C PUMP, Crank heater, Pump,

a sensor.jnod_working_status_mark ma wartość:

With or without heating,

Podczas grzania co encja sensor.jnod_output_symbol_1 ma wartość:

Compressor, Invalid, High fan speed,

sensor.jnod_output_symbol_2 ma wartość:

Chasis heater,

sensor.jnod_output_symbol_3 ma wartość:

A/C PUMP, Pump,

a sensor.jnod_working_status_mark ma wartość:

Heating demand, With or without heating,

Ciągle jeszcze nie mogę sobie poradzić z sensorami temeratury pod adresami 0x0011, 0x0015, 0x0016, 0x0028. Na przykład temperatura zewnętrzna - raz mam sensowne wartości a potem 65 533,00. Przesyłam kawałek logów z esp32 na poziomie VERY_VERBOSE - jak bedziesz miał ochotę to rzuć może okiem.
logs_pompa-ciepla-modbus_run.yaml (354,6 KB)
Linia 1740 na przykład:

[21:55:10][V][sensor:043]: ‘jnod Temperatura zewnętrzna’: Received new state 65532.000000

Ostatnia sprawa może ktoś ma wiedzę o współpracy kominka z płaszczem wodnym i pompy ciepła ? Ja mam taki układ że na powrocie do pc mam zamontowany wymiennik płytowy i po drugiej stronie jest właśnie kominek. Jeżeli temperatury spadną nisko to chcę móc odpalić kominek i podnieść w ten sposób temperaturę wody na powrocie do pc. Spróbowałem to raz zrobić i wydaje mi się, że sprężarka dziwnie się wtedy zachowywała, jakoś tak głośno chodziła i dałem sobie spokój. Potem zastanowiłem się i rzeczywiście to chyba nie jest poprawne - załóżmy że ze sprężarki w jednostce zewnętrznej wychodzi woda zasilająca o temperaturze około 35 stopni. Na powrocie zazwyczaj oczekuje się niższej temperatury żeby obebrać ciepło z czynnika chłodniczego w wymienniku płytowym jednostki zewnętrznej. Jeżeli powracająca woda, podgrzana przez kominek ma załóżmy 45 stopni to do odebrania ciepła nie dojdzie a raczej wręcz przeciwnie. Nie doprowadzi to raczej do niczego dobrego. Czy ktoś może przerabiał taki układ ? Zastanawiam się czy nie lepiej byłoby całkowicie wyłączyc pc i dopiero wtedy ewentualnie rozpalić w kominku. Co o tym sądzicie ?

a czasem nie było wtedy minus dwa stopnie?

No dokładnie było -2. :grinning: Ale jak to się ma do tej wartości ? 65533 - 65535 daje -2. Mam każdą wartość pomniejszać o 65535 żeby otrzymać prawdziwą temperaturę ?

Wystarczy zmienić typ danych z uint na int.

data_type: int16

Dla ESPHome

value_type: S_WORD
1 polubienie

Zgubiłem wyjście FAN w Output symbol1:

  - platform: modbus_controller
    modbus_controller_id: sprsun_pc
    name: ${friendly_name} Output symbol 1
    id: output_symbol_1
    register_type: holding
    address: 0x0004
    response_size: 2
    raw_encode: HEXBYTES
    #bitmask: 0
    lambda: |-
       std::string z = "";
       int idx = item->offset+1;
       if ((data[idx] & 0x0001) != 0) z += "Compressor, ";
       if ((data[idx] & 0x0002) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0004) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0008) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0010) != 0) z += "Invalid, ";
       if ((data[idx] & 0x0020) != 0) z += "Fan, ";
       if ((data[idx] & 0x0040) != 0) z += "4-way valve, ";
       if ((data[idx] & 0x0080) == 0) z += "Low fan speed, ";
       if ((data[idx] & 0x0080) == 128) z += "High fan speed, ";
   
       if(z.length() > 0){
         z.pop_back();
       }
       return {z};

Sprawdź czy masz kiedykolwiek Low fan speed na wyświetlaczu albo dodaj sensor output symbol 1 na wzór sensorów z dopiskiem raw i podaj mi liczbę na grzaniu i podczas bezczynności pompy.

EDIT. Już znalazłem, gdy pompa jest wyłączona to nadal w tym rejestrze 8 bit ustawia się na 1.

Dzięki wielkie RobinI30, rzeczywiście po zmianie

value_type: U_WORD

na

value_type: S_WORD

wartości są poprawne (przynajmniej tak mi się wydaje) :grinning:

Ja mam tak zrobione. Kominek na pellet z płaszczem wodnym. Bufor 900 litrów. Grzeją tak do 55 stopni z kominka. Drugi sezon i nic się nie dzieje. W tym roku podczas mrozów doskonale odciążyłem pompę. Niestety nie mogę zintegrować pompy z HA. Niby działa ale za chwilę wisi.

Dzięki za info.
Po dłuższym obserwowaniu pracy układu PC z kominkiem z płaszczem wodnym także dochodzę do wniosku że nic złego się nie dzieje i współpraca idze bardzo dobrze. :grinning:
Po rozpaleniu w kominku (podczas mrozów) czujnik temperatury na powrocie PC wyczuwa temperaturę, która jest wyższa niż wcześniej bo została dodatkowo podgrzana w wymienniku płytowym przez kominek i po prostu przestaje działać PC bo automatyka PC nie widzi już takiej potrzeby skoro powrót jest cieplejszy niż zasilanie. Pompa obiegowa działa cały czas jeśli wybrało się w panelu sterowania opcję praca ciągła, tak że nie ma żadnego problemu i wszystko jest OK.
Aha, wrzucam dla potomnych mój schemat takiego mieszanego układu, na wypadek gdyby ktoś coś takiego trenował, bo już wcześniej go zrobiłem :grinning:

1 polubienie

have the model SPRSUN CGK-040V3L-B
12kw, R32, motherboard from ELECHICO model CC902, Elfin-EW11, Heat Pump App NO Tuya

Can I integrate the Elfin into Home Assistant via Modbus with your code?

Or should I still buy the Zlan 7110m?

Thank you for your reply!