Alert2 - a new alerting component

Awesome thanks so much! One more question, can an alert be turned on with a condition_on and turned off with a manual_off, I presume on and off are independent actions?

You also literally just hit me on the day I need a condition_on use case that is only manually turned off so this is incredible (and hopefully the on/offs can be mixed)!

And incredible work so far

Yes, for split on/off alerts you can use any combination of ā€œ*_onā€ fields and any combination of ā€œ*_offā€ fields, as long as there is at least one ā€œonā€ field and one ā€œoffā€ field.
-J

That’s awesome! Thank you!

Hi All, I was going to turn some attention to staged alerting. Let me know what you think of the following:

Staged alerts proposal

I propose adding a new alert config field supersedes, that specifies that one alert entity takes precedence over another.

So for example:

  - domain: basement
    name: temperature_hot
    condition: "{{ states('sensor.b_temp') > 80 }}"

  - domain: basement
    name: temperature_very_hot
    condition: "{{ states('sensor.b_temp') > 90 }}"
    supersedes: { domain: basement, name: temperature_hot }
    notifier: something_noisy

And here’s a first take on the effect of supersedes:

When the superseding alert is firing, no notifications are send for the superseded alert. So while temperature_very_hot is firing, it’s as if it implicitly snoozes temperature_hot.

In the overview UI card, the superseding alert is shown, and the superseded alerts are ā€œcollapsedā€ underneath it. So temperature_very_hot would show, but temperature_hot would be visible only by expanding a UI carot or something.

I propose making generators work with supersedes by introducing a new generator variable genPreviousDomainName to let you chain supersedes (example below).

supersedes applies transitively. So if A supersedes B, and B supersedes C, then that means A supersedes C.

supersedes could also cause the alert to inherits settings from the alert it is superseding. This may reduce repetitive typing. [ I’m unsure if inheritance is a good idea ].

Lastly, I imagine we could separately add features like priority or something to affect how the alerts render in the UI.

Example: ā€œgood to knowā€ alerts

  - domain: basement
    name: door_open
    condition: "{{ states('sensor.door_open') }}"
    notifier: null

  - domain: basement
    name: door_open_too_long
    condition: "{{ states('sensor.door_open') }}"
    delay_on_secs: 300
    supersedes: { domain: basement, name: door_open }
    notifier: telegram

So an door_open alert appears in the UI, but sends no notifications and disappears if it’s superseded by the door being open too long. You could imagine adding a priority field or something so the ā€œgood to knowā€ alert to convey that it’s not as urgent as other alerts in the UI.

Example: door open and it gets cold

  - domain: basement
    name: door_open_too_long
    condition: "{{ states('sensor.door_open') }}"
    delay_on_secs: 300

  - domain: basement
    name: door_open_too_long_cold
    condition: "{{ states('sensor.door_open') and states('sensor.temp')|float < 60 }}"
    delay_on_secs: 300
    supersedes: { domain: basement, name: door_open_too_long }

Example: low disk space

  - domain: haserver
    name: diskspace_low_{{genElem}}
    condition: "{{ states('sensor.disk_free_mb') | float < genElem }}"
    supersedes: {{ genPreviousDomainName }}
    generator_name: g1
    generator: [ 500, 400, 300, 100 ]
    notifier: "{% if genElem|float <= 300 %} noisy_notifier {% else %} normal_notifier {% endif %}" 

The above generates four alerts that turn on at progressively lower disk-free amounts, and the alert shown in the UI (and notifying) will be the alert triggering on the lowest disk-free space. The second two alerts use a noisier notifier than the first two.

What I like about this proposal is that a staged alert is a normal alert with an extra annotation. So a staged alert is just as powerful and expressive as a normal alert.

Thoughts?
-Josh

Awesome - I’ll think about all of that!

Started using display_msg already. Two small thoughts. One, the alignment seems a little off, it’s to the left of other text somewhat under the icon:

I think it might better belong under the right side text (e.g entirely right aligned on the line, under the on and time text.). Also not sure we should show it for an off alert that’s snoozed. It’s not entirely bad seeing it there… but maybe inconsistent with the concept of ā€œoffā€.

(Damn though you sure have made me think about utility of just monitoring various for topics that aren’t yet really critical alerts… because seeing values as they get close to bad is actually kind of useful. But staging as we combine with priorities and then some grouping/sorting/colors is going to be huge and cover that! I mean you’ve literally made it so we can pick and choose various things we might be concerned about to just monitor and observe for a while once we have staging - without yet making it a major alert - until it is).

1 Like

Hi, Good suggestion. I just released UI v1.9.1 changing the display_msg to be right-justified. So it now looks like:

My inclination is to leave display_msg showing even in ā€œoffā€ alerts for a bit to see if it sparks any new ideas in people. It’s kinda novel. As I play with it, it raises the question of ā€œwhat am I not seeing in my alert overview that I might want to know?ā€. Similar to your observation about a value getting close to a threshold.

I then think about how should the info be presented and how to make it easy to write configs for it. For example, I don’t want to have to repeatedly write a 4-stage alert structure for every value I monitor to capture it as it gets close to some threshold. For that matter, many thresholds I choose for alerting have fuzz in them anyways. Is 83-degrees when to fire a too-hot alert? What about 82? Or 79?

In a sense, if I say alert at 83-degrees, I still am concerned about 82 or 79, just somewhat less so. For these kinds of alerts, it’s a continuum rather than a binary thing. This is related to the idea of an alert having gradations of being ā€œonā€.

display_msg opens up or highlights a can of worms to think about. I’m a little inclined to stick with implementing a staged-alerts proposal, such as I just sent, and get some experience with that, even though we don’t yet have answers to get all the worms back in the can (to stretch the analogy).

EDIT: I was thinking a bit further ahead about a proposal for alert priorities, UI display styles and whatnot, and I think it’ll fit well into my staged proposal or other proposals people have made.

-Josh

This looks good to me, and neatly wraps a couple of features together, too.

(As does the synthesis in 1.9 with the split on/off alerts. I’m going to have some fun with that. Haven’t had a chance to try it out yet, but hopefully in the coming week I’ll get to rewrite some of my alerts - and move 'em from YAML into the UI - and see how it works.)

I was probably a little quick - as I use this more I like display_msg with off alerts too so you know if the condition went way back to normal or is hovering near alert levels now for example.

@tman98, @cerebrate and others, any thoughts on the following two questions?

First, I’m thinking of adding the ability to define ā€œpresetsā€ - a collection of config settings that can be applied to an alert. The purpose is to reduce repetition in alert config, especially as we add more options like priority, UI colors, etc. So you could imagine defining a preset with common settings for low-priority alerts and one for high-priority alerts and so forth. The common settings you put in a preset might include priority, notifier, reminder_frequency_mins, etc. A new config field, preset would let you apply a pre-defined preset to an alert. Thoughts on idea or naming?

Second, if we have presets, then what is the role of a config field called priority? It seems necessary to at least convey how to order alerts in the UI (eg so important alerts are up top). Is there any other reason to have it?

EDIT: I could imagine using priority in notifier templates to determine who gets notified or how.

-Josh

Hi Josh - I want to second @cerebrate’s note on GitHub - great work with this release, the features are solid and the backwards compatibility has been seamless.

I love the idea of presets, and I agree that I have a lot of repeated code in my configuration right now that I think could get reduced. I want to note that some of the repeated code may be hard to reduce wiith presets, but I agree osome would be.

For example, here’s a typical bit of config for me now:

    - domain: temperature
      generator_name: low_indoor_temperature
      generator: "{% from 'entity_name_state.jinja' import expand_with_remote -%}{{ expand_with_remote('sensor.indoor_building_temperature_alert_group') }}"
      name: "{{ genRaw }}_is_low"
      friendly_name: "{{ state_attr(genRaw,'friendly_name') }} is low temp"
      condition: "{{ states(genRaw) != 'undefined' and  states(genRaw) != 'unavailable' and states(genRaw)|float < states('input_number.indoor_building_low_temperature_alert_value')|float }}"
      delay_on_secs: 900
      message: "Low temp of {{ states(genRaw)|float }}"
      display_msg: "Temp: {{ states(genRaw)|float }}"
      reminder_frequency_mins: 30

You’ll see the actually a bunch of my repeated code is between name, friendly_name, message and display_msg. I don’t have a great recommendation of how to entirely simplify that yet (e.g. could generator_name, name, and friendly_name be generally inferred from a single entry for example) or in a way that doesn’t make things overly configurable and magic.

Separate feature requests, could we add the ability to have a separate done_notifier if specified, including no notifier (null). When I have a critical notification set up for the phone, it’s disruptive to get a critical notification when the alert is over (especially if its in the middle of the night and I’ve decided to go back to sleep). I’d generally set critical notifications to have a non-critical done notification if i could.

1 Like

Been setting this up today, and just a minor quibble. When setting up conditions in the UI, using a binary sensor alone produces an error:

I’m presuming this is because it’s trying to evaluate it as a template, but I believe entity names (that produce truthy results) are still allowed as conditions? In which case it’s a little confusing.

So, while I was doing that, I decided I’d try out the generators for my door open alerts, and came up with this:

alert2:
  alerts:
   - domain: "{{ genElem }}"
     delay_on_secs: 600
     generator_name: door_left_open
     generator: "{{ expand('binary_sensor.outside_doors')|map(attribute="entity_id")|list|replace("binary_sensor.", "") }}"
     name: left_open
     friendly_name: "{{ genElem|replace("_", " ")|title }} Left Open"
     condition: "binary_sensor.{{ genElem }}"
     message: "The {{ genElem|replace("_", " ") }} has been left open."
     done_message: "The {{ genElem|replace(\"_", " ") }} has been closed."

Using the generator to first extract the list of doors from an existing template sensor, then spinning the alerts from it. Since some of y’all’ve been using generators for rather longer than me, thought I’d post it here for comment, especially on the efficiency of my templates.

As a side note, I have a couple of minor generator feature requests just to make it easier to see what the generators are doing -

Could the sensor.alert2generator_* sensor list the alerts that are created by the generator in its attributes, as well as showing the number of them in its state?

And could the Alert2 Manager card list the alerts separately, either underneath the sensor created for the generator, or under the domain they were created in (but linking back to the generator the way the sensor does now)?

Hi, I released v1.9.1 of Alert2 which fixes an issue with creating event alerts via the UI.

@cerebrate , I confirm the UI bug with displaying condition field input correctly when it’s a sensor name. May bundle fix with other stuff.

In your generator spec, I think the ā€œconditionā€ line won’t work. The detection of sensor names as a syntactic convenience feature is done before variable substitution. To do what you want, you need to say:
condition: "{{ states('binary_sensor.'+ genElem) }}"

I like the idea of making available the list of entities a generator created. I don’t think it can be an attribute of the generator entity because states&attributes are limited in size (to 255 chars?). Well, I suppose I could have a list of one attribute per created entity, but that seems klunky.

I’m not sure where to put that information. Maybe somewhere in the Alert Manager? That would be a bit of a change. At the moment, the entities listed in the manager are those defined in the UI, and clicking on them brings up the dialog to edit / delete them. If we want to list other entities, I guess we’d just have to mark them as not being editable from the UI.

I’m open to ideas.

EDIT: I could add e generated_by attribute to a generated entity. Then you could write a template expression to gather all the entities generated by a particular generator. Probably not a complete solution to your needs, but maybe a start.

Also, I’m unsure about adding unique_id to alert entities and the semantics of that. E.g., what happens if you delete an entity generated by a generator? The entity could be recreated at any time when the generator template is re-evaluated.

J

Oops. Didn’t realize that, and hadn’t tested them yet because the weather’s so bad here right now. Fixed and tested them now!

I think that’s a limitation on string sizes? I was thinking more something like, say, Magic Areas does. It has a feature which aggregates sensors together by areas, and the aggregate sensors include a list of the sensors they aggregate, so:

Which presumably works because it’s using a list of entity_ids, not a string. Which would be the most useful way to present it, I think, for when it comes time to use that information in templates/automation/other generators.

Well, my thoughts there were either to list them under the generator responsible (so we can see the names, but show them inside the same block so that clicking on them brings up the generator), or, if they’re listed separately under their own domain, still set it up so that clicking on them brings up the generator.

I mean, they are still entities defined in the UI, right? Just via the generator rather than directly, so bringing up the generator edit dialog seems like the right thing to do here.

I don’t think that’s a problem. Being able to delete (rather than just make cosmetic changes to) entities with unique IDs seems like it’s mostly there to let you clean up oopsen, and so manually deleted entities coming back if the integration is still using them is a feature/the correct behavior.

Hi All, I just released Alert2 v1.10 and the corresponding UI.

Changes

  • Add support for supersedes config option, which lets you define hierarchies of alerts (aka staged alerts). If alert A supersedes B (directly or transitively), then when A is firing, no notifications will be sent for B, although they will be logged. And the two alerts are grouped together in the Overview card.
  • Add support for priority config option, which affects sorting and coloring of alerts in the Alert2 UI Overview card. Values are low, medium or high. Medium and high color the badge orange and red, respectively, in the UI.
  • Support UI only use (no editing configuration.yaml). Make Alert2 Overview and Manager available to UI-managed dashboards
  • Add generated_ids attribute to generator sensor entity showing the list of entity_ids generated
  • Fix rendering of condition* fields in UI when using entity names
  • Repair rendering of more-info popup outside of Alert2 Overview card, and fix state rendering if alert has never fired
  • Tests and documentation

@cerebrate, I added generated_ids. Still might be good idea in future to add list of generated alerts to Manager UI.

Re unique_id, I don’t think there should be any dangling entities any more, especially not after an HA restart. Also, it’d require some thinking about what happens when e.g., a generated alert with a unique_id is deleted. My inclination is to punt on unique_ids for now.

-J

Hi,

I’ve been following this topic for sometime, but it all looked a bit too complicated and I kept putting it off, but I have now had a go, and found that once you start playing with it, it is not as difficult as I thought it would be - it is all quite logical and I have now got my first few alerts working okay - so great job, this is very useful and I’m sure that I will be adding lots more alerts in the future :slight_smile:

I’m interested in using the new ā€˜supesedes’ option, but my challenge is how do I use it when the alerts I want to supersede have been created with the generator?

As I understand it, I have to define the domain/name pairs that I want to supersede, but that will mean I would have to define them manually, which defeats the purpose of using the generator to create the alerts in the first place.

My initial use case is alerting when the toner cartridges get low in my laser printer. I have 4 cartridges, and I’ve used the generator to create the 4 alert entities and it all works as expected.

What I now want to do is have different priority alerts and messages as the toner gets lower.

For example

20% = low priority and message = order new toner cartridge
10% = medium priority and message = reminder to order cartridge
2% = high priority and message = replace toner today

I’m not sure if I can use a template for the domain/name pairs?

Thinking about it, I can define the domain in the alert, as that will be fixed, I would just need to use a template to define the name, and use the generated alert name instead, and use that to create the superseded alert name, replacing ā€˜medium’ with ā€˜low’ (for this to work I would need to keep the alert naming consistent, and just append _low, _medium, _high to the name to identify it’s priority.

Am I thinking along the right lines here, or is there a more elegant way of achieving my use case?

Apologies if I am jumping the gun here, as I know you have only just released the supersedes option, so this might be functionality you are planning in a future release.

Hi @ian_p , Thanks for trying out Alert2! Good question about supersedes and generators. Here’s my thought for how that might work using your toner example:

- domain: printer
  name: "toner_low_{{genElem}}"
  generator: [ 20, 10 , 2 ]
  condition: "{{ states('sensor.toner_percent') | float < genElem }}"
  supersedes: "{{ genPreviousDomainName }}"
  priority: "{{ [ 'low', 'medium', 'high' ][ genIdx ] }}"
  message: "{{ [ 'order new toner', 'reminder to order cartridge', 'replace toner today' ][ genIdx ] }}"
  generator_name: g1

So we’d introduce two new variable for generators:

  • genIdx - the index into the generator array. So 20 would be index 0, 10 would be index 1, etc.
  • genPreviousDomainName - this resolves to the domain+name of the previous generated alert, and resolves to the empty string for the first generated alert.

Thoughts?
Josh

Hi Josh,

That looks good to me, and simplifies the config considerably. I had visions of having what would effectively be a lot of duplicated YAML in my config to achieve this, but this I think addresses the requirement nicely, and will easily work for other similar use cases - eg I have a lot more batteries than I have toner cartridges, but the requirement is very similar.

Ian

Hi All, I received a PR for adding unique_id’s to alert2 entities. I looked into it and raised some possible issues and posted a few thoughts at:

-Josh

I am looking to give Alert2 a try as I think it has a few advantages over the Alert options in HA. After installing the Alert2 integration I am getting several persistent notifications that I am unsure why. Am I missing some settings?

Alert2 alert2_error: Global exception handler: a task died to due to an unhandled exception: <class 'IndexError'>: list index out of range. full context: {'message': 'Task exception was never retrieved', 'exception': IndexError('list index out of range'), 'future': <Task finished name='Scrape Coordinator - refresh' coro=<DataUpdateCoordinator._handle_refresh_interval() done, defined at /usr/src/homeassistant/homeassistant/helpers/update_coordinator.py:265> exception=IndexError('list index out of range')>}