Danfoss Ally TRV working with remote temp sensor

Hi all,

As promised, I’d post a topic on how to make the Danfoss Ally TRV work with a remote temperature sensor.

This is a very nifty feature, if your TRV is in a location that is not ideal for any TRV, resulting in poor heating (or too much heating, for that matter)

In order to make this work, you need the latest version of Homeassistant (2021.2.0 or later) and a working zigbee dongle connected to the ZHA integration. Note, that I have not been able to get this to work with zigbee2mqtt.

I have set up 2 things to get this to work: a script for sending the remote temp to the TRV, and an automation that will trigger this script whenever the state of the temp sensor changes.

Here’s this script:

alias: [Name of the script]
sequence:
  - service: zha.set_zigbee_cluster_attribute
    data:
      ieee: '[IEEE of your Danfoss Ally TRV]'
      endpoint_id: 1
      cluster_id: 513
      attribute: 16405
      cluster_type: in
      value: >-
        {{ (states("[the sensor you want to read the temperature from]") | float *
        100) | round(0)}}
mode: single

Here’s the (very simple) automation:

alias: Opdater external temp TRV_1
description: ''
trigger:
  - platform: state
    entity_id: [Temp sensor ID]
condition: []
action:
  - service: script.[name of the script above]
    data: {}
mode: single

Result in a graph:
office-heating

Top graph legend:
Blue is set-point on TRV
Green is temp measured from TRV
Red is external room temp

Hope this helps someone out there!

10 Likes

Great work!

I have a couple of questions, first off. The Temp sensor ID mentioned in the automation, is that the one of the external sensor, or the one built-in the TRV?

Second, I am assuming your scripts are split across multiple files, as that is why you don’t have an script name in there.

I have a combined Scripts file, and it won’t accept the indentation, can you guess what’s up?

scripts.yaml:

bathroom_temp_share:
  alias: Bathroom_Temp_Share
  service: zha.set_zigbee_cluster_attribute
  data:
    ieee: '84:2e:14:ff:fe:5e:41:dc'
    endpoint_id: 1
    cluster_id: 513
    attribute: 16405
    cluster_type: in
    value: >-
      {{ (states("sensor.bathroom_humidity_temperature") | float * 100) |
      round(0)}}

Thank you in advance!

The sensor id for the automation would be the external temp sensor - so whenever the external temp changes it’s sent to the TRV.

IDK about the indentation, I usually use the UI to set up scripts and sensors, and I just went into “edit as yaml” mode and copy/pasted it here.

Thank you. I went with your approach and sadly get this error:

From where I am seeing, it is exactly the same as you posted.

That’s my bad - I missed some details in the copy/pasted code. I’ve updated the script snippet in the OP.

1 Like

Thank you that is working great! I am looking forward to monitor how it works in practice!

image

I am on my way to purchase additional external sensors to get it implemented in my other rooms! :slight_smile:

Oh, and grouping target temperature of TRVs because I have a room with three present!

1 Like

How is your experience triggering on temperature sensor change? According to the docs uploaded in Danfoss Ally thermostat: firmware update/ota v1.08, open window & external temp [zha] [deconz] - Hardware - Home Assistant Community (home-assistant.io) it is recommended to only update every 30 min suggesting a time trigger instead

Recommended to be received from Gateway at least every 3 hours but not more often than every 30 minutes @ every 0,1K change

From what I can tell it works just fine when setting the external temp whenever the external sensor state updates (which is way more than once every 30 min which is apparently rarely more than twice an hour, according to the HASS logs).

I’ll try throttling it or something to limit updates to every 30 min and see if that has a positive/negative/neutral impract on the temperature regulation

I have it set to update on sensor change but not often than 5min:

condition:
  - condition: template
    value_template: "{{ ( as_timestamp(now()) - as_timestamp(state_attr('automation.external_trv_update', 'last_triggered')) |int(0) ) > 300 }}"

I didn’t notice anything bad happening. I wonder if this requirement isn’t related to the battery drain it can cause and the fact TRVs doesn’t work fast enough to have more updates. After all setting temp won’t make it happen in the room right away. :wink:

This looks pretty interesting. Are you able to get this to work with the standard firmware of the TRV or did you update to the 1.08 to make it work?

I had upgraded the version before I started fiddling with this, so I can’t say if it works in the older firmware.

Ah ok, how did you initiate the update?
I have already added the OTA code to my config file and uploaded the new firmware to my HA in a OTA folder, but I dont seem to be able to start the firmware update itself, or able to follow the update progress.

I can’t remember the exact process, it’s been a while - but I do remember it feeling “magic”, ie. with no real indication something had happened.

I can confirm this. The TRVs did it automatically, as soon as they could access the firmware.

I am just going to sneak in here: Godt arbejde!
I just received my Danfoss Ally, today spurred on by this topic.
However, I am not able to get the external sensors measurement to register on the Danfoss.
I am just getting into Home Assistant so I am sorry in advanced for the detailed write up, and if I have made some glaringly mistake.

I installed latest firmware on the Ally (0x00000108) and from a fresh start at Home Assistant installed ZHA, added the Ally (this added the entities power and thermostat), and added my temperature sensor (Xiaomi Aqara temperature, humidity and pressure sensors (WSDCGQ11LM)).
Then configuration, scripts, add script. I give it a name, mode. Single, and in sequence I choose edit in yaml. Then I enter your script (without luck) It seems to accept the following:

service: zha.set_zigbee_cluster_attribute
data:
  ieee: '84:2e:14:ff:fe:56:1a:8a'
  endpoint_id: 1
  cluster_id: 513
  attribute: 16405
  cluster_type: in
  value: >-
    {{ (states("sensor.lumi_lumi_weather_f54ab302_temperature") | float * 100) |
    round(0)}}

Likewise in automations.
Mode: Single
Trigger: state
Entity: the temperature sensor
Actions: call service – the script

I can see that the script does indeed run, when the temperature sensor registeres a change, so something is working.
I hope there is some minor detail I overlooked; this would be so great to have working. Further plans include closing the valves when windows are registered open (just by sensor)

Hi, I just want to be sure of what you mean with: “not able to get the external sensors measurement to register on the Danfoss”?

The display on the physical unit will always show what the target temperature is, and the temperature sensor in HA will always report the wrong value (typically warmer than reality).

Here is an example from my connected dining and living room:

image

The onboard sensor of the three TRVs report 23.1 celcius, and the 2 external sensors report 22.1 celcius which is closer to the target value of 22.0 celcius.

What will happen is that the reported temperature of your external sensor will be closer to what your set target temperature is. Again the temp readings of the device will still be there, just not used for anything.

These are my scripts and automation:
Scripts.yaml

bathroom_temp_follow:
  alias: Bathroom Temp Follow
  sequence:
  - service: zha.set_zigbee_cluster_attribute
    data:
      ieee: 84:2e:14:ff:fe:5e:41:dc #TRV ieee
      endpoint_id: 1
      cluster_id: 513
      attribute: 16405
      cluster_type: in
      value: '{{ (states("sensor.bathroom_air_temperature") | float * 100) |
        round(0)}}' #external sensor
  mode: single

Automation.yaml

- id: '1612470219876'
  alias: TEM01 - Update External Temp - Bathroom
  description: ''
  trigger:
  - platform: state
    entity_id: sensor.bathroom_air_temperature #external sensor
  condition: []
  action:
  - service: script.bathroom_temp_follow #script above
    data: {}
  mode: single
1 Like

Hi Bjorn, thanks for the quick response.

Sorry, what I ment was that I could not get the Danfoss to react, i.e. open/close despite manipulating the external temperature to much higher/lower themperatures than the target.

Oh I did not realise the sensor in HA will report wrong value, I assume it is the Danfoss you mean?
I have now installed the file editor, so I can edit the script.yaml and automation.yaml directly - will give it a go later.
One quick question in the meantime, your script deviates from Thors which has with the use of " ’ " and " >- " in the value:

ieee: '[IEEE of your Danfoss Ally TRV]'
vs
ieee: 84:2e:14:ff:fe:5e:41:dc #TRV ieee

      value: >-
        {{ (states("[the sensor you want to read the temperature from]") | float *
        100) | round(0)}}

vs

      value: '{{ (states("sensor.bathroom_air_temperature") | float * 100) |
        round(0)}}' #external sensor

What is the difference here? I will just follow your script at first (easier to troubleshoot)

Good question, I am not particularly sure if the difference has any impact. But I can confirm my version works.

Also, not sure if it’s the exact setup you want with open windows, but here are my two automations that sets the temperature (22 or 6 celcius) depending on if my window is open or not.

I assume there is a way to just turn the TRV on and off, please let me know if you figure it out.

- id: '1615488906764'
  alias: TEM06 - Open Window - set temperature to 6
  description: ''
  trigger:
  - type: opened
    platform: device
    device_id: f957ade113eea0ef1687eae1f313cb55
    entity_id: binary_sensor.lumi_lumi_sensor_magnet_aq2_on_off
    domain: binary_sensor
  condition: []
  action:
  - service: climate.set_temperature
    data:
      temperature: 6
    target:
      device_id: 22598ea4a60d608123e5a4b88d064a88
  mode: single
- id: '1615490307443'
  alias: TEM10 - Open Window - set temperature to 22
  description: ''
  trigger:
  - type: not_opened
    platform: device
    device_id: f957ade113eea0ef1687eae1f313cb55
    entity_id: binary_sensor.lumi_lumi_sensor_magnet_aq2_on_off
    domain: binary_sensor
  condition: []
  action:
  - service: climate.set_temperature
    data:
      temperature: 22
    target:
      device_id: 22598ea4a60d608123e5a4b88d064a88
  mode: single

*Quick edit for spelling errors.
Okay I did a fresh install of Home Assistant, just to leave out any possible bias.

I seem to have narrowed down the issue, the automation seems to trigger the script correctly, but the Danfoss does not open/close accordingly. When i look at the logs there are quite a few errors for both script and automation:

Logger: homeassistant.components.automation.tem01_update_external_temp_bathroom
Source: components/zha/core/device.py:518
Integration: Automation ([documentation](https://www.home-assistant.io/integrations/automation), [issues](https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+automation%22))
First occurred: 12:17:03 (106 occurrences)
Last logged: 12:42:50

* TEM01 - Update External Temp - Bathroom: Error executing script. Unexpected error for call_service at pos 1: 513
* While executing automation automation.tem01_update_external_temp_bathroom

Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 262, in _async_step await getattr( File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 466, in _async_call_service_step await self._async_run_long_action(service_task) File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 428, in _async_run_long_action long_task.result() File "/usr/src/homeassistant/homeassistant/core.py", line 1488, in async_call task.result() File "/usr/src/homeassistant/homeassistant/core.py", line 1523, in _execute_service await handler.job.target(service_call) File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 218, in service_handler await script_entity.async_turn_on( File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 323, in async_turn_on await coro File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1041, in async_run await asyncio.shield(run.async_run()) File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 254, in async_run await self._async_step(log_exceptions=False) File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 262, in _async_step await getattr( File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 463, in _async_call_service_step await service_task File "/usr/src/homeassistant/homeassistant/core.py", line 1488, in async_call task.result() File "/usr/src/homeassistant/homeassistant/core.py", line 1523, in _execute_service await handler.job.target(service_call) File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 712, in admin_handler await result File "/usr/src/homeassistant/homeassistant/components/zha/api.py", line 922, in set_zigbee_cluster_attributes response = await zha_device.write_zigbee_attribute( File "/usr/src/homeassistant/homeassistant/components/zha/core/device.py", line 553, in write_zigbee_attribute cluster = self.async_get_cluster(endpoint_id, cluster_id, cluster_type) File "/usr/src/homeassistant/homeassistant/components/zha/core/device.py", line 518, in async_get_cluster return clusters[endpoint_id][cluster_type][cluster_id] KeyError: 513

and

Logger: homeassistant.components.script.bathroom_temp_follow
Source: components/zha/core/device.py:518
Integration: Scripts ([documentation](https://www.home-assistant.io/integrations/script), [issues](https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+script%22))
First occurred: 12:10:40 (54 occurrences)
Last logged: 12:42:50

Bathroom Temp Follow: Error executing script. Unexpected error for call_service at pos 1: 513

`Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 262, in _async_step await getattr( File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 463, in _async_call_service_step await service_task File "/usr/src/homeassistant/homeassistant/core.py", line 1488, in async_call task.result() File "/usr/src/homeassistant/homeassistant/core.py", line 1523, in _execute_service await handler.job.target(service_call) File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 712, in admin_handler await result File "/usr/src/homeassistant/homeassistant/components/zha/api.py", line 922, in set_zigbee_cluster_attributes response = await zha_device.write_zigbee_attribute( File "/usr/src/homeassistant/homeassistant/components/zha/core/device.py", line 553, in write_zigbee_attribute cluster = self.async_get_cluster(endpoint_id, cluster_id, cluster_type) File "/usr/src/homeassistant/homeassistant/components/zha/core/device.py", line 518, in async_get_cluster return clusters[endpoint_id][cluster_type][cluster_id] KeyError: 513

Any idea what this could be? Perhaps related to the script’s endpoint, cluster type and id? Or perhaps the Danfoss firmware?

This is way above what I can comprehend. But it appears that your unit doesn’t recognize the zigbee attributes of the script. And if you have the same firmware (1.08) and values as mine above, I am out of ideas.

All except finding the right place at Github to log the issue.