OpenHAB1/2 Nilan heatpump

Check out these instructions… You might want setup udev rules to have fixed name for some specific device

I have succesfully configured the configured the modbus connection to a raspberry pi zero locked inside the heatpump enclosing. I want to get a connection from that PI to another machine running openhab, has anyone had any success accomplishing this? I’ve tried to set up a virtual comport using socat, but all i get is an ‘invalid argument’ error.

Traceback (most recent call last):
  File "", line 5, in <module>
    m = CTS602API('/dev/pts/1') # change appropriately
   File "/home/user/pycts602/", line 19, in __init__
     self.serial.parity = serial.PARITY_EVEN
   File "/home/pi/.local/lib/python2.7/site-packages/serial/", line 335, in parity
   File "/home/user/.local/lib/python2.7/site-packages/serial/", line 438, in _reconfigure_port
      [iflag, oflag, cflag, lflag, ispeed, ospeed, cc])
termios.error: (22, 'Invalid argument')

Hi @epqr ,
this seems like the module you use pycts602 is using minimalmodbus which is using pyserial, which produces that error see github::pyserial::issue196.
Seems to be a RaspberryPi specific issue, which is a little bit off-topic here. Please get yourself involved in the termios ticket/issue.

However: you can consider using mbusd which is a Modbus_Serial->Modbus_TCP software gateway (working on RPi) if Modbus TCP is an option on your client/consumer side.

I just updated my openhab from 2.3 stable to 2.4.0 M8 last night… I did fear that I would run into trouble with the modbus connection to my Nilan Ventilation system with CTS602 interface. And so I did :tired_face:

The old modbus binding is gone, and now there is this new one (i believe they call it modbus2 binding). And its alot different than the old one…

I wonder if anyone could help me or guide me on how to get from the old to the new modbus binding? I´m honestly no good at modbus at all. I understand very little, though I have tried several times. And this new binding didnt make my understanding much better. Infact it got alot worse now, as it seems it requires deep knowlegde of the way modbus is working.

I would highly appreciate any help I can get on this one.

Just (at the morning 20.12.2018) made upgrade from openhab2 to newer version and Nilan sitemap stopped showing data. At the sametime Grafana graphs stoppped.

Tests done

  • = “Connection to the Nilan instrument looks good!”


  • Installed/reinstalled: Map Transformation transformation-map - 2.4.0 (mapping errors in logs)

The Openhab logs doesn’t show (or I don’t watch correct things) nothing special. Will continue and will inform as soon I found something. Open ideas are welcom :grinning:

Which newer openhab version… 2.4 ?
In that case, you´ll need to start all over, cause the old modbus binding is no longer supported in openhab 2.4. You need to use the new modbus binding, which requires alot of changes to your seup…

This thread might give you a clue:

In this thread you´ll be able to follow my transistion from old modbus to the new one with my Nilan Comfort 300LR (Ventilation system), with CTS602 interface.

Thanks! Actually it’s fun to have a little configuration puzzle for holidays.

Yeah, but to warn you. This takes quite some time. Or at least it did/does for me, cause I started all over creating everything from scratch, including learning modbus, as well as running into some issues in the Nilan modbus documentations. Some of the adresses dont work on my Nilan system, even though the documentation says it should. And some adresses requires optional accessories, without specific telling.

That should not be the case. v1 binding should still work, you’d need to (a) turn on OH support for 1.x bindings (b) install the 1.x modbus binding and assiciated modbus.cfg, obviously. I don’t think it’ll coexist with v2 at all, though.

Ahh ofcouse… never thought about that.
Well, I´m on to the latest modbus binding, no need to stay with the old stuff :slight_smile:

Maybe a bit tougher job than I expected for a random copypaste-coder :grin:

I have a strange feeling that I should somehow try to build up my nilan.things combining these:


Thing <binding_id>:<type_id>:<thing_id> “Label” @ “Location” [ ]`

Kim’s example

Thing data hol1001 [ readStart="1001", readValueType="int16", writeStart="1001", writeValueType="int16", writeType="holding", writeMultipleEvenWithSingleRegisterOrCoil="true" ]

What I have in currently in nilan.items

Number Nilan_Input_T0_Controller “Controller board temperature [%.1f °C]” (gNilan) {modbus="<[nilan_input_analogio:0:transformation=JS(nilan_temp_div100.js)]"}



I have learned alot these last few days when I started over… Some I´ll probably change again, cause I started with new items names. And thats was stupid… Dont make the same mistake…

The Thing is build up like the example I´d show. It´s easy, but take some time…

I see you use the original items names as well. Thats good, cause it means you just have to translate “backward”… Start with your item name…


Now find this specific item as the adress in the modbus doc… I can tell you it´s “input register 200” in the Nilan modbus documentation.

This is my Bridge:

Bridge modbus:serial:myNilan [ port="/dev/ttyUSB0", id=30, baud=19200, stopBits="1.0", parity="even", dataBits=8, encoding="rtu" ] {

Notice “myNilan” is a name I choose. It´s needed in the channel for the item.

My Bridge Poller and Thing data file will then look something like this:
(I have done all suitable 200 series adresses for my Nilan system here. Notice!! I dont use 201 cause my Nilan system cant read it. Just concentrate on 200 for this example for an start).

  Bridge poller inputRegisters [ start=200, length=23, refresh=6000, type="input" ] {
      Thing data inp200 [ readStart="200", readValueType="int16", readTransform="JS(divide100.js)" ]
      Thing data inp202 [ readStart="202", readValueType="int16", readTransform="JS(divide100.js)" ]
      Thing data inp203 [ readStart="203", readValueType="int16", readTransform="JS(divide100.js)" ]
      Thing data inp204 [ readStart="204", readValueType="int16", readTransform="JS(divide100.js)" ]
      Thing data inp207 [ readStart="207", readValueType="int16", readTransform="JS(divide100.js)" ]
      Thing data inp208 [ readStart="208", readValueType="int16", readTransform="JS(divide100.js)" ]
      Thing data inp209 [ readStart="209", readValueType="int16", readTransform="JS(divide100.js)" ]
      Thing data inp210 [ readStart="210", readValueType="int16", readTransform="JS(divide100.js)" ]
      Thing data inp215 [ readStart="215", readValueType="int16", readTransform="JS(divide100.js)" ]
      Thing data inp221 [ readStart="221", readValueType="int16", readTransform="JS(divide100.js)" ]

Notice “inputRegisters” and “inp20x” - These are names I choose. They´re needed in the channel for the item.
Also notice that the transform now goes into the Thing data, and not in the item channel.

Next you need to change the channel in your items file for this adress.
This was your old item:

Number Nilan_Input_T0_Controller “Controller board temperature [%.1f °C]” (gNilan) {modbus="<[nilan_input_analogio:0:transformation=JS(nilan_temp_div100.js)]"}

Now change the channel to this:

Number Nilan_Input_T0_Controller “Controller board temperature [%.1f °C]” (gNilan) {channel="modbus:data:myNilan:inputRegisters:inp200:number"}

Notice: “myNilan:inputRegisters:inp200”, these are the names explained above…
Notice also the item type “Number”. Remember to set the channel to the same as well.

Thats it. You have moved “input register adress 200” to the new modbus binding…

Good luck! :wink:

Looks like this nilan device is pretty common and happy to see the community support working here well. If there’s someone who would like to contribute a to implement a device-specific binding to support it, I would be really interested to support and help here.

The new modbus binding was designed with extensibility in mind, and one can build an adapter with somewhat small amount of code on top of the common framework.

The “general” modbus binding is very flexible to support the typical device variations but that also means it has a steep learning curve as discussed here.

1 Like

My Nilan Comfort 300LR ventilation device works great with the new modbus binding.


Hi Sami,
That would be awesome and would probably omit some of the most common problems with the device (i.e. setup of variables) and additionally provide a common base.
Any links to get one started?

Hi Kim, any config (modbus.things or items) to share?

Yes, that was my plan as I promised Sami some time ago …

I just need to figure how to edit the manual page, and how Sami would like it. I have a full setup for the Nilan Comfort 300LR incl .things, items, sitemap, maps and rules.

I wonder if the best option is to do it like Chris has done the z-wave manual?
Or what do you think, @ssalonen?

1 Like

@nickma82 to get started with device bindings using modbus : this is a good example. Here the device is discovered / detected automatically but that is optional.

1 Like

I’m not sure about documentation… Sub pages might make sense since that will add a lot of content.

Btw, Zwave documentation is generated based on device database entries, but I guess it does not matter for this conversation

It´s all up to you… The files for the Nilan Comfort 300LR (CTS602 interface) are rather big…

I just took a short look at how to edit the docs… I must admit, I have no idea how to… Ended up with something about Fork on Github, and I have no idea what it is :slight_smile: