Last Notification sensor w/ consecutive notifications on Android

I’ve noticed a little strange behavior when making automations using the last_notification sensor. I am using Android.

On the app, I have the sensor enabled, and am using an AllowList with only one App (DoorDash).

If a DoorDash notification arrives before I have dismissed the previous one (I.e., the previous DoorDash notification is still in my list of notifications on my phone), then the sensor will not contain the actual text from the notification second. Instead it will just be “com.dd.doordash”.

Since DoorDash notifications come in clusters, in order to make it behave correctly, I need to be very diligent about dismissing each notification as it comes in… and if i am not, then my automations break,

Has anyone else seen this?
Can anyone else repro this behavior?

1 Like

use the active notification sensor to look at individual notification details

Interesting.
I did have it working using that sensor at one point, but it caused other issues.

It has to use a template to iterate through the 100s of attributes of the sensor every time my phone gets any notification. It feels really inefficient.

Also, when a notification I am interested in comes in, my automation runs… but then, if any other app on my phone causes the sensor to update again before I dismiss the notification I care about, then it re-triggers my automation again. I could iterate through all the attributes of BOTH the from_state and the to_state to detect a new notification but then it is even more inefficient. (Assuming from_state objects even have attributes?)

The active notification count just feels like the wrong tool for the job.

On the other hand, the last notification sensor with an allow list feels like it is meant to be used for this purpose. … Except for this strange behavior.

I suppose I could use the last notification sensor to trigger the automation, and then detect the weird failure case, and only then enumerate the active notification sensor’s attributes? It just feels messy.

Is this not a bug in the last notification sensor?
I feel like this probably isn’t the intended behavior.

1 Like

Based on everything you have mentioned can you share your sensor settings for Last Notification? The only time the app will send notifications from any app is if the setting is checked. Or something may be corrupted because if you have an allow list for only 1 app and you are not disabling the allow list then you should only get updates any time that 1 app posts a notification.

Sure,

The Last Notification sensor is enabled, I have DoorDash as the only app in the Allow list. And “Disable allow list requirement” is off.

The Active notification count sensor is disabled. (I don’t think it has any settings to set beyond that)

I think the Last Notification sensor is updating at the expected times. It only updates when DoorDash sends a notification. The issue is with the content of the message when it comes through. It is either the content of the notification, which feels correct… or it is just “com.dd.doordash” if I did not dismiss the previous dd notification before a new one comes in.

1 Like

that is correct and expected behavior for the notification as it becomes a grouped notification at that point which is where the active notification sensor helps by reading the individual notification instead of the group. Its possible doordash updated their app and how notifications are sent so to combat that you should probably adjust the automation so it only runs when you want it to.

Look at all the attributes specifically the group id and see if that changes?

Oh interesting. The grouped notification thing makes sense.

I guess I can turn on the Active notification count sensor, and then try to come up with a template expression that evaluates to the “text of the most recently issued doordash notification”… yikes. Not looking forward to that.

Thanks for the info and help!

Thinking more about it…
I might try to argue that the Last Notification sensor should probably not actually behave this way. Why is this behavior preferable to the behavior I was expecting?

the last notification sensor will relay the last posted notification, a grouped notification is still a notification that exists as 1 item on the status bar. This is the way the sensor has always behaved. We get updated data and send the data, nothing more beyond that.

Yeah, I suppose I see that.

It does make perfect sense from the perspective of the code and structures in the OS, etc., and I see why it behaves the way it does.

That said… I tend to think of the “Notifications” as the things inside the group, not the group itself. And then the group is a UI abstraction to cluster similar notifications together, not a first class “Notification” on its own. Kind of like the distinction between a files and directories. With that perspective, this behavior feels like the sensor is being a bit coy.

The sensor is saying “There is now one more notification from app X in the same group as an existing notification”, and I am not seeing why that is useful when compared to just giving the content of the new notification.

More on the last notification sensor behavior

I was playing with this tonight trying to come up with an “active notification count” based approach (which I did accomplish, and is below for anyone interested).

But I made another interesting discovery about the last notification sensor behavior: It is only the 2nd notification that is different. The 3rd and subsequent ones work the way I would expect.

I think what is happening is something like this:

  • First notification comes in. The sensor updates, and uses the notification for its content.
  • Second notification comes in, the sensor does not have time to update before (e.g) 271ms later a notification group is created, and the original notification and the new one are both placed inside it. The sensor updates, and uses the newest notification for the content (which is the group, because it is newer). I expect that if the sensor update was fast enough to update between the notification and the group, it would probably fire my automation twice, and I could ignore the one with no content.
  • A third notification comes in, and is placed in the group with the others, but no new group is created. The sensor updates, and uses the newest notification for its content (which is not the group).

I feel like this is surprising behavior. I don’t know if this is specific to the doordash app or not. If all apps behave similarly, it might be worth addressing it.

But, until then…

Using active notification count instead

For future travelers, this is the relevant bit of what I ended up doing in my automation to get around the “2nd notification in a group strangeness”:

  - variables:
      message: >-
        {%- set ns = namespace(max=0, msg=None) -%} {%- for attribute, value in
        states.sensor.thylacine_active_notification_count.attributes.items() -%}
        {%- if attribute.startswith('com.dd.doordash_') and
        attribute.endswith('_post_time') -%} {%- set msg =
        state_attr('sensor.thylacine_active_notification_count',
        'android.text_com.dd.doordash_' + attribute.split('_')[1] ) -%} {%- if
        msg != None and value > ns.max -%} {%- set ns.max = value -%} {%- set
        ns.msg = msg -%} {%- endif -%} {%- endif -%} {%- endfor -%} {{ ns.msg }}

(thylacine is the name of my phone)

Not pretty by any means, but it does seem to work.

A more readable version of that mess is:

{%- set ns = namespace(max=0, msg=None) -%}
{%- for attribute, value in states.sensor.thylacine_active_notification_count.attributes.items() -%}
  {%- if attribute.startswith('com.dd.doordash_') and attribute.endswith('_post_time') -%}
    {%- set msg = state_attr('sensor.thylacine_active_notification_count', 'android.text_com.dd.doordash_' + attribute.split('_')[1] ) -%}
    {%- if msg != None and value > ns.max -%}
      {%- set ns.max = value -%}
      {%- set ns.msg = msg -%}
    {%- endif -%}
  {%- endif -%}
{%- endfor -%}
{{ ns.msg }}

It finds the most recent notification that has a defined android.text attribute. There may be nicer ways to do it, but this is clean enough for me.

The idea is that there are attributes like com.dd.doordash_2147483647_post_time which say when (in ms) the notification was posted. That number in the middle is some sort of identifier is used to disambiguate the notifications that are from the same app.

Then you use that id to look up the text in the corresponding android.text_com.dd.doordash_2147483647 attribute (and skip it, if it is not defined), and only keep the one with the highest post time.

My automation still triggers off of the last notification sensor so that it only evaluates this mess when a doordash notification is posted (thanks to the allow list on the sensor), but it uses the attributes of the active notification count sensor to get the text, and at least so far, it seems to work. I have not seen any issues with a race condition between the two sensors (yet, anyway), though it might be wise to put a short (1sec?) delay at the top of the actions before you set the message variable using this code.

I hope this is useful to someone someday. :slight_smile:

What is an Allowlist? How do i create one?

By default the Last Notification and Last Removed Notification will not send any data as the allow list is blak. The allow list is a list of applications that are allowed to send notification data back home.

Settings > Companion App > Manage sensors > last notification > add your desired apps under the sensor settings

So HA core does not allow for historical data to be added, apps can only send the latest update. In this case yes there is potential to miss a notification as a result of the app not being able to send the first update. If you are seeing something like a delayed notification try to change the battery optimization settings for the app in question to see if that speeds up their delivery.

this is going to vary from use case to use case, device to device and app to app. The way the app works is that we register for updates to the status bar. If the incoming notification that is posted is one to be sent (allow list) we send the update, otherwise we ignore. We don’t know if a notification is going to change into a group once its posted. Groups are handled by apps and also the OS, if an app sets a group much like you can with our own notifications then groups get created immediately. If apps dont set a group and post more than X (OS controlled Pixel device is 4) amount of notifications without a group then the OS will create a “ranker_group” to add them to. The OS handles a lot of it, we can just subscribe to updates and send as needed.

1 Like

Thank you for sharing all this. This was the exact issue I was hitting with the last_notification sensor. I agree with you and share your frustrations, the change in behaviour of the sensor when there are multiple notifications from the same app unfortunately make it unreliable to use. You cannot predict whether the state will show the actual last notification information, or whether it will only show the package name if there are multiple notifications from the same app.

I would also make a case this sensor should be changed if it’s possible from a technical perspective.

I would much prefer to use the last notification sensor since it makes use of an allow list and would only update for specific notifications (better for battery I imagine) than have all notification information data sent on a much more frequent basis.

This issue looks related, however it’s slightly different in the sense it still shows the state of some of the multiple notifications but misses some, while mine just shows the package name and nothing else.

After using the active_notification_countattributes, I have found them to be similarly unreliable, but in different ways. The most frustrating thing is that some notifications just sometimes do not show up. I.e., the sensor does not update in some cases.

So… the TL;DR of it all is: I do not have a reliable or robust way to get notifications from apps and make them actionable in HA.

I am going to try to use some sort of hybrid approach… like trigger off of the last_notification sensor, but with a few seconds of delay (to give the active_notification_counta chance to be updated too), and then use the last_notification content, unless it is just the package name… and only in that case resort to the active_notification_countattributes using code similar to above.

This is definitely an ugly hack.

1 Like

I had a similar problem.

In the HASS Android application, when the Last Notification sensor is activated, everything works fine. But a few hours later, a problem occurs. When a new notification is received (from apps in the “Allow list”), the sensor data in the app is not updated. It remains in the data it received the last time it worked.

The same problem occurs on my both mobile devices.

Probably not same issue since you say you receive a notification but do you have lot of notifications on your phone when this happens? Android only allows a limited amount of notifications in the notification drawer/tray or whatever’s it’s called as I found out this week. So I installed macdroid to run a macro every X minutes to clear notifications; you can get it to clear from certain apps or clear all. This seems so have to have resolved my issue with the sensor not updating.

It’s not about many notification. Even a single notification doesn`t change the sensor data on companion app.

Do you think this problem is related to the sensor on the device side or the server side? I think the problem is with the device. Because devices sensor shows the last notification data where received a few days ago.

P.S.: i am using this sensor with Allow list(2 app in allow list)

quick question, what format is the “time” or “post_time” in this attribute?

milliseconds

https://developer.android.com/reference/android/service/notification/StatusBarNotification#getPostTime()