Issues with WRITE access over Modbus Binding

  • Platform information:
    • Hardware: Raspberry Pi 2 Model B Rev 1.1, 1 GB RAM, 14 GB storage
    • OS: _Linux openhabian 5.15.76-v7+ #1597 SMP Fri Nov 4 12:13:17 GMT 2022 armv7l _
    • Java Runtime Environment: openjdk 11.0.16 2022-07-19, OpenJDK Runtime Environment (build 11.0.16+8-post-Raspbian-1deb11u1), OpenJDK Server VM (build 11.0.16+8-post-Raspbian-1deb11u1, mixed mode)
    • openHAB version: openHAB 3.3.0 - Release Build
  • Issue of the topic:

Hello forum,

I have successfully installed OpenHAB 3 to monitor my Nilan Heatpump. To set-up, I mainly followed the thread here: Nilan heatpump cts 700 - #5 by mRintamaki

I have 54 things with status online and can readout 43 items without errors.

Now I would like to receive the current value of the humidity sensor. Unfortunately, this value is only accessible after providing admin password.

The Nilan modbus protocol CTS700_MODBUS-rev 2.01.pdf gives me Information about addresses and registers.

There I find the following instruction:

vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

(Page 12/106)
2. Introduction
This manual contains information regarding the monitoring and control of Administration level Nilan
NCS700 systems via MODBUS Ethernet. It include short protocol description, registers list and they a
mapping into NCS700 RTDB variables.

The slave device uses 502-nd port for requests receiving.
Modbus of NCS700 support two level of access to registers - the Common level and Administration level.
A access to Administration level registers executed with previous authentication only.
All attempts of access without previous authentication will fault and will return Modbus erro

(Page 13/106)
3.2. Authentication procedure
For receiving access to Administration level registers it is necessary to execute authentication procedure.
This procedure is an operation of password write into special registers.
If procedure is success and password is valid the access into Administration registers will open.
The authentication registers (first register number is 7777) description is placed in paragraph 4.267 [typo].

(Page 66/106)
4.267. Authentication registers
All registers of group are Write-Only and must be preset by one “Preset Multiple Registers” Modbus - function.

7777 (W) - Registers quantity : 8
The authentication string registers:
Reg1 Hi-byte: Password char
Reg1 Lo-byte: Password char
Reg2 Hi-byte: Password char
Reg2 Lo-byte: Password char
.
.
.
Reg8 Lo-byte: Password char
Reg8 Hi-byte: Password char

Note: All unused bytes must be filled by 0 (zero) symbol.

^^^^^^^^^^^^^^^^^^^^^^^

I also considered the documentation of modbus binding in Modbus - Bindings | openHAB

According to the above mentioned thread I supopose the modbus admin passwort is 6699 (or 7675)

So I composed the following lines in my nilan.things file:

vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

  Bridge poller NilanAdmin [ start=7777, length=1, refresh=10000, type="holding" ] {
        Thing data Nilan_Admin [ writeStart="7777", writeTransform="6699", writeMultipleEvenWithSingleRegisterOrCoil="true", writeValueType="int16", writeType="holding" ]
    }

In Browser this line is converted to:

UID: modbus:data:nilan:NilanAdmin:Nilan_Admin
label: Modbus Data
thingTypeUID: modbus:data
configuration:
  readTransform: default
  writeTransform: 0x3636,0x3939,0,0,0,0,0,0
  writeType: holding
  updateUnchangedValuesEveryMillis: 1000
  writeValueType: int16
  writeMultipleEvenWithSingleRegisterOrCoil: "true"
  writeMaxTries: 3
  writeStart: "7777"
bridgeUID: modbus:poller:nilan:NilanAdmin

^^^^^^^^^^^^^^^^^^^^^^^^^^^^

These lines - and several variants thereof - are (obviously) not working and result in an error message “Status: OFFLINE - BRIDGE_OFFLINE - No online bridge

probably relevant lines in openhab.log:

> 2022-11-27 21:08:46.224 [ERROR] [rt.modbus.internal.ModbusManagerImpl] - Last try 3 failed when executing request (ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_MULTIPLE_REGISTERS, start=7777, length=1, maxTries=3]). Aborting. Error was: net.wimpi.modbus.ModbusSlaveException Error Code = 2 [operation ID 3fa59e34-e366-4b54-89c7-916d5282e8cc]

My Questions:

  1. How to I reach all 8 registers at once (both hi- and lo-byte)
  2. How do I transfer the passwort “6699” (characters, not integern!?) to the registers of address 7777?
  3. How do I fill remaining 4(8) registers with 0 (values not characters)
  4. why is […] READ-multiple-register […] mentioned in openhab.log, athough I try a WRITE access?
  5. Or summarizing: What is wrong with my approach?

If I have a general misconception for this in mind, please point me to the right direction :wink:

Thanks in advance for any hints

Rai

One step further:

In my nilan.thing file I change from “Bridge poller” to “Bridge tcp”, so the new line looks like this:

    Bridge tcp NilanAdmin [ start=7777, length=1, refresh=10000, type="holding" ] {
        Thing data Nilan_Admin [ writeStart="7777",  writeTransform="0x3636, 0x3939, 0, 0, 0, 0, 0, 0", writeMultipleEvenWithSingleRegisterOrCoil="true", writeValueType="int16", writeType="holding" ]
    }

Now, there is no error message related to this address anymore (status “online”).

Still I have no access yet to read the address of the humidity sensor

In Nilan Modbus Protocol the description to this sensor is like this:

Page 56/106

4.214. Average value of Humidity sensor. ( VAL_AVERAGE_RH_SENSOR )
4717 (R/W): Registers quantity : 1
The average value of Humidity sensor device: Reg1 Hi-byte: MSB, Reg1 Lo-byte:
Limits (%): 0 ÷ 100

The corresponding lines in my nilan.thing file looks like this:

    Bridge poller NilanHumiditySensorAver [ start=4717, length=1, refresh=10000, type="input" ] {
        Thing data Nilan_Humidity_SensorAver [ readStart="4717", readValueType="uint16" ]
    }

In Browser I receive this error message related to this thing: " Status: OFFLINE - BRIDGE_OFFLINE - No online bridge"

In openhab.log the relevant line is this:

2022-12-04 20:32:44.709 [ERROR] [rt.modbus.internal.ModbusManagerImpl] - Last try 3 failed when executing request (ModbusReadRequestBlueprint [slaveId=1, functionCode=READ_INPUT_REGISTERS, start=4717, length=1, maxTries=3]). Aborting. Error was: net.wimpi.modbus.ModbusSlaveException Error Code = 2 [operation ID 20611bcb-e950-45d7-8360-48931403d604]

To me it looks, as if the address is still locked. Maybe my line for password transfer is still not correct.

What could I try next?

Thanks for any hints.

Rai

This looks to me like it is saying “write 8 registers in one transfer with your 16-character password”.
I would guess in ASCII code.

Your first obstacle appears to be that you don’t have/know a sixteen character password?

The next problem will be that the Modbus binding does not natively support writing a block of 8 registers in one transfer.
But this recent thread explores the same topic

and your requirement looks like a good example of using the transform-to-JSON modbus instruction feature.
You should be able to create a JS transform that takes a 16-char string command and converts to a single FC16 write of 8 registers.

Hello rossko,
thanks for looking at my issue,

Nilan’s modbus protocoll says 8 register and each register has a low byte and a high byte. That gives 16 bytes, equals 16 possible characters…

As I have only 4 characters (“6699”) I need to extend them to “6699000000000000” (but “0” as ASCII character will not convert to 00000000 in binary/byte format. This is not relevant here - right?)

I have seen advanced writing using JSON already, but I have no knowledge with java script so far. If it is necessary, I may try/learn it.

Besides the possible wrong content of writeTransform, do you think the rest of my line is useful?

    Bridge tcp NilanAdmin [ start=7777, length=1, refresh=10000, type="holding" ] {
        Thing data Nilan_Admin [ writeStart="7777",  writeTransform="????????", writeMultipleEvenWithSingleRegisterOrCoil="true", writeValueType="int16", writeType="holding" ]
    }

Thank you very much for your feedback

Rai

This makes me suspect that you do not have the 16-byte/character password that Nilan is talking about.

humm, well I’d guess you’d represent the “6” as ASCII decimal 54, so coding “66” as two ASCII chars in one 16-bit register would be decimal 13878 (256 *54, plus 54).
Then you’d have to decide whether to pad the front or the back of four digits to 16 digits, using decimal 48 (ASCII “0”) or decimal 00 (ASCII nul)

If you want the 8-reg transfer, you must.

Well, you’ve made a write-only data Thing.
When you use the “advanced write” feature by returning JSON from your transform, all the other parameters become irrelevant.

If you want to work through this, there’ll be some trial and error.
It’s actually fairly simple to set up a JS transform to do the same block write whatever command you actually give, but first you’ve got to work out what do. openHAB Modbus environment is not bery helpful for experiments (configuring assumes you know what you are doing) so I would recommend first using a tool like MBpoll to find out what you need.

Nilan are being really weird about security here, generally Modbus has none and relies on protecting your network.