Ok thx. Did some yaml tinkering and got it working. To save people from cursing the YAML language here is the Duco specific block in my configuration.yaml. This could be split up in different files but enough yaml for one day
Changed your example to the new home assistant yaml standard, changed the enity type for CO2 and relative humidity, added some comments and grouped things together per node so you can easily copy paste to add more nodes (valves) :
#duco stuff
#replace the XXX.XXX.XXX.XXX with the ip adress of the connectivity board in your duco box
#get info from all nodes trough the api and create the sensors
rest:
resource: https://XXX.XXX.XXX.XXX/info/nodes
scan_interval: 2
verify_ssl: false
sensor:
#node 1 is the ducobox itself
- unique_id: ducobox_node1_state
name: Ducobox - Status
value_template: "{{ value_json['Nodes'][0]['Ventilation']['State']['Val'] }}"
- unique_id: ducobox_node1_FlowLvlTgt
name: Ducobox - Flow Level Target
value_template: "{{ value_json['Nodes'][0]['Ventilation']['FlowLvlTgt']['Val'] }}"
unit_of_measurement: "%"
- unique_id: ducobox_node1_TimeStateRemain
name: Ducobox - tijd status resterend
value_template: "{{ value_json['Nodes'][0]['Ventilation']['TimeStateRemain']['Val'] }}"
- unique_id: ducobox_node1_TimeStateEnd
name: Ducobox - tijd status eind
value_template: "{{ value_json['Nodes'][0]['Ventilation']['TimeStateEnd']['Val'] }}"
#node2 (in my case bathroom with CO2 and relative humidity)
#-------------
- unique_id: ducobox_node2_state
name: Ventilatie node2 - status
value_template: "{{ value_json['Nodes'][1]['Ventilation']['State']['Val'] }}"
- unique_id: ducobox_node2_iaqrh
name: Ventilatie node2 - IAQRh
value_template: "{{ value_json['Nodes'][1]['Sensor']['IaqRh']['Val'] }}"
device_class: humidity
unit_of_measurement: "%"
- unique_id: ducobox_node2_iaqCO2
name: Ventilatie node2 - IAQCO2
value_template: "{{ value_json['Nodes'][1]['Sensor']['IaqCo2']['Val'] }}"
device_class: carbon_dioxide
unit_of_measurement: "%"
- unique_id: ducobox_node2_FlowLvlTgt
name: Ventilatie node2 - Flow Level Target
value_template: "{{ value_json['Nodes'][1]['Ventilation']['FlowLvlTgt']['Val'] }}"
unit_of_measurement: "%"
- unique_id: ducobox_node2_TimeStateRemain
name: Ventilatie node2 - tijd status resterend
value_template: "{{ value_json['Nodes'][1]['Ventilation']['TimeStateRemain']['Val'] }}"
- unique_id: ducobox_node2_TimeStateEnd
name: Ventilatie node2 - tijd status eind
value_template: "{{ value_json['Nodes'][1]['Ventilation']['TimeStateEnd']['Val'] }}"
#------------------
#add the other nodes you have on your system below here by copy pasting the block above,
#leave out the IaqRh sensor for valves that have CO2 only
#fans platform, add all nodes
fan:
- platform: template
fans:
ducobox:
unique_id: "ducobox_ventilatie_control"
friendly_name: "Ducobox"
value_template: >
{% if states('sensor.ducobox') != 'AUTO' %}
on
{% else %}
off
{% endif %}
turn_on:
- service: rest_command.ducobox_mode_change
data:
nodeId: "1"
state: MAN3
turn_off:
- service: rest_command.ducobox_mode_change
data:
nodeId: "1"
state: AUTO
preset_modes:
- "Auto"
- "Permanent manual 1"
- "Permanent manual 2"
- "Permanent manual 3"
- "Manual 1"
- "Manual 2"
- "Manual 3"
preset_mode_template: >
{% if states('sensor.ducobox') == "CNT1" %}
Permanent manual 1
{% elif states('sensor.ducobox') == "CNT2" %}
Permanent manual 2
{% elif states('sensor.ducobox') == "CNT3" %}
Permanent manual 3
{% elif states('sensor.ducobox') == "MAN1" %}
Manual 1
{% elif states('sensor.ducobox') == "MAN2" %}
Manual 2
{% elif states('sensor.ducobox') == "MAN3" %}
Manual 3
{% else %}
Auto
{% endif %}
set_preset_mode:
- service: rest_command.ducobox_mode_change
data:
nodeId: "1"
state: >
{% if preset_mode == "Permanent manual 1" %}
CNT1
{% elif preset_mode == "Permanent manual 2" %}
CNT2
{% elif preset_mode == "Permanent manual 3" %}
CNT3
{% elif preset_mode == "Manual 1" %}
MAN1
{% elif preset_mode == "Manual 2" %}
MAN2
{% elif preset_mode == "Manual 3" %}
MAN3
{% else %}
AUTO
{% endif %}
#--------------
badkamer:
unique_id: "ducobox_ventilatie_badkamer"
friendly_name: "Badkamer"
value_template: >
{% if states('sensor.ducobox') != 'AUTO' %}
on
{% else %}
off
{% endif %}
turn_on:
- service: rest_command.ducobox_mode_change
data:
nodeId: "2"
state: MAN3
turn_off:
- service: rest_command.ducobox_mode_change
data:
nodeId: "2"
state: AUTO
preset_modes:
- "Auto"
- "Permanent manual 1"
- "Permanent manual 2"
- "Permanent manual 3"
- "Manual 1"
- "Manual 2"
- "Manual 3"
preset_mode_template: >
{% if states('sensor.ducobox') == "CNT1" %}
Permanent manual 1
{% elif states('sensor.ducobox') == "CNT2" %}
Permanent manual 2
{% elif states('sensor.ducobox') == "CNT3" %}
Permanent manual 3
{% elif states('sensor.ducobox') == "MAN1" %}
Manual 1
{% elif states('sensor.ducobox') == "MAN2" %}
Manual 2
{% elif states('sensor.ducobox') == "MAN3" %}
Manual 3
{% else %}
Auto
{% endif %}
set_preset_mode:
- service: rest_command.ducobox_mode_change
data:
nodeId: "2"
state: >
{% if preset_mode == "Permanent manual 1" %}
CNT1
{% elif preset_mode == "Permanent manual 2" %}
CNT2
{% elif preset_mode == "Permanent manual 3" %}
CNT3
{% elif preset_mode == "Manual 1" %}
MAN1
{% elif preset_mode == "Manual 2" %}
MAN2
{% elif preset_mode == "Manual 3" %}
MAN3
{% else %}
AUTO
{% endif %}
#--------------
#copy paste the above block for every node in your system
#duco api change commands, change the IP adres to your setup
rest_command:
ducobox_mode_change:
url: https://XXX.XXX.XXX.XXX/action/nodes/{{ nodeId }}
method: POST
headers:
accept: "application/json"
content_type: "application/json"
payload: '{"Action":"SetVentilationState","Val":"{{ state }}"}'
verify_ssl: false
In the UI this now looks like this (4 more ventilators to add):
Nice, those new iaq sensors. Missed it. I had the config split over files so it was the best I could deliver for now :).
Somewhere coming time I will set the manual 1, 2, 3 in fan percentage steps. Think that is more understandable for others once it we have it in HomeKit (finishing new house these days).
Nice integration would be nice but with a proper template fan and rest template it is already quite okay, ain’t it?
Is there someone with the “old” communication print who can invest some time in a template fan and a proper templated rest command?
Note to self: maybe buy the combined co2/rh valves for bathroom and garage…
Thanks @miezie and @Steven_Cruysberghs for the great resources in this thread! I installed a connectivity board today on my Ducobox Focus, and got the template fan and rest sensors working almost immediately.
The only thing I modified is the ‘device_class’ of the ‘IaqRh’ and ‘IaqCo2’ sensors to ‘aqi’, since the unit ‘%’ is not supported on a ‘carbon_dioxide’ device_class.
Miezie’s OpenApi doc, and the Duco web UI mention extra capabilities when adding an API key. Is that an installer key, or is that something us mere mortals have access to too? My hope is that that would unlock the extra information that was accessible from the ‘boxinfo’ endpoints etc
Thank you @miezie and @Steven_Cruysberghs ! I got it working immediately. The only change I made was replacing the IP address with the hostname. That was easier to configure and I don’t need to set up the static IP.
I also looked for the API key but without success… I also wonder what it will bring and will keep looking for it.
I did find some other modes but didn’t include them yet. They speak pretty much for themselves: MAN1x2 and MAN1x3 (the same of course for MAN2 and MAN3) and AUTO1 (also up to 3).
I’ve just used this information successfully to read out data from my DucoBox Silent.
At first I didn’t understand the meaning of the numbers IaqRh and IaqCo2. These are a % as ‘Indoor air quality based on RH/CO2’ as specified in the Modbus TCP manual (see Duco website).
I would really like to read out the measured relative humidity (%), temperature (C) and CO2 level as reported by the sensor. I can see them in the ‘Duco Installer’ application, but cannot see them in the REST API reported. Does anyone have the actual REST API specification document or knows how to read these values using REST API?
API Spec is available at Duco Developer portal. The actual values are not exposed in the new API. Still hoping for it…
About an actual integration: why? There is a rest API and a REST approach in HA. Sample code is clear, it is generic… quite a bit of work for a one time yaml config.
I believe I still have the old API version that comes with the Communication board as opposed to the new one that apparently comes with the Connectivity board.
Does anyone know if it’s possible to upgrade the firmware on the DUCO box so that the new API can be used? If not, I will check with DUCO if it’s possible to upgrade the firmware
I got a reply from Duco that the Communication Print and Connectivity Board are two different products and that the new API will not be available at the old Communication Print (there will be no firmware updates at all).
SW VERSION 16036.1x.x.x is from the Communication Print (old), not the Connectivity Board (new). Although the topic states Communication Print, all discussion that indicates https is about the Connectivity Board (new). All examples with http (not s) should be applicable to your situation.
That’s a real pity. I don’t understand why they don’t take the effort to create a firmware update to streamline the API across the two boards. I can’t imagine it’s not feasible or a lot of work.
It took a while to figure out which examples relate to which board, but it’s all clear now!
Good question and I was just wondering the same. Not yet living in the house where the Ducobox is installed but if I look at my graph it seems to be a value that is not relative humidity but rather something inverted. We had a small waterleak in the bathroom (thunderstrom, open window don’t ask ) Tuesday evening and I see the IAQRh value go below 50% and going up again as things dry up…
It is a pitty that the Relative Humidity (RH) isn’t directly available from the API.
I am gathering data to be able to back-calculate the RH from the IaqRh.
An estimation of the RH can be calculated using a template:
{%
if states('sensor.ducobox_rf_keuken_iaqrh') is not in ['unknown',None,'unavailable']
%}
{{ (
((float(states('sensor.ducobox_rf_keuken_iaqrh'))/100)*-37.3)+93.3
)|round(3,'common') }}
{% else %}{{'unknown'}}{% endif %}
Yeah, figured it out yesterday. basically it says the quality of your air so if the sensor gives out 90 % i’ts good 30 % is bad. if we take a shower the percentage goes down and the fan flow control goes up.