I started with HA 7 years ago, and I can tell that HA is a lot more beginners friendly now than 7 years ago.
Which is kind of ironic since you switched to what this thread outlines as the mount Everest of all things.
Templates.
Or maybe that was another topic.
Can’t remember, there was so many topics created at the same saying everything is hard everywhere.
That’s not as contradictory as it sounds. For programmers, writing down their intent in code form is very easy. Sometimes even easier that getting a UI to reflect it.
For example: “x < 5 + y / 2” is super easy to write down. Have fun clicking that together as a condition in the template editor. Even with creating a couple of helpers, I somehow doubt you can.
For a non-programmer who wants that condition, HA is terrible. They cannot do it at all in either UI nor template.
For a programmer, it also is horrible. It’s not impossible, but getting the syntax of a template correct for pull in x and y can be super annoying and take ten minutes of trial and error. states.sensor.x? states.sensor.x.state? state_attr("sensor.x","xx")? states.sensor.x.xx? states.sensor.x.state_with_unit? states("sensor.x")? I have no idea.
HA is easy as long as what the UI offers is exactly what you need. It gets complicated when not. For those people who can code, the same happens in the next step. If what you need matches what HA offers, it’s easy, but the moment you need a bit more, it get complicated very quickly.
Let’s look at another example, something I recently needed: Daily maximum temperature. Yeah, no luck. There’s no UI that lets you tell HA that you want a daily max of some value (the Statistics helper has a “max”, but it is over the last n values or over the last n hours). So a UI user is lost. But a programmer also is lost as there’s also no way to write a template that goes over all data points of a day. You’d have to go all the way and write an addon to do that, it seems.
(Ok, I can think of a way of doing it, but it’s really convoluted. Have an automation that triggers on every state change, a numeric helper that keeps the max, and one for the current date. The automation checks if the date helper still is the same as now(), then either updates the temp numeric helper if the new value is bigger or simply sets the value. If you want clean final values for a graph over multiple days, you need a second helper and have the old max written there when the automation overrides it with the first value of the next day.)
There are at least 3 options that are just a Google search away from even the “UI user”:
- Daily Sensor integration
- Periodic Min/Max integration
- A single trigger-based template sensor that triggers on the state of the sensor in question as well as at midnight. With a couple attributes, this one will also let you store a timestamp and/or the previous day’s value.
This isn’t exactly about this specific problem, it’s about how a simple “I want to do that”, that’s not even about some weird outlandish idea, can frustrate a “non-guru user” and a user with programming background on completely different levels.
(Although those links are interesting, I’ll have a look.)
Because you haven’t read up on the backbone of templates, state objects. It’s really really simple when you read the template documentation as a programmer. I have much less programming experience than you and it took me a week at most to pick up templates. This was 9 years ago when there were hardly any resources, only forum posts to go by.
I agree with @HenryLoenwind … many ‘easy’ things in JS,VB,Python are a nightmare. Specific example I’ve already spent 5+ hrs on…
I cant get new code working (adding to the below code) that excludes entities using text input that check Entity ID and/or Friendly Name… I tried multiple methods: Template, Regex, Python – AND tried for hours with ChatGPT, DeepSeek, ClaudeAI. Nothing ever worked. Also tried using Labels… nope.
It says a ton about how difficult coding Templates is when, if you ask those AIs to convert or create code for real programming languages, they work flawlessly. But they all struggle with HA’s templates, sometimes even for simple things like above.
blueprint:
name: Offline Devices Report
description: '
list Offline Devices, send Persistant and Mobile Notifications
Author: LTek
Version: 2025.05.04.9
source_url: https://gist.github.com/Ltek/0c9cecf632b9c32915130680d834bcf7
'
domain: automation
input:
time:
name: Time of Day
description: Run at this time of the day
default: '6:00:00'
selector:
time: {}
day:
name: Week Day to Run Report
description: '0 = Daily ... 1 = Monday to 7 = Sunday'
default: 0
selector:
number:
min: 0
max: 7
mode: slider
step: 1
exclude_entities:
name: Excluded Sensors (optional)
description: Sensors to exclude (e.g., smartphone) from the list
default: []
selector:
entity:
multiple: true
domain:
- sensor
- binary_sensor
- switch
enable_mobile_notifications:
name: Enable Mobile Notifications
description: Send notifications to your mobile device
default: true
selector:
boolean: {}
mobile_notification_services:
name: Mobile Notification Services
description: Services to use for mobile notifications (e.g., notify.mobile_app_phone), one per line
default: notify.mobile_app
selector:
text:
multiline: true
enable_persistent_notifications:
name: Enable Persistent Notifications
description: Show persistent notifications in Home Assistant UI
default: true
selector:
boolean: {}
actions:
name: Additional Actions
description: Additional actions to run when offline devices are detected
default: []
selector:
action: {}
variables:
day: !input day
exclude_entities: !input exclude_entities
enable_mobile_notifications: !input enable_mobile_notifications
mobile_notification_services: !input mobile_notification_services
enable_persistent_notifications: !input enable_persistent_notifications
offline_devices: >
{% set result = namespace(offline_devices=[]) %}
{% for sensor in states.sensor
| selectattr('attributes.device_class', 'defined')
| selectattr('attributes.device_class', '==', 'battery') %}
{% if sensor.state == "unavailable"
and sensor.entity_id not in exclude_entities | list
and "cloud" not in sensor.entity_id %}
{% set cleaned_name = sensor.name.replace(' Battery', '') %}
{% set result.offline_devices = result.offline_devices + [cleaned_name] %}
{% endif %}
{% endfor %}
{% for binary_sensor in states.binary_sensor
| selectattr('attributes.device_class', 'defined')
| selectattr('attributes.device_class', '==', 'battery') %}
{% if binary_sensor.state == "unavailable"
and binary_sensor.entity_id not in exclude_entities | list
and "cloud" not in binary_sensor.entity_id %}
{% set cleaned_name = binary_sensor.name.replace(' Battery', '') %}
{% set result.offline_devices = result.offline_devices + [cleaned_name] %}
{% endif %}
{% endfor %}
{% for switch in states.switch %}
{% if switch.state == "unavailable"
and switch.entity_id not in exclude_entities | list
and "cloud" not in switch.entity_id %}
{% set result.offline_devices = result.offline_devices + [switch.name] %}
{% endif %}
{% endfor %}
{% if result.offline_devices | length > 0 %}
{% set unique_devices = result.offline_devices | sort | unique %}
- {{ unique_devices | join('\n- ') }}
{% else %}
No offline devices detected.
{% endif %}
offline_devices_count: >
{% set result = namespace(offline_devices=[]) %}
{% for sensor in states.sensor
| selectattr('attributes.device_class', 'defined')
| selectattr('attributes.device_class', '==', 'battery') %}
{% if sensor.state == "unavailable"
and sensor.entity_id not in exclude_entities | list
and "cloud" not in sensor.entity_id %}
{% set cleaned_name = sensor.name.replace(' Battery', '') %}
{% set result.offline_devices = result.offline_devices + [cleaned_name] %}
{% endif %}
{% endfor %}
{% for binary_sensor in states.binary_sensor
| selectattr('attributes.device_class', 'defined')
| selectattr('attributes.device_class', '==', 'battery') %}
{% if binary_sensor.state == "unavailable"
and binary_sensor.entity_id not in exclude_entities | list
and "cloud" not in binary_sensor.entity_id %}
{% set cleaned_name = binary_sensor.name.replace(' Battery', '') %}
{% set result.offline_devices = result.offline_devices + [cleaned_name] %}
{% endif %}
{% endfor %}
{% for switch in states.switch %}
{% if switch.state == "unavailable"
and switch.entity_id not in exclude_entities | list
and "cloud" not in switch.entity_id %}
{% set result.offline_devices = result.offline_devices + [switch.name] %}
{% endif %}
{% endfor %}
{% set unique_devices = result.offline_devices | unique | list %}
{{ unique_devices | length }}
trigger:
- platform: time
at: !input time
condition:
- condition: template
value_template: "{{ offline_devices != 'No offline devices detected.' and (day == 0 or day == now().isoweekday()) }}"
action:
- choose:
- conditions:
- condition: template
value_template: "{{ enable_persistent_notifications }}"
sequence:
- service: persistent_notification.create
data:
title: "Offline Devices Report"
message: >
{{ offline_devices_count }} total:
{{ offline_devices }}
default: []
- choose:
- conditions:
- condition: template
value_template: "{{ enable_mobile_notifications }}"
sequence:
- repeat:
for_each: >
{% set services = mobile_notification_services.split('\n') | map('trim') | reject('eq', '') | list %}
{{ services }}
sequence:
- service: "{{ repeat.item }}"
data:
title: "Offline Devices Report"
message: >
{{ offline_devices_count }} total:
{{ offline_devices }}
data:
tag: offline_devices_report
# Optional: You can add additional notification options like sound, clickAction, etc.
default: []
- alias: "Run additional actions"
sequence: !input actions
mode: single
That’s not templates, that’s yaml and jinja. Templates in HA are just the jinja, and all AI can work off of is patterns. Historically, AI is terrible with HA because it’s only material is questions from the forums, which are generally incorrect because they are people seeking help. So you can’t really correlate the difficulty of the language based on what AI can do. Especially when its 2 languages (Yaml & Jinja) combined and AI likely can’t tell the difference.
As for your particular problem above, you’ll have to explain “whats not working”. I see a few things you could be doing wrong with excluded entities that could lead to errors in your templates, all things that are unrelated to Jinja and related to selectors and their output.
All that says is how bad those LLMs are when their training data is limited, because they don’t actually have the ability to know or understand anything. It’s fancy statistics with a low sample size. And, much of the available sample corpus is composed of poison pills… you’ve just added a new one to the, particularly small, corpus of blueprints examples.
And here we are at the core of this thread.
For people like you, who live and breathe HA’s core concepts, everything is super easy, barely an inconvenience. For people who want to get deep into HA, it’s a couple weeks of reading docs and code to get up to speed. For people who just want to get things done within a couple of hours, it’s running into a cliff all the time.
I know jinja. I have worked with it before. It’s not my favourite language, especially when it’s used for something else than outputting formatted text, but I was not exactly unhappy to see it in use—there are worse things.
One thing that’s clear and straightforward in jinja is object access. object DOT field or object DOT method "()". Very universal notation—it’s so universal that there are seasoned devs out there who don’t even know there are other notations. And it works in HA…sometimes. You can take the code that worked perfectly on a sensor and try to access the sun’s elevation and it won’t work there.
Sure, this may all be perfectly logical in some way, but trying to use HA to accomplish something is different from taking a deep dive and learning the internal workings of it. You should not have to go down that deep for reasonably simple tasks. This:
{% if is_state("sun.sun", "above_horizon") -%}
The sun rose {{ relative_time(states.sun.sun.last_changed) }} ago.
{%- else -%}
The sun will rise at {{ as_timestamp(state_attr("sun.sun", "next_rising")) | timestamp_local }}.
{%- endif %}
should NOT need 3 different ways of accessing fields of the sun object and take half an hour to figure out for someone who already knows jinja. (No, I do not claim this is the only or best way to do that, this is just the first thing I got working when I did that months ago.)
(Side note: The template editor in the developer tools is a great tool to get template code working. But that it is hidden away in the developer tools and not front and centre in the user tools should mean something, shouldn’t it?)
What this thread intended was to say that we need to get too deep into HA’s inner workings for too simple tasks. To check if the sun is above the horizon, you shouldn’t need to read a programmer’s guide.
I have another real-life example of unnecessary complexity.
User request: “I want the garden lights to be on when it’s dark and the backdoor is open”.
HA gurus’ response: “No, you want the garden light to turn on when the backdoor is opened and it’s dark, you want the garden lights to turn off when the backdoor is closed and it’s dark, you want the garden lights to turn on when it’s getting dark and the backdoor is open, and you want the garden lights to turn off when the sun’s elevation becomes positive while the backdoor is open. See, how much simpler and easier than your convoluted and un-HA-ion request that is?”
My response: “Learn template programming and write your condition as a binary helper, then trigger off that.”
Perfect world: HA’s could trigger off the change a binary condition defined re-using the “and if” UI, directly offering two actions paths, one for “on” and one for “off”. (Internally, this could be implemented with a binary helper and an “if” around the actions, i.e. be a pure UI thing representing already existing functionality differently)
I’m sorry, you cannot expect the hardest aspect of home assistant to be picked up in a couple of hours. Templates are not even necessary for the basics, yet you’re trying to claim they are. Templating is hands down the most advanced part of home assistant, and it’s even spelled out that way in documentation. If you aren’t willing to put the time in to learning the hardest aspect of HA, then templates may not be for you. That’s ok, they are not required but your automations will be more verbose.
I know I’m going to sound like a broken record, but you need to read the documentation. You need to understand how to access a state object. It’s very simple and you’re putting it on a pedestal because you haven’t taken the time to read a 5 minute page on how to access them. Yes, it will take you 5 minutes to understand how to access them and what properties state objects have. I’m not being facetious here.
Please read the documentation. 1 method you showed is accessing things via the state object. The other 2 methods are checking states or attributes. All 3 can be interchanged depending on what you want to do. All 3 have the ability to do the exact same thing as well. Having more options to do the same thing is not bad, it gives you control over the template.
These are not simple tasks, this is where your thought process is not aligned with the project. A simple task is setting up an automation to turn on a light at a specific time. A simple task is turning on a light when motion is detected. A simple task is notifying you if the door is left open for 5 minutes.
Templates no matter what way you look at them, are advanced and not simple. That is why they are covered in advanced sections of the documentation.
Yes, this new trigger style is coming to automations. That was mentioned in the state of the open home last month and is presented at the nov 2024 roadmap.
I think you’re misrepresenting the problem in this case.
you don’t need a template to check if the sun is above the horizon. All you need is a condition.
condition: state
entity_id: sun.sun
state: "above_horizon"
or it can be created via the UI.
but the problem you are trying to solve isn’t checking to see if the sun is above the horizon. that part is easy using the above condition and no state object access or templating is required.
the question you are trying to solve in the template is the sunrise time relative to the current time.
that’s more complex and couldn’t be called a “simple task”.
I would use the elevation attribute in a numeric condition above 0.
All… The point both @HenryLoenwind are making is that even SIMPLE things are difficult… (not ‘just’ templating, please stop going back to that and saying everything else is just easy peasy). Heck, even doing a simple compare of two entities requires coding since HA cant do anything but a text compare in the UI (and it doesnt even tell you when you add the code!) While this is a basic example… its BASIC and should just be in the UI, properly (not just text). It is not hard to have the code compare based on value type.
Heck, most dashboard cards you cant even change font size, type, color without using CSS or a separate integration… even then half the darn card types dont work with card-mod or there are serious nuances that are different in most cards. Things like ‘disable clicks’ should be universal - period. They are not. Go try to disable everything in auto-entities and ‘just see status’ (I spent hours getting that working - and its not 100%)… should be a darn checkbox.
You need to learn 3 or 4 “languages”… JINJA, CSS, YAML, and sometimes Python. Then even more complex, when to use what, and how to use them together. Then sometimes nothing work (like in the case of simple substitutions (replace), and even trying Regex inside a template is not working… nice huh?
BUT, no matter what you think of AI, while it is not 100%, for doing HA coding, it it has been correct 80% of the time or more. I’ve learned 100x faster seeing how the AI has done things correctly, and incorrectly. It explains why things work, or dont… and its real time.
…AND STILL while AI knows a billion times more stuff, it still cannot do some basic ‘stuff’ like the text substitutions. The fact that you guys are arguing that ‘all is fine just learn it’ exemplifies the problem.
Yes, everything is easy after you have 5 years experience and bleeding from learning the insane amount of ‘exceptions’ since there are very few things in HA that are universal. There needs to be a serious rework and optimization of the visual editor to include more basic stuff and an overhaul of the way that things are coded for Dashboards - to include exposing basics (fonts properties, sizing, colors, borders, entity/value placement, etc) for Dashboard Integrations
Simple things are not difficult, the things you think are simple are not simple. That’s the disconnect here and it’s why you’re getting push back from veterans.
I’m not really sure what you’d even need this for. I’ve never seen a need to compare entities. That doesn’t mean there isn’t a use case for it… but then again, what home automation software has the ability to compare it’s devices side by side.
Home Assistant is currently working on making auto-generated dashboards easier to build and maintain. You saw the first step towards that goal in 2025.4.
Secondly, card mod is custom. Custom elements shouldn’t even be mentioned here because they are not maintained or distributed by Home Assistant.
Home Assistant only has 2 languages that face users. YAML and Jinja. Everything else you listed here is used in custom cards and it has no place in the conversation about base Home Assistant.
As for string replacement, it works pretty easily in Jinja with or without regex. I also have to add, regex is also an advanced subject. I know software devs with 30 years experience that still struggle with regex.
That hasn’t been the priority at all for dashboards. The priority at the moment is making automated dashboards easy to build and maintain without needing to set things up individually. I.e. Making dashboards easier.
As for all your comments about font, colors, sizing, borders, etc. The only official way to control these are through themes. All other methods you see used on the forums are custom things that are not created by Home Assistant. Home Assistant has maintained that it only supports these customizations through themes. Yes, there is room for improvement here. Possibly a theme editor.
I think you’re going to need to provide an example. This could mean multiple things and the solution depends on context.
you can do simple numerical comparisons by using the numeric_state condition/trigger.
you can do simple text comparisons by using the state condition/trigger.
otherwise we need an example. But I would venture a guess that it’s not as basic as you think it should be.
They aren’t designed to be able to be changed. That is considered advanced and if that’s something you want to do then you need to use advanced tools.
and everything you reference in the rest of that paragraph is all advanced stuff that by design is not supported in HA. But HA still let’s you do those advanced things using custom stuff. But the trade-off is that you need to learn more advanced techniques.
No. You don’t.
you only need to learn them if you want to do more advanced things. Simple things can be done without learning any of that aside from some occasional yaml.
the problem with that is that if you don’t know the building blocks for the advanced stuff then how will you know if the AI is 100% right or 80% right. and if it is 80% right then how do you know how to fix the other 20%.
I don’t know how it could explain why the thing it told you that was wrong isn’t working since it obviously doesn’t “know” it was telling you the wrong thing in the first place. if it “knew” it was wrong and can explain why it’s wrong then why didn’t it tell you the correct thing from the beginning?
But that stuff is not “basic”.
if all of that was exposed in the UI editor I think that the usual “basic users” would be overwhelmed fairly quickly with the potential myriad of selectable options. And then those same users would complain because the UI was too complicated to use and you need to be a rocket scientist to understand all of the options that it’s giving you. ![]()
all this being said, maybe an example of how other home automation software does things better/easier than HA? But it will also need to also be as versatile and powerful as HA is as well.
But then again if that already existed then I bet everybody would be using that instead of HA by now.
![]()
You can use an input_number entity as an above or below value in a numeric_state condition.
after reading these 2 posts, I now understand what they were saying with “compare”. I’m sitting here thinking of something like diff merging the device’s capabilities and y’all are talking about numerical comparisons.
I’m fairly sure comparing two strings in two entities needs a template.
If you know the value or values it can have beforehand then it might be doable in a very clunky way.
Although I can imagine a few scenarios this could be used in, I can’t really see any of them being relevant.
I generally want to know if someone is “home”, not at a specified zone I can type in in an input_text.
That is the only real reason I can see this used.
Maybe I have missed something.
I agree it sounds as a simple task but I guess nobody has seen the need for this and therefore it has not been implemented before.