I have made an automation to close blinds half way when the sun is too intensive and UV index is above 1 in two sunny rooms (each has its own cover). I would like to close the blinds half way from where they are, each time the automation starts. Ultimately, either the temperature in the sunny rooms stabilizes, or the automation would completely close the blinds.
Here is the automation entry (automation.yaml).
I have spent hours searching for the error and cannot find it. If I put a number in the first action service, such as 50, it works very well. But as soon as I set the expression, it fails with the following error:
Error executing script script.1583004153017. Invalid data for call_service at pos 1: expected int for dictionary value @ data['position']
In the template editor screen, the expressiion : {{ ((0 + states.cover.kitchen_blinds_controller.attributes.current_position )/2)| int}} gives the value 23.
- id: '1570981684762'
alias: BLINDS DOWN - All, Partial - On_Strong_Light_or_Too_Hot
description: Both covers (SOMFY and Kitchen) down partially when light too high
trigger:
- above: '1200'
entity_id: sensor.terrasse_nord_illuminance
for: 00:03:00
platform: numeric_state
condition:
- condition: and
conditions:
- condition: or
conditions:
- condition: template
value_template: '{{ states.cover.kitchen_blinds_controller.attributes.current_position |
int > 40 }}'
- condition: template
value_template: '{{ states.cover.time_based_cover_2.attributes.current_position
| int > 40 }}'
- above: '1'
condition: numeric_state
entity_id: sensor.dark_sky_uv_index
- above: '25.0'
condition: numeric_state
entity_id: sensor.terrasse_nord_temperature
action:
- data:
mycover: cover.kitchen_blinds_controller
set_position: '"{{ ((0 + states.cover.kitchen_blinds_controller.attributes.current_position
)/2)| int}}"'
service: script.1583004153017
- data:
mycover: cover.time_based_cover_2
set_position: '"{{ ((0 + states.cover.time_based_cover_2.attributes.current_position
) /2)|int}}"'
service: script.1583004153017
- data:
message_title: BLINDS DOWN - All, Partial - On_Strong_Light_or_Too_Hot
service_template: script.{% if states.input_select.notify_fh_on_events.state ==
'info'%}1582713804730{%else%}1582707732926{%endif%}
- data:
option: weather_dependant
entity_id: input_select.blinds_auto_close
service: input_select.select_option
Any help to figure where the error is would be greatā¦
What an amazing Community! As soon as I have set the ā|intā in the script, it worked. So many hours searching for the error, and that was it! many thanks to both of you.
The reason why I used data (instead of data_template) in the actions is that I was following the UI automation editor, which is great, but still has some mysteries.
I converted also all āstates.XXXā to functions, it makes sense because it happens that some sensors are unavailable due to WIFI rssi.
May I ask you why it shall be data and not data_template? Whatās the rule to tie-break between these two? Do you mean that data_template conserves the data type passed to the service, and that ādataā systematically converts the arguments to strings?
If you specify data_template the automation will pass the evaluation result of the template to your script (as a string, always as a string). e.g. "24"
If you use data in the automation it will pass the whole template unevaluated to your script ( again, as a string). e.g.
'{{ states.cover.kitchen_blinds_controller.attributes.current_position | int > 40 }}'
You must then ensure your script is set up to evaluate that template by using data_templates in your script.
Personally, Iād use data_template in both.
In the automation so it only has to pass the result not the whole template (it uses minutely less memory and is fractionally faster).
In the script to convert the result string into a number required for your service.
because itās well documented (rule no.1 - surprise!), reading docs may save you a lot of time!
I never thought about it that wayā¦ just followed the simple rule āhave templateā ā āuse data_templateā (and it makes sense, doesnāt it?) so thanks for the explanation, even if I wonāt be using that knowledge
Thank you Tom, I learnt something. In other words data_template is passing-by-value, while ādataā is passing the entire formula of the template. It could be useful if the target script modifies the data upon which the template is calculated. Is it not?
afaik when HA sees data_template, it evaluates (i.e substitutes templates with their calculated value) every value below it and then assigns the results of that evaluations (always strings) to appropriate keys. That way this (simplified example)
data_template:
number: "{{ 2*2 }} steps"
will result in numberā value being set to ā4 stepsā and that value will be used in script/service/whatever.
and itās the same as saying
data:
number: "4 steps"
On the other hand, if we forget to use data_template and use data instead
data:
number: "{{ 2*2 }} steps"
HA wonāt evaluate anything and numberā value will be set to ā{{ 2*2 }} stepsā. Sometimes we need it - for example, to pass a string that contains double curly brackets.
However, if we need to dynamically change data that we assign to number, we have to use templates as they give us runtime evaluation. And for that evaluation to work we need to instruct HA accordingly by using data_template instead of data.
Thank you Ahmad, for this very detailed explanation. Both your response and Tom and Coryās responses helped a lot to solve my issue. My deepest thanks to all for sharing your knowledge!
Best regards, Felix