Strange behaviour with next_alarm entity provided by HA App

So the timestamp provided is that which your device reports as local time. That is what you see in time in milliseconds, that is pure raw data from the android API. If you are referring to what the Front end is displaying to you then that is entirely different from what the app provides. We only take the system provided time and convert the state to UTC format since that is what the front end expects and the attributes remain as local time to help the user with less conversions.

ok. But why is there an offset between the next alarm entity and the information the companion app provides? Is there maybe an error or rounding error in code mentioned above?

Here is all the logic for this sensor, as you can see we dont do any rounding

I have very similar issues as pete does.
I also have a sensor that formats the time that is based on the same principle.

Yesterday it was correct. (I have the same alarm time every day)

Look at Andreas alarm here:


I see you guys are using templates, if you don’t use templates does the state change at all or is it as expected?

You can see if templates from this thread help: How to use next alarm sensor

This is the template I’m using

It doesn’t do anything more than change the format.
The strange thing is that some days it’s +1 min and sometimes -3 mins and anything in between.

I believe it’s a problem with jinja/HA not the app, to be clear.

If I use this:

And input this: 1604463400000

I get 5:16

More than likely its a jinja issue. One thing we added recently to the beta version of the app is sleep as android integration…The sleep as android app has some neat events that may do away with some of this templating. For example you can tell when an alarm was triggered, snoozed or even dismissed. No need for templating or looking at the time etc…

Here is the problem…
There is 100 seconds difference on the as_timestamp and the timestamp in milliseconds.

Whatever is creating the attribute is doing it wrong… or differently than as_timestamp at least.

This is raw data from google as I mentioned up above. We don’t change it and only convert to date/time in UTC format as you can see in the code linked up above.

Yes I see that too.
But something makes a change in the timestamp.

But as I said before, it’s not enough to cause an issue and definitely not enough to do more debugging in my opinion.

in my case there is an offset of exactly 60 seconds.

{{ (state_attr('sensor.pixel_4_xl_next_alarm', 'Time in Milliseconds')) / 1000 }}
{{ (as_timestamp(states('sensor.pixel_4_xl_next_alarm'))) }}
1604436360.0
1604436300.0

So, that means the timestamp is being shown incorrectly while the template to trigger the condition should be accurate in case we leave out the timestamp function, right?

I believe we can use as_timestamp of the state instead of state_attr of time in milliseconds and it will be correct.

Right, that seems to work.

current time      : {{((as_timestamp(now())|int ) | timestamp_custom('%a %h %d %H:%M %Z %Y')) }}
alarm time        : {{((as_timestamp(states('sensor.pixel_4_xl_next_alarm'))|int ) | timestamp_custom('%a %h %d %H:%M %Z %Y')) }}
current time sec  : {{(as_timestamp(now())|int ) }}
alarm time sec    : {{((as_timestamp(states('sensor.pixel_4_xl_next_alarm'))|int - 0*60 )) }}
trigger condition : {{((as_timestamp(now())|int )) == (((as_timestamp(states('sensor.pixel_4_xl_next_alarm')) | int) - 0*60 ))}}

Best

I changed my template and it’s correct today at least.
We’ll see what happens.

I’ve noticed a similar issue, with this template:

State: {{ states('sensor.steves_phone_next_alarm') }}
Attribute: {{ state_attr('sensor.steves_phone_next_alarm', 'Time in Milliseconds') / 1000 }}
State as Timestamp: {{  (as_timestamp(states('sensor.steves_phone_next_alarm'))) }}

returning

State: 2020-11-04T15:25:00.000Z
Attribute: 1604503470.0
State as Timestamp: 1604503500.0

Looking at the code, I wonder if it is because the next alarm time returned by the AlarmManager is a Long but the SensorManager is treating the “Time in Milliseconds” attribute as a float (Long and Float are both subclasses of Number):

This could be resulting in floating point conversion issues.

I realized that the now() function can’t be used for triggering automations.

therefore, here’s a little update on the template which seems to work now:

{{ ((as_timestamp(states('sensor.date_time').replace(',','')) | int) + 1*60) == ((as_timestamp(states('sensor.pixel_4_xl_next_alarm')) | int)) }}

of course one need to create a template sensor for this:

- platform: time_date
  display_options:
    - 'date_time'

the .replace(’,’,’’) still feels a bit hacky but this seems to be the only option to get reasonable values from sensor.date_time

I’ve confirmed that the floating point conversion is likely to be the cause of the issue by running this code in an online Kotlin compiler:

fun main() {
    val originalTimeStamp: Long = 1234567890;
    val timeStampString = originalTimeStamp.toString();
    val timeStampFloat = timeStampString.toFloat();
    val timeStampLong = timeStampString.toLong();
    System.out.format("Original %d\n",  originalTimeStamp);
    System.out.format("String %s\n",   timeStampString);
    System.out.format("Float %f\n",   timeStampFloat);
    System.out.format("Long %d\n",   timeStampLong);
}

and getting this response

Original 1234567890
String 1234567890
Float 1234567936.000000
Long 1234567890

So, the alarm timestamp is being converted from a Long into a string (to store it in the app database) and then back into a Float which is causing the value to change. If it is converted from the string into a Long, the same issue doesn’t occur.

Nice research! Did you want to submit a PR to get this corrected since you spent the time to see where the issue happened? :slight_smile:

I’ve created a PR with the change:

I’ve tested this fix in Android Studio with an emulated device, and the “Time in Milliseconds” attribute (when divided by 1000) exactly matches the timestamp from the state.

2 Likes