veista / nilan

Nilan integration for Home Assistant
Apache License 2.0
50 stars 12 forks source link

CTS700 - what is needed? #19

Open Chrunchy opened 1 year ago

Chrunchy commented 1 year ago

Ive currently added my Air 9 with CTS700 through modbus into HA with the network cable attached to the system. Currently i'm mapping each adress (Mine is a none geo version).

What is needed to add support for CTS700 too?

Mine is currently added to HA:

`modbus:
  - name: nilan
    type: tcp
    host: 192.168.2.217
    port: 502
    sensors:
      - name: nilan_humidity
    # Current humidity
        address: 21776
        unit_of_measurement: "%"
        slave: 1
      - name: nilan_t20_outdoor_temperature
    # Outdoor unit temperatur
        unit_of_measurement: "°C"
        slave: 4
        address: 20688
        count: 1
        scale: 0.1`

etc. etc.

Some data is placed at slave 1 (Indoor unit), and the outdoor unit data is placed on slave 4 for instance. Latest ModBus guide i could find is dated back in 2018, but seems to be working somewhat atleast. https://www.en.nilan.dk/Files/Files/Engelsk/Downloads/7.%20Modbus%20-%20BACnet/2018_04_Modbus_CTS700_Modbus_protokol.pdf

veista commented 1 year ago

Hi,

It's great that you are interested in this project! There are a lot of changes needed to the integration to accommodate cts700. If you are willing to help me with this endeavor I think we can succeed. I have never even seen a cts700 device so you will have to help me with testing, and give me detailed explinations with pictures etc. If needed. Remember that the integration should support all cts700 devices, not just your model/version.

I will start by writing up the registers. After that we will try to figure out how to saftely recognise your device through the integration.

When this is all done we can start adding functionality.

veista commented 1 year ago

Please respond if you are up for this? I can not do this by myself.

Chrunchy commented 1 year ago

I'm definitely up for helping with what i can, but i will have limited time from christmas and untill mid january. Currently i'm importing all registers from nilans documents for the CTS700. Of course i can't test everything as i don't have the geo model as mine is the Air9 with a air to water heatpump for centralheating. It's a limited amount of different registers for the GEO model.

jakobmoll commented 1 year ago

Hi

I'm currently using a manual modbus over tcp configuration for my Nilan Compact P (CTS700). The package I've setup for my integrations is listed here - perhaps this could help?

https://gist.github.com/jakobmoll/96d67a6e3c98b1742230057c5923da63

veista commented 1 year ago

Hi,

I'm at a bit of a loss here.

So I guess the older versions of Compact P use the manual found here https://symlink.dk/stuff/CTS700_MODBUS-rev%202.01.pdf

And the newer versions with Air and Geo support use the manual found in @Chrunchy link.

I'm not sure how to support both, I cannot seem to find a version register on the newer document.

Can you @Chrunchy test register 4632 if you can read the version number?

mbobinac commented 1 year ago

Hi,

i have Nilan CTS700 and looking for integration support. My version is 1.40.05.38 from 2015 and has not been updated since. I have a client app i can login as Installer (uses MODBUS to connect to CTS700) version 1.4.139 from 1.4.2018.

I can connect to CTS700 via the app from my server, but if i use MODBUS tools (Modbus pool) it says read error when connecting to CTS700. Not sure if permission or something else, i need password to login as Installer, but should not need anything to go as User. The Nilan App just does not allow anything else as Installer.

I've installed your HACS code, but when connecting to Nilan says "Invalid Response from Device" which is expected as you probably check some version data in one of the registers.

Cheers

veista commented 1 year ago

Hi. Unfortunately cts700 is not supported. I would like to add it, but it seems to be a mess to implement and I do not have access to one so debugging would be hard.

convicte commented 1 year ago

Hi @veista,

I've ended up purchasing an Elfin EW11A unit to integrate my Compact S pump, but struggle with finding both documentation (modbus registrars for compact S) as well as ready integrations.

If you could advise on what you'd need, I would be happy to at least try.

veista commented 1 year ago

Hi @veista,

I've ended up purchasing an Elfin EW11A unit to integrate my Compact S pump, but struggle with finding both documentation (modbus registrars for compact S) as well as ready integrations.

If you could advise on what you'd need, I would be happy to at least try.

I believe Compact S is a cts602 device so your question is in the wrong place. You can open a discussion, if you need generic help. I can not help with your setup: Read previous issues for hints, follow the instructions on the front page and then we can add Compact S to the supported devices.

lauer commented 1 year ago

Hi @veista I am also using @jakobmoll 's manuel modbud sensor config to interact with my Nilan Compact P Air 9 - CTS700.

Even though python is not my main language, I might be able to help testing and fixing stuff. Right now, the plugin gives the following error when trying to connect

  File "/config/custom_components/nilan/config_flow.py", line 108, in async_step_tcp
    await async_validate_device(
  File "/config/custom_components/nilan/config_flow.py", line 67, in async_validate_device
    result.registers[0].to_bytes(2, "little", signed=False),
    ~~~~~~~~~~~~~~~~^^^
IndexError: list index out of range

But it could be a UnitID problem, because I can't see why it should be 30 as default. If its the same as slave, it should have been '1', but that doesn't work either.

veista commented 1 year ago

Hi,

Cts700 works differently than cts602. I have some modifications to support cts700 in my code, but at the moment absolutely NO functionality has been implemented. I have slowly made it even theoretically possible to support cts700. Adding support will take time and I am a busy man.

Thanks for your understanding, I will report here once there is something to test.

lauer commented 1 year ago

okay, so its not just creating a registry mapping for cts700 like the one for 602? Could you create a branch with you work until now?

veista commented 1 year ago

There is no branch yet. There is no code yet. It is complicated to add since I have not originally thought about adding cts700.

Keep in mind that there is also two types of cts700 as I mentioned before in this issue. Both are completely different.

maisun commented 10 months ago

Hi, I have tried to setup CTS700 myself with OH Modbus integration, I’d like to ask if anybody knows which register to read containing the below info: 1) Compressor state: can be off, defrosting, hot water production, heating, cooling 2) Flag indicate if the supplementary eletrical heater for the water tank is running or not (the red dot on the display) Many thanks!

lauer commented 9 months ago

I know you havn't written that it was ready.

However, I would like to give the new 1.12.13b on my Nilan CompactP Air a try, but I just get "invalid response" with no further log in console, when I try to add the integration.

I fetch data using modbus plugin in HA using the same IP, port and device (1), so I know it answers, but could it give problems, what some processes are already communicating with it?

Please tell me, how I can help testing it?

veista commented 9 months ago

Thanks for your enthusiasm. I will let you know when I need your help. It will take some time to get to that point.

Do you have the old or new cts700?

leonkdk commented 9 months ago

I have a CTS700 Touch. Display Software Version: 09.06.45 (2017-07-08) Print Software Version: 2.02.13.93 (2017-07-08) I am very interested in a working connection to my Home Assistant and as such would like to offer my help as well!

veista commented 7 months ago

I have finally started to create development tools for implementing cts700 devices.

It would be great help if owners of cts700 devices would dump all registers to a file with qmodmaster or equivalent accompanied with device information and a picture of the type plate.

Johannes-288 commented 7 months ago

Hello everyone, here is the yaml in a package of my Nilan Compct P Geo 6, which has already been working for a few weeks! Unfortunately, a few little things are still missing (for example: manual control of fan speed 1-4) A small note: I have translated my yaml from German into English. There might have been mistakes

modbus:

template:

terkilddk commented 6 months ago

I have a CTS700 and a Nilan compact P Air9 and would like to help, i use this config for my modbus connection today. https://pastebin.com/PZNHBRXM

Software is updated to latest version by Nilan last week

I will be happy to help with qmodmaster if someone can guide me.

lauer commented 6 months ago

Same here, however, I only have macs and linux servers, and most of the tools seems to require windows :/

maisun commented 6 months ago

I have a CTS700 and a Nilan compact P Air9 and would like to help, i use this config for my modbus connection today. https://pastebin.com/PZNHBRXM

Software is updated to latest version by Nilan last week

I will be happy to help with qmodmaster if someone can guide me.

Thanks for sharing your config! Have you figured out how to control active cooling? Neither 3284 nor 5288 works for me, already tried to Google for years with no clue....

veista commented 6 months ago

Same here, however, I only have macs and linux servers, and most of the tools seems to require windows :/

What do you mean? For example qmodmaster works on linux and is open source. You just need to compile it yourself.

veista commented 6 months ago

I have a CTS700 and a Nilan compact P Air9 and would like to help, i use this config for my modbus connection today. https://pastebin.com/PZNHBRXM

Software is updated to latest version by Nilan last week

I will be happy to help with qmodmaster if someone can guide me.

What kind of guidance do you need? The software is pretty straight forward.

veista commented 6 months ago

What I need is: 1. dump of all register contents. This can be tedious. 2. A picture of the device type plate. 3. A clear correlation between register in modbus and function in HMI

maisun commented 5 months ago

What I need is: 1. dump of all register contents. This can be tedious. 2. A picture of the device type plate. 3. A clear correlation between register in modbus and function in HMI

Hi @veista : today I tried the tool QModMaster however couldn't really get it to work. I have the "older" version of CTS700 so all registers are below 10000. How can I dump all registers with their contents? It can only read max 100 at a time, and looks to me like if there is any unknown register it will just fail to get the rest values. I think I know the addresses of almost everything except for Active Cooling - the address is not documented in the ModBus technical document, so the best approach is to find a tool that can somehow can dump all registers and compare before/after the change.

veista commented 5 months ago

What I need is: 1. dump of all register contents. This can be tedious. 2. A picture of the device type plate. 3. A clear correlation between register in modbus and function in HMI

Hi @veista : today I tried the tool QModMaster however couldn't really get it to work. I have the "older" version of CTS700 so all registers are below 10000. How can I dump all registers with their contents? It can only read max 100 at a time, and looks to me like if there is any unknown register it will just fail to get the rest values. I think I know the addresses of almost everything except for Active Cooling - the address is not documented in the ModBus technical document, so the best approach is to find a tool that can somehow can dump all registers and compare before/after the change.

As I said this can be tedious. You can write your own dump tool that suits your needs better easily with python.

maisun commented 5 months ago

What I need is: 1. dump of all register contents. This can be tedious. 2. A picture of the device type plate. 3. A clear correlation between register in modbus and function in HMI

Hi @veista : today I tried the tool QModMaster however couldn't really get it to work. I have the "older" version of CTS700 so all registers are below 10000. How can I dump all registers with their contents? It can only read max 100 at a time, and looks to me like if there is any unknown register it will just fail to get the rest values. I think I know the addresses of almost everything except for Active Cooling - the address is not documented in the ModBus technical document, so the best approach is to find a tool that can somehow can dump all registers and compare before/after the change.

As I said this can be tedious. You can write your own dump tool that suits your needs better easily with python.

Ok thanks! I don’t think I have the skills and time for that sadly.

jellevictoor commented 3 months ago

I have everything i could find mapped out for the cts700 for the compact P + geo 3. when reading this i see a correlation between the Air and the geo. the second board is apparently on the modbus ID 4, while the compact p's mainboard is on modbus ID 1.

I'll create a PR with the registers

maisun commented 3 months ago

I have everything i could find mapped out for the cts700 for the compact P + geo 3. when reading this i see a correlation between the Air and the geo. the second board is apparently on the modbus ID 4, while the compact p's mainboard is on modbus ID 1.

I'll create a PR with the registers

Thanks, have you managed to find what register is for controlling active cooling? It's not mentioned in any document I have found from Nilan. Thanks

jellevictoor commented 3 months ago

I have everything i could find mapped out for the cts700 for the compact P + geo 3. when reading this i see a correlation between the Air and the geo. the second board is apparently on the modbus ID 4, while the compact p's mainboard is on modbus ID 1. I'll create a PR with the registers

Thanks, have you managed to find what register is for controlling active cooling? It's not mentioned in any document I have found from Nilan. Thanks

i dont think i have that one exactly. i have 2 documents, one with wrong addresses and no explanation, and one with the right adresses and the correct explanation. WRONG_ADDRESS cts700 description.pdf Modbus_Registers_Description_CTS700.pdf

maisun commented 3 months ago

I have everything i could find mapped out for the cts700 for the compact P + geo 3. when reading this i see a correlation between the Air and the geo. the second board is apparently on the modbus ID 4, while the compact p's mainboard is on modbus ID 1. I'll create a PR with the registers

Thanks, have you managed to find what register is for controlling active cooling? It's not mentioned in any document I have found from Nilan. Thanks

i dont think i have that one exactly. i have 2 documents, one with wrong addresses and no explanation, and one with the right adresses and the correct explanation. WRONG_ADDRESS cts700 description.pdf Modbus_Registers_Description_CTS700.pdf

Thanks for the reply! I have searched for a couple of years and couldn't find out what register they use to control active cooling. Also tried to contact their technical support without luck. My idea is to control active cooling based on temperature and electricity price etc.

jellevictoor commented 3 months ago

i have found multiple documents over the years, over when I even still used openhab. i think i posted everything there then. now i have a lot of info, but my motherboard seems to be losing connection to the controller once and a while. to resolve this i need to physically remove the power cable from the mainboard. i dont really know what is causing this.

FYI, here is my home assistant config atm for a compact p (xl don;t know if that matters) + geo 3 module the ones in comment work, but i didnt need them


  type: tcp
  host: 192.168.1.11
  port: 502
  message_wait_milliseconds: 30
  binary_sensors:
    # - name: Nilan_do1_compressor
    #   address: 5284
    #   input_type: holding
    #   slave: 1
    - name: Nilan_do2_dwh_heater
      address: 5285
      input_type: holding
      slave: 1
    - name: Nilan_dwh_heater_enabled
      address: 3938
      input_type: holding
      slave: 1
    # - name: Nilan_do3_user_select_to_output
    #   address: 5286
    #   input_type: holding
    #   slave: 1
    # - name: Nilan_do4_bypass_damper
    #   address: 5287
    #   input_type: holding
    #   slave: 1
    - name: Nilan_do5_air_heating_valve
      address: 5288
      input_type: holding
      slave: 1
    - name: Nilan_do6_dhw_heating_valve
      address: 5289
      input_type: holding
      slave: 1    
    # - name: Nilan_do7_dhw_preheater_relay
    #   address: 5290
    #   input_type: holding
    #   slave: 1    
    # - name: Nilan_do8_dhw_allow_external_heating
    #   address: 5291
    #   input_type: holding
    #   slave: 1
    # - name: Nilan_di1_high_pressure_switch
    #   address: 5096
    #   input_type: holding
    #   slave: 1
    # - name: Nilan_di2_freeze_overheat
    #   address: 5097
    #   input_type: holding
    #   slave: 1
    # - name: Nilan_di3_user_select
    #   address: 5098
    #   input_type: holding
    #   slave: 1
    # - name: Nilan_di4_deicing_thermostat
    #   address: 5099
    #   input_type: holding
    #   slave: 1
    # - name: Nilan_di5_fire_thermostat
    #   address: 5100
    #   input_type: holding
    #   slave: 1  
    # - name: Nilan_di6_user_select_2
    #   address: 5101
    #   input_type: holding
    #   slave: 1     
    # - name: Nilan_di7_block_cooling_or_heating
    #   address: 5102
    #   input_type: holding
    #   slave: 1 
    # - name: Nilan_di8_brine_pressure_switch
    #   address: 5103
    #   input_type: holding
    #   slave: 1 
    # - name: Nilan_di9_filter_guard
    #   address: 5104
    #   input_type: holding
    #   slave: 1 
    # - name: Nilan_geo_do1_compressor
    #   address: 5284
    #   input_type: holding
    #   slave: 4
    # - name: Nilan_geo_do2_dwh_heater
    #   address: 5285
    #   input_type: holding
    #   slave: 4
    # - name: Nilan_geo_geo_do3_user_select_to_output
    #   address: 5286
    #   input_type: holding
    #   slave: 4
    # - name: Nilan_geo_do4_bypass_damper
    #   address: 5287
    #   input_type: holding
    #   slave: 4
    # - name: Nilan_geo_do5_air_heating_valve
    #   address: 5288
    #   input_type: holding
    #   slave: 4
    # - name: Nilan_geo_do6_dhw_heating_valve
    #   address: 5289
    #   input_type: holding
    #   slave: 4   
    # - name: Nilan_geo_do7_dhw_preheater_relay
    #   address: 5290
    #   input_type: holding
    #   slave: 4  
    # - name: Nilan_geo_do8_dhw_allow_external_heating
    #   address: 5291
    #   input_type: holding
    #   slave: 4
    # - name: Nilan_geo_di1_high_pressure_switch
    #   address: 5096
    #   input_type: holding
    #   slave: 4
    # - name: Nilan_geo_di2_freeze_overheat
    #   address: 5097
    #   input_type: holding
    #   slave: 4
    # - name: Nilan_geo_di3_user_select
    #   address: 5098
    #   input_type: holding
    #   slave: 4
    # - name: Nilan_geo_di4_deicing_thermostat
    #   address: 5099
    #   input_type: holding
    #   slave: 4
    # - name: Nilan_geo_di5_fire_thermostat
    #   address: 5100
    #   input_type: holding
    #   slave: 4  
    # - name: Nilan_geo_di6_user_select_2
    #   address: 5101
    #   input_type: holding
    #   slave: 4     
    # - name: Nilan_geo_di7_block_cooling_or_heating
    #   address: 5102
    #   input_type: holding
    #   slave: 4
    # - name: Nilan_geo_di8_brine_pressure_switch
    #   address: 5103
    #   input_type: holding
    #   slave: 4 
    # - name: Nilan_geo_di9_filter_guard
    #   address: 5104
    #   input_type: holding
    #   slave: 14
  climates:
    - name: Nilan_Temp_DHW_setpoint
      address: 5548
      target_temp_register: 5548
      slave: 1
      data_type: int16
      input_type: holding
      max_temp: 60
      precision: 1
      scale: 0.1
      temperature_unit: C
    - name: Nilan_UserTemperature_setpoint
      address: 4746
      target_temp_register: 4746
      slave: 1
      data_type: int16
      input_type: holding
      max_temp: 33
      precision: 10
      scale: 0.1
      temperature_unit: C
    - name: Nilan_floorTemperature_setpoint
      address: 4746
      target_temp_register: 4746
      slave: 4
      data_type: int16
      input_type: holding
      max_temp: 50
      precision: 10
      scale: 0.1
      temperature_unit: C
  sensors:
    - name: Nilan_Temp_T1_Outdoor
      address: 5152
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 1
      unit_of_measurement: °C
    - name: Nilan_Temp_T2_Supply
      address: 5153
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 1
      unit_of_measurement: °C
    - name: Nilan_Temp_T3_Extract
      address: 5154
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 1
      unit_of_measurement: °C
    - name: Nilan_Temp_T4_Discharge
      address: 5155
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 1
      unit_of_measurement: °C
    - name: Nilan_Temp_T5_Condenser
      address: 5156
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 1
      unit_of_measurement: °C
    - name: Nilan_Temp_T6_Evaporator
      address: 5157
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 1
      unit_of_measurement: °C
    - name: Nilan_Temp_T7_Inlet_air_after_reheating
      address: 5158
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 1
      unit_of_measurement: °C
    - name: Nilan_Temp_T8_Outdoor_air_after_preheating
      address: 5159
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 1
      unit_of_measurement: °C
    - name: Nilan_Temp_T9_water_reheat
      address: 5160
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 1
      unit_of_measurement: °C
    - name: Nilan_Temp_T11_DHW_Top
      address: 5162
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 1
      unit_of_measurement: °C
    - name: Nilan_Temp_T12_DHW_Bottom
      address: 5163
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 1
      unit_of_measurement: °C
    - name: Nilan_Temp_T13_BrineBefore
      address: 5164
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 4
      unit_of_measurement: °C
    - name: Nilan_Temp_T14_BrineAfter
      address: 5165
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 4
      unit_of_measurement: °C
    - name: Nilan_Temp_T15_Room
      address: 5166
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 4
      unit_of_measurement: °C
    - name: Nilan_Temp_T16_BeforeCondensor
      address: 5167
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 4
      unit_of_measurement: °C
    - name: Nilan_Temp_T17_AfterCondensor
      address: 5168
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 4
      unit_of_measurement: °C
    - name: Nilan_Temp_T18_SupplyCentralHeating
      address: 5169
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 4
      unit_of_measurement: °C
    - name: Nilan_Temp_T20_Outdoor
      address: 5171
      data_type: int16
      scale: 0.1
      precision: 2
      input_type: holding
      slave: 4
      unit_of_measurement: °C
    - name: Nilan_param_UserFanSpeed
      address: 4747
      slave: 1
      data_type: int16
      input_type: holding
      offset: -100
    - name: Nilan_param_pause_mode
      address: 4727
      slave: 1
      data_type: int16
      input_type: holding   
    - name: Nilan_humidity
      address: 4716
      slave: 1
      scale: 1
      data_type: int16
      input_type: holding
      unit_of_measurement: '%'
    - name: Nilan_extract_fan
      address: 4700
      slave: 1
      scale: 1
      data_type: int16
      input_type: holding
      unit_of_measurement: '%'
    - name: Nilan_supply_fan
      address: 4699
      slave: 1
      scale: 1
      data_type: int16
      input_type: holding
      unit_of_measurement: '%'
    - name: Nilan_reheating_output
      address: 5374
      slave: 1
      scale: 1
      data_type: int16
      input_type: holding
      unit_of_measurement: '%'      
    - name: Nilan_allow_external_cooling
      address: 5375
      slave: 1
      scale: 1
      data_type: int16
      input_type: holding
      unit_of_measurement: '%' 
    - name: Nilan_pressure_geo
      address: 5272
      slave: 4
      data_type: int16
      input_type: holding
      virtual_count: 12
    - name: Nilan_compressor
      address: 4706
      slave: 1
      data_type: int16
      input_type: holding
      virtual_count: 6
    - name: Nilan_geo_compressor
      address: 4706
      slave: 4
      data_type: int16
      input_type: holding
      virtual_count: 6
    - name: Nilan_4way_valve
      address: 4703
      slave: 1
      data_type: int16
      input_type: holding
    - name: Nilan_bypass1State
      address: 4704
      slave: 1
      data_type: int16
      input_type: holding
    - name: Nilan_operation_mode
      address: 5432
      slave: 1
      data_type: int16
      input_type: holding
    - name: Nilan_geo_operation_mode
      address: 5432
      slave: 4
      data_type: int16
      input_type: holding
    - name: Nilan_filter_in_limit
      address: 1326
      slave: 1
      data_type: int16
      input_type: holding
    - name: Nilan_filter_out_limit
      address: 1327
      slave: 1
      data_type: int16
      input_type: holding
    - name: Nilan_filter_in_days
      address: 1328
      slave: 1
      data_type: int16
      input_type: holding
    - name: Nilan_filter_out_days
      address: 1329
      slave: 1
      data_type: int16
      input_type: holding```

      ```sensor:
  - platform: template
    sensors:
      nilan_operating_mode_text:
          friendly_name: "Nilan Operation mode"
          value_template: >-
            {% set mapper =  {
                '0' : 'Undefined',
                '1' : 'Cooling mode',
                '2' : 'Heating mode',
                '3' : 'Ventilation mode',
                '4' : 'Hot water mode'} %}
            {% set state =  (states('sensor.Nilan_operation_mode')) %}
            {{ mapper[state] if state in mapper else 'Unknown' }}
  - platform: template
    sensors:
      nilan_geo_operating_mode_text:
          friendly_name: "Nilan Geo Operation mode"
          value_template: >-
            {% set mapper =  {
                '0' : 'Undefined',
                '1' : 'Cooling mode',
                '2' : 'Heating mode',
                '3' : 'Ventilation mode',
                '4' : 'Hot water mode'} %}
            {% set state =  (states('sensor.Nilan_geo_operation_mode')) %}
            {{ mapper[state] if state in mapper else 'Unknown' }}

fan:
  - platform: template
    fans:
      ventilation:
        friendly_name: "balansventilatie"
        value_template: >-
          {% if states('sensor.Nilan_param_pause_mode')| int == 0 %} on {% else %} off {% endif %}
        percentage_template: "{{ (states('sensor.nilan_param_userfanspeed') | float) * 25 }}"
        turn_on:
          service: modbus.write_register
          data:
            hub: nilan
            slave: 1
            address: 4727
            value: 0
        turn_off:
          service: modbus.write_register
          data:
            hub: nilan
            slave: 1
            address: 4727
            value: 1
        speed_count: 4
        set_percentage:
          service: modbus.write_register
          data_template:
            hub: nilan
            slave: 1
            address: 4747
            value: "{{ (percentage/25) + 100 }}"
        speed_count: 4```
MarcelPrinsen commented 3 months ago

This modbus protocol also works (file from 2018): 2018_04_Modbus_CTS700_Modbus_protokol.pdf

It is working together with the older version from 2015 in the comment from maisun.