# Making a Modbus/TCP heat pump work with Emonhub

**URL:** <https://community.openenergymonitor.org/t/making-a-modbus-tcp-heat-pump-work-with-emonhub/26151>\
**Category:** emonHub\
**Tags:** modbus, nibe, emoncms, heatpumps\
**Created:** [16 May 2024 18:30 UTC](https://community.openenergymonitor.org/t/making-a-modbus-tcp-heat-pump-work-with-emonhub/26151 "2024-05-16T18:30:20Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jkjaer](https://community.openenergymonitor.org/user_avatar/community.openenergymonitor.org/jkjaer/32/30163_2.png) [@jkjaer](https://community.openenergymonitor.org/u/jkjaer)\
**Post date:** [16 May 2024 18:30 UTC](https://community.openenergymonitor.org/t/making-a-modbus-tcp-heat-pump-work-with-emonhub/26151/1 "2024-05-16T18:30:21Z")

</div>

Ever since getting a heat pump installed in September last year, I have been monitoring it using Home Assistant. However, HA never really felt like the right heat pump monitoring tool so when I recently discovered Emoncms, I simply had to try it out. Unfortunately, it turned out to be somewhat of a struggle to get everything up and running so I figured it would be worthwhile to share my findings.

Background info:

- Heat pump hardware: NIBE VVM S320 (indoor) + NIBE S2125 (outdoor)
- Sensors: Internal heat pump sensors
- Communication protocol: Modbus/TCP (Wi-Fi)
- Emoncms HW: Raspberry Pi 4 (I initially tried with an old Raspberry Pi 1, but it couldn’t start the Apache server due to an insufficient amount of memory)
- Location: Silkeborg, Denmark

In short, I had to do the following to get everything up and running:

1. Fixing a bug in EmonModbusTcpInterfacer.py [1].
2. Changing EmonModbusTcpInterfacer.py from reading holding registers to reading input registers.
3. Removing the subtraction by 1 of the register number when reading data (I am not sure why the -1 is there in the first place, but maybe it is needed for some Manufacturers). Alternatively, the specified addresses in the emonhub configuration can also be incremented by 1.
4. Making sure I did not have too many open connections with the heat pump since it only allows 5 simultaneous connections [2]. It took me a long time to figure out that this was the reason why reading data kept failing, even though I had an open connection.

My impression is that the Modbus/TCP interfacer in Emonhub is not used by a lot of users, but I still hope this information might be useful to some. Now, I look forward to start tracking metrics and optimise the heat pump settings. I also hope that the internal sensors provides reasonable accurate data (I got hope from [3]) so that I do not feel the urge to go invest in some MID certified sensors 😉

Thanks for making such a great piece of SW open source!

[1] [Change Endian.Big to Endian.BIG as per pymodbus change · Issue #213 · openenergymonitor/emonhub · GitHub](https://github.com/openenergymonitor/emonhub/issues/213)  
[2] See changelog of SW 2.27.5: [https://www.nibe.eu/webdav/files/myuplink\_changelog/nibe-n.pdf](https://www.nibe.eu/webdav/files/myuplink_changelog/nibe-n.pdf)  
[3] Search for nibe-onboard-monitoring-accuracy/25598 in this forum (new users can only include two links in a post so I cannot provide a direct link)

---

<div class="post-metadata">

**Author:** ![Bill.Thomson](https://community.openenergymonitor.org/user_avatar/community.openenergymonitor.org/bill.thomson/32/1834_2.png) [@Bill.Thomson](https://community.openenergymonitor.org/u/Bill.Thomson)\
**Post date:** [16 May 2024 18:54 UTC](https://community.openenergymonitor.org/t/making-a-modbus-tcp-heat-pump-work-with-emonhub/26151/2 "2024-05-16T18:54:43Z")

</div>

> [@jkjaer](#):
>
> (I am not sure why the -1 is there in the first place, but maybe it is needed for some Manufacturers

Hello Jesper,

The Modbus specification says _“Registers are addressed starting at zero. Therefore input registers numbered 1-16 are addressed as 0-15.”_

Register numbers are _transmitted_ as zero based values, but are _referred to_ as one-based values.

As you surmised, not all manufacturers follow this spec.

Ref:

> **[PI\_MBUS\_300.pdf](https://modbus.org/docs/PI_MBUS_300.pdf)**
>
> 172.26 KB

Note: Despite the name MBUS\_300, the document referenced above is _not_ a meter bus article.

---

<div class="post-metadata">

**Author:** ![borpin](https://community.openenergymonitor.org/user_avatar/community.openenergymonitor.org/borpin/32/193_2.png) [@borpin](https://community.openenergymonitor.org/u/borpin)\
**Post date:** [16 May 2024 19:36 UTC](https://community.openenergymonitor.org/t/making-a-modbus-tcp-heat-pump-work-with-emonhub/26151/3 "2024-05-16T19:36:17Z")

</div>

> [@jkjaer](#):
>
> Changing EmonModbusTcpInterfacer.py from reading holding registers to reading input registers.

Yes, this is a limitation of the implementation. It can do one or the other.

---

<div class="post-metadata">

**Author:** ![jkjaer](https://community.openenergymonitor.org/user_avatar/community.openenergymonitor.org/jkjaer/32/30163_2.png) [@jkjaer](https://community.openenergymonitor.org/u/jkjaer)\
**Post date:** [17 May 2024 18:41 UTC](https://community.openenergymonitor.org/t/making-a-modbus-tcp-heat-pump-work-with-emonhub/26151/4 "2024-05-17T18:41:35Z")

</div>

Hi Bill,

Thanks a lot for the clarification. I guess I have thought of registers and addresses as being the same thing which explains my confusion. When I interpret the numbers NIBE give as addresses, it works fine. To add to the confusion, NIBE refer to them as IDs in their manual [1] 🙂

[1] [https://forum.iobroker.net/assets/uploads/files/1694376961026-m12676en.pdf](https://forum.iobroker.net/assets/uploads/files/1694376961026-m12676en.pdf)

---

<div class="post-metadata">

**Author:** ![borpin](https://community.openenergymonitor.org/user_avatar/community.openenergymonitor.org/borpin/32/193_2.png) [@borpin](https://community.openenergymonitor.org/u/borpin)\
**Post date:** [19 May 2024 17:59 UTC](https://community.openenergymonitor.org/t/making-a-modbus-tcp-heat-pump-work-with-emonhub/26151/5 "2024-05-19T17:59:23Z")

</div>

> [@jkjaer](#):
>
> When I interpret the numbers NIBE give as addresses, it works fine.

Before or after you have made this change?

> [@jkjaer](#):
>
> Removing the subtraction by 1

The easiest way to check what the documentation is giving you is (as Bill said) to see what the first number is. If 0 - it is an address, if 1 it is a Register number.

---

<div class="post-metadata">

**Author:** ![jkjaer](https://community.openenergymonitor.org/user_avatar/community.openenergymonitor.org/jkjaer/32/30163_2.png) [@jkjaer](https://community.openenergymonitor.org/u/jkjaer)\
**Post date:** [20 May 2024 06:46 UTC](https://community.openenergymonitor.org/t/making-a-modbus-tcp-heat-pump-work-with-emonhub/26151/6 "2024-05-20T06:46:08Z")

</div>

Hi Brian,

Sorry for not being completely clear. I have ended up doing the following:

1. Left the -1 unaltered in EmonModbusTcpInterfacer.py
2. Interpreted the IDs listed in the NIBE Modbus documentation [1] as addresses which means that the registers entered in the Emonhub configuration must be +1 compared to the NIBE IDs.

[1] [https://forum.iobroker.net/assets/uploads/files/1694376961026-m12676en.pdf](https://forum.iobroker.net/assets/uploads/files/1694376961026-m12676en.pdf)
