OpenHAB1/2 Nilan heatpump

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:

Heh, not really – it’s open-source community project, I have no ultimate decision power when it comes to contributions :slight_smile:

Perhaps @Confectrician @rossko57 @rlkoshak have more opinions how to organize documentation when it comes to these kind of examples.

That said, I’m happy to review in case you contribute some examples

Unfortunately I’m not all that up to date on how the README.MD file for the binding gets converted to the webpage in the docs. But clearly this problem has been solved in the zwave binding so it shouldn’t be too hard to determine how to do it.

I don’t think there is any set standard for the docs approach in this regard. I personally would just leave it up to you to organize it on one or many pages based on what makes sense to you. As long as the docs include complete and usable information I don’t have an opinion either way.

Jerome might have stronger opinions since he is more hands on on this sort of thing.

1 Like

Specific configurations would best fit as subbapges in my opinion.
They would blew up the docs article too much and are only useful for people who are owning the special device.

To be honest, i am not completely into the process of how zwave is doing this.
I looked at it some time ago, but i would have to work into it too to help out with starting this.

If you can wait some time i would offer my help after i am back from vacation in april.

Maybe I can reply here with my observations relating to Nilan-integration as previous post was moved to area where it wasnt noticed by anyone…Nilan 602/Raspberry/openhab2

Shortly, looking for stable environment for Nilan communication setup on Raspberry3, versions and installations proven to work, aka. “minimal setup”.

I have now installed Openhab2 2.4 from scratch 2 times on Rpi with exactly same results, i.e. Nilan connection does not work. (Python script for connection test works however) These instruction followed: Last line in log is still the same:

2019-03-24 17:04:41.306 [WARN ] [rm.AbstractFileTransformationService] - Could not transform ‘-’ with the file ‘’ : Target value not found in map for ‘-’

First of all…
All warnings about transformation should be ignore in the first place. Transformation is just… transformation. It transformate a value from one text to another text. If your device for some reason does not read the first text, then ofcouse transformation wouldn´t work either. But it has nothing to do with your original problem. It´s just an indication that something else is wrong, in your situation…

It´s very unclear to me, which version of openhab you have installed (how you installed it, ie manual or from an image on an Rpi etc…
Second. It´s unclear which modbus binding you have installed. There are two modbus bindings. So this information is required as well.
Third… You´ll need to post your modbus configuration as well. Without it´s impossible to help.

A common treatment for that would be to edit the file and add a line like
The underlying cause is probably a NULL Item.

Thanks a lot for prompt comments!

Starting from Kim’s reply.

I have version pi@raspberrypi:~ $ openhab-cli info
Version: 2.4.0 (Build)

I Installed it using Package Repository option,
pi@raspberrypi:~ $ cat /etc/apt/sources.list.d/openhab2.list
deb stable main

About MOdbus binding:
Modbus Binding
binding-modbus - 2.4.0

openhab console:
209 ? Active ? 80 ? 2.4.0 ? Modbus Binding
210 ? Active ? 80 ? 2.4.0 ? openHAB MODBUS Transport Bundle

Modbus.cfg copied as such from

Then for rossko57:

You are right, after adding those lines in each of *.map files, no WARNs anymore, last log line is now:

2019-03-24 19:15:26.079 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Error during the execution of startup rule ‘nilan date items concatenation’: For input string: “NULL”