| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- blueprint:
- name: AI Event Summary (v1.4.1)
- author: valentinfrlch
- description: 'AI-powered summaries for security camera events. Sends a notification
- with a preview to your phone that is updated dynamically when the AI summary is
- available.
- '
- domain: automation
- source_url: https://raw.githubusercontent.com/valentinfrlch/ha-llmvision/refs/heads/main/blueprints/event_summary.yaml
- input:
- important:
- name: Important (Experimental)
- description: 'Use AI to classify events as Critical, Normal or Low. Notifications
- are sent only for events classified as Normal or higher. Critical events override
- ''Do Not Disturb'' settings. Use with caution: AI can make mistakes.
- '
- default: false
- selector:
- boolean: {}
- remember:
- name: Remember
- description: Stores this event in the Timeline so you can ask about it. If important
- is enabled, only events classified as Normal or Critical will be saved.
- default: false
- selector:
- boolean: {}
- use_memory:
- name: Use Memory
- description: Use information stored in memory to provide additional context.
- Memory must be set up.
- default: false
- selector:
- boolean: {}
- message:
- name: Prompt
- description: Model prompt for the video_analyzer action
- default: 'Summarize the events based on a series of images captured at short
- intervals. Focus only on moving subjects such as people, vehicles, and other
- active elements. Ignore static objects and scenery. Provide a clear and concise
- account of movements and interactions. Do not mention or imply the existence
- of images—present the information as if directly observing the events. If
- no movement is detected, respond with: ''No activity observed.'''
- selector:
- text:
- multiline: true
- multiple: false
- run_conditions:
- name: Run Conditions
- description: All conditions must be true in order for the blueprint to run.
- default: []
- selector:
- condition: {}
- notify_device:
- name: Notify Device
- description: The devices to send the notification to. Multiple devices may be
- used. Only works with Home Assistant mobile app.
- default: []
- selector:
- device:
- multiple: true
- filter:
- - integration: mobile_app
- notification_delivery:
- name: Notification Delivery
- description: "Controls how notifications are delivered. \n \n **Dynamic** immediately
- notifies with a live preview and updates the notification silently with a
- summary once it is available. \n **Consolidated** Delays the notification
- until the event summary is generated. Use this if you're receiving multiple
- notifications for the same event."
- default: Dynamic
- selector:
- select:
- options:
- - Dynamic
- - Consolidated
- custom_value: false
- multiple: false
- sort: false
- camera_entities:
- name: Camera Entities
- description: List of camera entities to monitor
- default: []
- selector:
- entity:
- multiple: true
- filter:
- - domain:
- - camera
- trigger_state:
- name: Trigger State
- description: Automation starts when one of your camera changes to this state.
- default: recording
- selector:
- text:
- multiline: false
- multiple: false
- motion_sensors:
- name: Motion Sensor
- description: Set if your cameras don't change state (Frigate). Use the same
- order used for camera entities.
- default: []
- selector:
- entity:
- multiple: true
- filter:
- - domain:
- - binary_sensor
- preview_mode:
- name: Preview Mode
- description: "Choose between a live preview or a snapshot of the event. \n\n
- **Important:** Live Preview is only supported on iOS."
- default: Snapshot
- selector:
- select:
- options:
- - Snapshot
- - Live Preview
- custom_value: false
- multiple: false
- sort: false
- cooldown:
- name: Cooldown
- description: Time in minutes to wait before running again. Strongly recommended
- for busy areas.
- default: 10
- selector:
- number:
- min: 0.0
- max: 60.0
- mode: slider
- step: 1.0
- tap_navigate:
- name: Tap Navigate
- description: Home Assistant dashboard to navigate to when notification is opened
- (e.g. /lovelace/cameras).
- default: /lovelace/0
- selector:
- text:
- multiline: false
- multiple: false
- duration:
- name: Duration
- description: Duration to record for analysis (in seconds).
- default: 5
- selector:
- number:
- min: 1.0
- max: 60.0
- mode: slider
- step: 1.0
- max_frames:
- name: Max Frames
- description: How many frames to analyze. Picks frames with the most movement.
- default: 3
- selector:
- number:
- min: 1.0
- max: 60.0
- mode: slider
- step: 1.0
- provider:
- name: Provider
- description: Provider to use for analysis. See docs for additional information.
- selector:
- config_entry:
- integration: llmvision
- model:
- name: Model
- description: Which model to use. Depends on chosen provider.
- default: gpt-4o-mini
- selector:
- text:
- multiline: false
- multiple: false
- target_width:
- name: Target Width
- description: Downscale images (uses less tokens and speeds up processing)
- default: 1280
- selector:
- number:
- min: 512.0
- max: 3840.0
- mode: slider
- step: 1.0
- max_tokens:
- name: Maximum Tokens
- description: Maximum number of tokens to generate. Use this to control the length
- of the summaries.
- default: 20
- selector:
- number:
- min: 1.0
- max: 100.0
- mode: slider
- step: 1.0
- temperature:
- name: Temperature
- description: Randomness. Lower is more accurate, higher is more creative.
- default: 0.1
- selector:
- number:
- min: 0.1
- max: 1.0
- step: 0.1
- mode: slider
- variables:
- important: !input important
- remember: !input remember
- cooldown: !input cooldown
- preview_mode: !input preview_mode
- notify_devices: !input notify_device
- notification_delivery: !input notification_delivery
- device_name_map: "{% set ns = namespace(device_names=[]) %} {% for device_id in
- notify_devices %}\n {% set device_name = device_attr(device_id, \"name\") %}\n
- \ {% set sanitized_name = \"mobile_app_\" + device_name | slugify %}\n {% set
- ns.device_names = ns.device_names + [sanitized_name] %}\n{% endfor %} {{ ns.device_names
- }}\n"
- camera_entities_list: !input camera_entities
- motion_sensors_list: !input motion_sensors
- camera_entity: "{% if motion_sensors_list and not trigger.entity_id.startswith(\"camera\")
- %}\n {% set index = motion_sensors_list.index(trigger.entity_id) %}\n {{ camera_entities_list[index]
- }}\n{% else %}\n {{ trigger.entity_id }}\n{% endif %}\n"
- tag: '{{ camera_entity + int(as_timestamp(now()))|string }}
- '
- group: '{{ camera_entity }}
- '
- label: Motion detected
- camera: '{{ camera_entity.replace("camera.", "").replace("_", " ")|capitalize }}
- '
- importance_prompt: 'Classify the security event based on this image. Choose from
- the following options: "passive" for unimportant events, "time-sensitive" for
- notable but non-critical events such as a person at the front door, and "critical"
- only for potential burglaries or highly suspicious activity. Respond with one
- of these options exactly, without additional explanation.
- '
- max_exceeded: silent
- mode: single
- triggers:
- - trigger: state
- entity_id: !input camera_entities
- to: !input trigger_state
- id: camera_trigger
- - trigger: state
- entity_id: !input motion_sensors
- to: 'on'
- id: motion_sensor_trigger
- condition:
- - condition: and
- conditions: !input run_conditions
- action:
- - choose:
- - conditions:
- - condition: template
- value_template: '{{ important }}'
- sequence:
- - action: llmvision.image_analyzer
- data:
- image_entity: '{{[camera_entity]}}'
- provider: !input provider
- model: !input model
- message: '{{importance_prompt}}'
- include_filename: true
- target_width: 1280
- max_tokens: 3
- temperature: 0.1
- response_variable: importance
- - choose:
- - conditions:
- - condition: template
- value_template: '{{ important and importance.response_text|lower == ''passive''
- }}'
- sequence:
- - stop: Event is not important
- - choose:
- - conditions:
- - condition: template
- value_template: '{{ notification_delivery == ''Dynamic'' }}'
- sequence:
- - alias: Send instant notification to notify devices
- repeat:
- for_each: '{{device_name_map}}'
- sequence:
- - action: notify.{{ repeat.item }}
- data:
- title: '{{ label }}'
- message: '{{camera}} has detected activity.'
- data:
- entity_id: '{{camera_entity}}'
- url: !input tap_navigate
- clickAction: !input tap_navigate
- tag: '{{tag}}'
- group: '{{group}}'
- alert_once: true
- push:
- interruption-level: '{{importance.response_text|lower if importance
- is defined else ''active''}}'
- - alias: Analyze event
- action: llmvision.stream_analyzer
- data:
- image_entity: '{{[camera_entity]}}'
- duration: !input duration
- provider: !input provider
- model: !input model
- message: !input message
- use_memory: !input use_memory
- remember: !input remember
- expose_images: '{{preview_mode == ''Snapshot'' or remember}}'
- generate_title: !input remember
- include_filename: true
- max_frames: !input max_frames
- target_width: !input target_width
- max_tokens: !input max_tokens
- temperature: !input temperature
- response_variable: response
- - alias: Update label with title
- variables:
- label: '{{response.title}}'
- - choose:
- - conditions:
- - condition: template
- value_template: '{{ preview_mode==''Snapshot'' }}'
- sequence:
- - alias: (Snapshot) Update notification on notify devices
- repeat:
- for_each: '{{device_name_map}}'
- sequence:
- - action: notify.{{ repeat.item }}
- data:
- title: '{{ label }}'
- message: '{{response.response_text}}'
- data:
- image: '{{response.key_frame.replace(''/config/www/'',''/local/'') }}'
- url: !input tap_navigate
- clickAction: !input tap_navigate
- tag: '{{tag}}'
- group: '{{group}}'
- push:
- interruption-level: '{{''passive'' if notification_delivery==''Dynamic''
- else ''active''}}'
- - conditions:
- - condition: template
- value_template: '{{ preview_mode==''Live Preview'' }}'
- sequence:
- - alias: (Live Preview) Update notification on notify devices
- repeat:
- for_each: '{{device_name_map}}'
- sequence:
- - action: notify.{{ repeat.item }}
- data:
- title: '{{ label }}'
- message: '{{response.response_text}}'
- data:
- entity_id: '{{camera_entity}}'
- url: !input tap_navigate
- clickAction: !input tap_navigate
- tag: '{{tag}}'
- group: '{{group}}'
- push:
- interruption-level: '{{''passive'' if notification_delivery==''Dynamic''
- else ''active''}}'
- - delay: 00:{{cooldown|int}}:00
|