How to connect to Nibe heat pump without the cloud

I’ve been working hard to get a NIBE heat pump to display it’s data in HA, and this has been a bit of a journey, so I thought I’d share my setup here in case other users would like to get their up and running.

First thing to mention, there is a Nibe integration for HA which interacts with the Nibe cloud platform v1. This has been superceded by a new (and not terribly much improved) cloud API for Nibe such that new heat pumps don’t work with this integration. But TBH, I’m not really sure why one would want to bother with that integration in the first place as this can all be accomplished in an entirely local, zero-cloud, modbus setup.

First things first, enable modbus over tcp on your Nibe control unit. I’ve got the NIBE SMO S40 (UK) control unit. You can enable modbus in menu 7.5.9 - simply change the setting to “on” and your control unit will communicate modbus via the configured internet connection. I’m assuming that you have already connected up the SMOS40 with an internet configuration. Mine is using ethernet with an address set up via DHCP (this can be found in menu 5.2.2).

Next, you need to add entries to configuration.yml - here’s how I have mine set up:

modbus:
  - name: Nibe
    type: tcp
    host: 192.168.1.xxx # put in your server ip address here
    port: 502
    sensors:
      - name: nibe_smos40_bt1
        friendly_name: "BT1: Outdoor Temperature"
        unit_of_measurement: °C
        data_type: int16
        device_class: temperature
        address: 1
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
        slave: 1
      - name: nibe_smos40_bt7
        friendly_name: "BT7: Hot Water Top"
        unit_of_measurement: °C
        data_type: int16
        input_type: input
        scale: 0.1
        precision: 1
        address: 8
        slave: 1
      - name: nibe_smos40_bt6
        friendly_name: "BT6: Hot Water Charging"
        unit_of_measurement: °C
        address: 9
        slave: 1
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_f2040_bt3
        friendly_name: "BT3: Heating medium return line temp"
        unit_of_measurement: °C
        slave: 1
        address: 1475
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_f2040_bt14
        friendly_name: "BT14: Hot gas discharge temp"
        unit_of_measurement: °C
        slave: 1
        address: 1479
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_f2040_bt15
        friendly_name: "BT15: Condenser fluid pipe"
        unit_of_measurement: °C
        slave: 1
        address: 1480
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_f2040_bt17
        friendly_name: "BT17: Suction Gas"
        unit_of_measurement: °C
        slave: 1
        address: 1481
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_f2040_bt12
        friendly_name: "BT12: Condenser supply line temp"
        unit_of_measurement: °C
        slave: 1
        address: 1478
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_f2040_bt28
        friendly_name: "BT28: Outdoor ambient temp"
        unit_of_measurement: °C
        slave: 1
        address: 1621
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_smos40_bt50
        friendly_name: "Room temperature"
        unit_of_measurement: °C
        slave: 1
        address: 26
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_smos40_bt25
        friendly_name: "BT25: External supply line temp"
        unit_of_measurement: °C
        slave: 1
        address: 39
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_f2040_bt16
        friendly_name: "BT16a: Evaporator"
        unit_of_measurement: °C
        slave: 1
        address: 1622
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_f2040_bt16_2
        friendly_name: "BT16b: Evaporator"
        unit_of_measurement: °C
        slave: 1
        address: 1966
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_smos40_bt71
        friendly_name: "BT71: Return temperature"
        unit_of_measurement: °C
        slave: 1
        address: 88
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_f2040_bp4
        friendly_name: "BP4: Pressure" 
        unit_of_measurement: bar
        slave: 1
        address: 1801
        input_type: input
        scale: 0.1
        precision: 1
      - name: nibe_f2040_bp2
        friendly_name: "BP2: Low pressure switch"
        unit_of_measurement: bar
        slave: 1
        address: 1802
        input_type: input
        scale: 0.1
        precision: 1
      - name: nibe_f2040_ep14_total_time
        friendly_name: "Compressor total run time"
        unit_of_measurement: hours
        slave: 1
        address: 1491
      - name: nibe_f2040_compressor_freq
        friendly_name: "Compressor current frequency"
        unit_of_measurement: hz
        slave: 1
        address: 1803
      - name: nibe_smos40_eb100-gp12
        friendly_name: "Charge Pump (EB100-GP12)"
        slave: 1
        address: 1636
        unit_of_measurement: Percent
        data_type: int16
        device_class: power_factor
        input_type: input
        scale: 1
        precision: 1
        state_class: measurement
      - name: nibe_smos40_supply_temp_min
        unit_of_measurement: °C
        slave: 1
        address: 34
        data_type: int16
        device_class: temperature
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_smos40_supply_temp_max
        unit_of_measurement: °C
        slave: 1
        address: 38
        data_type: int16
        device_class: temperature
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_smos40_prioritisation
        friendly_name: "Operating prioritisation 1-off, 2-hot water 3- heat"
        slave: 1
        address: 1028
      - name: nibe_smos40_alarm
        slave: 1
        address: 1975
      - name: nibe_smos40_hot_water_demand
        friendly_name: "Hot Water Demand (Sm/Md/Lg/Smart)"
        slave: 1
        address: 56
        scan_interval: 60
      - name: nibe_smos40_bt70_outgoing_hot_water
        unit_of_measurement: °C
        slave: 1
        address: 87
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement
      - name: nibe_smos40_degree_minutes
        slave: 1
        address: 18
      - name: nibe_smos40_degree_minutes_cooling
        slave: 1
        address: 20
      - name: nibe_smos40_reset_alarm
        slave: 1
        address: 22
      - name: nibe_smos40_heating_curve
        slave: 1
        address: 26
      - name: nibe_smos40_offset_curve
        slave: 1
        address: 30
      - name: nibe_smos40_flow_sensor
        unit_of_measurement: "l/m"
        slave: 1
        address: 40
        scan_interval: 60
      - name: nibe_smos40_current_be3
        slave: 1
        address: 46
      - name: nibe_smos40_current_be2
        slave: 1
        address: 48
      - name: nibe_smos40_current_be1
        slave: 1
        address: 50
      - name: nibe_smos40_degree_minutes_start_additional_heat
        slave: 1
        address: 97
      - name: nibe_smos40_degree_minutes_start_compressor
        slave: 1
        address: 159
      - name: nibe_smos40_alarm_action_lower_room_temp
        slave: 1
        address: 196
      - name: nibe_smos40_alarm_action_lower_hw_temp
        slave: 1
        address: 197
      - name: nibe_smos40_operating_mode
        slave: 1
        address: 237
      - name: nibe_smos40_pulse_energy_meter_be7
        unit_of_measurement: kWh
        slave: 1
        address: 396
      - name: nibe_smos40_pulse_energy_meter_be6
        unit_of_measurement: kWh
        slave: 1
        address: 398
      - name: nibe_smos40_calculated_supply_temp
        friendly_name: "Calculated supply temp"
        unit_of_measurement: °C
        slave: 1
        address: 1017
        data_type: int16
        device_class: temperature
        input_type: input
        scale: 0.1
        precision: 1
        state_class: measurement

Voila, once you’ve restarted HA core, you should have a suite of sensors. I tend to have mine in a few different panels, “heat pump” “water tank” and then more niche stats in " Heat Pump - Refridgerant Circuit" and “Heat Pump - Heat Medium Circuit”. I’ve found the Nibe installers manuals to be pretty useful in terms of identifying where the various sensors fit and what they do for the heat pump. Here’s an annotated version I made for my own use:

and another more generic diagram (also annotated with sensors):

Good luck getting yours up online!

6 Likes

Good guide, but perhaps a clarification in the topic or the ingress that it is only the newer Nibe S-series that support Modbus TCP and the newer cloud myUplink (thanks Nibe for the really stupid naming scheme here).

The older versions, the ones supporting the Nibe Uplink, can use the older API that have a custom component that can be found here: Nibe Uplink API (non S-series). The older models still support Modbus but only over serial connection.

1 Like

@kidwellj did you manage to send any new parameters to the pump? Like you can do it in native indoor module modbus?

Like “hot water demand” or set a desire room temperature?

Regards

2 Likes

Hi Jeremy

With your guide I first time managed to get some data displayed for my Nibe F2120-12 on my Homeassistant.
The here available Nibe integration never got any data with endless trials from my side.
Thanks a lot for this working solution.

May I ask you following questions:

  1. Your configuration.yaml includes the parameter friendly_name that is not working on my site, see Configuration validation message:

Invalid config for [modbus]: [friendly_name] is an invalid option for [modbus]. Check: modbus->modbus->0->sensors->0->friendly_name. (See /config/configuration.yaml, line 213).

After deleting friendly_name validation is ok.

  1. Where do you get all the name strings like “nibe_smos40_bt1”. Is there a complete list specific to NIBE models. As I have a F2120-12 not all
    Parameters you have in your config is working on my site.

Thanks a lot for any tipps.

Cheers,

Rene

You can plug an USB to your indoor module of the pump and get all the modbus sensors that ara available.

I have made a Nibe MQTT service. It uses same NibeGW Arduino module as Openhab’s nibeheatpump integration already uses.


1 Like

Does it work with S series?

With TCP Modbus? Not today, but should be easy to add. Need a tcp dump for request and reply. Or you are welcome to contribute =)

1 Like

I have added TCP and Serial Modbus support to the library. Somebody needs to try:

If all works then I will release it and add support to nibe-mqtt as well.

3 Likes

Would love to test it, but just don’t have the knowledge to work outside of HA. :pensive:

I copied your configuration exactly into my Home Assistant, and the config gave the error message
Invalid config for [modbus]: [friendly_name] is an invalid option for [modbus].
So I took out all the friendly names, and it worked. But there is no unique_id, so you can’t alter parameters in the UI.

1 Like

Here is my take. I created a nibe.yaml file and put in all the parameters I needed (There are a lot more) for my S1255 and I will add them as I go along.

My yaml file below:

- name: Nibe
  type: tcp
  host: 192.XXX.XX.XXX
  port: 502
  
  sensors:

# Overview

  - name: "Heatpump Power Usage"
    unique_id: "power_usage"
    unit_of_measurement: "W"
    data_type: int16
    device_class: power
    address: 2166
    input_type: input
    scale: 1
    precision: 0
    slave: 1

  - name: "Heatpump Priority"
    unique_id: "operating_prioritisation"
    data_type: int16  # int8
    # 10: Off, 20: Hot Water, 30: Heat, 40: Pool, 60: Cooling
    address: 1028
    input_type: input  # R/W
    scale: 1
    precision: 0
    state_class: measurement
    slave: 1

# Heating

  - name: "Heatpump Calculated Supply (Heating)"
    unique_id: "calculated_supply_heating"
    unit_of_measurement: "°C"
    data_type: int16
    device_class: temperature
    address: 1017
    input_type: input  # R
    scale: 0.1
    precision: 1
    state_class: measurement
    slave: 1

  - name: "Heatpump - Supply Line (BT2)"
    unique_id: "supply_line_BT2"
    device_class: temperature
    state_class: measurement
    unit_of_measurement: "°C"
    data_type: int16
    address: 5
    count: 1
    slave: 1
    precision: 1
    input_type: input
    scale: 0.1
    scan_interval: 30

  - name: "Heatpump - Return Line (BT3)"
    unique_id: "return_line_BT3"
    device_class: temperature
    state_class: measurement
    unit_of_measurement: "°C"
    data_type: int16
    address: 7
    count: 1
    slave: 1
    precision: 1
    input_type: input
    scale: 0.1
    scan_interval: 30

  - name: "Heatpump - Outdoor Temperature (BT1)"
    unique_id: "outdoor_temperature_BT1"
    device_class: temperature
    state_class: measurement
    unit_of_measurement: "°C"
    data_type: int16
    address: 1
    count: 1
    slave: 1
    precision: 1
    input_type: input
    scale: 0.1
    scan_interval: 30

  - name: "Heatpump - Average Temperature (BT1)"
    unique_id: "average_temp_heatpump_BT1"
    device_class: temperature
    state_class: measurement
    unit_of_measurement: "°C"
    data_type: int16
    address: 37
    count: 1
    slave: 1
    precision: 1
    input_type: input
    scale: 0.1
    scan_interval: 30

  - name: "Heatpump Condenser Supply (BT12)"
    unique_id: "condenser_supply_bt12"
    unit_of_measurement: "°C"
    data_type: int16
    device_class: temperature
    address: 12
    input_type: input  # R
    scale: 0.1
    precision: 1
    state_class: measurement
    slave: 1

  - name: "Heatpump - Brine In (BT10)"
    unique_id: "brine_in_BT10"
    device_class: temperature
    state_class: measurement
    unit_of_measurement: "°C"
    data_type: int16
    address: 10
    count: 1
    slave: 1
    precision: 1
    input_type: input
    scale: 0.1
    scan_interval: 30

  - name: "Heatpump - Brine Out (BT11)"
    unique_id: "brine_out_BT11"
    device_class: temperature
    state_class: measurement
    unit_of_measurement: "°C"
    data_type: int16
    address: 11
    count: 1
    slave: 1
    precision: 1
    input_type: input
    scale: 0.1
    scan_interval: 30

# Hot Water

  - name: "Heatpump - Hot Water Top (BT7)"
    unique_id: "hotwater_top_BT7"
    device_class: temperature
    state_class: measurement
    unit_of_measurement: "°C"
    data_type: int16
    address: 8
    count: 1
    slave: 1
    precision: 1
    input_type: input
    scale: 0.1
    scan_interval: 30

  - name: "Heatpump - Hot Water Charging (BT6)"
    unique_id: "hotwater_charging_BT6"
    device_class: temperature
    state_class: measurement
    unit_of_measurement: "°C"
    data_type: int16
    address: 9
    count: 1
    slave: 1
    precision: 1
    input_type: input
    scale: 0.1
    scan_interval: 30

  - name: "Heatpump - Compressor Status"
    unique_id: "compressor_status"
    data_type: int16  # uint8
    # 0: Off, 1: On (Operate)
    address: 1100
    input_type: input  # R
    scale: 1
    precision: 0
    state_class: measurement
    slave: 1

# Other

  - name: "Heating Curve Offset"  # 1.30.1
    unique_id: "heating_curve_offset"
    data_type: int16  # int8
    address: 30
    input_type: holding
    scale: 1
    precision: 0
    state_class: measurement
    slave: 1
1 Like

Now my question, has anyone been able to write to the heat pump?

I want to be able to do 2 things:

  1. Turn the heating on/off - currently i have it off because its warm.

  2. Adjust the heating curve offset. On my system its ranges from -10 to +10 and would like to create a slider for that.

Any assistance would be appreciated.

I haven’t found a way to write to modbus. With MQTT integration should be the easiest.

1 Like

this adds no new sensors for me. Should it work with VVM S320?

1 Like

Thank you for this!
This is what my config looks like https://take.ms/olfqS
These are the entities discovered: https://take.ms/RCz1R
Wondering what I am missing. Hint please :slight_smile: (I’m new to mqtt stuff)

This is intended to work with Nibe S series with Modbus TCP. Does yours have modbus tcp and usb port?

Victor, you look like you made more progress than i did. Please share the steps you used to get in into MQTT?

Oh! That was it! My pump had the modbus disabled. Just enabled it. I am now adding to the config list the sensors I would like to use with my hass. So far added the one for outside temp and the one for hot water (per your example). Please note that when using your config, and then check the sensors, each says that there’s no unique id present and so I have added the unique_id prop to the list.
So far the config: https://take.ms/xQc0u and the output in dashboard https://take.ms/BCpFq :smiley:

You use Modbus integration. Not my library. :slight_smile: