@Mutt Like I said, change the input_datetime to only track date and you’re done…
It is in a has time=false date time but the ‘time stamp’ (not the value) is the full “inaccurate” value
ie you can still get the time from a “has time=false” date time.
It just gives me a migraine
And pulling a value (ie ‘states’) in and converting that to a timestamp is WAAAAAY more hassle
@Mutt Lol, okay, air enough. But if you just use the replace(microsecond=0) and timestamp as data it saves you from the awkward %Y-%m-%d %H:%M’~’:00 dance…
[edit]Quick check, it does not. I have a input_datetime which I set with a now().timestamp() and the last value is 1617746400 which is Wednesday, 7 April 2021 00:00:00. And I can tell you, I’m not that accurate in pressing a button nor did I clean the little box at nightnight (Yes, that’s what it tracks)
Since we have some folks who like optimizing templates, shameless plug for my other thread soliciting for thoughts/opinions on my lighting rules approach:
I haven’t updated the example to eliminate using of last_changed
so I know that’s an issue.
I wasn’t at a workstation so I couldn’t reply properly (theres’ only so much you can do on a phone)
Anyway here’s what I get in the template editor using : -
{% set next_date = state_attr('input_datetime.id_meds_date_statin','timestamp') %}
next {{ next_date }}
datestamp equiv {{ next_date | timestamp_custom('%Y-%m-%d %H:%M:%S') }}
{% set today = as_timestamp(states.sensor.date.last_changed) %}
today {{ today }}
datestamp equiv {{ today | timestamp_custom('%Y-%m-%d %H:%M:%S') }}
{% set delta = ((next_date - today) / (24 * 60 * 60)) | round(0) %}
delta {{ delta }}
diff {{ (next_date - today) }}
{% set days = ((next_date - today) / (24 * 60 * 60)) | int %}
which is {{ days ~ "d " ~ (next_date - today) | timestamp_custom('%H:%M', false) }}
This is just after a forced restart to help with the demostration
This demonstrates that I don’t get the proper answer (which should be a ‘delta’ of 51 days). Even when using last changed without a reboot I get 50d 23:59 (which may or maynot resolve to 51 with a little coaxing) The point is - it doesn’t generate the number I need which is 51 (in this case) hence why I did it like I did. (that’s not to say there may not be a better way but … haven’t seen one yet AND this is only at most 2 days old, I may come back and finesse it later).
For clarity : -
Edit : You are right about the datetime only holding the date, dunno how I missed that.
I guess I’m spending tomorrow clawing a few microseconds per evaluation back
My OCD again.
You already have pnbruckner and Taras on that thread (two of the best guys I know (literally !))
My two cents would be two automations and one helper (input boolean)
the normal activity is lights on at sunset-15m and off at 01:00 UNLESS input_boolean.gdoor is on.
input_boolean.gdoor is put on when (dark- obviously) and the door opens and turned off when the timer expires
You can also do the same for the other automation so the door doesn’t switch the light off at say 21:15 (or you could repeat the conditions of the sunset automation) The point is - helpers are there to help you pracis other code into an individual state that can be reused easily.
Edit: I read further and see that @septillion suggested pretty much the same thing
You shouldn’t cross thread post like this, you should maybe tag them for their attention in that thread (but that can sometimes be considered rude )
@Mutt That’s because you grab it from a last_changed. But you can fix that by rounding up or by using a date object.
So
{% set next_date = state_attr('input_datetime.id_meds_date_statin','timestamp') %}
next {{ next_date }}
datestamp equiv {{ next_date | timestamp_custom('%Y-%m-%d %H:%M:%S') }}
{% set today = as_timestamp(states.sensor.date.last_changed) %}
today {{ today }}
datestamp equiv {{ today | timestamp_custom('%Y-%m-%d %H:%M:%S') }}
{% set delta = ((next_date - today) / (24 * 60 * 60)) | round(0, 'ceil') %}
delta {{ delta }}
diff {{ (next_date - today) }}
{% set days = ((next_date - today) / (24 * 60 * 60)) | int %}
which is {{ days ~ "d " ~ (next_date - today) | timestamp_custom('%H:%M', false) }}
Or with date() (I think, harder for me to check without your variables)
{% set next_date = (now().fromtimestamp(state_attr('input_datetime.id_meds_date_statin','timestamp')).date() ) %}
next {{ next_date }}
{% set today = states.sensor.date.last_changed.date() %}
today {{ today }}
{% set delta = (next_date - today).days %}
delta {{ delta }}
I have to admit, That’s pretty damn good
I’ve never come across the Jinja2 ceiling command before - round(0, ‘ceil’)
In Excel it’s common but then so is adding 0.5 and rounding as Excel ‘actually rounds’ (Jinja2 is a different matter, you have to test every assumption)
I also like the .date()
bit which is self explanatory but the : -
(now().fromtimestamp(state_attr('input_datetime.id_meds_date_statin','timestamp')).date()
Is NOT
you’re gonna have to explain that one as I don’t see where now() comes in to it.
But the upshot I get is that : -
"{{ (states.sensor.date.last_changed.replace(hour=0,minute=0,second=0,microsecond=0) + timedelta(days=(states('input_number.in_meds_days_statin') | int))).strftime('%Y-%m-%d') }}"
Could just become : -
"{{ (states.sensor.date.last_changed.date() + timedelta(days=(states('input_number.in_meds_days_statin') | int))).strftime('%Y-%m-%d') }}"
Or even as a timestamp …
"{{ (states.sensor.date.last_changed.date() + timedelta(days=(states('input_number.in_meds_days_statin') | int))) }}"
And that my test simply use the ceiling to ensure everything is ‘bob on’
Many Thanks I’ve learned something good today
OK–back to the original topic.
I think it’s a bug in the UI. I think I can better characterize the issue now.
I’m using core-2021.4.0, and I think it starts when you change the date and time of the widget.
When you call input_datetime.set_datetime
only the time will update. Multiple calls with same date will continue only to update the time. The date will not correct itself until you make a subsequent call to input_datetime.set_datetime
with a different date than the first service call. I’m fairly certain that this is different buggy behavior that I observed in core-2021.2.1 yesterday, where two calls with the same datetime
would fix the issue.
Looks like it might be the same issue as #8813 that @baunan mentioned. I originally dismissed this since I assumed it would be in core-2021.4.0, but it was merged literally 3 days ago.
There is a ceil formula in Excel too.
Yeah, I have to agree with you. This is because states()
always returns a string (str
), whatever the datatype. Even input_datetime
is just stored as a str
. And second the lack of being able (as far as I know) to call constructors. So making the input_datetime
a datetime
-object is a bit hard.
The cheat is to grab a datetime
-object, for example now()
, and call fromtimestamp()
on that object to have a new datetime
-object with the desired date and time set. now()
basically acts as pointer to the datetime Python library.
But yeah, the whole “states() always returning a str” is on my list for a What the heck month. I think it would be very useful if states()
would return a suiting datatype and only revert to str
if it does not know. Especially for helpers it’s always known what the expected datatype is. input_number
=> float
, input_boolean
=> bool
etc. A states()
on an input_datetime
could just return a datetime
-object (or even a date
-object or a time
-object if it would check has_time
and has_date). I mean, we also always have to add a
floator
intfilter to every
input_number`` we want to do math on
I did a test and I’m a bit amazed…
First of, I made a test input_datetime
with time and date. It was set to ‘2021-04-09 00:00:00’. Did a service call with datetime: '2021-07-08 12:34:56'
. This correctly set the input_datetime
without a problem. So I don’t see a bug there.
But then I played with it a bit more, setting the datetime a couple more times to different values. Looking at it from dev tools => states it updated every time. Then I opened the info. First thing I noticed is that ill will show already a change when you open up the details tab (without actually changing the values). But even weirder, this is how the history looked. Mind you, I used a couple of different date and times
The history graph does reflect that but the logbook entries all show setting it to the last value! So it seems to me the setting part is correct but the storing/retrieving from history values in the logbook is broken!
[edit]Now scanning through the GitHub issue, I think I opening details wasn’t flagged as change but it’s because a call with datetime
causes two changes.
Yes, that’s what I said : -
But there’s more than one way to skin a cat - as I went on to say
There has been work on the Jinja2 interpreter.
Historically storing all values as strings was just easier.
The data arrays were just of one type.
I don’t think that’s going to change but the way the Jinja2 values are produced have (this may be the way yaml interprets them so a grey area)
Anyway, there are circumstances where you don’t get a string (it’s why testing assumptions in the templating tool is so important (but there are issues with that too (see later) ).
Most recently where stored strings have (occasionally) incorrectly been interpreted as numbers, specifically codes passed to infra-red control devices. For some reason they are seen as exponents. I don’t remember the full details as its not an area I play in (I have no devices requiring infra-red control) (I think Tom_l and Taras were in that discussion thread if you want to search).
So it seems that the ‘conversion’ (if any) is being done on the fly based on what the stored value ‘looks like’ rather than “this came from an input boolean - it must be a boolean”
You have to bear in mind any project starts with the best of intentions as yet on day one compromises are made. Given the nature of the current ‘minimum hardware recomendations’ compared to the first pass, it’s at least an order of magnitude.
Regardless, we carry our baggage with us and changing the database structure or the way values are parsed may affect many things (causing major breaking changes a cross the board would not be popular. Even your example that input numbers are float is arguable as it may have been intended as an integer (this should not affect calculations from it but … ) Generally casting an int to an int (or any number to a float) or a timestamp to a timestamp etc. Should not be a problem but will they take that risk ? You could argue that storing a value to an input number implicitly declares it a float, thus the evaluation from it should the same.
I liked your explanation as it assumes no background knowledge (the thread should be able to be read by ALL)
I think (I’m gonna have to check) that my text method of getting a timestamp is about the same length as your now() method and maybe more intuitive/readable but I’ll have to run timings on it as regardless of what I’ve said I may well go with the faster version.
TL;DR
It’s always best to test thoroughly any template, passing ranges of expected values and also checking what happens (say) when a sensor value is ‘unavailable’
Edit: I forgot about “later”
If I enter : -
{{ states | count }}
In the templating tool I get : - 1183
If I create a sensor with the same statement, it displays : - 1051
Edit : I have since done an update to core-2021.4.1 and now ‘both’ versions report 1188
I never saw it, out of curiosity, do you have an example? I also couldn’t find a method or filter to just show the type. Only some tests for float for example.
You would say a date from datetime
would look like a date
True it could also be used as an int
but at least you can do calculations with it. And “float” is how they are stored in text as well, even if you set an input_number
to whole numbers only, it is stored as 3.0 etc. That’s why I think float
would make sense and gives you the option to cast it to int later on.
Think the risk is pretty minimal as all those types can be printed as a str
without casting. So places where they are now used as a str
still work. Alternative option would be to give us at least filters or converters to the types you can already have in a template (like datetime
, time
and date
). Just doing states()|date
would already be more readable / easier.
Agreed but checking that isn’t particularly easy at the moment.
Interesting. I did a quick check and here the sensor and the template tool agree. Although only after I checked when HA was fully started, template tool didn’t update automatically.
Think that sums it up
An example (but one of several I think) : -
When you search, you have the ‘options’ link, which gives you more ‘options’
Re: the unavailable problem, Petro has expounded at great length on this issue. Again search for unavailable and add Petro as the poster
The devs (for the most part) are unpaid individuals. They ‘choose’ the work they do based on what they feel capable of and what interests them. There are a few devs paid by Nabu casa but we’ve given up trying to predict where they will focus their attention.
The issue with the history I wrote about in this thread:
All I got was “it’s being worked” with no reference to a particular defect report.
Regarding your test, all I can say is your version of software may matter, as well as the browser/OS you’re using.
I find it a bit hard to pinpoint the issue and I’m certainly not the person to open an issue about it
About software:
- HA 2021.4.1
- Window 10 x64
- Firefox (I assume my laptop also uses the same version as my desktop aka 87.0 (64-bit))
Well, there you go. You’re on 2021.4.1 and I’m on 4.0. Of course, I don’t know why I wasn’t upgraded to 4.1 when I upgraded to the latest version 2 days ago.
I believe the latest version is less than two days old.