Skip to content

Notification Classes

Info

See the Class Diagram for how these relate to each other.

custom_components.supernotify.notification.Notification

Bases: ArchivableObject


              flowchart TD
              custom_components.supernotify.notification.Notification[Notification]
              custom_components.supernotify.archive.ArchivableObject[ArchivableObject]

                              custom_components.supernotify.archive.ArchivableObject --> custom_components.supernotify.notification.Notification
                


              click custom_components.supernotify.notification.Notification href "" "custom_components.supernotify.notification.Notification"
              click custom_components.supernotify.archive.ArchivableObject href "" "custom_components.supernotify.archive.ArchivableObject"
            
METHOD DESCRIPTION
apply_enabled_scenarios

Set media and action_groups from scenario if defined, first come first applied

base_filename

ArchiveableObject implementation

camera_variables

Camera of the notification for conditions and templates, with its cameras config if there is any

contents

ArchiveableObject implementation

convert_exposed_notify_entities

Short circuit the notify entity of a scenario or delivery given as a target, see

convert_notify_entities

Short circuit supernotify notify entities so they're handled directly so not

delivery_outcomes

One outcome for each delivery that took part in this notification, with the reason when

delivery_skip_reason

Why a selected delivery won't be attempted at all, checked before any targets are worked out

diagnostics_selected

A notification sent with debug: true asked for its trace, so it is archived

initialize

Async post-construction initialization

media_requirements

If no media defined, look for iOS / Android actions that have media defined

record_result

Debugging (and unit test) support for notifications that failed or were skipped

senders

The automations or scripts that sent this notification, found once from its context - a later

snooze_tags

What a tag snooze can name this notification by - its scenarios, what the entities it's

apply_enabled_scenarios()

Set media and action_groups from scenario if defined, first come first applied

base_filename()

ArchiveableObject implementation

camera_variables()

Camera of the notification for conditions and templates, with its cameras config if there is any

contents(diagnostics=False, **_kwargs)

ArchiveableObject implementation

convert_exposed_notify_entities(target, action_data)

Short circuit the notify entity of a scenario or delivery given as a target, see ExposedNotifyEntity in notify.py. It is taken out of the targets, and its scenario applied or delivery selected just as the entity itself would, rather than the entity being called and making a second notification.

convert_notify_entities(target=None)

Short circuit supernotify notify entities so they're handled directly so not going round in circles via calls to notify.send_message. A genuine other-integration notify entity is left alone for NotifyEntityTransport to handle normally.

Defined here rather than in models/Target since requires access to registries.

supernotify.notify's target: field also accepts the dict shape Home Assistant's own target selector produces, e.g. {"entity_id": ["person.jey", "notify.recipient_alice"]} - unlike this integration's other dict-shaped targets (recipient/delivery config), that entity_id list is Home Assistant's raw picker output, not pre-sorted by category: a person entity picked that way still needs to end up as a person_id, same as if it had been typed directly into notify.supernotify's flat target list, or it would otherwise be silently dropped by Target() (whose entity_id category explicitly excludes the person domain - see Target.is_entity_id/is_person_id in model.py).

delivery_outcomes()

One outcome for each delivery that took part in this notification, with the reason when skipped: success if any of its envelopes was delivered, else error if any failed (or the delivery itself raised), else skipped - its envelopes suppressed, or none generated.

delivery_skip_reason(delivery)

Why a selected delivery won't be attempted at all, checked before any targets are worked out

diagnostics_selected(outcome_policy)

A notification sent with debug: true asked for its trace, so it is archived with the full diagnostic content whatever the configured diagnostics outcomes

initialize() async

Async post-construction initialization

media_requirements(data)

If no media defined, look for iOS / Android actions that have media defined

Example is the Frigate blueprint, which generates image, video etc in the data section, that can also be used for email attachments

record_result(delivery, envelope=None, targets=None, suppression_reason=None)

Debugging (and unit test) support for notifications that failed or were skipped

senders()

The automations or scripts that sent this notification, found once from its context - a later run of the same automation would change the context its state carries

snooze_tags()

What a tag snooze can name this notification by - its scenarios, what the entities it's about are called, from entity_id in its data or its camera, and the automation or script that sent it

custom_components.supernotify.envelope.Envelope

Bases: DupeCheckable


              flowchart TD
              custom_components.supernotify.envelope.Envelope[Envelope]
              custom_components.supernotify.common.DupeCheckable[DupeCheckable]

                              custom_components.supernotify.common.DupeCheckable --> custom_components.supernotify.envelope.Envelope
                


              click custom_components.supernotify.envelope.Envelope href "" "custom_components.supernotify.envelope.Envelope"
              click custom_components.supernotify.common.DupeCheckable href "" "custom_components.supernotify.common.DupeCheckable"
            

Wrap a notification with a specific set of targets and service data possibly customized for those targets

METHOD DESCRIPTION
__eq__

Specialized equality check for subset of attributes

__repr__

Return a concise string representation of the Envelope.

content_key

What this envelope would actually make the transport do - the transport, its action, the

core_action_data

Build the core set of service_data dict to pass to underlying notify service

customize_data

Return data filtered by delivery data_keys_select option, pruning empty maps by default.

grab_image

Grab an image from a camera, snapshot URL, MQTT Image etc

hash

Alpha hash to reduce noise from messages with timestamps or incrementing counts

notification_uri

URI to open when the notification itself is tapped, from a level: notification mobile action

record_recipient_notifications

Update every involved recipient's notify.recipient_ entity (if it has one),

render_action

Mobile action with its action_template, title_template and uri_template rendered, and level dropped

__eq__(other)

Specialized equality check for subset of attributes

__repr__()

Return a concise string representation of the Envelope.

The returned string includes the envelope's message, title, and delivery name in the form: Envelope(message={message},title={title},delivery={delivery_name}).

Primarily intended for debugging and logging; note that attribute values are inserted directly and may not be quoted or escaped.

content_key()

What this envelope would actually make the transport do - the transport, its action, the resolved targets, and the exact text, data and media - but not which delivery it came from. Two envelopes with the same key are the same delivery to the person receiving it, so a fallback doesn't repeat what another delivery already sent.

A short blake2b digest rather than the built-in hash(), so the key stays the same across restarts and could be used in an id

core_action_data(force_message=True)

Build the core set of service_data dict to pass to underlying notify service

customize_data(data, prune_empty=True)

Return data filtered by delivery data_keys_select option, pruning empty maps by default.

grab_image() async

Grab an image from a camera, snapshot URL, MQTT Image etc

hash()

Alpha hash to reduce noise from messages with timestamps or incrementing counts

notification_uri(absolute=False)

URI to open when the notification itself is tapped, from a level: notification mobile action

Where there's more than one, an action on the notification wins, then the action groups in the order chosen, which is those on the notification followed by each scenario in turn. absolute is for where a path relative to Home Assistant, like /lovelace/cameras, won't do.

record_recipient_notifications(recorded_person_ids)

Update every involved recipient's notify.recipient_ entity (if it has one), so its state (or, on HA < 2026.3, its last_notified attribute - see RecipientNotifyEntity.record_notification()) reflects delivery regardless of which target form the caller used - a plain person_id, an email/phone/mobile override, notify.recipient_ itself, or anything else Recipient.initialize() folds into the same Target. Delivery target selection keeps person_ids, and generate_targets() narrows them to the recipients each envelope actually reaches (see _attach_person_ids()), so that's the one reliable link back from an arbitrary envelope to the Recipient objects it reached - see RecipientNotifyEntity.record_notification() for why this call is needed at all rather than leaving it to HA's own NotifyEntity state tracking.

recorded_person_ids are the recipients already recorded by the notification's other envelopes, which this adds to, so a recipient reached by several deliveries is only recorded once - each is a state write, and would otherwise show up in the logbook as several identical entries at the same moment.

render_action(action)

Mobile action with its action_template, title_template and uri_template rendered, and level dropped

custom_components.supernotify.target.Target

METHOD DESCRIPTION
__add__

Create a new target by adding another to this one

__eq__

Compare two targets

__len__

How many targets, whether direct or indirect

__sub__

Create a new target by removing another from this one, ignoring target_data

is_person_id

True for a real Person entity_id, or a Recipient's synthetic user.<name> id - used

resolve_selectors

Replace area_id/floor_id/label_id targets with the entities they reference

select

Narrow this target to what a delivery can use, leaving this one untouched

__add__(other)

Create a new target by adding another to this one

__eq__(other)

Compare two targets

__len__()

How many targets, whether direct or indirect

__sub__(other)

Create a new target by removing another from this one, ignoring target_data

is_person_id(target) classmethod

True for a real Person entity_id, or a Recipient's synthetic user.<name> id - used to identify a recipient with no Person record (see people.Recipient.entity_id). Both are person_id-category target values, resolved the same way downstream.

resolve_selectors(hass_api)

Replace area_id/floor_id/label_id targets with the entities they reference

Resolution goes through the same core helper as a Home Assistant entity action, so groups are expanded and an entity inherits the area of its device. An entity in more than one of them - the kitchen, the first floor and the voice label - is kept once, and data attached to a selector is inherited by each of its entities, the same way as for a group member. Transports therefore never see a selector, and only the exception of an action that genuinely knows about areas needs extra_data.

Returns this target untouched when there is no selector to resolve.

select(categories, own_names, hass_api, target_selector=None)

Narrow this target to what a delivery can use, leaving this one untouched

categories are the delivery's declared target categories, and own_names its own name and its transport's. A target category named after either is always destined for that delivery. The two serve different purposes and both stay available: - the TRANSPORT name ({sms: value}) reaches every delivery of that transport, so scenario/time/occupancy selection logic can still decide which one actually fires - the same as it would for a plain, auto-matched value - a specific DELIVERY name ({shortcode_sms: value}) pins the target to just that one delivery, for when two deliveries of the same transport must stay distinct (e.g. email vs html_email)

person_ids are always kept, whatever the delivery declares, since they aren't delivered to but are the link back to the recipients a delivery reaches (see Notification.generate_targets(), which narrows them to those actually in each envelope). They are kept out of the target_selector too, as it's for choosing between values a transport can address.

custom_components.supernotify.model.TargetType

Bases: StrEnum


              flowchart TD
              custom_components.supernotify.model.TargetType[TargetType]

              

              click custom_components.supernotify.model.TargetType href "" "custom_components.supernotify.model.TargetType"
            

custom_components.supernotify.snoozer.Snooze

METHOD DESCRIPTION
__eq__

Check if two snoozes for the same thing

__repr__

Return a string representation of the object.

to_storage_dict

Full-fidelity serialization for persistence (unlike export(), which is a display

__eq__(other)

Check if two snoozes for the same thing

__repr__()

Return a string representation of the object.

to_storage_dict()

Full-fidelity serialization for persistence (unlike export(), which is a display summary that loses the date part of timestamps).

custom_components.supernotify.notification.DeliveryTargetOverride dataclass