Ah I see sorry.
no doesn’t work:
Does it work with the hard coded value?
What version of HA are you running?
try separating the states() into it’s own variable then.
keep getting the identical results
fear I must let it go, frustrating as it is…thanks for you relentless help !
It’s 100% the format of the states() result because hardcoded works. try stripping whitespace with .strip() on the states() variable.
dont know why, but this now seems to work:
though
{{relative_time(strptime(states('sensor.solaredge_last_updatetime'), '%Y-%m-%d %H:%M:%S'))}}
still give me the ‘Unknown error rendering template’
cause you aren’t stripping the whitespace. Seems like a bug in whatever code is creating the solaredge_last_updatetime
{{relative_time(strptime(states('sensor.solaredge_last_updatetime').strip(), '%Y-%m-%d %H:%M:%S'))}}
No, ive tried that, and it doesn’t work (or make a difference):
btw, I now notice this in the home assistant log:
2020-03-10 22:47:17 ERROR (MainThread) [aiohttp.server] Error handling request
Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/aiohttp/web_protocol.py", line 418, in start
resp = await task
File "/usr/local/lib/python3.7/site-packages/aiohttp/web_app.py", line 458, in _handle
resp = await handler(request)
File "/usr/local/lib/python3.7/site-packages/aiohttp/web_middlewares.py", line 119, in impl
return await handler(request)
File "/usr/src/homeassistant/homeassistant/components/http/real_ip.py", line 39, in real_ip_middleware
return await handler(request)
File "/usr/src/homeassistant/homeassistant/components/http/ban.py", line 72, in ban_middleware
return await handler(request)
File "/usr/src/homeassistant/homeassistant/components/http/auth.py", line 135, in auth_middleware
return await handler(request)
File "/usr/src/homeassistant/homeassistant/components/http/view.py", line 123, in handle
result = await result
File "/usr/src/homeassistant/homeassistant/components/api/__init__.py", line 388, in post
return tpl.async_render(data.get("variables"))
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 221, in async_render
return compiled.render(kwargs).strip()
File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 1090, in render
self.environment.handle_exception()
File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 832, in handle_exception
reraise(*rewrite_traceback_stack(source=source))
File "/usr/local/lib/python3.7/site-packages/jinja2/_compat.py", line 28, in reraise
raise value.with_traceback(tb)
File "<template>", line 1, in top-level template code
File "/usr/local/lib/python3.7/site-packages/jinja2/sandbox.py", line 462, in call
return __context.call(__obj, *args, **kwargs)
File "/usr/src/homeassistant/homeassistant/util/dt.py", line 195, in get_age
delta = now() - date
TypeError: can't subtract offset-naive and offset-aware datetimes
could this be the error we’re facing here (thought an unknown error was unknown… apparently the log show what’s going wrong after all)
ah, you need to add a fake timezone to it.
hmm. I’ve found this as solution, but can’t use it presumably. As I am guessing and not yet understanding the core issue at hand, I need some assistance…
.replace(tzinfo=None)
Look at strftime.org figure out whats expected when you use the timezone format, add that to the string and your format.
must be completely missing the point, but anything I try with relative_time throws the template error. This is what does work but leads to nothing:
adding the timezone %z to the strptime doesnt change the output, so probably wrong too…
yes you are missing the point… if you were to add a timezone to the string and the format… it would look like this:
states('sensor.solaredge_last_updatetime') ~ ' +0000'
and your format would be
'%Y-%m-%d %H:%M:%S %z'
EDIT: And I just tested your as_timestamp | timestamp_custom and it worked. Didn’t work for you because you reversed the date and time…
{% set ts = states('sensor.solaredge_last_updatetime') %}
{% set fmat = "%Y-%m-%d %H:%M:%S" %}
{% set tz = " %z" %}
{% set ts2 = as_timestamp(strptime(ts, fmat)) | timestamp_custom(fmat ~ tz) %}
{{ relative_time(strptime(ts2, fmat ~ tz)) }}
yes! his is indeed working as hoped for, thank you very much!
devil is in the details… sorry bout that. this is one for the templates cookbook. thx again.
update
of course the base states('sensor.solaredge_last_updatetime')
we worked with here was my current template sensor, so I changed that into:
solaredge_last_updatetime:
friendly_name: 'SolarEdge last update'
value_template: >
{% set ts = state_attr('sensor.solaredge_overview','lastUpdateTime') %}
{% set fmat = "%Y-%m-%d %H:%M:%S" %}
{% set tz = "%z" %}
{% set ts2 = as_timestamp(strptime(ts, fmat)) | timestamp_custom(fmat ~ tz) %}
{{ relative_time(strptime(ts2, fmat ~ tz)) }} ago
with the solar edge.overview being a rest sensor, providing all the details:
- platform: rest
name: Solaredge overview
resource: !secret se_overview_resource
value_template: >
{{value_json.overview.currentPower.power|round}}
unit_of_measurement: 'W'
json_attributes_path: '$.overview'
json_attributes:
- lastUpdateTime
- lifeTimeData
- lastYearData
- lastMonthData
- lastDayData
- currentPower
- measuredBy
scan_interval: 400
resulting in:
lot of effort in such a small entity-row
thanks!
Hi @petro,
Think I need to get back on this. Every once in a while the ret sensor doesnt get data, resulting in:
2020-03-19 22:21:28 ERROR (MainThread) [homeassistant.helpers.entity] Update for sensor.solaredge_last_updatetime fails
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 279, in async_update_ha_state
await self.async_device_update()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 474, in async_device_update
await self.async_update()
File "/usr/src/homeassistant/homeassistant/components/template/sensor.py", line 224, in async_update
self._state = self._template.async_render()
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 221, in async_render
return compiled.render(kwargs).strip()
File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 1090, in render
self.environment.handle_exception()
File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 832, in handle_exception
reraise(*rewrite_traceback_stack(source=source))
File "/usr/local/lib/python3.7/site-packages/jinja2/_compat.py", line 28, in reraise
raise value.with_traceback(tb)
File "<template>", line 1, in top-level template code
File "/usr/local/lib/python3.7/site-packages/jinja2/sandbox.py", line 462, in call
return __context.call(__obj, *args, **kwargs)
File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 813, in strptime
return datetime.strptime(string, fmt)
TypeError: strptime() argument 1 must be str, not None
Ive tried to add a test for existence first, so not to error out, but that doesnt seem to help. Could you please check I did it correctly:
solaredge_last_updatetime:
friendly_name: 'SolarEdge last update'
value_template: >
{% if states('sensor.solaredge_overview') != None %}
{% set ts = state_attr('sensor.solaredge_overview','lastUpdateTime') %}
{% set fmat = '%Y-%m-%d %H:%M:%S' %}
{% set tz = '%z' %}
{% set ts2 = as_timestamp(strptime(ts, fmat))|timestamp_custom(fmat ~ tz) %}
{{relative_time(strptime(ts2, fmat ~ tz))}} ago
{% else %} Unknown
{% endif %}
thanks if you would
looks like the lastUpdateTime is None. Check for that instead.
like this:
{% if state_attr('sensor.solaredge_overview','lastUpdateTime') != None %}
{% set ts = state_attr('sensor.solaredge_overview','lastUpdateTime') %}
{% set fmat = '%Y-%m-%d %H:%M:%S' %}
{% set tz = '%z' %}
{% set ts2 = as_timestamp(strptime(ts, fmat))|timestamp_custom(fmat ~ tz) %}
{{relative_time(strptime(ts2, fmat ~ tz))}} ago
{% else %} Unknown
{% endif %}
I would have thought the full rest sensor to be unavailable and as a consequence so would its attributes (of which lastUpdateTime is one). That’s why I hoped to make it easier and test for that rest sensor.
Will test and report back if necessary. thanks.
I figured out from For_less_than: time that the better way to do this is:
{{ as_timestamp(now()) - as_timestamp(state_attr('sensor.solaredge_overview','lastUpdateTime'))| int }}
not sure what you mean to be better, but what you post hardly is a replacement for what I was looking for?:
btw, why I didnt come up with this:
{{relative_time(states.sensor.solaredge_overview.last_changed)}}
before is beyond me. It doesnt yield the same outcome as the larger template, but is very useable info…difference is the relative_time sensor is based on the states machines state for the sensor, while the template sensor is based on the attribute lastUpdateTime
the SolarEdge data returns. Which seems to be 1 cycle behind:
btw 2 if you’re looking for simpler ways to write those less than X time ago
templates try this:
{{(now() - trigger.from_state.last_changed).total_seconds() > X|int}}
using this in my setup all the time:
{{(now() - trigger.from_state.last_changed).total_seconds() >
states('input_number.presence_timer')|int}}
so you can control the timing in the frontend.