Git Product home page Git Product logo

nibe's Introduction

Test and Lint PyPI - Status PyPI - Downloads PyPI PyPI - License Codecov

Nibe library

Library for communication with Nibe heatpumps.

Supported heatpump models

  • F1145
  • F1155
  • F1245
  • F1255
  • F1345
  • F1355
  • F370
  • F470
  • F730
  • F750
  • S320
  • S325
  • S735
  • S2125
  • SMO20
  • SMO40
  • SMOS40
  • VVM225
  • VVM310
  • VVM320
  • VVM325
  • VVM500

Connection methods

  • RS485 hardwired using NibeGW on Arduino or RPi. NibeGW was developed by Pauli Anttila for Openhab's integration.
  • (Not yet tested) TCP Modbus for S Models
  • (Not yet tested) Serial Modbus for Nibe Modbus 40)

NibeGW

For this connection method to work you will need to connect an Arduino with special firmware that will act as a proxy between Heatpump RS485 and this library. Some details regarding how this method works can be found here.

NibeGW firmware for Arduino or RPi can be download here.

  • Library will open 9999 UDP listening port to receive packets from NibeGW.
  • For read commands library will send UDP packets to NibeGW port 9999.
  • For write commands library will send UDP packets to NibeGW port 10000.

Ports are configurable

import asyncio
import logging

from nibe.coil import CoilData
from nibe.connection.nibegw import NibeGW
from nibe.heatpump import HeatPump, Model

logger = logging.getLogger("nibe").getChild(__name__)

def on_coil_update(coil_data: CoilData):
    logger.debug(coil_data)

async def main():
    heatpump = HeatPump(Model.F1255)
    # heatpump.word_swap = False  # uncomment if you have word swap disabled in 5.3.11 service menu
    await heatpump.initialize()

    heatpump.subscribe(HeatPump.COIL_UPDATE_EVENT, on_coil_update)

    connection = NibeGW(heatpump=heatpump, remote_ip="192.168.1.2")
    await connection.start()

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)

    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.run_forever()

TCP Modbus

With S series heatpumps

import asyncio
import logging

from nibe.coil import CoilData
from nibe.connection.modbus import Modbus
from nibe.heatpump import HeatPump, Model

logger = logging.getLogger("nibe").getChild(__name__)

def on_coil_update(coil_data: CoilData):
    logger.debug(f"on_coil_update: {coil_data}")

async def main():
    heatpump = HeatPump(Model.F1255)
    # heatpump.word_swap = False  # uncomment if you have word swap disabled in 5.3.11 service menu
    await heatpump.initialize()

    heatpump.subscribe(HeatPump.COIL_UPDATE_EVENT, on_coil_update)

    connection = Modbus(heatpump=heatpump, url="tcp://192.168.1.2:502", slave_id=1)

    coil = heatpump.get_coil_by_name('bt50-room-temp-s1-40033')
    coil_data = await connection.read_coil(coil)

    logger.debug(f"main: {coil_data}")

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)

    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.run_forever()

Serial Modbus

With NIBE MODBUS 40

import asyncio
import logging

from nibe.coil import CoilData
from nibe.connection.modbus import Modbus
from nibe.heatpump import HeatPump, Model

logger = logging.getLogger("nibe").getChild(__name__)

def on_coil_update(coil_data: CoilData):
    logger.debug(f"on_coil_update: {coil_data}")

async def main():
    heatpump = HeatPump(Model.F1255)
    # heatpump.word_swap = False  # uncomment if you have word swap disabled in 5.3.11 service menu
    await heatpump.initialize()

    heatpump.subscribe(HeatPump.COIL_UPDATE_EVENT, on_coil_update)

    connection = Modbus(heatpump=heatpump, url="serial:///dev/ttyS0", slave_id=1, conn_options={"baudrate": 9600})

    coil = heatpump.get_coil_by_name('bt50-room-temp-s1-40033')
    coil_data = await connection.read_coil(coil)

    logger.debug(f"main: {coil_data}")

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)

    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.run_forever()

Model auto detection

With NibeGW it is possible to auto identify heatpump model. Heatpump sends information about model every 15 seconds.

heatpump = HeatPump()  # Note that we do not specify model here

# ...

connection = NibeGW(heatpump=heatpump, remote_ip="192.168.1.2")
await connection.start()
heatpump.product_info = await connection.read_product_info()
await heatpump.initialize()

Disclaimer

Nibe is registered mark of NIBE Energy Systems.

The code was developed as a way of integrating personally owned Nibe heatpump, and it cannot be used for other purposes. It is not affiliated with any company, and it doesn't have commercial intent.

The code is provided AS IS and the developers will not be held responsible for failures in the heatpump operation or any other malfunction.

HOWTOs for developers

How to capture and replay traffic from NibeGW

Requirements

APT:

  • tcpdump
  • tcpreplay

On recipient device run:

sudo tcpdump -i eth0 udp port 9999 -w nibe-9999.pcap

tcprewrite --infile=nibe-9999.pcap --outfile=nibe-9999rw.pcap --dstipmap=192.168.1.3:192.168.1.2 --enet-dmac=CC:CC:CC:CC:CC:CC --fixcsum

sudo tcpreplay --intf1=eth0 nibe-9999rw.pcap

You will need to replace IP addresses for rewrite and Mac address of new recipient device

I want to add/update registers in the library

To add/edit registers in the library first of all you need to find documentation how these parameters are officially called. There will be a backward compatibility break if a name will change.

The process contains of mainly next steps: 1. Update source CSV files. 2. Convert CSV files to JSON. 3. Edit extensions.json if needed. 4. Submit PR.

1.A For F series pumps

Use ModbusManager. Do CSV export for the unit you want to update. Find the correct file in nibe/data folder. Merge data into that file (Do not change/update any lines. All CSV files are source files they must not be changed).

1.B For S serires pumps

Change your pump language to English and do registers export. Merge that data into the correct file in nibe/data folder (Do not change/update any lines. All CSV files are source files they must not be changed).

2. Convert source CSV files to JSON

python3 -m nibe.console_scripts.convert_csv

3. Verify JSON files

Verify that convertion was succesful and required lines correctly appeared in the json files. If some modifications are required you need to edit extensions.json to fix these. Do not edit source CSV files.

4. Submit PR

Attach your source CSV file for reference so we could verify as well.

nibe's People

Contributors

andih avatar dependabot[bot] avatar elupus avatar gaaf avatar geekuality avatar husolodge avatar johanschelin avatar kptnhaddock avatar malatg avatar qjkx avatar rasmusbe avatar rwaiboer avatar svollebregt avatar tanelvakker avatar tizianodeg avatar tommatheussen avatar tomrennen avatar vrcif avatar yozik04 avatar zeunerts avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

nibe's Issues

Add support for Energy logs for S series with update

With new firmware there are new power and energy related registers available:

Energy log - Energy produced for heat during current hour	MODBUS_INPUT_REGISTER	2283	100	kWh	6	0	0	0
Energy log - Energy produced for hot water during current hour	MODBUS_INPUT_REGISTER	2285	100	kWh	6	0	0	0
Energy log - Energy produced for pool during current hour	MODBUS_INPUT_REGISTER	2287	100	kWh	6	0	0	0
Energy log - Energy produced for cooling during current hour	MODBUS_INPUT_REGISTER	2289	100	kWh	6	0	0	0
Energy log - Energy used for heat during current hour	MODBUS_INPUT_REGISTER	2291	100	kWh	6	0	0	0
Energy log - Energy used for hot water during current hour	MODBUS_INPUT_REGISTER	2293	100	kWh	6	0	0	0
Energy log - Energy used for pool during current hour	MODBUS_INPUT_REGISTER	2295	100	kWh	6	0	0	0
Energy log - Energy used for cooling during current hour	MODBUS_INPUT_REGISTER	2297	100	kWh	6	0	0	0
Energy log - Energy used by additional heater for heat during current hour	MODBUS_INPUT_REGISTER	2299	100	kWh	6	0	0	0
Energy log - Energy used by additional heater for hot water during current hour	MODBUS_INPUT_REGISTER	2301	100	kWh	6	0	0	0
Energy log - Energy used by additional heater for pool during current hour	MODBUS_INPUT_REGISTER	2303	100	kWh	6	0	0	0
Energy log - Current power consumption	MODBUS_INPUT_REGISTER	2305	100	kW	6	0	0	0
Energy log - Current power consumption, components	MODBUS_INPUT_REGISTER	2307	100	kW	6	0	0	0
i

Full modbus adresses output from SMO S40 (s2125 pump)
modbus_addresses_all_20230218-06765422234035-3.csv

Add support for cooling curve parameters for S series (SMOS40)

Can you please add the cooling parameters for the SMOS40 (curve, etc)

mobus_all_adresses_2023_04_25.xlsx

Min. supply temp. cooling climate system 1 MODBUS_HOLDING_REGISTER 720 1 °C 1 7 30 18
Own curve, cooling P3 MODBUS_HOLDING_REGISTER 721 1 °C 1 7 40 20
Own curve, cooling P5 MODBUS_HOLDING_REGISTER 722 1 °C 1 7 40 20
Cooling connected, climate system 1 MODBUS_HOLDING_REGISTER 726 1 4 0 1 1
Period time cooling MODBUS_HOLDING_REGISTER 736 1 min 4 0 180 30
Cooling delta temp. 20°C MODBUS_HOLDING_REGISTER 738 1 °C 1 3 10 3
Cooling delta temp. 40°C MODBUS_HOLDING_REGISTER 739 1 °C 1 3 20 6
Operating mode circulation pump cooling heat pump 2 MODBUS_HOLDING_REGISTER 831 1 4 0 1 1
Operating mode circulation pump cooling heat pump 1 MODBUS_HOLDING_REGISTER 832 1 4 0 1 1
(SPA), cooling activated MODBUS_HOLDING_REGISTER 849 1 4 0 1 1
Cooling curve climate system 1 MODBUS_HOLDING_REGISTER 967 1 1 0 9 0
Cooling offset climate system 1 MODBUS_HOLDING_REGISTER 975 1 1 -10 10 0
Own curve, cooling P4 MODBUS_HOLDING_REGISTER 976 1 °C 1 7 40 20
Own curve, cooling P2 MODBUS_HOLDING_REGISTER 977 1 °C 1 7 40 20
Own curve, cooling P1 MODBUS_HOLDING_REGISTER 978 1 °C 1 7 40 20

Modbus problem writing negative degree-minutes

It was a problem on 2.4, it's still not working on 2.5.1.

Python 3.9.2, Nibe S320. Tested on 2.4 and 2.5.1

Whenever I try to write degreeminutes field (which is usually negative), it gets stored as 0.
I did some deep-down debugging and it was really weird, as the bytes were similar. If I tried to write what I've received from modbus, the library send the same stream of bytes, and yet value got reset to 0.

I then discovered (by trials and errors, honestly), that if I reverse the list of registers:

connection = Modbus(heatpump=heatpump, url="tcp://" + NIBE_IP + ":502", slave_id=1)
# Patch write method to work with degreeminutes
orig = connection._client.write_registers
connection._client.write_registers = lambda slave_id, starting_address, values: orig(slave_id, starting_address, list(reversed(values)))

then it works... as long as I stay on the same side of 0. That is: if DM are already negative, I can write any negative number correctly. But if they are positive, then writing negative number results in 0. I haven't tried writing positive number when DM is negative.

I really wonder if this is maybe a fault with my heatpump.
But maybe you have an idea what is wrong. s32 type is little tricky. No rush, as the workaround does the trick for me.

Invalid values slip through

Unfortunately we have a regression that now invalid values slip into HomeAssistant:

NibeGw, register address 40016 (EB100-EP14-BT11 Brine Out Temp). Which is signed 16bit.
image

Add support for external energy meter BE6

Got the external pulse energy meter (based on the S0 interface) to work with my Nice S1255-6 PC over modbusTCP and thought I'd share how.

I'm aware that my setting is against the spec, which claims the register to be 398 for BE6, and with an offset of 30001 we should end up at 30399. But the USB-extract retrieved from the pump gives 396, and the respective 30397 works like a charm. So I suspect the spec is in error here. Please consider for a merge.

Here's what I added to s1155_s1255.json:

"30397": {
"title": "Pulse energy meter (BE6/BF2)",
"factor": 100,
"size": "u32",
"unit": "kWh",
"name": "pulse-energy-meter-be6-bf2-30397"
},

Incorrect registers for weather control data (S1155)

I've noticed that any values regarding weather forecast are always null:

Wind speed, weather forecast MODBUS_INPUT_REGISTER 960 10 5 0 0 0
Humidity, weather forecast MODBUS_INPUT_REGISTER 961 10 % 5 0 0 0
Temperature, weather forecast MODBUS_INPUT_REGISTER 962 10 °C 2 0 0 0
Temperature, weather data (forecast) MODBUS_INPUT_REGISTER 963 10 °C 2 0 0 0

While in myuplink something like this is shown:
Screenshot 2024-01-21 at 20 48 56

Does anyone get useful weather data?

F1255 holiday-activated-48043 decoding problems

I failed to deactivate Holiday mode yesterday. It was certainly working before. It might be related to my HeatPump FW update.

Jul 14 11:34:50 smarthomepi python3[992]: 2024-07-14 11:34:50,603 - WARNING  - Ignoring coil 48043 value 01000000 - failed to decode
Jul 14 11:34:50 smarthomepi python3[992]: --- Logging error ---
Jul 14 11:34:50 smarthomepi python3[992]: Traceback (most recent call last):
Jul 14 11:34:50 smarthomepi python3[992]:   File "/smarthome/services/nibe/venv/lib/python3.11/site-packages/nibe/coil.py", line 123, in get_mapping_for
Jul 14 11:34:50 smarthomepi python3[992]:     return self.mappings[str(value)]
Jul 14 11:34:50 smarthomepi python3[992]:            ~~~~~~~~~~~~~^^^^^^^^^^^^
Jul 14 11:34:50 smarthomepi python3[992]: KeyError: '1'
Jul 14 11:34:50 smarthomepi python3[992]: During handling of the above exception, another exception occurred:
Jul 14 11:34:50 smarthomepi python3[992]: Traceback (most recent call last):
Jul 14 11:34:50 smarthomepi python3[992]:   File "/smarthome/services/nibe/venv/lib/python3.11/site-packages/nibe/connection/encoders.py", line 88, in decode
Jul 14 11:34:50 smarthomepi python3[992]:     return CoilData.from_raw_value(coil, value)
Jul 14 11:34:50 smarthomepi python3[992]:            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jul 14 11:34:50 smarthomepi python3[992]:   File "/smarthome/services/nibe/venv/lib/python3.11/site-packages/nibe/coil.py", line 196, in from_raw_value
Jul 14 11:34:50 smarthomepi python3[992]:     return CoilData.from_mapping(coil, value)
Jul 14 11:34:50 smarthomepi python3[992]:            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jul 14 11:34:50 smarthomepi python3[992]:   File "/smarthome/services/nibe/venv/lib/python3.11/site-packages/nibe/coil.py", line 181, in from_mapping
Jul 14 11:34:50 smarthomepi python3[992]:     return CoilData(coil, coil.get_mapping_for(value))
Jul 14 11:34:50 smarthomepi python3[992]:                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jul 14 11:34:50 smarthomepi python3[992]:   File "/smarthome/services/nibe/venv/lib/python3.11/site-packages/nibe/coil.py", line 125, in get_mapping_for
Jul 14 11:34:50 smarthomepi python3[992]:     raise NoMappingException(
Jul 14 11:34:50 smarthomepi python3[992]: nibe.exceptions.NoMappingException: Mapping not found for holiday-activated-48043 coil for value: 1
Jul 14 11:34:50 smarthomepi python3[992]: The above exception was the direct cause of the following exception:
Jul 14 11:34:50 smarthomepi python3[992]: Traceback (most recent call last):
Jul 14 11:34:50 smarthomepi python3[992]:   File "/smarthome/services/nibe/venv/lib/python3.11/site-packages/nibe/connection/nibegw.py", line 281, in read_coil
Jul 14 11:34:50 smarthomepi python3[992]:     return await asyncio.wait_for(future, timeout)
Jul 14 11:34:50 smarthomepi python3[992]:            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jul 14 11:34:50 smarthomepi python3[992]:   File "/usr/lib/python3.11/asyncio/tasks.py", line 479, in wait_for
Jul 14 11:34:50 smarthomepi python3[992]:     return fut.result()
Jul 14 11:34:50 smarthomepi python3[992]:            ^^^^^^^^^^^^
Jul 14 11:34:50 smarthomepi python3[992]:   File "/smarthome/services/nibe/venv/lib/python3.11/site-packages/nibe/connection/nibegw.py", line 432, in _on_raw_coil_value
Jul 14 11:34:50 smarthomepi python3[992]:     coil_data = self.coil_encoder.decode(coil, raw_value)
Jul 14 11:34:50 smarthomepi python3[992]:                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Jul 14 11:34:50 smarthomepi python3[992]:   File "/smarthome/services/nibe/venv/lib/python3.11/site-packages/nibe/connection/encoders.py", line 91, in decode
Jul 14 11:34:50 smarthomepi python3[992]:     raise DecodeException(
Jul 14 11:34:50 smarthomepi python3[992]: nibe.exceptions.DecodeException: Failed to decode holiday-activated-48043 coil from raw: 01000000, exception: Mapping not found for holiday-activated-48043 coil for value: 1

When table read is done then it just ignores:

Jul 14 23:59:57 smarthomepi python3[992]: 2024-07-14 23:59:57,506 - WARNING  - Ignoring coil 48043 value 01000000 - failed to decode
Jul 14 23:59:57 smarthomepi python3[992]: 2024-07-14 23:59:57,507 - WARNING  - Poll holiday-activated-48043 failed: Failed decoding response for holiday-activated-48043: Failed to decode holiday-activated-48043 coil from raw: 01000000, exception: Mapping not found for holiday-activated-48043 coil for value: 1

Modbus write using wrong encoding

Extracted from #50

We are seemingly not providing the write command with an array of int16 values.

Logger: homeassistant.components.websocket_api.http.connection
Source: custom_components/nibe_heatpump/init.py:224
Integration: Home Assistant WebSocket API ([documentation](https://www.home-assistant.io/integrations/websocket_api), [issues](https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+websocket_api%22))
First occurred: 12:06:09 AM (3 occurrences)
Last logged: 12:07:07 AM

[1657699968] The value contained in the request data field is not an allowable value for the server.
Traceback (most recent call last):
File "/usr/local/lib/python3.10/site-packages/umodbus/functions.py", line 1515, in values
struct.pack(">" + conf.MULTI_BIT_VALUE_FORMAT_CHARACTER, value)
struct.error: required argument is not an integer

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 202, in handle_call_service
await hass.services.async_call(
File "/usr/src/homeassistant/homeassistant/core.py", line 1738, in async_call
task.result()
File "/usr/src/homeassistant/homeassistant/core.py", line 1775, in _execute_service
await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 207, in handle_service
await service.entity_service_call(
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 678, in entity_service_call
future.result() # pop exception if have
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 931, in async_request_call
await coro
File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 715, in _handle_entity_call
await result
File "/usr/src/homeassistant/homeassistant/components/number/init.py", line 109, in async_set_value
await entity.async_set_native_value(native_value)
File "/config/custom_components/nibe_heatpump/number.py", line 68, in async_set_native_value
await self._async_write_coil(value)
File "/config/custom_components/nibe_heatpump/init.py", line 304, in _async_write_coil
await self.coordinator.async_write_coil(self._coil, value)
File "/config/custom_components/nibe_heatpump/init.py", line 224, in async_write_coil
coil = await self.connection.write_coil(coil)
File "/usr/local/lib/python3.10/site-packages/nibe/connection/modbus.py", line 110, in write_coil
result = await self._client.write_registers(
File "/usr/local/lib/python3.10/site-packages/async_modbus/core.py", line 233, in write_registers
request = self.protocol.write_multiple_registers(
File "/usr/local/lib/python3.10/site-packages/umodbus/client/tcp.py", line 221, in write_multiple_registers
function.values = values
File "/usr/local/lib/python3.10/site-packages/umodbus/functions.py", line 1517, in values
raise IllegalDataValueError
umodbus.exceptions.IllegalDataValueError: The value contained in the request data field is not an allowable value
for the server.

SMO40 - Filter time: wrong format

I'm using the HA core library made by @elupus. I noticed it exposes the Outdoor filter time parameter (47377). This is exposed as being an enum with either 12 hours or 24 hours selection. This setting however in reality allows any value between 1-48, meaning this currently gets mapped to Unknown if it's not set to either 12 or 24. Is this as easy as updating the respective lines in the data json? Or should the HA Core component handle these types of exceptions to the exports?

F750 Airflow sensors lack of units

Hi, I'm using the NIBE Integration in HomeAssistant. Was wondering why there are no units for the airflow sensors. Couldn't use it for automations and it didn't show a graph.

After a little research I found the problem. The airflow sensors in your F750 file have no units. Should be m3/h. Affects EB100-BS1 Air flow (40050), Airflow ref. (43124) and EB100-BS1 Air flow unfiltered (40051).

Would be nice if you could add it.

Fan speed current shows wrong %

Instead of showing the current % of the fan, it shows a number between 0-4.

eg. if Fan Mode 2 is 30% it shows:
image

I do not see how we can take the current configured % with extensions.json
This would be the best we can do without bigger changes:
image

see also #111

Is the SMO 20 really supported?

So I'm trying to find if I can locally connect to my SMO 20 / F2120. It is mentioned on some places:

  • the yozik04/nibe repo
  • Home Assistant integration, which seems to use your list

If I dig in to the documentation, I go to the NibeGW docs. Here the SMO 20 is not listed anywhere.

I would really love to use the SMO 20 with an ESP/Arduino, but I think it is impossible. I can't find anything about any modbus or RS485 in the installer manual from the SMO 20 / F2120.

TCP Modbus example does not work?

Windows10
Python 3.9
PyCharm

I just got a SMOS40/S2125 installed. I was able to integrate with Home Assistant and get some readings (hence, TCP MODBUS is working).

If I use the README.md TCP Modbus example, I do get errors...and in this example a bit clueless what to change. I literately took README.md, changed to Model.SMOS40 and try to read current-outdoor-temperature-bt1-30002.

I do get the following errors in PyCharm/Windows (I reduced paths a bit to make readable). Any hints appreciated! :) Thanks

DEBUG:asyncio:Using proactor: IocpProactor
DEBUG:nibe.nibe.connection.modbus:Sending read request
DEBUG:sockio.TCP(192.168.1.16:502):open connection (#1)
Traceback (most recent call last):
  File "nibe-s2125\test.py", line 31, in <module>
    loop.run_until_complete(main())
  File "Python39\lib\asyncio\base_events.py", line 647, in run_until_complete
    return future.result()
  File "nibe-s2125\test.py", line 23, in main
    await connection.read_coil(coil)
  File "Python39\lib\site-packages\nibe\connection\modbus.py", line 86, in read_coil
    result = await self._client.read_input_registers(
  File "Python39\lib\site-packages\async_modbus\core.py", line 194, in read_input_registers
    return await self._send_message(request)
  File "Python39\lib\site-packages\async_modbus\core.py", line 142, in _send_message
    return await self.protocol._async_send_message(
  File "Python39\lib\site-packages\async_modbus\core.py", line 39, in send_message_tcp
    await writer.drain()
  File "Python39\lib\site-packages\async_modbus\core.py", line 113, in drain
    await self._write_coro
  File "Python39\lib\site-packages\sockio\aio.py", line 31, in wrapper
    await self.open()
  File "Python39\lib\site-packages\sockio\aio.py", line 287, in open
    self.reader, self.writer = await coro
  File "Python39\lib\site-packages\sockio\aio.py", line 158, in open_connection
    configure_socket(sock, no_delay=no_delay, tos=tos, keep_alive=keep_alive)
  File "Python39\lib\site-packages\sockio\aio.py", line 117, in configure_socket
    sock.setsockopt(socket.SOL_IP, socket.IP_TOS, tos)
  File "Python39\lib\asyncio\trsock.py", line 82, in setsockopt
    self._sock.setsockopt(*args, **kwargs)
OSError: [WinError 10022] An invalid argument was supplied

Signed 8 bit values fails to write to modbus correctly

When writing s8 values to modbus pumps. We end up calling write_coils and write_registers with 8 bits of data. These registers are always 16 bits long, and AsyncModbus prefixes the data with 0000, to extend it to 16 bit. This leads to invalid values for negative numbers.

We must encode all writes to a minimum of 16 bits for coils and holding registers.

Reference: home-assistant/core#101774

erroneous modbus values eb100-beX - NibeGW ESPHOME - F1255

Getting these erroneous values in homeassistant:

INFO (MainThread) [nibe.nibe.connection.nibegw] Coil eb100-be3-current-40079, value: 13107.2
INFO (MainThread) [nibe.nibe.connection.nibegw] Coil eb100-be2-current-40081, value: 65536.0
INFO (MainThread) [nibe.nibe.connection.nibegw] Coil eb100-be1-current-40083, value: 32768.0

Checked the csv and json files for F1255 and they are correct.

It used to work with the same heat pump while using NibePI. So most likely not the heatpump raw values that are incorrect.

Support for S735 wanted

Hi,

Recently installed a Nibe S735 heat pump. I'd very much would like this heat pump to be supported thru the native modbus integration.

Attaching the registerdump. Unfortunately in Swedish. Please respond if you have to have this in English. i suppose I could switch the language on the pump to english temporarily, if that would be of any help.

modbus_addresses_all_20230502-06613223019004-1.csv

Separate coil configuration from data

Right now the coil object database ends up being state-full, with the value being stored in the object loaded by the json database. This make things somewhat tricky to test and can have odd behaviours with the coil value changing behind ones back.

coil = heatpump.get_coil(1234)
coil.value = 1

await asyncio.sleep()
# During the await, we get an out of band update of coil 1234,
# which will revert it's value to what it was before we changes it's value to 1, let's say 0.

# Now we try to write the coil, which have reverted back to 0.
await connection.write_coil(coil)

The coil value should not be stored in the Coil object.

VVM S320 registers missing

I exported my registers from newly installed VVM S320 R and compared it to S320_S235.csv.
It seems to be 76 missing registers.

Haven't used GitHub much so I didn't know how I should add those registers, but here is attached csv which seems to include all previous registers and also 76 new.
Maybe it's possible to add those registers?
modbus_addresses_all_20230118.csv

Parameters with date values are not handled.

We lack parameters for holiday date ranges and the used set values. These also encode a date as part of the numeric value. That seem to be a day offset from "Monday, 1 January 2007".

This is data from nibeuplink for these types of values:

[
  {
    "parameterId": 48043,
    "name": "48043",
    "title": "Holiday",
    "designation": "",
    "unit": "",
    "displayValue": "active",
    "rawValue": 10
  },
  {
    "parameterId": 48044,
    "name": "48044",
    "title": "Holiday",
    "designation": "",
    "unit": "",
    "displayValue": "2023-08-24",
    "rawValue": 6079
  },
  {
    "parameterId": 48045,
    "name": "48045",
    "title": "Holiday",
    "designation": "",
    "unit": "",
    "displayValue": "2023-08-30",
    "rawValue": 6085
  },
  {
    "parameterId": 48047,
    "name": "48047",
    "title": "Holiday",
    "designation": "",
    "unit": "",
    "displayValue": "economy",
    "rawValue": 0
  },
  {
    "parameterId": 48048,
    "name": "48048",
    "title": "Holiday",
    "designation": "",
    "unit": "",
    "displayValue": "speed 2 (30%)",
    "rawValue": 2
  },
  {
    "parameterId": 48051,
    "name": "48051",
    "title": "Holiday",
    "designation": "",
    "unit": "°C",
    "displayValue": "18.0°C",
    "rawValue": 180
  }
]

Also see: elupus/esphome-nibe#37 for reference.

Support for SMOS40 + S2125

The new HA version made me aware of this project.
At this moment, I am directly using the modbus integration to get some values, but this one seems very promising.
But alas, I cannot use the official integration, because I have a newer S series, and tcp/modbus.

Which seems to be listed here as experimental. Great.

I see some install instructions for Docker and PyPi, but not for HA OS.
Can anyone give me some pointers on how to install and try this?

SMO S40 no longer seen after full reset - custom integration

So back in November, I was amoung the ones to beta test the SMO S40, using custom Home Assistant integration.
It was always working, but now after a full factory reset on my SMO S40, I lost all connection.

I did remember to reactivate the Modbus TCP , and in fact I can actually read it usign the Homo Assistant direct modbus integration.

Obvious choice is to delete the device, and re-add it from scratch.
But I am thinking, I probably also want to do that with the. surely by now no longer custom integration.
What is the best way to remove the custom integration from November?

F750 missing fan mode register (maybe?)

I am trying to find out how to set the fan mode on my Nibe F750. I have not been able to do so.
I am not sure, but I suspect this may be because of the missing 47260-register (which is defined for a couple of other pumps).

TCP Modbus s1255

First of all, thank you for your contribution!
I used your example code in readme.md
I tested the TCP modbus with my Nibe S1255 and I had to change read_coil to read_input_registers in the modbus.py file.

S1255 only have registers. And I had to change in the f1255 json-file to match one address. And it worked.

I did not test writing to a holding register.

Decoder error

I've recently updated from 2.4.0 to 2.5.0 because I've seend that modbus s8 handling has been fixed.

However, I've got a following exception:

Traceback (most recent call last):
  File "/home/jacek/dev/smarthome/nibe/nibe_monitor2.py", line 207, in <module>
    loop.run_until_complete(main())
  File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/home/jacek/dev/smarthome/nibe/nibe_monitor2.py", line 88, in main
    data[name] = await connection.read_coil(coil)
  File "/home/jacek/.local/lib/python3.9/site-packages/tenacity/_asyncio.py", line 88, in async_wrapped
    return await fn(*args, **kwargs)
  File "/home/jacek/.local/lib/python3.9/site-packages/tenacity/_asyncio.py", line 47, in __call__
    do = self.iter(retry_state=retry_state)
  File "/home/jacek/.local/lib/python3.9/site-packages/tenacity/__init__.py", line 314, in iter
    return fut.result()
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 433, in result
    return self.__get_result()
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 389, in __get_result
    raise self._exception
  File "/home/jacek/.local/lib/python3.9/site-packages/tenacity/_asyncio.py", line 50, in __call__
    result = await fn(*args, **kwargs)
  File "/home/jacek/.local/lib/python3.9/site-packages/nibe/connection/modbus.py", line 111, in read_coil
    coil_data = self.coil_encoder.decode(coil, result)
  File "/home/jacek/.local/lib/python3.9/site-packages/nibe/connection/encoders.py", line 84, in decode
    value = self.decode_raw_value(coil.size, raw)
  File "/home/jacek/.local/lib/python3.9/site-packages/nibe/connection/encoders.py", line 166, in decode_raw_value
    raw_bytes = [byte for value in raw for byte in value.to_bytes(2, "little")]
  File "/home/jacek/.local/lib/python3.9/site-packages/nibe/connection/encoders.py", line 166, in <listcomp>
    raw_bytes = [byte for value in raw for byte in value.to_bytes(2, "little")]
AttributeError: 'numpy.uint16' object has no attribute 'to_bytes'

Python 3.9.2

Seems that some library returned numpy numbers instead of ints (?).

Coil 47377 failed to decode

In my Home Assistant setup, I'm getting regular warning messages including the following message:

Ignoring coil 47377 value 04006400 - failed to decode

I have a F1245PC model, I think the filter time is currently set to 4 Hours (I will verify later today).

Alarm flipping between 0 and 0.0

Discussed in #97

Originally posted by humbeecc March 12, 2023
Since more than a week, the logbook shows almost every second a "F1145 Alarm changed to 0.0" and "F1145 Alarm changed to 0" message.
The F1145 is connected via the esphome-nibe component.
Maybe some int or float typing issue was introduced lately?

Coil read error (NoneType error)

Nibe 2.5.1
Unfortunatelly, I do not know which coil caused the error.

Traceback (most recent call last):
  File "/home/jacek/dev/smarthome/nibe/nibe_monitor.py", line 215, in <module>
    loop.run_until_complete(main())
  File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/home/jacek/dev/smarthome/nibe/nibe_monitor.py", line 99, in main
    data[name] = await connection.read_coil(coil)
  File "/home/jacek/.local/lib/python3.9/site-packages/tenacity/_asyncio.py", line 88, in async_wrapped
    return await fn(*args, **kwargs)
  File "/home/jacek/.local/lib/python3.9/site-packages/tenacity/_asyncio.py", line 47, in __call__
    do = self.iter(retry_state=retry_state)
  File "/home/jacek/.local/lib/python3.9/site-packages/tenacity/__init__.py", line 314, in iter
    return fut.result()
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 433, in result
    return self.__get_result()
  File "/usr/lib/python3.9/concurrent/futures/_base.py", line 389, in __get_result
    raise self._exception
  File "/home/jacek/.local/lib/python3.9/site-packages/tenacity/_asyncio.py", line 50, in __call__
    result = await fn(*args, **kwargs)
  File "/home/jacek/.local/lib/python3.9/site-packages/nibe/connection/modbus.py", line 111, in read_coil
    coil_data = self.coil_encoder.decode(coil, result)
  File "/home/jacek/.local/lib/python3.9/site-packages/nibe/connection/encoders.py", line 85, in decode
    if self._is_hitting_integer_limit(coil.size, value):
  File "/home/jacek/.local/lib/python3.9/site-packages/nibe/connection/encoders.py", line 99, in _is_hitting_integer_limit
    return int_value >= limit
TypeError: '>=' not supported between instances of 'NoneType' and 'int'

Allow listening to multicast address

It would be nice to configure the gateway device to send to a multicast address.

To make this work properly, the socket needs to be manually constructed and passed to create_datagram_endpoint. This is requires since the standard function will not join multicast addresses, which mean it will not work on setups where switches or wlan access points have igmp snooping enabled.

Reject absurd values on SMO S40

I open this in a new issue, not sure if I am doing right on that. Maybe you want it direct to one of the other S40 threads.
And in fact, I am not even sure if it is an issue in this software, maybe you already do this value sanitation.

But I read the MODBUS directly in HA and I noticed, every time I turn off/on the device, some temperatures' first reported value is -3276.8 Celcius. Scientist would love to get their hands on this device :)

It rather messes up the graphs though. So far, I have removed the values with SQL (see below) but maybe you can pre-empt this and reject any temperatures below 0 Kelvin or something.

image

SELECT * FROM "states" where entity_id like "%BT%" and entity_id like "%temp%" and cast(state as float)<-1000

state_id | domain | entity_id | state
40001087 | NULL | sensor.wp_supply_line_temperature_bt12 | -3276.8 
40001088 | NULL | sensor.wp_return_line_temperature_bt3 | -3276.8
40001151 | NULL | sensor.wp_avg_outdoortemperatur_bt1 | -3276.8

DELETE FROM "states" where entity_id like "%BT%" and entity_id like "%temp%" and cast(state as float)<-1000
DELETE FROM "statistics_short_term" where exists ( select * from statistics_meta B where metadata_id=b.id and b.statistic_id like "%BT%" and b.statistic_id like "%temp%" and cast(min as float)<-1000 )

Duplicate library

Not a real issue. I just found your library while working on my own (https://github.com/elupus/nibeudp). Im thinking of writing a home assistant integration for nibe, (was thinking native instead of mqtt) to at some point replace my nibe uplink one.

Let me know if i can help out in some way. Im elupus on discord, feel free to drop me a pm.

How can i help get S735 into the Nibe integration.

Is their anyway i can help the devs to collect the neccesory information to get a better integration for my Nibe S735. Can also help with testing modbus over TCP and thats how I´m connected today to my Nibe S735.
I´m not a coder but I´m happy to help where ever i can like documentation or anything else.

S1255 Smart price problem

The smart price settings for my S1255 are no longer a switch, they are a select

(SPA), heating activated (SPA)	MODBUS_HOLDING_REGISTER	844	1		4	0	3	1
spa_heating_activated_spa_40845
0 = Off, 1 = Comfort, 2 = Saving, 3 = Saving PLUS

(SPA), hot water activated	MODBUS_HOLDING_REGISTER	846	1		4	0	4	0
spa_hot_water_activated_40847
0 = Off, 4 = Use electricity price only HW

20240130429884

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.