Alert2 - a new alerting component

Hi All,
I took a shot at improving alerting and would love to get feedback. I created a new component, Alert2. The main features beyond what the existing Alert component does are:

  • Native event-based alerting. No need to approximate it with conditions and time windows.
  • Template conditions. No need for extra binary sensors. Also means the logic for an alert is in one place in your config file, which makes it easier to manage.
  • Snooze / disable / throttle notifications. Handy for alerts that fire frequently. Example: a temperature sensor that hovers right around a threshold.
  • Persistent notification details. In your HA dashboard, you can view past alert firings as well as the message text sent in notifications.
  • Custom frontend card. Makes it easier to view and manage recent alerts.
  • Hysteresis. Reduce spurious alerts as sensors fluctuate.
  • Template notifiers. Dynamically specify who gets notified.
  • Generator patterns. Dynamically define multiple similar alerts, with wildcard support.

Alert2 also includes a lovelace card showing just recently active alerts, with controls for ack’ing:

overview

And here’s what the more-info dialog looks like when clicking on an alert2 entity. It shows firing history as well as notification messages sent, and controls for snoozing and disabling:

Also, the component includes a python task creation helper that automatically fires an alert on un-handled exceptions. I’ve found that handy during component development for catching problems that would otherwise cause a task to silently fail.

I looked into adding features on to the existing Alert component rather than creating a new component, but the existing Alert component has some built-in assumptions that didn’t seem very compatible with Alert2 features.

Thanks for any thoughts.
-Josh

13 Likes

Snooze / disable notifications. Handy for alerts that fire frequently. Example: a temperature sensor that hovers right around a threshold.

Please consider adding a hysteresis field, like the builtin Threshold Sensor binary sensor includes. Hysteresis is the general solution to the motivating problem you mentioned - in my example it would mean (depending on implementation choices) that once the event fires (pressure goes above 100 pa in this example), it stays in the new state until pressure drops below 98 (100 minus 2), so that the value fluttering around 99-101 doesn’t result in a flurry of state changes.
20240730_133743_firefox_947

Alert2 looks better than the base Alert component in almost every way, but without hysteresis I wouldn’t be able to replace the extra binary sensor. I too find the need for the extra binary sensor an obnoxious and clumsy limitation of the Alert integration (really, everything about the Alert integration is clumsy).

Hi @tofof, thanks for the suggestion. I wonder what is the best way to add hysteresis. Two possibilities come to mind:

  1. Add a new config field, condition_numeric, that evaluates to a float. Add some other new fields hysteresis_* that specify the upper/lower limit and hysteresis value as in the Threshold sensor.

or

  1. Enrich the information available to the condition field so you can express hysteresis directly in the condition template. If I make the current alert state available as a variable in the condition template (eg in a variable this), that’d be sufficient. So your example above could be expressed as something like:

    condition: "{{ (this.state == 'off' && sensor.pressure > 100) || (this.state == 'on' && sensor.pressure > 98) }}"

    and I may even be able to make a function available to you to make it syntactically simpler to write:

    condition: "{{ hysteresis(this, sensor.pressure, 2, null, 100) }}"

Any opinion? My first impression is that option 2 seems clearer and easier to extend in the future.

I’d personally much prefer the first option; I don’t want to have to manually work out the logic of how to correctly implement hysteresis for myself every time I want to use it.

Good point. How about this form:

condition: "{{  threshold( states('sensor.test_pressure'),
            upperLimit=100, hysteresis=5 ) }}"

It uses a threshold() function that mirrors what the Threshold integration does. Thinking more on the design, I think doing it this way may be more flexible than adding extra fields to the config.

For example, I have a nest thermostat that sometimes reports a faulty value “32.0”. If I want to alert on low temperature with hysteresis but ignore the faulty value, I could express the alert condition as:

condition: "{{ states('sensor.nest_fl1_temperature') != '32.0'
             and threshold( states('sensor.nest_fl1_temperature'),
                            lowerLimit=50, hysteresis=5 ) }}"`

I think this would be more complicated to express if the alert config has extra fields like threshold_value, threshold_lower_limit, threshold_hysteresis.
What do you think?

Again, I think you need the fields. You’re not improving on the existing alert and threshold sensor setup compared to them otherwise.

OK, to express hysteresis via extra fields, how about adding a threshold section, like this:

alert2:
  defaults: ...
  alerts:
    - domain: myvessel
      name: high_pressure
      threshold:
        value: {{ states('sensor.my_pressure_sensor') }}
        maximum: 100
        hysteresis: 5
      message: "Pressure is {{ states('sensor.my_pressure_sensor') }}"

I think I now agree with you that extra fields is probably preferable to packing logic into a single condition field. It’s hard for me to see how additional forms of hysteresis could be packed into that single field - like triggering an alert only if a condition is true for a minimum amount of time, or not changing alert state at all for certain sensor values.

I didn’t totally understand your comment about enhancing the condition field not improving on the existing alert & threshold setup and think maybe I didn’t communicate what I had in mind clearly, but it’s a moot point since I don’t think it’s a good idea anymore.

@tofof and any others interested, I updated Alert2 to version 1.3, adding support for the value-based hysteresis we’ve been discussing, fixing a few bugs, making Alert2 more robust to config errors, and a few other improvements described on the project page.

Feedback welcome!

I think you should make it a priority to allow installation through HACS, you will have many more potential users and testers then :slight_smile:

1 Like

Agreed. I generally won’t install custom integrations unless I can manage them through HACS. This looks
 Interesting. But no HACS, no install here.

I have installed it since I think it has great potential, but I won’t be updating as often if it’s a manual thing and probably won’t use as much as I should because of this.

1 Like

Since I’m making suggestions anyway, another great thing is to make the repo a dev container. It greatly adds to the probability of help on the integration too (I might help for example). And also UI config flow for setting up the integration. :slight_smile:

I just updated Alert2 to support HACS install as of v1.3.1. As part of that, I had to move the accompanying Alert2 Lovelace card into a separate repository, Alert2 UI. I recommend installing the Lovelace card as well. I updated the instructions in the README in both repositories.

@teachingbirds and @NathanCu, thanks for the suggestion. Let me know what you think.

@teachingbirds, most of an Alert2 yaml config is a (lengthy) list of alert definitions. I didn’t think config flows were built for that kind of thing. I think of the list of Alert2 definitions as of the same flavor as lists of automations or scripts that a HA install typically has. So I wasn’t sure where would be better to put the Alert2 definitions.

Sincerely,
Josh

3 Likes

However much I appreciate this addition to our toolbox, I would like to advocate for the inclusion of some of the useful options the old (and admittedly somewhat weird) alert integration features :

  1. the equivalent of the ‘repeat’ option (with variable & multiple times) iso the single fixed notification_frequency_mins
  2. the (message) ‘data’ option, which makes for a much more flexible notification system, especially so when used in a mobile notification context
  3. to a lesser extent : the skip_first & the done_message options

Thanks nonetheless for your very promising contribution, and for eventually considering these FRs :+1:

1 Like

@pav, thanks for the suggestions. Can I get your opinion on a couple of details:

  1. For notification frequency management (e.g., the “repeat” parameter), how about config parameters similar to the following:

    • notification_frequency_min | list
      Similar to the existing “repeat”, takes a list of numbers. This list does not cycle but saturates at the last value of the list. Is there any use case in which cycling is useful?
    • reset_when_fires | bool=false
      When an event alert fires or a condition alert goes from off->on, if this parameter is true, the notification repeat logic resets, resulting in an immediate notification. If false, then the logic does not reset and a notification may not be sent until the next time specified in the list.
    • stop_after_gap | bool=true
      After an event or condition alert fires, do notificaitions continue until explicitly ack’d (even after a condition alert turns off) or do they stop once a time interval elapses larger than the current “repeat” value.

    Alternatively, I’m intrigued by the idea of making repeat take a template that evalutes to the next repeat value. I could expose variables in the template eval so you could express whatever logic you wanted.

    In addition to the above, snoozing or disabling notifications is also available.

  2. By default I annotate notification messages with extra information (like how long ago an alert started firing, how many events since last notification, etc). That probably interferes with the special “clear_notification” message that the mobile_app notification platform recognizes. So seems like I should also add parameters:

    • done_message | template
      Message used for notifications that a condition alert has stopped firing.
    • done_message_raw | bool=false
      Whether to annotate done_messages.

I’ll add the data field for notifications. And also the target and trigger fields.
Sincerely,
Josh

1 Like

I just redownloaded via Hacs and that works great, thanks for listening to feedback. It will be much easier to keep up with when new releases are coming out.

Would you rather that we make issues in github or continue communicating here? Or a good mix :smiley:

I have noticed some oddities. For example my old alerts are visible in the custom alert-overview, but not my alert2-alert. When I open more-info on an old alert the alert2 more-info opens, and sometimes the regular one is opened on top, and sometimes under it.
Edit: When the alert2 entity fired for the first time it showed up in your card.

I would be nice to add friendly names to the alert2 entities, both the automatic ones and the alerts themselves for better presentation.

It would also be nice to have the notifiers for the alert in the more-info dialog.

I was going to mention the data field for notifications but I see you’re already on top of that. It’s really important for me to be able to make some alerts into critical notifications on my phone for example. And also, be able to have actionable notifications so that we can acknowledge directly from the notification.

Agree on all points! Skip first is kind of important I think, since alerts for things like doors left open for example, you dont want an alert everytime someone opens the door to walk through it, but if it’s left open for 2 minutes, then alert. Might of course be possible with conditioning somehow.

@redstone99 Somewhat overwhelmed :upside_down_face: by your willingness to cater for my humble requests and by your very well thought-out suggestions concerning their implementation. I hereby offer my own remarks re 1) :

  • notification_frequency_min | list : I also cannot off the top of my head think of any use case for cycling the list
  • reset_when_fires | bool=false : this one has got me puzzled. Mostly so, because I never felt the need for having it NOT reset the repeat logic when firing the alert. But hey, who am I to question the need or usefulness of this option :innocent:
  • stop_after_gap | bool=true : I’ve always been ok with the notification repeating using the last value of the repeat list whilst the alert is still on and unack’d. But again : this is just me 
 :man_shrugging:

And re 2) I’m sure you’re right about the interference with the command-type pseudo messages of the mobile notifications. The ‘raw’ parameter should take care of that.
I would suggest though to not limit its applicability to the done_message, but have it at the ‘general’ level, i.e. applicable to all messages - because I can imagine use cases where I’d prefer my message to be unadorned with the extra information you standard provide 


Thanks beforehand for such extreme dedication !
Respect & greetz,
Paul

1 Like

I think we’re on the same page :wink:
Care to review & shed your light on my most recent reply ?

Everything you wrote is on point imo :ok_hand: