Nilan heatpump cts 700

You might be right, but I have a couple of reasons to believe that your assumption is wrong:

  • The document I linked to above is titled “CTS700 Modbus Registers Description” (and has the correct register addresses for the items above).
  • When I look at nilan.dk download archives for the Compact P (the model I have), there are several documents regarding different software versions, but there is only CTS-602 and CTS-700.
  • When Googling NCS700, the only thing I have found related to Nilan is in a draft version of “CTS700 Modbus Registers Description” from 2014, where there are references to three documents called something like NCS700 Events and NCS700 Modbus Registers (dated 2011/2012).

This leads me to believe that NCS-700 is either an internal name for the CTS700, or is the name of the raw circuit board where CTS700 is the controller board (with components).

Can someone here add any information, like if you have a CTS700, what hardware and software information is reported by the system?

Hi
thank you for sharing your config, this does work for me. I find the same document with the wrong Modbus addresses (20140520) and the link you supplied is no longer working.
I’m wondering, what is the closest you got to the official documentation? Could you please add a working link so I could look into it a bit further?
I’m super thrilled this works!

I contacted Nilan support and got a much more complete protocol. Unfortunately there are still some things that are not available via modbus, but apart from the temperatures I can now read out the filter replacement warnings, change the fan speed and temperature setpoint, etc.

Unfortunately, sometimes the network connection is not working (even the link-beat LED on the switch turns off). The connection is re-established after a while, sometimes a day, sometimes several days. It would be nice to know if this is a general problem, of if there is something wrong with my Nilan control board (sometimes the display also looses connection).

I will try to find the time to update this thread with my current configuration. Unfortunately I am currently very busy.

can you share the documentation? if you have the addresses, I can move on :slight_smile:
i have found this document www.nilan.de/Admin/Public/Download.aspx?File=Files%2FFiler%2FDownload%2FFrench%2FDocumentation%2FGuide+dutilisation%2FModbus+CTS+700%2FModbus_Registers_Description_CTS700.pdf

the addresses are equal to the ones you are using, I’ll move further with this in the meanwhile.

I have found some addresses that work, but really a lot of them are not working, so I’m very interested where you are. I could scrape the Modbus registers, but it is nearly impossible to start identifying values without context with reverse engineering. The only guide is the values on the display, but I have seen they are not as accurate as of the values in the Modbus registers (rounding etc)

Which modbus binding and OH version do you use?
I have had no serious issues using USB FDI serial or RS485<>ethernet for my CTS602 board. But I know there has been some updated for the modbus binding, which infact will crash.
Atm I´m running OH 2.5.10 with modbus binding 2.5.10 as well.

I am also on 2.5.10 for both OH and binding. However, this is very different from your setup, because it is modbus TCP directly to the Ethernet port on CTS700. And when the network connection disappears, even the LED on the Ethernet switch port where the Nilan CTS is connected turns off (as I wrote, no link-beat).

So I don’t think this is related to the modbus binding.

But finding out if the problem is instability in my CTS700 board, or a software problem (on the CTS700) would be nice.

Ahh sorry, totally missed that part that you´re running direct ethernet.
I would say its an defective CTS board, specially when you mention the display turns off as well. That should never happen.

I did a full readout from address 0 to address 11000 and i got these readings back, and mapped them on the documentation of nilan. I also have addresses where there i no reference in the documentation, but i get a reading back.

The temp sensors of my geo pump are not filled (all inidcate 0 instead of a temp value), which is a bummer tbh.

In the range 10000 - 11000 there are some values, but i don’t have any ideas what they could mean.

did i help someone with this?

1047 System's working mode
1323 Compressor's control for DHW
1325 Buzzer mode
1326 Inlet filter's Time threshold
1327 Outlet filter's Time threshold
1328 Pass days for Inlet software filter
1329 Pass days for Outlet software filter 
2402 The Force Operation mode
2403 The Inlet temperature Max
register 2404 The summer Inlet temperature Min
register 2405 The winter Inlet temperature Min
register 2406 The Setpoint of Sum/Win selecting
register 2407 The Offset of Sum/Win selecting
register 2828 Max. of DHW temperature
register 2836 Duration of Extended operation 1
register 2841 Duration of Extended operation 2 
register 3153 has value [0]
register 3154 has value [0]
register 3155 has value [0]
register 3156 has value [1]
register 3157 has value [2]
register 3158 has value [2]
register 3159 has value [1]
register 3160 has value [1]
register 3161 has value [1]
register 3162 has value [2]
register 3163 has value [2]
register 3164 has value [1]
register 3256 Allow the user to Stop system
register 3259 Timeout of Buffer tank electric heater enabling
register 3260 Level of BD back light
register 3261 Timeout of BD sleeping (back light switch off)
register 3935 DHW min. supply limit
register 3938 DHW heater enable
register 3941 Anti-Legionella mode
register 3942 Start Hour of Anti-Legionella mode.
register 3951 BD work interface language
register 3953 Circuital pump default flow
register 4090 Compressor out door low limit
register 4094 Circuital pump speed for Cooling mode
register 4104 has value [1]
register 4233 DHW sacrificial anode protection
register 4235 Events list sort mode
register 4689 Control of Air Damper 1 switch
register 4690 Control of Air Damper 2 switch
register 4691 Control of Air Damper 3 switch
register 4692 Deterioration of Inlet filter
register 4693 Deterioration of Outlet filter
register 4699 Control of Inlet Fan
register 4700 Control of Outlet Fan
register 4701 Control of Heater
register 4703 Control of 4Way
register 4704 Control of Bypass1
register 4705 Control of Bypass2
register 4706 Control of Compressor1
register 4707 Control of Compressor2
register 4708 Control of Compressor3
register 4709 Control of Compressor4
register 4710 Control of Compressor5
register 4711 Control of Compressor6
register 4712 Value of CO2 sensor
register 4713 Value of BD temperature sensor
register 4715 Control of BypassDamper
register 4716 Value of Humidity sensor
register 4727 Pause mode enable
register 4746 User setpoint value
register 4747 User Fan speed setting
register 4748 Anti-Legionella mode activity
register 4749 Anti-Legionella mode force
register 4756 Inlet filter reset
register 4757 Outlet filter reset


register 5019 Heater external state
register 5021 BD TPanel temperature sensor state
register 5059 Anti-Legionella mode activity for Solar
register 5088 Temperature of Master sensor
register 5096 DI value 1
register 5097 DI value 2
register 5098 DI value 3
register 5099 DI value 4
register 5100 DI value 5
register 5101 DI value 6
register 5102 DI value 7
register 5103 DI value 8
register 5104 DI value 9
register 5105 DI value 10
register 5132 AI value 1
register 5133 AI value 2
register 5134 AI value 3
register 5135 AI value 4
register 5136 AI value 5
register 5137 AI value 6
register 5138 AI value 7
register 5139 AI value 8
register 5140 AI value 9
register 5152 Temperature sensor 1
register 5153 Temperature sensor 2
register 5154 Temperature sensor 3
register 5155 Temperature sensor 4
register 5156 Temperature sensor 5
register 5157 Temperature sensor 6
register 5158 Temperature sensor 7
register 5159 Temperature sensor 8
register 5160 Temperature sensor 9
register 5161 Temperature sensor 10
register 5162 Temperature sensor 11
register 5163 Temperature sensor 12
register 5164 Temperature sensor 13
register 5165 Temperature sensor 14
register 5166 Temperature sensor 15
register 5167 Temperature sensor 16
register 5168 Temperature sensor 17
register 5169 Temperature sensor 18
register 5170 Temperature sensor 19
register 5171 Temperature sensor 20
register 5172 Temperature sensor 21
register 5173 Temperature sensor 22
register 5174 Temperature sensor 23
register 5175 Temperature sensor 24
register 5176 Temperature sensor 25
register 5177 Temperature sensor 26
register 5178 Temperature sensor 27
register 5179 Temperature sensor 28
register 5180 Temperature sensor 29
register 5181 Temperature sensor 30
register 5182 Temperature sensor 31
register 5183 Temperature sensor 32
register 5184 Temperature sensor 33
register 5185 Temperature sensor 34
register 5186 Temperature sensor 35
register 5187 Temperature sensor 36
register 5188 Temperature sensor 37
register 5189 Temperature sensor 38
register 5190 Temperature sensor 39
register 5191 Temperature sensor 40
register 5192 Temperature sensor 41
register 5193 Temperature sensor 42
register 5194 Temperature sensor 43
register 5195 Temperature sensor 44
register 5196 Temperature sensor 45
register 5197 Temperature sensor 46
register 5198 Temperature sensor 47
register 5199 Temperature sensor 48
register 5200 Temperature sensor 49
register 5201 Temperature sensor 50
register 5272 Pressure sensor 1
register 5273 Pressure sensor 2
register 5274 Pressure sensor 3
register 5275 Pressure sensor 4
register 5276 Pressure sensor 5
register 5277 Pressure sensor 6
register 5278 Pressure sensor 7
register 5279 Pressure sensor 8
register 5280 Pressure sensor 9
register 5281 Pressure sensor 10
register 5282 Pressure sensor 11
register 5283 Pressure sensor 12
register 5284 Digital output 1
register 5285 Digital output 2
register 5286 Digital output 3
register 5287 Digital output 4
register 5288 Digital output 5
register 5289 Digital output 6
register 5290 Digital output 7
register 5291 Digital output 8
register 5292 Digital output 9
register 5293 Digital output 10
register 5367 Digital output 40
register 5372 Analog output 1
register 5373 Analog output 2
register 5374 Analog output 3
register 5375 Analog output 4
register 5376 Analog output 5
register 5432 Current regulation mode
register 5450 Current phase of defrosting
register 5468 Control of Pre-Heater
register 5470 Control of BA HEX
register 5474 Control of Pump1
register 5475 Control of Pump2
register 5476 Control of Pump3
register 5516 Temperature 40 sensor as Digital Input
register 5517 Temperature 41 sensor as Digital Input
register 5518 Temperature 42 sensor as Digital Input
register 5519 Temperature 43 sensor as Digital Input
register 5520 Temperature 44 sensor as Digital Input
register 5521 Temperature 45 sensor as Digital Input
register 5522 Temperature 46 sensor as Digital Input
register 5523 Temperature 47 sensor as Digital Input
register 5524 Temperature 48 sensor as Digital Input
register 5525 Temperature 49 sensor as Digital Input
register 5526 Temperature 50 sensor as Digital Input
register 5539 Hardware version
register 5548 User DHW setpoint value

Sorry about the late reply.

Since I did not have to sign any NDA or similar, and the document does not in any way indicate that it is restricted information, I guess it is not a problem to share it. Unfortunately it is too big 1.57MB to upload it here. I will upload and host it on my own server and post a link here, but I don’t have time right now. @Jelle_Victoor: If you are eager, drop me a PM with your email address, and I will send it to you.

But I can tell you that registers 10000-10256 are event log registers.

I also created a Python script for scraping the registers. I made it work with the authentication procedure, so it can read out the admin registers as well. And making a full dump of all the registers, then changing a value on the display, and making a new dump, and comparing with a diff tool has helped me understand a few things.

For instance it turns out the fan speed setting in register 4747 is set to 101 for step 1, 102 for step 2, etc., and not 20-100% as the documentation states. I have the following in my sitemap:

Switch  item=Nilan_User_Fan_speed icon="fan" mappings=[ 101="1", 102="2", 103="3", 104="4"]

I am a little limited by the 4 steps. I would like to have the following:
1=low ventilation, e.g. house unoccupied or low humidity
2=normal ventilation
3=normal boost, e.g. when humidity rises (shower)
4=high boost, e.g. activated for a couple of hours after hanging clothes on the line
5=max inlet, min outlet, to be used with the range hood is used during cooking.

It may be possible to achieve this with one of the user modes. It looks like the documentation says you can set the inlet and extract speed separately, but this may no longer be accurate, as the user interface seems to set one of the 4 ventilation steps for the user modes. Also, I have not found a way to activate the two user modes from the CAN interface, so maybe I have to connect a few relays to the inputs.

@Jelle_Victoor: Do you have any problems with loosing the network connection from time to time?

Hi
In meanwhile I reversed engineered the interface as much as possible, also by scraping. I found a lot when I learned that all the geo info was on slave 4 instead of slave 1.
I do not have any issues with network stability. I am afraid this is something on your side.
I also have python scripts that scrape the interface, the admin interface and authentication i have not used yet, at this point. I’ll drop you a DM for my email address.

I currently have this

Here is the script I use to read out the registers:

#!/usr/bin/env python3
# Mikkel Holm Olsen, 2020

from pyModbusTCP.client import ModbusClient
import time

modbus = ModbusClient(host="10.0.0.107", port=502, unit_id=1, auto_open=True)

# Use the admin password "6699" for authentication.
if not modbus.write_multiple_registers(7777, [0x3636, 0x3939, 0, 0, 0, 0, 0, 0]):
  print("Error auth");
  exit(0)

# I guess we already know this...
admin_pwd = modbus.read_holding_registers(1352, 8)
print("admin "+(" ".join(map("{:02X}".format, admin_pwd))))

install_pwd =modbus.read_holding_registers(1360, 8) 
print("install "+(" ".join(map("{:02X}".format, install_pwd))))

superusr_pwd =modbus.read_holding_registers(1368, 8) 
print("super "+(" ".join(map("{:02X}".format, superusr_pwd))))

for reg in range(1, 10500):
  vals = modbus.read_holding_registers(reg, 1)
  if vals:
    val = vals[0]
    print('{0:5d} 0x{1:04X} {1:5d}'.format(reg,val))  
  else:
    print('{0:5d} err'.format(reg))  
  time.sleep(0.02)

Notice that some registers need to be read in one go, and will otherwise return an error (this is the case for the authentication registers).

I think I need to get in touch with Nilan regarding the network problems :frowning:

i see you are not closing your modbus connection, i had some issues when i did not close it, causing the nilan to be unstable.
have you tried closing it after each execution?

Do you mean each execution of the script, or each request from OH?

The connection is closed when script is done. The script is just run manually from the command line. And when I have been using the script, I have had OpenHab disabled, to not cause problems.

In OH I just use the modbus binding, with configuration similar to the snippet in a previous post. I have not tried to get authentication to work from OH, because I have not found a use for changing any admin registers from OH, but I’m guessing it would be possible from a rule to execute the authentication sequence (writeMultipleRegisters).

Regarding the network problems, since the LED on the network switch turns off, this seems to be a problem with the hardware. I will contact Nilan support and ask if they have any suggestions.

Kim, a bit off-topic, but I have been following your various posts and have earlier successfully implemented Openhabian for a Nilan with CTS602 following your guides. However when trying to connect Openhabian to Google Home I have invanely tried to make the “Fan Speed” controllable this way. Could you possibly share your items file code for this functionality? I can connect to Google Home, but have not been able to find the code for a multi-value setting (“0”, “1”, “2”, “3”, “4”).
Thanks in advance :slight_smile:

You cant do it in one go. You´ll need to define each step as proxy switchs, and then tell google to turn on “step 1”. After that I run a small rule which set the actual step ON and the others off. Its not a nice rule, and could probably be better. I just made it very fast:

This is my items (proxy switches):

Switch  nilanVent0    "Ventilation trin 0 [%s]" 	 <switch> 	(gVentState)    { ga="Fan" }
Switch  nilanVent1    "Ventilation trin 1 [%s]" 	 <switch> 	(gVentState)    { ga="Fan" }	
Switch  nilanVent2    "Ventilation trin 2 [%s]" 	 <switch> 	(gVentState)    { ga="Fan" }	
Switch  nilanVent3    "Ventilation trin 3 [%s]" 	 <switch> 	(gVentState)    { ga="Fan" }	
Switch  nilanVent4    "Ventilation trin 4 [%s]" 	 <switch> 	(gVentState)    { ga="Fan" }	

This is my rule:

rule "Nilan ventilation trin 0"

when
    Item nilanVent0 changed from OFF to ON
then
	Nilan_Control_VentSet.sendCommand(0)
end


rule "Nilan ventilation trin 1"

when
    Item nilanVent1 changed from OFF to ON
then
	Nilan_Control_VentSet.sendCommand(1)
end


rule "Nilan ventilation trin 2"

when
    Item nilanVent2 changed from OFF to ON
then
	Nilan_Control_VentSet.sendCommand(2)
end


rule "Nilan ventilation trin 3"

when
    Item nilanVent3 changed from OFF to ON
then
	Nilan_Control_VentSet.sendCommand(3)
end


rule "Nilan ventilation trin 4"

when
    Item nilanVent4 changed from OFF to ON
then
	Nilan_Control_VentSet.sendCommand(4)

end

 

rule "Manual ventilation steps"

when
      Item Nilan_Control_VentSet changed 
then

if(Nilan_Control_VentSet.state == 4)   {
        logInfo("debug", "Vent 4 ON all others OFF")
	 nilanVent4.postUpdate(ON)
         nilanVent0.postUpdate(OFF)
         nilanVent1.postUpdate(OFF)
         nilanVent2.postUpdate(OFF)
         nilanVent3.postUpdate(OFF) 

   }
else
if(Nilan_Control_VentSet.state == 3)   {
	 nilanVent3.postUpdate(ON)
         nilanVent0.postUpdate(OFF)
         nilanVent1.postUpdate(OFF)
         nilanVent2.postUpdate(OFF)
         nilanVent4.postUpdate(OFF) 
        logInfo("debug", "Vent 3 ON all others OFF")
   }
else
if(Nilan_Control_VentSet.state == 2)   {
	 nilanVent2.postUpdate(ON)
         nilanVent0.postUpdate(OFF)
         nilanVent1.postUpdate(OFF)
         nilanVent3.postUpdate(OFF)
         nilanVent4.postUpdate(OFF) 
        logInfo("debug", "Vent 2 ON all others OFF")
   }
else
if(Nilan_Control_VentSet.state == 1)   {
	 nilanVent1.postUpdate(ON)
         nilanVent0.postUpdate(OFF)
         nilanVent2.postUpdate(OFF)
         nilanVent3.postUpdate(OFF)
         nilanVent4.postUpdate(OFF)
        logInfo("debug", "Vent 1 ON all others OFF") 
   }
else
if(Nilan_Control_VentSet.state == 0)   {
	 nilanVent0.postUpdate(ON)
         nilanVent1.postUpdate(OFF)
         nilanVent2.postUpdate(OFF)
         nilanVent3.postUpdate(OFF)
         nilanVent4.postUpdate(OFF) 
        logInfo("debug", "Vent 0 ON all others OFF")
   }

end

As said, the rule is not nice. But it works :smiley:

Many thanks for your time and efforts Kim :grinning: I added the items lines to my Nilan.items file, and as I have not used rules before, created a file called Nilan.rules in the rules folder, and added your lines. When opening Google Home the five new switches popped up perfectly. However, when trying to click one of the switched I get these messages "“opretter forbindelse” (connecting), “Svarer ikke” (No reply) and the switch appears with the text “Offline” / “Fra” underneath. This looops indefinetely but never turns “On”.
Probably it is something trivial missing on my side. I guess it might have something to do with the rules file not executing the rules. Also I guess .sitemap and .things files does not need new entries here for this to work? :blush:

Struggled some time and suddenly it worked. Fantastic!!
Many thanks for helping :grinning:

1 Like

Glad you got it working! :+1:

OK, finally got around to uploading the CTS700 protocol to my webserver, as promised. For those interested, you can find it here:

@Mogens_Lunde, @Kim_Andersen: Please start a new thread or use PM if you have a question that is not related to this thread.

1 Like

I contacted Nilan after-sales support, and they assumed it was a problem with the power supply (apparently a known problem on some Nilan systems), so they sent a service technician. He made a modification to the power supply, and the problem is gone now (no issues for 23 days, whereas the previous month I had 10 periods of network issues, ranging from 6 hours to 3½ days) :smiley:

Hats off to Nilan who fixed the problem without charging me, even for a system that is more than 5 years old.

So I guess I can finally get on with actually controlling the system from OH. Until now I have only been logging data, because the network instability made me reluctant to change settings (e.g. turn down the ventilation when leaving the house, but if network stops responding, ventilation could not be turned up again when someone arrived back home).

1 Like