I’m new to HA and trying to configure a template binary sensor but couldn’t seem to get it work. The idea is the sensor should only be triggered when the ink level is low at 8:30 and 20:30. The sensor should be off any time when the ink level is restored. The below template works when the sensor triggers ON at 8:30, however at 8:31 it resets to OFF. I have some logic to continue the ON state when it’s not 8:30 so I’m not sure what’s problem with my template?
Many thanks in advance!
- binary_sensor:
state: >
{% set black = states('sensor.office_printer_black_ink') | int %}
{% set cyan = states('sensor.office_printer_cyan_ink') | int %}
{% set magenta = states('sensor.office_printer_magenta_ink') | int %}
{% set yellow = states('sensor.office_printer_yellow_ink') | int %}
{% set any_low = (black < 5 or cyan < 5 or magenta < 5 or yellow < 5) %}
{% set hour = now().hour %}
{% set minute = now().minute %}
{% if not any_low %}
false
{% else %}
{% if (hour in [8, 20]) and (minute == 30) %}
true
{% elif is_state('sensor.office_printer_ink_low', 'on') %}
true
{% else %}
false
{% endif %}
{% endif %}
attributes:
warning_message: >
{% set low = [] %}
{% set black = states('sensor.office_printer_black_ink') | int %}
{% set cyan = states('sensor.office_printer_cyan_ink') | int %}
{% set magenta = states('sensor.office_printer_magenta_ink') | int %}
{% set yellow = states('sensor.office_printer_yellow_ink') | int %}
{% if black < 5 %}
{% set low = low + ['🖤 Black: ' ~ black ~ '%'] %}
{% endif %}
{% if cyan < 5 %}
{% set low = low + ['🔵 Cyan: ' ~ cyan ~ '%'] %}
{% endif %}
{% if magenta < 5 %}
{% set low = low + ['🔴 Magenta: ' ~ magenta ~ '%'] %}
{% endif %}
{% if yellow < 5 %}
{% set low = low + ['🟡 Yellow: ' ~ yellow ~ '%'] %}
{% endif %}
{% if low | length > 0 %}
{{ low | join('\n') }}
{% else %}
✅ All ink cartridges are OK.
{% endif %}
For starters - ALL returned states need to be enclosed in double curly brackets - i.e. {{ false }}, {{ true }}, etc. You have done it for some - but not all.
Also - use the template editor in Developer tools - I will help finding this sort of error.
Thanks you! I have now added the braces but still doesn’t work.
Does HA allow to set the state based on the current state? I’m wondering could the is_state returns false because the value was reset?
I’m still learning the template and would like to get some help with regards to the following template - it sort of works for what I want however the code is really ugly.
The purpose: the binary sensor should only change to ON at 8:30 or 20:30 when any ink of my printer is below 5%. When all are Ok, it should change immediately.
Ok please bare with me with the ugly code below:
It’s difficult for us to tell you the reason it isn’t working if you do not describe how you are testing it.
When first created, a trigger-based template sensor’s state will be unknown until one of its triggers fire.
Here’s one way to condense the configuration a little by using a trigger variable to hold the list of ink sensors so you don’t have to repeat them so many times. Since the actual color name isn’t needed until the message portion and that information is already part of the entity ID, there really isn’t a need to build color name keyed dictionaries over and over.
- trigger:
- id: 'on'
trigger: time
at:
- "08:30"
- "20:30"
- id: 'off'
alias: When all ink levels are above 5
trigger: template
value_template: |
{% set ents = ['sensor.office_printer_black_ink', 'sensor.office_printer_cyan_ink', 'sensor.office_printer_magenta_ink', 'sensor.office_printer_yellow_ink'] %}
{{ents | map('states') | map('int') | select('lt', 5) | list | count == 0 }}
variables:
ents:
- sensor.office_printer_black_ink
- sensor.office_printer_cyan_ink
- sensor.office_printer_magenta_ink
- sensor.office_printer_yellow_ink
low: >
{% set sensor_states_list = ents|map('states')|map('int', 0)|list %}
{{ zip(ents, sensor_states_list)|selectattr(1, '<', 5)|map(attribute=0)|list }}
condition:
- "{{ trigger.id == 'off' or (trigger.id == 'on' and low|count> 0) }}"
binary_sensor:
- name: "Office Printer Ink Low"
unique_id: office_printer_ink_low
device_class: problem
state: "{{ trigger.id }}"
attributes:
warning_message: |
{%- if trigger.id == "off" %}
✅ All ink cartridges are OK.
{%- else %}
{% set icon = {'black': '⚫ Black:','cyan': '🔵 Cyan:','magenta': '🔴 Magenta:','yellow': '🟡 Yellow:'} %}
{%- for c in low %}
{{ icon[c.split('_')[-2]] }} {{ states(c)|int }}%
{%- endfor %}
{%endif%}
Wow, that’s impressive! I’d very much like to try it but not sure I understand - it doesn’t looks like a trigger template and I have tried to copy - paste in my template.yaml which looks like the following:
So I start with some trigger template (I think that’s the name), then some regular template sensors. Not sure how to put your code in the yaml. Or is your code meant for automation?
Forgive me if I ask something obvious but I’m very eagle to learn HA
It’s a trigger-based Template Binary sensor, just like you had before, only using a couple extra configuration keys that you might not be familiar with. You should be able to paste it into you template.yaml file as it is in my previous post, just make sure the indentations match your existing sensor configurations.
Thanks, maybe I didn’t do correctly, I put the template sensor in the file but received the error after restart. In the vs editor it also complains “variables” and “condition” properties are not allowed.
Invalid config for ‘template’ at template.yaml, line 1: ‘trigger_variables’ is an invalid option for ‘template’, check: trigger_variables
I must have mis-remebered that trigger variables were available for trigger-based template sensors.
Those are definitely allowed, they’re in the docs. You may be using an outdated version of the HA extension for VS Code.
I’ve adjusted the config in my earlier post to have the entity list in the trigger and the under variable key… not quite a clean as it would be if we could use trigger variables, but it should work.
Thanks a lot! It works almost, the only strange behaviour is when I reload template.yaml (and all ink sensors return value > 5), so instead of stay off, it first went off, and then immediately flip to on, despite that the condition should stay off.
I have lost many hairs trying to figure out why but no answer…
If the binary sensor is ‘off’ prior to reloading the template integration, what I see is the expected behavior… it goes unavailable during a reload of the template integration, then assumes the prior state of ‘off’. As I understand it, at the end of the reload process the only options are for the previous state to be reinstated or for the state to be marked as unknown.
The only thing that should set the sensor’s state to “on” is the trigger with “on” as the trigger ID.
Is it possible that a time trigger happened immediately before you hit reload or immediately after the integration finished reloading?