Strange behaviour with next_alarm entity provided by HA App

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