Modbus write_register function code 16 for single value

Hi all,

I am writing a modbus integration for the Itho HRU 400. I have been able to read all the reading registers as sensors in home assistant and use them in a dashboard. Now I want to be able to set the flow of my 4 zones by using an input_number and an automation.

In the documentation of the HRU 400 it says I need to use function code 16 to write to the holding registers. However, function code 16 is for arrays in the modbus integration. Function code 6 is for single values.

In the developer tools I am testing the write_register

service: modbus.write_register
data:
  address: 2210
  unit: 72
  hub: hru400
  value: 140

This sends a write message with function code 6. There is an error returned from the HRU.

2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.transaction] Current transaction state - TRANSACTION_COMPLETE
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.transaction] Running transaction 7698
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.transaction] SEND: 0x48 0x6 0x8 0xa2 0x0 0x8c 0x25 0xb4
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.framer.rtu_framer] Changing state to IDLE - Last Frame End - 1642613164.377034, Current Time stamp - 1642613165.095405
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.client.sync] New Transaction state 'SENDING'
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.transaction] Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.transaction] Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.transaction] RECV: 0x48 0x86 0x1 0x52 0x76
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.framer.rtu_framer] Getting Frame - 0x86 0x1
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.factory] Factory Response[134]
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.framer.rtu_framer] Frame advanced, resetting header!!
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.transaction] Adding transaction 72
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.transaction] Getting transaction 72
2022-01-19 18:26:05 DEBUG (SyncWorker_4) [pymodbus.transaction] Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
2022-01-19 18:26:05 ERROR (SyncWorker_4) [homeassistant.components.modbus.modbus] Pymodbus: hru400: Exception Response(134, 6, IllegalFunction)

Then alternatively, when I try:

service: modbus.write_register
data:
  address: 2210
  unit: 72
  hub: hru400
  value:
    - 140

When I write [140] in the value in the UI, and check the yaml it generates the above. If I send this command with function code 16, it doesn’t generate an error, but it also doesn’t change the flow on the hru 400.

2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.transaction] Current transaction state - TRANSACTION_COMPLETE
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.transaction] Running transaction 6147
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.transaction] SEND: 0x48 0x10 0x8 0xa2 0x0 0x1 0x2 0x0 0x8c 0x6c 0xe4
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.framer.rtu_framer] Changing state to IDLE - Last Frame End - 1642611874.247123, Current Time stamp - 1642611882.312135
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.client.sync] New Transaction state 'SENDING'
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.transaction] Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.transaction] Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.transaction] RECV: 0x48 0x10 0x8 0xa2 0x0 0x1 0xac 0x12
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.framer.rtu_framer] Getting Frame - 0x10 0x8 0xa2 0x0 0x1
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.factory] Factory Response[WriteMultipleRegistersResponse: 16]
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.framer.rtu_framer] Frame advanced, resetting header!!
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.transaction] Adding transaction 72
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.transaction] Getting transaction 72
2022-01-19 18:04:42 DEBUG (SyncWorker_7) [pymodbus.transaction] Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'

I am a bit at a loss of how to get the modbus integration to send the single value with function code 16, like the manual of the device mentions.

Do I need to hack the modbus.py? Or might there be another options?

Ok, I figured out what was wrong. The register is blocked for writing. You first need to disable the valve by sending a [0] command to another register, then change the original setting, and then enable the valve with sending a [1] command.

So in general, it’s easy: to use function code 16 to write to a register, you can just put the decimal value in the array: e.g. [140] for 140m3/h in my case.

Maarten
Can you share your code? I want to write to an OEG boiler and change the temperature limit setting .
Reading the modbus register and storing the data in HA is not a problem, but writing to the register ??
thanks
robert

@RobertDeserranno its described here:
https://gathering.tweakers.net/forum/list_messages/2109156