My mission: To assign a numeric value in the last row of the script.
My problem: value: “{{ counter }}” in the code below does not get an numeric value from counter.
- alias: "Count people at home"
initial_state: true
trigger:
- platform: state
entity_id:
- device_tracker.galaxynote8
- device_tracker.galaxynote8_2
action:
- service_template: >-
{%- set counter = 0 %}
{%- for device in states.device_tracker %}
{%- if device.state == "home" and
(device.entity_id == "device_tracker.galaxynote8_2" or
device.entity_id == "device_tracker.galaxynote8" ) %}
{%- set counter = counter + 1 %}
{%- endif %}
{%- endfor %}
variable.set_variable
data:
variable: count_pepole_home
value: "{{ counter }}"
The code above is ment to count people at home and store the amount of people in a variable using the custom component Variable. That custom component works fine, so that’s not an issue here.
When this automation has ran and when i check variable.count_pepole_home in the entities list, it’s state is not the expected numeric value, it’s the string “{{ counter }}” , but of course without quotes.
If both of us are at home, I’d like the value at the end of the script to be set to 2.
I guess the solution is quite simple when you know where to look.
Any piece of advice or other kind of assistans would be very appreciated.
I’d do what Burningstone suggested unless there’s an insurmountable obstacle. But I’m going to go over the problems I’m seeing in your code nonetheless.
If you want "{{ counter }}" to be interpreted you need a data_template, not data.
Also the service you call seems to be constant, so you can use service there instead of service_template.
The computation you have in service_template appears to me to be used only for the value data field you pass to the service. It should be moved to the value of the value field. AFAICT each template has its own scope. So if you set a variable in one template, it won’t be seen in other templates. So you have to have the computation where you use the result of that computation.
You’re running into an annoying quirk of jinja: loops create their own scope, and setting a variable in a loop creates a new variable for that scope, which is lost when the scope ends. See this question on SO, for instance.
So something like:
action:
- service: variable.set_variable
data:
variable: count_people_home
data_template:
value: >-
{%- set ns = namespace(counter=0) %}
{%- for device in states.device_tracker %}
{%- if device.state == "home" and
(device.entity_id == "device_tracker.galaxynote8_2" or
device.entity_id == "device_tracker.galaxynote8" ) %}
{%- set ns.counter = ns.counter + 1 %}
{%- endif %}
{%- endfor %}
{{ ns.counter }}
I’ve used the workaround of creating a namespace (set ns = namespace(...)) in order for the loop to have a lasting effect after its scope ends.
@Burningstone and @lddubeau , I can’t thank you enough. Both for the template-solution as well as for the correction of my code. It is when other forum members says “you’re totally wrong, here’s some other solutions” that me and others can learn how to do things right.