How to connect to Nibe heat pump without the cloud

Dear community,

I’m using NIBE VVM320 (no S-series) with Home Assistant via cloud. Now I have chance to buy MODBUS 40 for acceptable price. I have few questions which may be already answered, but honestly the offer is time limited and I don’t have much time for looking for the answers.

  1. I found that MODBUS 40 can read only up to 20 values. Is it true also when use with Home Assistant?
  2. Is it possible to control the heat pump without subscription with MODBUS 40 via Home Assistant (vacation mode, water temperature,…) ? Is there any limitation?
  3. What else except MODBUS 40 I need? I could use RJ45 LAN which is now used directly by VVM320.
  4. What is frequency of data update via MODBUS

Thank you in advance for your replies and sorry that I maybe ask for already answered questions.

Hello again,

so I bought the MODBUS 40 for my VVM320 and now I solve how to get data from it to Raspberry where I run HA. I found three options and I would ask you for your experience.

  1. Convert RS485 to USB - I would need approximately 10 m long USB cable to reach Raspberry and I’m afraid of data loss then.

  2. Convert RS485 to WiFi - I found here that it’s possible to use HF2211, but I don’t have power socket near heat pump. Did anyone tried to take power from power of MODBUS 40? As I found, there should be 12 V which should be enough to HF2211, but I don’t know if it has enough current.

  3. Convert RS485 to RJ45 - this convertor could be powered by PoE via injector in rack and I could use RJ45 cable from heat pump, but than I will loose connection to NIBE uplink. It wouldn’t be such problem, but I’m afraid, that MODBUS 40 can transfer only max. 20 parameters.

Can you please help to choose the best option? Thank you in advance.

Why would you need a long USB? Just use a longer RS485 cable.

You can read all values. You can choose 20 values that are fast to read. This is explained in modbus 40 installers manual.

Hi Johannes, are you able to start hot water charging with SMOS40 through Home Assistant? Thanks :slight_smile: Pietro

Thank you. Honestly, I thought that there is no difference if the RS485-USB will be next to heat pump or next to Raspberry, but you are right that RS485 handle longer distances better.

Thanks, I thought that Home Assistant uses only fast readed values

Is it possible to combine these registers into the water heater entity?

This is also explained in modbus 40 installers manual.

Yes, RS485 installed with quality cable and low baud rate up to 1200 meters.

Hi there, have you managed to control the F2120 + SMO S40 with Home Assistant? E.g. steering the heating curve or switching on/off hot water charging?

I have the same system and I am just able to read data from modbus.

Thanks!
Pietro

Initially I set up my S1155-6 with external passive cooling module using Modbus, but I was not able to get the more hot water control and holiday mode working there.
Now I found this integration and it seems to make much things easier.
The more hot water works well when setting it to 2 in HA, I also get the return value when I manually activate it on the heat pump.
But I struggle with the following issues:

  • External cooling supply temperature (BT25) (sensor.external_cooling_supply_temperature_bt25_30120) just returns “unknown”, when using Modbus register 39 I can read the values correct. Code used there:
      - name: "Nibe external supply line temperature"
        unique_id: "nibe_external_supply_line_temperature"
        unit_of_measurement: "°C"
        data_type: int16
        device_class: temperature
        address: 39
        input_type: input
        scale: 0.1
        precision: 1
        slave: 1
  • Holiday mode also not working with the integration. I found “S1155 Holiday function status” in the integration but it neither returns a value when manually activating the mode on the heat pump nor does happen anything when I change it in HA. According to the Modbus register export it should be register 19 with type holding register. I tried the following Modbus configuration also without success:
    switches:
      - name: "Nibe holiday mode"
        write_type: holding
        address: 19
        slave: 1
        command_on: 3
        command_off: 0
        verify:

Any ideas what I’m doing wrong?

Is it possible to see somewhere which registers and settings the integration uses?

Sorry for my incompetence using Github but how to do this? :woozy_face:

You’re life saver, thanks a lot! Too bad it took me three days to find your post…

I did everything the same as you did and i get this stupid error … i think there is an error in NibeGwComponent.cpp file. :roll_eyes:

or is there something wrong with my config? :roll_eyes:

external_components:
  - source: 
      type: git
      url: https://github.com/elupus/esphome-nibe.git
    components: [ nibegw ]

uart:
  id: my_uart
  rx_pin: GPIO33
  tx_pin: GPIO26
  baud_rate: 9600

nibegw:
  dir_pin:
    number: GPIO25
    inverted: false

  # If you have a named uart instance, you can specify this here.
  uart_id: my_uart

  udp:
    # The target address(s) to send data to. May also be multicast addresses.
    target:
      - ip: 192.168.20.3
        port: 9999

    # List of source address to accept read/write from, may be empty for no filter, but
    # this is not recommended.
    source:
      - 192.168.20.3

    # Optional port this device will listen to to receive read requests. Defaults to 9999
    read_port: 9999

    # Optional port this device will listen to to receive write request. Defaults to 10000
    write_port: 10000


  acknowledge:
    - MODBUS40

    # Enable a dummy RMU40 accessory to receive updates
    # to certain registers faster. This should not be
    # enabled if you have an actual RMU40.
    - RMU40_S4

  # Constant replies to certain requests can be made
  constants:
    - address: MODBUS40
      token: ACCESSORY
      data: [
            0x0A, # MODBUS version low
            0x00, # MODBUS version high
            0x02, # MODBUS address?
      ]

    # Accessory version response
    - address: RMU40_S4
      token: ACCESSORY
      data: [
            0xEE, # RMU ?
            0x03, # RMU version low
            0x01, # RMU version high
      ]

    # Unknown response that nibepi uses
    - address: RMU40_S4
      token: RMU_DATA
      command: RMU_WRITE
      data: [
            0x63,
            0x00,
      ]

    # Constant fixed temperature to avoid pump going into alarm.
    - address: RMU40_S4
      token: RMU_WRITE
      data: [
            0x06, # Temperature
            0x14, # degrees low
            0x00, # degrees high
      ]

Any help would be appreciated. Thanks :sweat_smile:

Hi all,

I have twisted wire (3 pairs + ground) for connection of VVM 320 - MODBUS 40 - USBxRS485 convertor and I’m struggling how should be pairs used in connection. I know which ports should be connected. Is there someone who could help me with connection? I looked for something on Google, but I’m not sure if it’s correct. Below is connection based on my current knowledge (god bless MS Paint :grinning:). Is it correct, that A and B should be on the same pair? Thank you.

Hello!

I have KMP PRODINo esp32 board (ESP32D) with basic config from esphome page and Nibegw esphome.

(Relays are working with that config!)

When i enable Modbus in nibe pump (F470) system settings menu my pump keeps going in to error state.So I guess something is wrong with rs485 config. I have tried to change the wires A to B and A to A and so on.

and the code (there may be errors in the code due to the fact that I have tried different things that could affect the problem)

wifi:
  power_save_mode: none
  
logger:
#  baud_rate: 0
#  level: VERBOSE

# Load nibe component
external_components:
  - source: 
      type: git
      url: https://github.com/elupus/esphome-nibe.git
    components: [ nibegw ]

spi:
  clk_pin: GPIO18
  mosi_pin: GPIO23
  miso_pin: GPIO19

# Modbus RS485 from here
uart:
  id: uart_mod_bus
  tx_pin: GPIO16
  rx_pin: GPIO04
  baud_rate: 9600
#  parity: even
#  stop_bits: 1
#  debug:

modbus:
#  flow_control_pin: GPIO02
  id: modbus1
  uart_id: uart_mod_bus

modbus_controller:
  - id: modbusc1
    ## the Modbus device addr
    address: 0x1
    modbus_id: modbus1
    setup_priority: -10
# Modbus RS485 till here
# Configure NibeGW
nibegw:
  dir_pin:
    number: GPIO02
    inverted: false 
#######    
  uart_id: uart_mod_bus
  udp:
    # The target address(s) to send data to. May be a multicast address.
    target:
      - ip: 192.168.6.2
        port: 9999
       

    # List of source address to accept data from, may be empty for no filter
    source:
      - 192.168.6.2
    
    # Optional port this device will listen to to receive read requests. Defaults to 9999
    read_port: 9999

    # Optional port this device will listen to to receive write request. Defaults to 10000
    write_port: 10000 

  acknowledge:
    - MODBUS40

  # Constant replies to certain requests cabe made
  constants:
    - address: MODBUS40
      token: ACCESSORY
      data: [
            0x0A, # MODBUS version low
            0x00, # MODBUS version high
            0x01, # MODBUS address?
      ]
#

I would very much appreciate some hints or troubleshooting ideas because I wasted so much time on this.

edit. found this RS485 & GND Issues. Need to test with other powersupply…
edit2. Same result with separate power supply. Heat pump goes into fault state

edit3. bellow is log from esphome device

[19:09:19][W][modbus:108]: Modbus CRC Check failed! D621!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D461!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D461!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D461!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D621!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D621!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D621!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D461!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D461!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D461!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D621!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D621!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D621!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D461!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D461!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! D461!=BFD4
[19:09:19][W][modbus:108]: Modbus CRC Check failed! BAF9!=21B9
[19:09:19][W][modbus:108]: Modbus CRC Check failed! 872F!=BF9F
[19:09:19][W][modbus:108]: Modbus CRC Check failed! 49B0!=970F
[19:09:19][W][modbus:108]: Modbus CRC Check failed! 2368!=D4C3
[19:09:19][W][component:214]: Component modbus took a long time for an operation (0.09 s).
[19:09:19][W][component:215]: Components should block for at most 20-30ms.
[19:09:23][W][modbus:108]: Modbus CRC Check failed! 1380!=FDDF
[19:09:27][W][modbus:108]: Modbus CRC Check failed! 3030!=FF

Edit 4. if I understood correctly, my rs485 device won’t work. It needs modbus module support in the nibegw code?

Hello,

First of all, thank you very much for NIBE plugin for HA. I’m using it via MODBUS 40 and installation was really easy. However I have few questions.

When I try to set some value, e.g. “DM start heating” in some cases I got CRC validation error. The value is set, but it cause that all values are unavailible for few seconds. Also automation are shown as failed in this case. Can you please help me, what’s the problem?

2023-11-17 09:36:33.956 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [547033687616] CRC validation failed.
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 230, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 2035, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2072, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 235, in handle_service
    return await service.entity_service_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 876, in entity_service_call
    response_data = await _handle_entity_call(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 948, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/number/__init__.py", line 106, in async_set_value
    await entity.async_set_native_value(native_value)
  File "/usr/src/homeassistant/homeassistant/components/nibe_heatpump/number.py", line 74, in async_set_native_value
    await self._async_write_coil(value)
  File "/usr/src/homeassistant/homeassistant/components/nibe_heatpump/__init__.py", line 340, in _async_write_coil
    await self.coordinator.async_write_coil(self._coil, value)
  File "/usr/src/homeassistant/homeassistant/components/nibe_heatpump/__init__.py", line 253, in async_write_coil
    await self.connection.write_coil(data)
  File "/usr/local/lib/python3.11/site-packages/tenacity/_asyncio.py", line 88, in async_wrapped
    return await fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/tenacity/_asyncio.py", line 47, in __call__
    do = self.iter(retry_state=retry_state)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/tenacity/__init__.py", line 314, in iter
    return fut.result()
           ^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/concurrent/futures/_base.py", line 449, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/usr/local/lib/python3.11/site-packages/tenacity/_asyncio.py", line 50, in __call__
    result = await fn(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/nibe/connection/modbus.py", line 164, in write_coil
    result = await self._client.write_registers(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/async_modbus/core.py", line 236, in write_registers
    return await self._send_message(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/async_modbus/core.py", line 142, in _send_message
    return await self.protocol._async_send_message(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/async_modbus/core.py", line 78, in send_message_rtu
    return rtu.parse_response_adu(response_error_adu + response_remainder, adu)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/umodbus/client/serial/rtu.py", line 183, in parse_response_adu
    validate_crc(resp_adu)
  File "/usr/local/lib/python3.11/site-packages/umodbus/client/serial/redundancy_check.py", line 76, in validate_crc
    raise CRCError('CRC validation failed.')
umodbus.client.serial.redundancy_check.CRCError: CRC validation failed.
2023-11-17 09:36:36.959 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Unexpected error fetching Nibe Heat Pump data: CRC validation failed.
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 290, in _async_refresh
    self.data = await self._async_update_data()
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/nibe_heatpump/__init__.py", line 266, in _async_update_data
    return await self._async_update_data_internal()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/nibe_heatpump/__init__.py", line 288, in _async_update_data_internal
    async for data in self.connection.read_coils(_get_coils()):
  File "/usr/local/lib/python3.11/site-packages/nibe/connection/__init__.py", line 43, in read_coils
    yield await self.read_coil(coil, timeout)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/tenacity/_asyncio.py", line 88, in async_wrapped
    return await fn(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/tenacity/_asyncio.py", line 47, in __call__
    do = self.iter(retry_state=retry_state)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/tenacity/__init__.py", line 314, in iter
    return fut.result()
           ^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/concurrent/futures/_base.py", line 449, in result
    return self.__get_result()
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
    raise self._exception
  File "/usr/local/lib/python3.11/site-packages/tenacity/_asyncio.py", line 50, in __call__
    result = await fn(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/nibe/connection/modbus.py", line 116, in read_coil
    result = await self._client.read_holding_registers(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/async_modbus/core.py", line 181, in read_holding_registers
    return await self._send_message(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/async_modbus/core.py", line 142, in _send_message
    return await self.protocol._async_send_message(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/async_modbus/core.py", line 78, in send_message_rtu
    return rtu.parse_response_adu(response_error_adu + response_remainder, adu)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/umodbus/client/serial/rtu.py", line 183, in parse_response_adu
    validate_crc(resp_adu)
  File "/usr/local/lib/python3.11/site-packages/umodbus/client/serial/redundancy_check.py", line 76, in validate_crc
    raise CRCError('CRC validation failed.')
umodbus.client.serial.redundancy_check.CRCError: CRC validation failed.

Second question is about reading freqency. When I selected first value to get from heat pump, the update frequency was less then 2 minutes. Now I has approx. 20 values and update frequency is slightly above 2 minutes. When I tried allow all params, the update frequency was for sure more than 20 minutes. Is it correct, that more values cause longer update period? I’m confused that difference between 1 and 20 values isn’t significant.

Third question is regarding heat meter values. When I allow them for my VVM320, the value is stil 0 kWh. Isn’t that some bug?

Last questions is probably just my wish :slightly_smiling_face: Is it possible to set some priority to values? For example outdoor temperature or heat meter can be updated once per 10 minutes, so it doesn’t have to lower the udate frequency for other entities. I know that I can choose 20 values for fast reading, but I mean something different. Kind of workaround I’m using is getting these values by NIBE API online, but one day I would like to use just MODBUS connection and don’t use NIBE API anymore.

Thank you all who read this post to the end :slightly_smiling_face:

Hi,

has anyone thought how could one use RMU40 as a controller? I have one on the wall but my unit is so old that I have to buy internet thingy separately and its about 500% vat 0% here in Finland.

I’m really a big dummie in these things but just had a thought, seen people making really nice things from scratch :slight_smile:

Same error here :frowning:

Nevermind, big user error, for some reason I was running an ancient version of esphome. Sorry for the confusion, currently compiling :slight_smile: