Modbus write using wrong encoding
elupus opened this issue · comments
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.
@yozik04 can you help me out here. We should be grabbing the coil integer value and splitting it over 16 bit int blocks. Now we sort pass through an array of bytes. I think i missunderstood the API previously.
So we can either use the coil -> bytes, then do bytes -> array of int16, or we do a direct coil -> int16 (taking wordswap into account). Any thoughts?
I am a total noob in TCP modbus. I'd make a small script for testing a single register and checking different inputs/outputs.
There are not many int32 settable registers which would want an array of int16.