Yes, I understand how the code works. My point was: If the code is getting re-rendered because it’s updating every 30 seconds, the code will never give you anything other than less than a minute.
Thanks for all your help so far! Now I understand your point using automations as trigger, that really works brilliantly and together with Petro`s pice of code it delivers exactly what I was looking for. I only removed the seconds to limit the display to minutes.
One final question if you don’t mind. Occasionally it throws back the following error message, even though all is working. I understand that the root cause is the code I added to sensor.yaml and the system seems to be irritated by the attribute ‘None’. Any idea why?
Logger: homeassistant.components.template.template_entity
Source: components/template/template_entity.py:71
Integration: template (documentation, issues)
First occurred: 16:41:50 (5 occurrences)
Last logged: 16:41:50
- TemplateError(‘UndefinedError: ‘None’ has no attribute ‘attributes’’) while processing template ‘Template("{%- set up = as_timestamp(now())-as_timestamp(states.automation.letzte_bewegung_im_aussenbereich.attributes.last_triggered) %} {%- macro phrase(name,divisor,mod=None) %} {%- set value = ((up//divisor) % (mod if mod else divisor))|int %} {%- set end = ‘’ if value > 1 else ‘’ %} {{- ‘{} {}{}’.format(value,name,end) if value|int > 0 else ‘’}} {%- endmacro %} {%- set values = [phrase(‘w’,6060247), phrase(‘d’,606024,7), phrase(‘h’,6060,24), phrase(‘m’,60)] |select(’!=’,’’)|list %} {{values[:-1]|join(’, ‘) ~ ’ ’ ~ values[-1] if values|length > 1 else values|first}}")’ for attribute ‘_state’ in entity ‘sensor.since_last_motion_outdoor’
it’s because you’re using states.automation.letzte_bewegung_im_aussenbereich.attributes.last_triggered
. Change the syntax to
state_attr('automation.letzte_bewegung_im_aussenbereich', 'last_triggered')
That will not work for last_changed or last_updated.
yes, as I posted/edited above already.
fyi, it has to do with the way templates are dealt with when an entity isnt ‘ready yet’ see the warning at https://www.home-assistant.io/docs/configuration/templating/#states
It’s not looking for an attribute ‘None’, it’s in fact saying there is no attribute (because somehow the state isn’t available in HA’s state machine)
haha, like your ‘irritated’. that’s what we all can relate to in these circumstances…
Thanks guys…seems to work like a charm now - and so far without errors
Also thanks for the explanation. I guess I still need some time until I figure those things out in detail!
So following along I got all this working after much headaches with dictionary syntax (this post being very useful https://github.com/rogro82/hass-variables/issues/47#issuecomment-717864105) and variables… the indenting is such a nightmare as well… I guess you get used to it.
I have a History Graph working nicely for variable.last_motion (as per https://diyfuturism.com/index.php/2017/12/15/useful-sensor-motion-last-seen-________/) but now I’d like to add a card as per Alex’s above, i.e, sensor name on the left, last motion on the right and I’m just not sure how to do it.
I have since_last_motion_mhd added as a binary_sensor as per @Mariusthvdb post above but it doesn’t seem to be updating as it shows the time since last boot. I changed the automation name in the template as for some reason in all my fiddling it got renamed to automation.update_last_motion_2 (side note: can I fix this?). It was throwing TypeError: unsupported operand type(s) for -: ‘float’ and ‘NoneType’, I imagine due to automation.update_last_motion having a Null value for last_triggered?
Looking now I see it has thrown it once since the last reboot as well but it’s reporting it a little differently:
File “<template>”, line 7, in top-level template code
TypeError: unsupported operand type(s) for -: ‘float’ and ‘NoneType’
Here is how I have the template set up:
binary_sensor:
- platform: template
sensors:
since_last_motion_mhd:
friendly_name: 'Since Last Motion'
value_template: >-
{%- set up = as_timestamp(now())-as_timestamp(state_attr('automation.update_last_motion_2','last_triggered')) %}
{%- macro phrase(name,divisor,mod=None) %}
{%- set value = ((up//divisor) % (mod if mod else divisor))|int %}
{%- set end = 's' if value > 1 else '' %}
{{- '{} {}{}'.format(value,name,end) if value|int > 0 else ''}}
{%- endmacro %}
{%- set values = [phrase('week',60*60*24*7),
phrase('day',60*60*24,7),
phrase('hour',60*60,24),
phrase('min',60),
phrase('sec',1,60)]
|select('!=','')|list %}
{{values[:-1]|join(', ') ~ ' and ' ~ values[-1] if values|length > 1 else
values|first}}
Also, it does seem to update if I throw it into the Template editor:
binary_sensor:
- platform: template
sensors:
since_last_motion_mhd:
friendly_name: 'Since Last Motion'
value_template: >-
58 secs
Ah, changed from binary_sensor to sensor and I get a value now in lovelace. Also wrapped the template code in an if block to prevent the error… seems effective if maybe not the best way?
{% if state_attr(‘automation.update_last_motion_2’,‘last_triggered’) != None %}
Still not sure how to config the lovelace card for each sensor to show last_triggered.
Wow that is pretty cool! I actually meant as per Alex’s screenshot with the name on the left and the data from the template on the right (just to understand how it works), but I do like what you are doing there.
yeah, but tbh, that screenshot is pre-Lovelace I fear
my screen dump is a section of all my motion sensors, and I can click those to toggle the sensor (green is on/ grey is off) Note these are Philips Hue sensors, so require some serious back end config for the switches.
to get you started, here’s a single button:
- type: horizontal-stack
cards:
- type: custom:button-card
template: button_motion
name: Laundry
entity: binary_sensor.laundry_sensor_motion
triggers_update: switch.laundry_sensor_motion
variables:
clear_icon: mdi:washing-machine
etcetc
with the button_motion template:
button_motion:
template: button_body
variables:
motion_icon: motion_icon
clear_icon: clear_icon
show_last_changed: true
tap_action:
action: call-service
service: switch.toggle
service_data:
entity_id: >
[[[return 'switch.' + entity.entity_id.split('.')[1] ]]]
# switch.laundry_sensor_motion
# binary_sensor.laundry_sensor_motion
state:
- value: 'on'
styles:
card:
- color: red
name:
- color: black
icon:
- color: red
- operator: template
value: >
[[[ var id = 'switch.' + entity.entity_id.split('.')[1];
return states[id].state == 'on';
]]]
icon: >
[[[ return variables.clear_icon ]]]
styles:
card:
- color: grey
icon:
- color: green
state:
- color: green
- operator: default
icon: >
[[[ return variables.clear_icon ]]]
styles:
card:
- color: grey
# - opacity: 0.8
icon:
- color: grey
and the used button_body:
button_body:
color: auto
size: 30%
aspect_ratio: 1/1
show_state: true
show_label: true
tap_action:
action: more-info
haptic: light
hold_action:
action: more-info
haptic: success
styles:
icon:
- color: grey
lock:
- color: red
card:
- background-color: var(--card-background-color)
- color: var(--primary-color)
- padding-left: 5px
name:
- font-family: Helvetica
- font-size: 13px
- font-weight: bold
- justify-self: start
- text-align: start
- text-overflow: unset
- white-space: unset
- word-break: break-word
label:
- font-family: Helvetica
- font-size: 11px
- justify-self: start
- text-align: start
state:
- font-family: Helvetica
- font-size: 11px
- font-weight: bold
- justify-self: start
- text-align: start
- text-transform: capitalize
grid:
- grid-template-areas: '"i" "n" "s" "l"'
- grid-template-columns: 1fr
- grid-template-rows: 1fr min-content min-content
img_cell:
- align-items: start
- justify-content: start
So I have it working pretty much as per your screenshot. Since I’m new to this, some discoveries (maybe for my future self when I forget what I did).
-
installed HACS - manually step by step as the install script failed due to permissions even though I was running sudo. Quite a good video here- https://www.youtube.com/watch?v=OcJd3MzCD9A&feature=emb_logo
-
installed button-card custom card via HACS. Since I’m new it wasn’t obvious that this wasn’t core HA.
-
added your button_motion and button_body templates to my Dashboard via the top right “Raw Configuration Editor” when in edit mode. Put them above “title:” and under “button_card_templates:” (create this). If you’re running in YAML mode this needs to go in ui-lovelace.yaml instead.
-
after that make the new card with a combination of vertical and horizontal-stacks with cards like this:
- type: horizontal-stack cards: - type: 'custom:button-card' template: button_motion entity: alarm_control_panel.home variables: clear_icon: 'mdi:shield-home-outline' - type: 'custom:button-card' template: button_motion name: Front Door entity: binary_sensor.front_door variables: clear_icon: 'mdi:door'
So the part I don’t have working is how to use the since_last_motion_mhd to add a custom label. It looks like just a sensor to me that shows the time since any of my sensors (tied to the automation) last saw motion. How would I use that generically for each sensor?
From my reading it seems like I’d need to re-write it as [[[ some javscript equivalent ]]] and add it to a template under button_card_templates: or add to each button individually if I needed one off formatting? Any way to re-use the Jinja2 code that I already have?
unless I misunderstand you, but you don’t have to don’t you? each sensor has got its last motion in the last_changed field, as you already experienced.
your last paragraph is not very clear to me. Please tell us what you want to accomplish (what data do you want to see where)
fwiw, here’s my last_motion button:
- type: custom:button-card
template: button_body
entity: variable.last_motion
tap_action:
action: more-info
name: >
[[[
var fakestate = `<span style="color: red;font-size: 11px;word-wrap:break-word;"> ${entity.state.substr(0, entity.state.length-10)} </span>`;
return 'Last motion' + "<br>" + fakestate
]]]
show_label: false
show_state: false
show_last_changed: true
show_name: true
# label_template: >
# return entity.state.substr(0, entity.state.length-11) +
# "<br>" + entity.last_changed
state:
- operator: default
styles:
card:
- color: grey
# - opacity: 0.8
icon:
- color: red
it’s still using a variable fakestate in the name field, because at that time my FR for the now available state_display
wasn’t written yet
That works for me too. Funky. But you’re using your fakestate [[[ JavaScript ]]] to format the data.
I’ll rephrase. This thread started off talking about making a card that showed the last time any sensor was triggered, though formatted in a particular way, then you proposed a YAML template to format week, day, hour, min, sec right? That’s all pretty clear.
Then Alex posts that he got this working and shows an example like this, i.e. two different sensors each displaying their own formatted last_triggered, presumably via the YAML template.
The implication, as I read it, was that he used that generic template to somehow pass in a sensor name and output the fomatted last_triggered time for each sensor individually, not just one card with the name and last_triggered of the last sensor that called the automation, but multiple sensors on individual rows.
That’s the bit that stumps me… I feel like I’ve got that completely wrong and he just used JavaScript (much like your fakestate example) on a custom card like button-card (though not sure how he laid it out horizontally like that) and didn’t use the YAML template at all?
Maybe the question is, can you use a YAML template to format the label on custom cards or do you need to use JavaScript? If not, what was the point of writing the template? Was it only for that initial use case of showing the last sensor that triggered?
There’s simply not just 1 answer to this. You’ve got to remember the last_motion (using custom integration Variable) automation and template sensors were written some time ago (before Lovelace came along). Also, this is all done in the backend.
With core Lovelace, (strictly Frontend), you needed backend templates to reveal those last_changed data fields. Until a secondary_info line was introduced, which now can make that happen without any template at all.
Of course, there are other options, to minimize Lovelace card configs even further. Most notable would be to have a look at custom card auto-entities, and throw that at multiple or _globbed entities (seems to be what you ask?)
- type: custom:auto-entities
card:
type: entities
title: Motion sensors
filter:
include:
- entity_id: binary_sensor.*_sensor_motion
options:
secondary_info: last-changed
showing like:
no template used at all.
You can even combine that card with template-entity-row, to have each line configured exactly as you like (using Jinja templates in a Lovelace card config) …
Note though, that doing so doesn’t create any backend state sensor. If you need any data derived from those motion sensors, you’d still have to create template sensors for that (or use templates in an automation/script)
So again, its all up to you, and depending on your needs.
The options are endless.
(must confess the colors and icons are customized, and not in the Lovelace configs). The card will work without that too obviously, albeit not as nicely looking
OK, so I guess the answer is, it depends then, but if I were to pureful use button-config I’d need some JS, whereas template-entity-row accepts Jinja2… maybe that’s what Alex did in some fashion. I didn’t really need to to do it per se, I just wanted to understand.
Anyway, thanks for the explanations, it’s been very helpful and I have it working mostly how I want it now. There’s a lot of complexity here and standards vary a lot across customisations. The help could be expanded a lot. Seems there is a lot of local/assumed knowledge going and and you have to trawl through forums to work it out.
Now I just need to work out how to install Add-ons (like Samba) without Supervisor. The help says:
“Add-ons are only available if you’ve used the Home Assistant installer. If you installed Home Assistant using any other method then you cannot use add-ons (but you can achieve the same result manually).”
… which if I’m honest, isn’t very helpful I suppose I could just install it straight onto the pi.
Thanks again!
I basically used the template and applied it to all sensors and/or groups that I needed. Might not be the most efficient way, but it does the trick. For example:
’
since_last_motion_outdoor:
friendly_name: ‘Letzte Bewegung im Außenbereich’
value_template: >
{%- set up = as_timestamp(now())-as_timestamp(state_attr(‘automation.letzte_bewegung_im_aussenbereich’,‘last_triggered’)) %}
{%- macro phrase(name,divisor,mod=None) %}
{%- set value = ((up//divisor) % (mod if mod else divisor))|int %}
{%- set end = '' if value > 1 else '' %}
{{- '{} {}{}'.format(value,name,end) if value|int > 0 else ''}}
{%- endmacro %}
{%- set values = [phrase('w',60*60*24*7),
phrase('d',60*60*24,7),
phrase('h',60*60,24),
phrase('m',60)]
|select('!=','')|list %}
{{values[:-1]|join(', ') ~ ' ' ~ values[-1] if values|length > 1 else values|first}}
since_last_motion_storage:
friendly_name: 'Letzte Bewegung im Abstellraum'
value_template: >
{%- set up = as_timestamp(now())-as_timestamp(state_attr('automation.bewegung_im_abstellraum','last_triggered')) %}
{%- macro phrase(name,divisor,mod=None) %}
{%- set value = ((up//divisor) % (mod if mod else divisor))|int %}
{%- set end = '' if value > 1 else '' %}
{{- '{} {}{}'.format(value,name,end) if value|int > 0 else ''}}
{%- endmacro %}
{%- set values = [phrase('w',60*60*24*7),
phrase('d',60*60*24,7),
phrase('h',60*60,24),
phrase('m',60)]
|select('!=','')|list %}
{{values[:-1]|join(', ') ~ ' ' ~ values[-1] if values|length > 1 else values|first}}
’
After a while running the code, I also got the failure that you mentioned {% if state_attr(‘automation.update_last_motion_2’,‘last_triggered’) != None %}, but I neglected it, as it really appears very infrequent (once every week or so). It also does not seem to impact standard operation.
Ah thanks for that. So basically you made multiple copies of the template.
Which card did you use in that example? It looks like button-card but I couldn’t make it lay out like that.
I used an “entities” card and after Marius’ last input, I added the secondary_info to it, which made the look even smoother and produced the same result.
Only for “general movement within the house” I am still using sensors.yaml as I am checking if any of the motion sensors is triggered (as per Reolof’s example). I am using this for the movement status in my entities card, but also as trigger for the alarm system. To me this one pice of code was simpler than adding each motion sensor separately as trigger.