How to connect to Nibe heat pump without the cloud

nvm, I think I’ve fixed this. Merry Christmas to me (and my heatpump?) :sweat_smile:

Seriously though, if anyone has this issue:
I’ve installed pyserial.

sudo apt install python3-serial

Ran the waveshare HEX receive script to test (Do set the baud to 9600 though and rename the file as they messed up spacing). (RS485 CAN HAT - Waveshare Wiki)

wget https://www.waveshare.com/w/upload/0/00/RS485-CAN-HAT-For-Hex.zip
unzip RS485-CAN-HAT-For-Hex.zip
sudo chmod 777 RS485-CAN-HAT-For-Hex.zip
cd RS485-CAN-HAT-For-Hex
#Receive Hex
sudo python3 RS485-CAN-HAT-receive-hex.py

This received the data for me, after restarting the nibegw all was working!

So I guess… something with the installation of pyserial fixed this issue?? not to sure though…

Merry Christmas for all!

@elupus First - thanks a lot for creating this integration.

I’ve not seen anyone commenting or writing about the serial modbus connection yet. I can confirm that my F1245 works using the serial:// URL and connected to the USB port on my RPi4. The connection is USB → RS485 dongle → Nibe MODBUS 40 shunt → F1245 heat pump.

One thing I would like to ask - the HA entities are currently logging/updating values only every 5 minutes. In between everything shows as “Unavailable” on the dashboard. Is there a way to set the update interval to a shorter period? I don’t see anything about this in the documentation and could not figure it out from a quick look in to the source code. Everything I read is in the LOG.SET file on the heat pump and I can read it in short intervals through my Python test script using @yozik04 's nibe library.

They should not go unavailable inbetween. Do you have some errors in your logs?

Ps. I think you might be the first person running an actual modbus40 unit with this integration.

Thanks for such a quick reply!
No there are no logs / errors regarding the integration.

Well, if I’m the first I’m also ready to help with debugging and stuff.

EDIT: Looking once more at the logs… There actually came up this one:

2022-12-26 15:10:23.494 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for bt2-supply-temp-s1-40008

Just quickly coming back to this in case it helps someone else.
This didn’t actually fix the issue. It temporarily resolved it by settings some params on the serial port.
After rebooting the pi it was broken again.

I wouldn’t call myself a programmer by any means… so I might be wrong here.
But it turns out the issue is related to running the serial port in canonical vs non-canonical mode.

Freshly booting the pi sets these params on /dev/ttyS0:

user@rpizero2w:~ $ stty -F /dev/ttyS0 -a
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S;
susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc

Running the nibegw (nibegw -d /dev/ttyS0 -a 10.10.10.10 -vv) makes this:

user@rpizero2w:~ $ stty -F /dev/ttyS0 -a
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S;
susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 1;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc

Running the waveshare read python script turns this to:

user@rpizero2w:~ stty -F /dev/ttyS0 -a
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S;
susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 0; time = 0;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke -flusho -extproc

Running the nibegw again after this makes it work (since settings are changed):

user@rpizero2w:~ stty -F /dev/ttyS0 -a
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S;
susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 1;
-parenb -parodd -cmspar cs8 hupcl -cstopb cread clocal crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke -flusho -extproc

The hardware-control param (crtscts) is settable through the nibegw script, so I didn’t touch that.
I disabled all the other params in the original C code to match the last state… and guess what… rebooting the pi and starting my modified nibegw (via systemctl) just works.

Strange that no one else has this issue with the product? (I’m rocking rpi zero 2w rev. 1, Waveshare RS485 CAN hat) Should I create a pull request for this or is there another explanation? (@elupus)

For those wondering, replace the initSerialPort (line 95-134) with this:

int initSerialPort(int fd, int hwflowctrl)
{
	struct termios options;
	
	// Get the current options for the port...
	
	tcgetattr(fd, &options);
	
	// Set the baud rates
	cfsetispeed(&options, B9600);
	cfsetospeed(&options, B9600);
	
	// Enable the receiver and set local mode...
	options.c_cflag |= (CLOCAL | CREAD);
	
	// 8 data bits, no parity, 1 stop bit
	options.c_cflag &= ~PARENB;
	options.c_cflag &= ~CSTOPB;
	options.c_cflag &= ~CSIZE;
	options.c_cflag |= CS8;
	
	if (hwflowctrl)
		options.c_cflag |= CRTSCTS;		// Enable hardware flow control
	else
		options.c_cflag &= ~CRTSCTS;	// Disable hardware flow control
	
	// Flow control
	options.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL );
	
	// Local flags
	options.c_lflag &= ~(ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHONL | ECHOCTL | ECHOKE );
	
	options.c_oflag &= ~(OPOST | ONLCR);
	
	options.c_cc[VMIN] = 1;				// Min character to be read
	options.c_cc[VTIME] = 1;			// Time to wait for data (tenth of seconds)
	
	// Set the new options
	if (tcsetattr(fd, TCSANOW, &options) < 0 )
	{
		return -1;
	}
	
	return 0;
}

Extra info: (removed some as I cannot post more then 2 links yet)

https://www.gnu.org/software/libc/manual/html_node/Local-Modes.html

Yes a pull request would be good. The C version of the program is part of OpenHAB project.

@elupus Is it possible to tweak the read timeout and read interval using some options for the integration? It turns out I’m running into random read timeouts with the MODBUS 40… Thanks.

Probably. Do you have logs?

Sure. What exactly would you need?

home-assistant.log has just this to say:

2022-12-26 22:48:40.235 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for bt1-outdoor-temperature-40004
2022-12-26 23:15:46.460 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for eb100-ep14-bt10-brine-in-temp-40015
2022-12-26 23:23:20.455 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for eb100-ep14-bt10-brine-in-temp-40015
2022-12-26 23:29:47.412 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for bt6-hw-load-40014
2022-12-26 23:36:14.288 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for bt2-supply-temp-s1-40008
2022-12-26 23:58:56.450 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for eb100-ep14-bt10-brine-in-temp-40015
2022-12-27 00:30:18.456 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for eb100-ep14-bt10-brine-in-temp-40015
2022-12-27 00:33:30.329 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for eb100-ep14-bt3-return-temp-40012
2022-12-27 00:37:47.371 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for bt7-hw-top-40013
2022-12-27 02:01:13.456 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for eb100-ep14-bt10-brine-in-temp-40015
2022-12-27 02:10:57.451 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for eb100-ep14-bt10-brine-in-temp-40015
2022-12-27 02:15:14.414 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for bt6-hw-load-40014

Strange. The default timeout is 5 seconds. That should have been enough. The library uses the same. You say you can use the nibe library to read?

Ps. It has a commandline tool too.

pip install nibe[cli]

Then you can use: nibe-cli commandline tool.

Yes, it is strange… I wrote a script reading 20 coils in a row and it works OK. I only get CRC errors if HA is running and your integration tries to read simultaneously too.

Interesting is that in HA it fails on timeout many times in a row and then it is able to successfully read all data in just under 2 seconds.

This is log with debug output enabled:

2022-12-27 11:00:02.369 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.048 seconds (success: False)
2022-12-27 11:01:09.142 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 6.820 seconds (success: False)
2022-12-27 11:02:14.322 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.002 seconds (success: False)
2022-12-27 11:03:19.360 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.038 seconds (success: False)
2022-12-27 11:04:24.389 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.068 seconds (success: False)
2022-12-27 11:05:29.322 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.001 seconds (success: False)
2022-12-27 11:06:34.413 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.093 seconds (success: False)
2022-12-27 11:07:39.745 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.424 seconds (success: False)
2022-12-27 11:08:44.324 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.002 seconds (success: False)
2022-12-27 11:09:46.049 INFO (MainThread) [homeassistant.components.nibe_heatpump] Fetching Nibe Heat Pump data recovered
2022-12-27 11:09:46.049 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 1.727 seconds (success: True)
2022-12-27 11:10:51.376 ERROR (MainThread) [homeassistant.components.nibe_heatpump] Error fetching Nibe Heat Pump data: Failed to update: Timeout waiting for read response for bt2-supply-temp-s1-40008
2022-12-27 11:10:51.379 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.058 seconds (success: False)
2022-12-27 11:11:56.358 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.037 seconds (success: False)
2022-12-27 11:13:01.369 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.048 seconds (success: False)
2022-12-27 11:14:06.718 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.398 seconds (success: False)
2022-12-27 11:15:11.363 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.042 seconds (success: False)
2022-12-27 11:16:16.375 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.054 seconds (success: False)
2022-12-27 11:17:21.356 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 5.036 seconds (success: False)

Anyway, can I supply some options to the integration to try and raise the default timeout and polling interval? Maybe I will find the right values to get a reliable read out…

There is no option for controlling it. You have to patch the library. Its this line: nibe/nibe/connection at a23b7bd5067dd75e01e6a32d40d646f21d23e53e · yozik04/nibe · GitHubinit.py#L10

Does however feel like something else is going on.

Thanks for the support!

It seems like I have been successfully able to tweak it to have a continuous read out. I will test it more and if it remains stable & reliable I will send in some PR into @yozik04 's library. I had to add a short delay in between of each read_coil and raise the default timeout value a bit.

2022-12-27 15:39:07.943 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 13.826 seconds (success: True)
2022-12-27 15:40:20.774 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 13.658 seconds (success: True)
2022-12-27 15:41:33.898 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 13.780 seconds (success: True)
2022-12-27 15:42:46.749 DEBUG (MainThread) [homeassistant.components.nibe_heatpump] Finished fetching Nibe Heat Pump data in 13.632 seconds (success: True)

At least it looks like it could now be usable like this.

In my opinion raising default timeout to more than 5 seconds is wrong. It is a plenty of time. Short timeout between reads feels also strange as there is a lock that won’t let you to read next until a response for previous is received.

I’m still testing it and trying around what could work… But previously it failed in around 99% of cases, after adding 1 second delay in between each read_coil() it fails in about 50% of cases usually on one specific coil… If I increase the timeout it gets even better but never to 100% success rate and the read out starts to fail on random coils.

Without the added delay it practically could not read anything. Just once in maybe 10-15 minutes it had a successful run.

Currently I’m on default_timeout of 7 s and 1 s delay. This works in about 75% of the time.
The recommendation in the MODBUS 40 manual is timeout of 2,1 seconds. Somewhere on the internet forums I found out someone recommending to use 3 seconds timeout and 1 second delay (which he/she wrote is very important). With 2,1 or 3 s timeout the read out is very unstable for me. But that description was meant for some kind of PLC application…

I think you need to try an another RS485 module… Very suspicious. I am using same lib code and it almost never fails.

And you use it straight with Nibe MODBUS 40 same as me? I thought that serial connection to MODBUS 40 was untested? But sure I can try to get my hands on different USB dongle.

Hi @elupus,

I am not able to find the pump speed in the integration:

Currently I am using this modbus command to get it:

  • name: “Wärmepumpe - Drehzahl Heizungsumwälzpumpe (GP1)”
    unique_id: Nibe.address.1636
    unit_of_measurement: “%”
    data_type: int16
    device_class: power_factor
    address: 1636
    input_type: input
    scale: 1
    precision: 1
    state_class: measurement
    slave: 1

I activated every sensor in the integration with “pump” but I was not able to find it.
Am I blind or is it possible that the GP1 speed sensor is missing?

Thanks

There seem to be another sensor: heating-medium-pump-speed-gp1-31103

Not sure why that sensor you mention is not exported from the pumps.