From 20322b225158d9b593f4d6ac290adbf48e8efd6c Mon Sep 17 00:00:00 2001 From: CeeWeasel Date: Sun, 29 Jun 2025 22:39:39 -0400 Subject: [PATCH] Cleanup and prepping for bed presence --- .gitignore | 2 +- automations/people/goodnight_kids.yaml | 4 +- automations/people/goodnight_kids_tts.yaml | 2 +- .../great_room/great_room_light_cycle.yaml | 20 +- blueprints/automation/SgtBatten/Stable.yaml | 2020 +++++++++++++++++ .../hunterjm/frigate_notification.yaml | 225 -- components/packages/google_assistant.yaml | 5 + esphome/bed-presence/base.yaml | 80 + esphome/bed-presence/bluetooth-proxy.yaml | 15 + esphome/bed-presence/diagnostics.yaml | 59 + esphome/bed-presence/sensor.yaml | 240 ++ glances/glances.conf | 321 --- lovelace/view-ha-floorplan.yaml | 2 +- lovelace/view-overview.yaml | 27 +- 14 files changed, 2450 insertions(+), 572 deletions(-) create mode 100644 blueprints/automation/SgtBatten/Stable.yaml delete mode 100644 blueprints/automation/hunterjm/frigate_notification.yaml create mode 100644 esphome/bed-presence/base.yaml create mode 100644 esphome/bed-presence/bluetooth-proxy.yaml create mode 100644 esphome/bed-presence/diagnostics.yaml create mode 100644 esphome/bed-presence/sensor.yaml delete mode 100644 glances/glances.conf diff --git a/.gitignore b/.gitignore index f9dc319..5cabc24 100644 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,7 @@ backup_config.yaml .storage/ .cloud/ .automatic/ -.tts.token +.tts.token* customize.yaml image/ open-zwave/ diff --git a/automations/people/goodnight_kids.yaml b/automations/people/goodnight_kids.yaml index 29b1165..4113449 100644 --- a/automations/people/goodnight_kids.yaml +++ b/automations/people/goodnight_kids.yaml @@ -105,8 +105,8 @@ action: target: entity_id: media_player.downstairs_roku - - service: homeassistant.turn_off - entity_id: switch.shelly_projector + # - service: homeassistant.turn_off + # entity_id: switch.shelly_projector - service: input_select.select_option data: diff --git a/automations/people/goodnight_kids_tts.yaml b/automations/people/goodnight_kids_tts.yaml index f475e82..1de600b 100644 --- a/automations/people/goodnight_kids_tts.yaml +++ b/automations/people/goodnight_kids_tts.yaml @@ -68,7 +68,7 @@ action: - media_player.all_speakers - media_player.front_room_tv - media_player.downstairs_roku - - switch.shelly_projector + #- switch.shelly_projector - service: input_select.select_option data: diff --git a/automations/rooms/great_room/great_room_light_cycle.yaml b/automations/rooms/great_room/great_room_light_cycle.yaml index 988f343..bc0fb26 100644 --- a/automations/rooms/great_room/great_room_light_cycle.yaml +++ b/automations/rooms/great_room/great_room_light_cycle.yaml @@ -15,17 +15,17 @@ trigger: from: 'on' to: 'off' - - id: projector_off - platform: state - entity_id: switch.shelly_projector - from: 'on' - to: 'off' + # - id: projector_off + # platform: state + # entity_id: switch.shelly_projector + # from: 'on' + # to: 'off' - - id: projector_on - platform: state - entity_id: switch.shelly_projector - from: 'off' - to: 'on' + # - id: projector_on + # platform: state + # entity_id: switch.shelly_projector + # from: 'off' + # to: 'on' - id: setting_change platform: state diff --git a/blueprints/automation/SgtBatten/Stable.yaml b/blueprints/automation/SgtBatten/Stable.yaml new file mode 100644 index 0000000..7361224 --- /dev/null +++ b/blueprints/automation/SgtBatten/Stable.yaml @@ -0,0 +1,2020 @@ +blueprint: + name: Frigate Notifications (0.14.0.2w) + author: SgtBatten + homeassistant: + min_version: 2024.11.0 + description: "## Frigate Notifications\n\nA highly customisable Notification template + for Frigate Camera Notifications.\n\n### Software Version Requirements\n - Minimum + Home Assistant Version: 2024.10\n - Minimum Frigate Version: 0.14.0\n - Minimum + Frigate Integration Version: 5.7.0\n - **Note:** \"Enable the unauthenticated + notification event proxy\" must be ticked during setup\n - An MQTT broker connected + to Home Assistant and Frigate.\n - Minimum iOS Version: 15.0\n\n### Required + Configuration Options:\n - Frigate Cameras\n - Mobile Device (Running HA Companion + App)\n\n### Features:\n - Easily select the camera entities or mobile device + using a drop-down menu.\n - Configure multiple cameras in one automation. \n\n + \ For the full features list visit the [GitHub Repository][1]\n\n[1]: https://github.com/SgtBatten/HA_blueprints/blob/main/Frigate_Camera_Notifications\n\n## + Support\nGo to https://github.com/SgtBatten/HA_blueprints to report bugs, request + new features, or get support with your configuration.\n" + domain: automation + source_url: https://github.com/SgtBatten/HA_blueprints/blob/main/Frigate_Camera_Notifications/Stable.yaml + input: + camera: + name: Frigate Cameras + description: "Select the cameras that will trigger notifications. \nIf you do + not see cameras listed in the drop-down, check you have the Frigate integration + installed.\nTo more effectively customise the notifications you may need to + create one automation per camera.\n" + selector: + entity: + filter: + - integration: frigate + domain: + - camera + multiple: true + notify_device: + name: Mobile Device + description: Select a device that runs the official Home Assistant app to receive + notifications. If you wish to notify a group of devices and/or Android/Fire + TV use the field below to override this selection. This will be ignored in + that case but is still required. + default: false + selector: + device: + filter: + - integration: mobile_app + multiple: false + notify_group: + name: Notification Group or Android/Fire TV (Optional) + description: 'The name of the group or individual TV to send notifications to. + + If set, this will override the individual devices above. + + + Note: If the group contains both mobile devices and TVs, the TV will not display + the snapshot unless "TV notifications" is set to true. However, this will + stop Android phones from receiving thumbnails. + + ' + default: '' + base_url: + name: Base URL (Optional) + description: 'The external URL for your Home Assistant instance. + + Recommended for iOS and required for Android/Fire TV. + + Must include the scheme i.e http:// or https:// + + Examples: http://192.168.1.25:8123 https://homeassistant.mydomain.com + + ' + default: '' + mqtt_topic: + name: MQTT Topic (Advanced) + description: The MQTT topic Frigate sends review messages in. + default: frigate/reviews + client_id: + name: Client ID (Optional-Advanced) + description: Used to support multiple instances of Frigate. Leave blank if you + don't know what to do. + default: '' + telegram: + name: '# Telegram Configuration + + ' + description: These are Telegram specific Options. + icon: mdi:phone-outline + collapsed: true + input: + telegram_base_url: + name: Telegram Base URL (Optional) + description: 'The internal URL for your Home Assistant instance. + + Used only for telegram integration (For downloading media). Useful when + your base URL points to a proxy instance + + which could be unreachable from your home assistant instance. If unset + telegram will use Base URL. + + Must include the scheme i.e http:// or https:// + + Examples: http://192.168.1.25:8123 + + ' + default: '' + notify_telegram_chat_id: + name: Telegram Chat ID (Optional) + description: 'The chat ID to send telegram notifications to. + + If set, this will override individual devices and groups above. Note: + TV (far below) must be set to false. + + Base URL must start with https since telegram URL buttons only work with + https. + + ' + default: '' + notification_customisations: + name: '# Notification Customisations + + ' + description: These are Notification Customisation Options + icon: mdi:bell + collapsed: true + input: + title: + name: Notification Title (Optional) + description: The title of the notification. + default: '' + message: + name: Notification Message + description: 'The message of the notification. + + You can use variables such as {{camera_name}} and {{label}} + + e.g., A {{ label }} {{ '' was'' if type == ''end'' else '''' }} detected + on the {{ camera_name }} camera. + + ' + default: A {{ label }} {{ 'was detected' }} on the {{ camera_name }} camera. + selector: + select: + options: + - label: 'Default: e.g., A Person was detected on the Side camera.' + value: A {{ label }} {{ 'was detected' }} on the {{ camera_name }} + camera. + - label: 'Short: e.g., Person detected - Side' + value: '{{ label }} detected - {{ camera_name }}' + - label: Short with a timestamp HH:MM + value: '{{ label }} detected - {{ camera_name }} at {{event[''after''][''start_time'']|timestamp_custom(''%H:%M'')}}' + - label: 'Long: e.g., A Person was detected on the Side camera + in the driveway.' + value: '{{ label }}{{ '' was'' if type == ''end'' else '''' }} detected + on the {{ camera_name }} camera{{'' in the '' if after_zones|length}}{{ + after_zones | join('', '') | replace(''_'', '' '' ) | title }}.' + - label: Long with a timestamp HH:MM + value: '{{ label }}{{ '' was'' if type == ''end'' else '''' }} detected + on the {{ camera_name }} camera{{'' in the '' if after_zones|length}}{{ + after_zones | join('', '') | replace(''_'', '' '' ) | title }} at + {{event[''after''][''start_time'']|timestamp_custom(''%H:%M'')}}.' + custom_value: true + multiple: false + sort: false + update_sub_label: + name: Update Sub Labels (Advanced) + description: 'Update the title and/or message with the matched face name + and trigger a notification update. + + + Requires face detection to be configured via Double Take (Advanced). Requires + Title and/or Message to contain {{ label }} variable + + ' + default: true + selector: + boolean: {} + subtitle: + name: Subtitle + description: A secondary heading you can use in your notifications. + default: '' + critical: + name: Critical Notification (Optional) + description: 'Send as a critical notification to the mobile device. This + will ignore silent/vibrate modes. + + You can choose to limit critical notifications to certain times using + a template (some examples are provided but you can enter your own as long + as it outputs true or false) + + ' + default: 'false' + selector: + select: + options: + - 'false' + - 'true' + - '{{''false'' if now().hour in [8,9,10,11,12,13,14,15,16,17,18] else + ''true''}}' + - '{{''true'' if is_state(''sun.sun'', ''above_horizon'') else ''false'' + }}' + - '{{ event[''after''][''top_score''] |float(0) > 0.8 }}' + custom_value: true + multiple: false + sort: false + tts: + name: Use TTS to override silent/dnd modes on specific phones. + description: 'Some phones (the Samsung galaxy line, in particular,) disable + the ability to use `alarm_stream` as a means to bypass the current sound + settings. This option allows TTS to announce the alert instead, which + does bypass the sound settings. + + ' + default: false + selector: + boolean: {} + tts_helper: + name: Entity to store ids already alerted by TTS + description: 'In order for TTS to honor alert_once settings, create a text + helper (/config/helpers), which will be used to store the ids for any + tts alerts that have gone out. Set the maximum character count to 250 + to store the latest 25 alert ids. Then select it here + + ' + default: '' + selector: + entity: + filter: + - integration: input_text + multiple: false + alert_once: + name: Alert Once (Optional) + description: Only the first notification for each event will play a sound. + Updates, including new thumbnails, will be silent. iOS users who use Critical + Notifications above will still hear default critical sounds for updates. + default: false + selector: + boolean: {} + attachment: + name: Initial Attachment + description: 'Choose which image or GIF to attach to the initial notification. + + + Note: TVs will always get sent the snapshot. + + ' + default: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/thumbnail.jpg' + selector: + select: + options: + - label: Thumbnail + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/thumbnail.jpg' + - label: Snapshot + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg' + - label: Snapshot with bounding box + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?bbox=1' + - label: Snapshot cropped + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?crop=1' + - label: Snapshot cropped with bounding box + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?bbox=1&crop=1' + - label: Review GIF + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{review_id}}/review_preview.gif' + - label: Object 1 Event GIF + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/event_preview.gif' + - label: Thumbnail (2:1) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/thumbnail.jpg?format=android' + - label: Snapshot (2:1) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?format=android' + - label: Snapshot with bounding box (2:1) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?bbox=1&format=android' + - label: Snapshot cropped (2:1) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?crop=1&format=android' + - label: Snapshot cropped with bounding box (2:1) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?bbox=1&crop=1&format=android' + mode: dropdown + custom_value: false + multiple: false + sort: false + attachment_2: + name: Subsequent Attachment (Optional) + description: "Choose which image or GIF to attach to the notification for + any updates. It is recommended to enable Final Update\nSet to None to + continue using Initial Attachment for updates. \n\nNote: TVs will get + sent the snapshot if GIF is selected.\n" + default: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/thumbnail.jpg' + selector: + select: + options: + - label: None + value: '' + - label: Thumbnail + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/thumbnail.jpg' + - label: Snapshot + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg' + - label: Snapshot with bounding box + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?bbox=1' + - label: Snapshot cropped + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?crop=1' + - label: Snapshot cropped with bounding box + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?bbox=1&crop=1' + - label: Review GIF + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{review_id}}/review_preview.gif' + - label: Object 1 Event GIF + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/event_preview.gif' + - label: Thumbnail (2:1) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/thumbnail.jpg?format=android' + - label: Snapshot (2:1) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?format=android' + - label: Snapshot with bounding box (2:1) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?bbox=1&format=android' + - label: Snapshot cropped (2:1) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?crop=1&format=android' + - label: Snapshot cropped with bounding box (2:1) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg?bbox=1&crop=1&format=android' + mode: dropdown + custom_value: false + multiple: false + sort: false + video: + name: Video (Optional) + description: You can optionally attach the clip to the notification which + will replace the attachment above, if available. + default: '' + selector: + select: + options: + - label: None + value: '' + - label: Review GIF + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{review_id}}/review_preview.gif?format=ts' + - label: Object 1 Event GIF + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/event_preview.gif?format=ts' + - label: Clip mp4 + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/{{camera}}/clip.mp4' + - label: Clip m3u8 (IOS) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/{{camera}}/master.m3u8' + mode: dropdown + custom_value: false + multiple: false + sort: false + final_update: + name: Final update (Optional) + description: Update the notification at the end of the event. Used to ensure + the full video of GIF is sent. Configure the delay if necessary in the + timers section (default - 5 seconds). + default: false + selector: + boolean: {} + color: + name: Notification Color - Android and TV only (Optional) + description: "Set the color of the notification on your Android mobile device + or TV. \nTV supports `grey`, `black`, `indigo`, `green`, `red`, `cyan`, + `teal`, `amber` or `pink` only.\n" + default: '#03a9f4' + selector: + select: + options: + - label: Primary (Steelblue) + value: '#03a9f4' + - label: Red + value: '#f44336' + - label: Pink + value: '#e91e63' + - label: Purple + value: '#926bc7' + - label: Deep Purple + value: '#6e41ab' + - label: Indigo + value: '#3f51b5' + - label: Blue + value: '#2196f3' + - label: Light Blue + value: '#03a9f4' + - label: Cyan + value: '#00bcd4' + - label: Teal + value: '#009688' + - label: Green + value: '#4caf50' + - label: Light Green + value: '#8bc34a' + - label: Lime + value: '#cddc39' + - label: Yellow + value: '#ffeb3b' + - label: Amber + value: '#ffc107' + - label: Orange + value: '#ff9800' + - label: Deep Orange + value: '#ff5722' + - label: Brown + value: '#795548' + - label: Light Grey + value: '#bdbdbd' + - label: Grey + value: '#9e9e9e' + - label: Dark Grey + value: '#606060' + - label: Blue Grey + value: '#607d8b' + - label: Black + value: '#000000' + - label: White + value: '#ffffff' + custom_value: false + multiple: false + sort: false + icon: + name: Notification Icon (Optional) + description: Change the icon that displays on the notification. You can + enter a single icon or create a template like the example given in the + dropdown. You must include 'mdi:' in the icon name. + default: mdi:homeassistant + selector: + select: + options: + - mdi:homeassistant + - mdi:cctv + - mdi:{{'account-outline' if label == 'Person' else 'dog' if label == + 'Dog' else 'cat' if label == 'Cat' else 'car' if label == 'Car' else + 'home-assistant'}} + custom_value: true + multiple: false + sort: false + group: + name: Group + description: The group name that will determine if notifications are grouped + on your mobile device. If you want notifications grouped by camera, ensure + it contains {{camera}} + default: '{{camera}}-frigate-notification' + sound: + name: Notification Sound - iOS only (Optional) + description: You can specify a sound file on your device that will play + for the notifications. You will need to import the sound file into Home + Assistant. + default: default + selector: + select: + options: + - default + - none + custom_value: true + multiple: false + sort: false + volume: + name: Volume Sound - iOS only (Optional) + description: You can specify a sound level between 0 and 100 + default: 100 + selector: + number: + max: 100.0 + min: 0.0 + unit_of_measurement: '%' + step: 1.0 + mode: slider + ios_live_view: + name: Live View Entity - iOS only (Optional) + description: Attach a live view from the selected entity to the notification + for iOS devices. + default: '' + selector: + entity: + filter: + - domain: + - camera + multiple: false + android_auto: + name: Android Auto + description: Show the notification on Android Auto if the receiving device + is connected. + default: false + selector: + boolean: {} + sticky: + name: Sticky - Android only (Optional) + description: 'When enabled, the notification will stay active on the device + after tapping it and remain there until cleared. + + ' + default: false + selector: + boolean: {} + channel: + name: Notification Channel - Android only (Optional) + description: Create a new channel for notifications to allow custom notification + sounds, vibration patterns, and override of Do Not Disturb mode. Configured + directly on the device. + default: '' + filters: + name: '# Filters + + ' + description: These help limit when or what you are notified about. + icon: mdi:filter + collapsed: true + input: + review_severity: + name: Event Type + description: 'Specify the classification of Frigate events to be notified + about. + + ' + default: + - alert + - detection + selector: + select: + options: + - label: Alerts + value: alert + - label: Detections + value: detection + multiple: true + custom_value: false + sort: false + master_condition: + name: Master Condition (Optional) + description: Set conditions that will stop the automation from running if + the result is false. No other tests will be conducted later. This is a + kill switch on initiation. + default: [] + selector: + condition: {} + zone_filter: + name: Zone Filter on/off (Optional) + description: Enable to only notify if an object has entered a zone listed + below. + default: false + selector: + boolean: {} + zones: + name: Required Zones (Optional - Enabled Above) + description: 'Enter the name of one zone at a time. It must be lowercase + and include underscores as per your Frigate config. + + By default any zone is acceptable. If you desire ALL listed zones to be + entered before getting a notification, enable the multi toggle below. + + ' + default: [] + selector: + select: + options: + - examples + - porch + - front_door + - side + - garden + multiple: true + custom_value: true + sort: false + zone_multi: + name: Multi-Zone (Optional) + description: Require all zones specified above to be entered, instead of + any listed zone. Zone Filter must be enabled also. + default: false + selector: + boolean: {} + zone_order_enforced: + name: Zone Order Enforced (Optional) + description: "Combined with Multi-Zone, requires zones to be entered in + the same order as their requirement. \nUseful for alerting on arriving + vehicles, while ignoring departing vehicles, for instance\n" + default: false + selector: + boolean: {} + labels: + name: Object Filter (Optional) + description: Specify objects you wish to be notified about. Enter or select + one object at a time. + default: '' + selector: + select: + options: + - person + - dog + - cat + - car + - package + - bird + multiple: true + custom_value: true + sort: false + presence_filter: + name: Presence Filter (Optional) + description: Only notify if ALL of the selected presence entities are not + "home". + default: '' + selector: + entity: + filter: + - domain: + - device_tracker + - person + - group + multiple: true + state_filter: + name: State Filter on/off (Optional) + description: Enable the two State Filter settings below. Only notify if + the selected entity is in the specified states. + default: false + selector: + boolean: {} + state_entity: + name: State Filter Entity (Optional) + description: Only notify if the selected entity is in the below state. You + must enable "State Filter" above to use this. + default: '' + selector: + entity: {} + state_filter_states: + name: State Filter States (Optional) + description: Enter the states that the above entity must be in, one at a + time. + default: [] + selector: + select: + options: [] + multiple: true + custom_value: true + sort: false + disable_times: + name: Time Filter (Optional) + description: Prevent notifications from being sent during the specified + hours + default: [] + selector: + select: + multiple: true + options: + - label: 00:00 - 00:59 + value: '0' + - label: 01:00 - 01:59 + value: '1' + - label: 02:00 - 02:59 + value: '2' + - label: 03:00 - 03:59 + value: '3' + - label: 04:00 - 04:59 + value: '4' + - label: 05:00 - 05:59 + value: '5' + - label: 06:00 - 06:59 + value: '6' + - label: 07:00 - 07:59 + value: '7' + - label: 08:00 - 08:59 + value: '8' + - label: 09:00 - 09:59 + value: '9' + - label: 10:00 - 10:59 + value: '10' + - label: 11:00 - 11:59 + value: '11' + - label: 12:00 - 12:59 + value: '12' + - label: 13:00 - 13:59 + value: '13' + - label: 14:00 - 14:59 + value: '14' + - label: 15:00 - 15:59 + value: '15' + - label: 16:00 - 16:59 + value: '16' + - label: 17:00 - 17:59 + value: '17' + - label: 18:00 - 18:59 + value: '18' + - label: 19:00 - 19:59 + value: '19' + - label: 20:00 - 20:59 + value: '20' + - label: 21:00 - 21:59 + value: '21' + - label: 22:00 - 22:59 + value: '22' + - label: 23:00 - 23:59 + value: '23' + custom_value: false + sort: false + custom_filter: + name: Custom Filter (Optional - Advanced) + description: A filter that must result in true or false but can be templated + as necessary. You will need to ensure it is enclosed with appropriate + \"quotes\" and \{\{brackets\}\}. + default: true + timers: + name: '# Timers + + ' + description: These are Timers you can customise + icon: mdi:gesture-double-tap + collapsed: true + input: + cooldown: + name: Cooldown (Optional) + description: Delay before sending another notification for this camera after + the last event. + default: 0 + selector: + number: + max: 86400.0 + min: 0.0 + unit_of_measurement: seconds + step: 1.0 + mode: slider + timeout: + name: Timeout + description: Length of time the automation will wait for MQTT updates. + default: 2 + selector: + number: + max: 90.0 + min: 0.0 + unit_of_measurement: minutes + step: 1.0 + mode: slider + silence_timer: + name: Silence New Notifications (Optional) + description: "How long to pause notifications for this camera when requested + as part of the actionable notification. \nNote: Restarting Home Assistant + during the period will break the timer and may disable the automation\n" + default: 30 + selector: + number: + max: 3600.0 + min: 0.0 + unit_of_measurement: minutes + step: 1.0 + mode: slider + loiter_timer: + name: Loitering Notifications (Optional) + description: 'Sends new loitering notification if a stationary object is + detected for longer than the specified time. 0 is off and will not send + notifications. + + ' + default: 0 + selector: + number: + max: 3600.0 + min: 0.0 + unit_of_measurement: seconds + step: 1.0 + mode: slider + initial_delay: + name: Delay initial notification (Optional) + description: 'How long to delay the first notification for each event. Only + applies if all conditions are met when the first event is defined by frigate + + + Use this if you DO NOT use "update image" and are experiencing notifications + without attached images. Start with small numbers. + + ' + default: 0 + selector: + number: + max: 15.0 + min: 0.0 + unit_of_measurement: seconds + step: 1.0 + mode: slider + final_delay: + name: Delay Final notification (Optional) + description: 'How long to delay the final notification for each event. Only + applies if Final Update is enabled. + + ' + default: 5 + selector: + number: + max: 20.0 + min: 0.0 + unit_of_measurement: seconds + step: 1.0 + mode: slider + actions: + name: '# Action Buttons and URLS + + ' + description: These are Action Buttons and URL Options + icon: mdi:gesture-double-tap + collapsed: true + input: + tap_action: + name: Tap Action URL + description: 'The URL to open when tapping on the notification. Some presets + are provided, you can also set your own by typing in the box. + + These options define the text and URLs associated with the three action + buttons at the bottom of the notification.' + default: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/{{camera}}/clip.mp4' + selector: + select: + options: + - label: View Clip + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/{{camera}}/clip.mp4' + - label: View Clip (IOS) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/{{camera}}/master.m3u8' + - label: View GIF + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{review_id}}/review_preview.gif' + - label: View Snapshot + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg' + - label: View Stream + value: '{{base_url}}/api/camera_proxy_stream/camera.{{trigger.payload_json[''after''][''camera''] + | lower | replace(''-'',''_'')}}?token={{state_attr( ''camera.'' + ~ camera, ''access_token'')}}' + - label: Open Home Assistant (web) + value: '{{base_url}}/lovelace' + - label: Open Home Assistant (app) + value: /lovelace + - label: Open Frigate + value: /ccab4aaf_frigate/dashboard + - label: Open Frigate (Full Access) + value: /ccab4aaf_frigate-fa/dashboard + - label: Open Frigate (proxy) + value: /ccab4aaf_frigate-proxy/dashboard + - label: Open Reolink App (Android) + value: app://com.mcu.reolink + - label: None (Android) + value: noAction + - label: Notification History (Android) + value: settings://notification_history + custom_value: true + multiple: false + sort: false + button_1: + name: Action Button 1 Text + description: The text used on the first Action button at the bottom of the + notification. Set the URL below. (Default is "View Clip") + default: View Clip + url_1: + name: Action Button 1 URL + description: Customise what happens when you press the first Action Button. + Select from one of the preconfigured options or enter your own custom + URL. + default: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/{{camera}}/clip.mp4' + selector: + select: + options: + - label: View Clip + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/{{camera}}/clip.mp4' + - label: View Clip (IOS) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/{{camera}}/master.m3u8' + - label: View GIF + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{review_id}}/review_preview.gif' + - label: View Snapshot + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg' + - label: View Stream + value: '{{base_url}}/api/camera_proxy_stream/camera.{{trigger.payload_json[''after''][''camera''] + | lower | replace(''-'',''_'')}}?token={{state_attr( ''camera.'' + ~ camera, ''access_token'')}}' + - label: Open Home Assistant (web) + value: '{{base_url}}/lovelace' + - label: Open Home Assistant (app) + value: /lovelace + - label: Open Frigate + value: /ccab4aaf_frigate/dashboard + - label: Open Frigate (Full Access) + value: /ccab4aaf_frigate-fa/dashboard + - label: Open Frigate (proxy) + value: /ccab4aaf_frigate-proxy/dashboard + - label: Open Reolink App (Android) + value: app://com.mcu.reolink + custom_value: true + multiple: false + sort: false + icon_1: + name: Action Button 1 icon - iOS Only + description: Customise the Icon on the first Action Button. Only the iOS + SFSymbols library is supported, not mdi:icons. e.g., sfsymbols:bell + default: '' + button_2: + name: Action Button 2 Text + description: The text used on the second Action button at the bottom of + the notification. Set the URL below. + default: View Snapshot + url_2: + name: Action Button 2 URL + description: Customise what happens when you press the second Action Button. + Select from one of the preconfigured options or enter your own custom + URL. + default: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg' + selector: + select: + options: + - label: View Clip + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/{{camera}}/clip.mp4' + - label: View Clip (IOS) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/{{camera}}/master.m3u8' + - label: View Snapshot + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg' + - label: View Stream + value: '{{base_url}}/api/camera_proxy_stream/camera.{{trigger.payload_json[''after''][''camera''] + | lower | replace(''-'',''_'')}}?token={{state_attr( ''camera.'' + ~ camera, ''access_token'')}}' + - label: Open Home Assistant (web) + value: '{{base_url}}/lovelace' + - label: Open Home Assistant (app) + value: /lovelace + - label: Open Frigate + value: /ccab4aaf_frigate/dashboard + - label: Open Frigate (Full Access) + value: /ccab4aaf_frigate-fa/dashboard + - label: Open Frigate (proxy) + value: /ccab4aaf_frigate-proxy/dashboard + - label: Open Reolink App (Android) + value: app://com.mcu.reolink + - label: Custom Action (Manual Trigger) + value: custom-{{ this.entity_id }} + custom_value: true + multiple: false + sort: false + icon_2: + name: Action Button 2 icon - iOS Only + description: Customise the Icon on the second Action Button. Only the iOS + SFSymbols library is supported, not mdi:icons. e.g., sfsymbols:bell + default: '' + button_3: + name: Action Button 3 Text + description: The text used on the third Action button at the bottom of the + notification. Set the URL below. + default: Silence New Notifications + url_3: + name: Action Button 3 URL + description: Customise what happens when you press the third Action Button. + Select from one of the preconfigured options or enter your own custom + URL. + default: silence-{{ this.entity_id }} + selector: + select: + options: + - label: Silence New Notifications + value: silence-{{ this.entity_id }} + - label: View Clip + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/{{camera}}/clip.mp4' + - label: View Clip (IOS) + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/{{camera}}/master.m3u8' + - label: View Snapshot + value: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg' + - label: View Stream + value: '{{base_url}}/api/camera_proxy_stream/camera.{{trigger.payload_json[''after''][''camera''] + | lower | replace(''-'',''_'')}}?token={{state_attr( ''camera.'' + ~ camera, ''access_token'')}}' + - label: Open Home Assistant (web) + value: '{{base_url}}/lovelace' + - label: Open Home Assistant (app) + value: /lovelace + - label: Open Frigate + value: /ccab4aaf_frigate/dashboard + - label: Open Frigate (Full Access) + value: /ccab4aaf_frigate-fa/dashboard + - label: Open Frigate (proxy) + value: /ccab4aaf_frigate-proxy/dashboard + - label: Open Reolink App (Android) + value: app://com.mcu.reolink + - label: Custom Action (Manual Trigger) + value: custom-{{ this.entity_id }} + custom_value: true + multiple: false + sort: false + icon_3: + name: Action Button 3 icon - iOS Only + description: Customise the Icon on the third Action Button. Only the iOS + SFSymbols library is supported, not mdi:icons. e.g., sfsymbols:bell + default: '' + custom_action_manual: + name: Custom Action (Manual Trigger) + description: Customisable action that you can trigger with the Custom Action + buttons in the notification. Select Custom Action on any Action Button + above. + selector: + action: {} + default: [] + custom_action_auto: + name: Custom Action (Auto Trigger) + description: Customisable action that will trigger on the initial notification + (subject to all other notification conditions). + selector: + action: {} + default: [] + custom_action_auto_multi: + name: Custom Action (Auto Trigger in Loop) + description: Customisable action that will trigger on all subsequent notifications + (subject to all other notification conditions). If you want it to also + trigger on the initial notification, you must enter it in both input fields. + selector: + action: {} + default: [] + tv_notifications: + name: '# TV Notifications + + ' + description: These are TV Notification Options + icon: mdi:television + collapsed: true + input: + tv: + name: TV Notification (Optional) + description: 'Set to true if you are notifying an Android/Fire TV + + Can also be used to prioritise snapshots on the TV over Android mobile + apps when notifying a mixed device group. + + Base URL must be set + + + The below settings are for TV notifications only + + ' + default: false + selector: + boolean: {} + tv_position: + name: TV Notification Position (Optional) + description: Set the position of the notification on your TV + default: center + selector: + select: + mode: dropdown + options: + - bottom-right + - bottom-left + - top-right + - top-left + - center + custom_value: false + multiple: false + sort: false + tv_size: + name: TV Notification Size (Optional) + description: Set the size of the notification on your TV. + default: large + selector: + select: + mode: dropdown + options: + - small + - medium + - large + - max + custom_value: false + multiple: false + sort: false + tv_duration: + name: TV Notification Duration (Optional) + description: The duration (in seconds) that the notification will display + on your TV. + default: 10 + selector: + number: + max: 300.0 + min: 0.0 + unit_of_measurement: seconds + step: 1.0 + mode: slider + tv_transparency: + name: TV notification Transparency (Optional) + description: Set the transparency of the notification on your TV. + default: 0% + selector: + select: + mode: dropdown + options: + - 0% + - 25% + - 50% + - 75% + - 100% + custom_value: false + multiple: false + sort: false + tv_interrupt: + name: TV Notification Interrupt (Optional) + description: If set to true the notification is interactive and can be dismissed + or selected to display more details. Depending on the running app (e.g., + Netflix), this may stop playback. + default: false + selector: + boolean: {} + debug: + name: '# DEBUG + + ' + description: These are DEBUG Options + icon: mdi:bug + collapsed: true + input: + debug: + name: Debug + description: Enable to send debug messages to the home assistant logbook. + default: false + selector: + boolean: {} + redacted: + name: Redact Base URL + description: Hides the Base URL in the debug output for easier sharing. + Does not hide it from other parts of the trace. + default: true + selector: + boolean: {} +mode: parallel +trigger_variables: + mqtt_topic: !input mqtt_topic +triggers: +- trigger: mqtt + topic: '{{mqtt_topic}}' + payload: new + value_template: '{{value_json[''type'']}}' + id: frigate-event +- trigger: event + event_type: mobile_app_notification_action + event_data: + action: silence-{{ this.entity_id }} + id: silence +- trigger: event + event_type: mobile_app_notification_action + event_data: + action: custom-{{ this.entity_id}} + id: custom +variables: + input_camera: !input camera + input_camera_name: '{{input_camera|expand|map(attribute=''attributes.camera_name'', + default=''none'')|list}}' + camera: '{{trigger.payload_json[''after''][''camera''] if trigger.id == ''frigate-event''}}' + camera_name: '{{ camera | replace(''_'', '' '') | title }}' + input_severity: !input review_severity + severity: '{{trigger.payload_json[''after''][''severity''] if trigger.id == ''frigate-event''}}' + type: '{{trigger.payload_json[''type''] if trigger.id == ''frigate-event''}}' + input_base_url: !input base_url + base_url: '{{ input_base_url.rstrip(''/'')}}' + input_telegram_base_url: !input telegram_base_url + telegram_base_url: '{{ input_telegram_base_url.rstrip(''/'') if input_telegram_base_url + else base_url }}' + update_sub_label: !input update_sub_label + input_client_id: !input client_id + client_id: '{{input_client_id if not input_client_id else ''/'' + input_client_id + if ''/'' not in input_client_id else input_client_id }}' + alert_once: !input alert_once + final_update: !input final_update + ios_live_view: !input ios_live_view + android_auto: !input android_auto + notify_group: !input notify_group + notify_group_target: '{{ notify_group | lower | regex_replace(''^notify\.'', '''') + | replace('' '',''_'') }}' + telegram_chat_id: !input notify_telegram_chat_id + telegram: '{{true if (telegram_chat_id | length > 0) else false}}' + zone_only: !input zone_filter + input_zones: !input zones + zones: '{{ input_zones }}' + zone_multi: !input zone_multi + zone_order_enforced: !input zone_order_enforced + input_labels: !input labels + labels: '{{ input_labels | list | lower }}' + presence_entity: !input presence_filter + disable_times: !input disable_times + cooldown: !input cooldown + timeout: !input timeout + loitering: false + loiter_timer: !input loiter_timer + initial_delay: !input initial_delay + final_delay: !input final_delay + fps: '{{ states(''sensor.'' + camera + ''_camera_fps'')|int(5) }}' + state_only: !input state_filter + input_entity: !input state_entity + input_states: !input state_filter_states + states_filter: '{{ input_states | list | lower }}' + custom_filter: !input custom_filter + color: !input color + sound: !input sound + input_volume: !input volume + volume: '{{ (1 * input_volume|int(100))/100 }}' + sticky: !input sticky + tv: !input tv + tv_position: !input tv_position + tv_size: !input tv_size + tv_duration: !input tv_duration + tv_transparency: !input tv_transparency + tv_interrupt: !input tv_interrupt + debug: !input debug + redacted: !input redacted + master_condition: !input master_condition + severity_satisfied: '{{input_severity|select(''in'', severity)|list|length > 0 if + trigger.id == ''frigate-event''}}' + objects: '{{ trigger.payload_json[''after''][''data''][''objects''] if trigger.id + == ''frigate-event'' }}' + objects_satisfied: '{{ not labels|length or labels|select(''in'', objects)|list|length + > 0 or (''person-verified'' in objects and ''person'' in labels) }}' + initial_home: '{{ presence_entity != '''' and presence_entity|expand|selectattr(''state'',''eq'',''home'')|list|length + != 0 }}' + state_satisfied: '{{ not state_only or states(input_entity)|lower in states_filter + }}' + before_zones: '{{ trigger.payload_json[''before''][''data''][''zones''] if trigger.id + == ''frigate-event'' }}' + after_zones: '{{ trigger.payload_json[''after''][''data''][''zones''] if trigger.id + == ''frigate-event'' }}' + zone_multi_filter: '{{zone_only and zone_multi and after_zones|length and zones + and zones |reject(''in'', after_zones) |list |length == 0 }}' +conditions: + condition: or + conditions: + - condition: trigger + id: silence + - condition: trigger + id: custom + - condition: and + conditions: + - condition: trigger + id: frigate-event + - alias: Camera Match + condition: template + value_template: '{{ input_camera_name|select(''equalto'', camera)|list|length>0 + }}' + - alias: Master Condition + condition: !input master_condition + - alias: Cooldown + condition: template + value_template: '{{ not this.attributes.last_triggered or (now() - this.attributes.last_triggered).seconds + > cooldown }}' + - alias: Disable Times + condition: template + value_template: '{{ not disable_times|length or not now().hour in disable_times|map(''int'')|list + }}' +actions: +- choose: + - alias: Silence New Object Notifications + conditions: + - condition: trigger + id: silence + sequence: + - action: automation.turn_off + target: + entity_id: '{{ this.entity_id }}' + data: + stop_actions: false + - delay: + minutes: !input silence_timer + - action: automation.turn_on + target: + entity_id: '{{ this.entity_id }}' + - alias: Custom Action Manual + conditions: + - condition: trigger + id: custom + sequence: !input custom_action_manual + - alias: Frigate Event + conditions: + - condition: trigger + id: frigate-event + sequence: + - variables: + event: '{{ trigger.payload_json }}' + detections: '{{ event[''after''][''data''][''detections''] }}' + review_id: '{{event[''after''][''id'']}}' + id: '{{ detections[0] }}' + objects: '{{ event[''after''][''data''][''objects''] }}' + sub_labels: '{{ event[''after''][''data''][''sub_labels''] }}' + label: "{% if update_sub_label %}\n {% set data = namespace(labels=[]) %} + \n {% if labels|length %}\n {% for obj in objects|select('in', labels) + %}\n {% if \"-verified\" in obj %}\n {% else %}\n {% set + data.labels = data.labels + [obj] %}\n {% endif %}\n {% endfor %} + {% set data.labels = data.labels + sub_labels %} \n {{ data.labels | + unique | list | sort | join(\", \") | title }}\n {% else %}\n {% for + obj in objects %}\n {% if \"-verified\" in obj %}\n {% else %}\n + \ {% set data.labels = data.labels + [obj] %}\n {% endif %}\n + \ {% endfor %} {% set data.labels = data.labels + sub_labels %} \n {{ + data.labels | unique | list | sort | join(\", \") | title }}\n {% endif + %}\n{% else %}\n {{ objects | list | join(\", \") | title }}\n{% endif + %}" + any_zones_entered: '{{ zones | length == 0 or ((zones | select(''in'', after_zones) + | list | length) > 0) }}' + zone_single_satisfied: '{{ any_zones_entered if zone_only else true}}' + all_zones_entered: '{{ zones | length == 0 or ((zones | reject(''in'', after_zones) + | list | length) == 0) }}' + zone_multi_satisfied: '{{ all_zones_entered if zone_only and zone_multi else + true}}' + ordered_zones_match: "{% set ns = namespace(intersection=[]) %} {% for item + in after_zones %}\n {% if item in zones %}\n {% set ns.intersection + = ns.intersection + [item] %}\n {% endif %}\n{% endfor %} {{ ns.intersection + == zones }}\n" + zone_order_satisfied: '{{ (zone_only and zone_multi and ordered_zones_match) + if zone_order_enforced else true }}' + zones_satisfied: '{{zone_single_satisfied and zone_multi_satisfied and zone_order_satisfied}}' + title: !input title + message: !input message + subtitle: !input subtitle + tap_action: !input tap_action + button_1: !input button_1 + button_2: !input button_2 + button_3: !input button_3 + url_1: !input url_1 + url_2: !input url_2 + url_3: !input url_3 + icon_1: !input icon_1 + icon_2: !input icon_2 + icon_3: !input icon_3 + critical_input: !input critical + critical: '{{ true if critical_input == ''true'' else true if critical_input + == True else false }}' + tts: !input tts + tts_helper: !input tts_helper + custom_filter: !input custom_filter + icon: !input icon + group: !input group + channel: !input channel + attachment: !input attachment + video: !input video + custom_action_auto: !input custom_action_auto + - alias: 'Debug: Initial Output' + choose: + - conditions: + - '{{debug}}' + sequence: + - action: logbook.log + data_template: + name: Frigate Notification + message: "DEBUG: \n Info:\n FPS: {{fps}}, \n Frigate Review id: + {{review_id}}{{', Frigate client ID: ' + client_id if client_id else + ''}}, \n Frigate Detections: {{detections}}\n Objects: {{label}},\n + \ Sub Labels: {{sub_labels | join(', ')}}\n Config: \n Camera(formatted): + {{camera}}({{camera_name}}), \n Base URL: {{'REDACTED' if base_url + and redacted else base_url}},\n Critical: {{critical}}, \n TTS: + {{tts}} \n TTS Helper: {{tts_helper if tts else 'N/A'}},\n Alert + Once: {{alert_once}}, \n Final_Update (delay): {{final_update}} ({{final_delay}})s, + \n Attachment: {{attachment if not redacted or not base_url else + attachment |replace(base_url, 'REDACTED')}}\n Video: {{video if not + redacted or not base_url else video |replace(base_url, 'REDACTED')}}, + \n iOS URL: {{(video if not redacted or not base_url else video |replace(base_url, + 'REDACTED')) if video|length >0 else attachment if not redacted or not + base_url else attachment |replace(base_url, 'REDACTED')}}\n Target: + {{'group (input/formatted): ' + notify_group + '/' + notify_group_target + + ', ' if notify_group else 'Mobile Device'}}, \n Cooldown: {{cooldown}}s, + \n Initial Delay: {{initial_delay}}s, \n Color: {{color}}, \n + \ Sound: {{sound}}, \n Volume: {{ iif(sound == 'none', 0, volume) + }}\n IOS Live entity: \"{{ios_live_view}}\"\n Android Auto: {{android_auto}}, + \n Tag: {{ id }}, \n Group: {{group}}, \n Channel: {{channel}} + {{' - overridden by alarm_stream' if critical}}, \n Sticky: {{sticky}}, + \n Title: {{title}}, \n Message: {{message}},\n Subtitle: {{subtitle}}, + \n Tap Action: {{tap_action if not redacted or not base_url else + tap_action |replace(base_url, 'REDACTED')}}, \n Action Button 1 Text/URL/Icon: + {{iif(button_1, button_1, 'unset')}} ({{url_1 if not redacted or not + base_url else url_1 |replace(base_url, 'REDACTED')}}) {{icon_1}}, \n + \ Action Button 2 Text/URL/Icon: {{iif(button_2, button_2, 'unset')}} + ({{url_2 if not redacted or not base_url else url_2 |replace(base_url, + 'REDACTED')}}) {{icon_2}}, \n Action Button 3 Text/URL/Icon: {{iif(button_3, + button_3, 'unset')}} ({{url_3 if not redacted or not base_url else url_3 + |replace(base_url, 'REDACTED')}}) {{icon_3}}, \n Icon: {{icon}}\n + \ TV: {{ tv }}, \n Position: {{tv_position}}, \n Size: {{tv_size}}, + \n Duration: {{tv_duration}}, \n Transparency: {{tv_transparency}}, + \n TV Interrupt: {{tv_interrupt}}, \n Telegram: {{telegram}},\n + \ Telegram_chat_id: {{telegram_chat_id}},\n Filters: \n Severity:\n + \ Required Severity: {{input_severity}},\n TEST: {{'PASS' if + severity_satisfied else 'FAIL'}} - {{severity}}\n Zones: \n Zone + Filter toggle on: {{zone_only}}, \n Multi-Zone toggle on: {{zone_multi}}, + \n Required zones: {{input_zones}}, \n Zone Order toggle on: + {{zone_order_enforced}}\n Entered Zones: {{after_zones}},\n TEST: + {{'PASS' if zones_satisfied else 'FAIL' }} {{'(Multi)' if zone_only + and zone_multi}} {{'(Order-Enforced)' if zone_only and zone_multi and + zone_order_enforced}}, \n Required objects: \n Input: {{input_labels}}, + \n TEST: {{'PASS' if objects_satisfied else 'FAIL'}} - {{objects}}\n + \ presence entity (not home):\n Entity: {{presence_entity}}\n + \ TEST: {{'PASS' if not initial_home else 'FAIL'}}, \n disabled + times: {{disable_times}}, \n State Filter: \n State Filter toggle + on: {{state_only}}, \n State Filter Entity: {{input_entity}}, \n + \ Required States: {{input_states}}, \n TEST: {{'PASS' if state_satisfied + else 'FAIL' }},\n Custom Filter: {{custom_filter}}\n" + - choose: + - conditions: + - alias: Severity Filter + condition: template + value_template: '{{ severity_satisfied }}' + - alias: Object Filter + condition: template + value_template: '{{ objects_satisfied }}' + - alias: Zone Filter + condition: template + value_template: '{{ zones_satisfied }}' + - alias: Presence Filter + condition: template + value_template: '{{ not initial_home }}' + - alias: State Filter + condition: template + value_template: '{{ state_satisfied }}' + - alias: Custom Filter + condition: template + value_template: '{{ custom_filter }}' + sequence: + - alias: Delay for image + choose: + - conditions: '{{initial_delay > 0}}' + sequence: + - delay: + seconds: '{{initial_delay}}' + - alias: Custom Action Auto + choose: + - conditions: '{{ custom_action_auto |length > 0 }}' + sequence: !input custom_action_auto + - alias: Send Notification + sequence: + - choose: + - conditions: '{{ telegram }}' + sequence: + - action: telegram_bot.send_photo + data: + target: '{{telegram_chat_id}}' + caption: '{{message}}' + url: '{{attachment|replace( base_url, telegram_base_url )}}' + - conditions: '{{ not notify_group_target }}' + sequence: + - device_id: !input notify_device + domain: mobile_app + type: notify + title: '{{title}}' + message: '{{message}}' + data: + tag: '{{ id }}' + group: '{{ group }}' + color: '{{color}}' + subject: '{{subtitle}}' + image: '{{attachment}}' + video: '{{video}}' + clickAction: '{{tap_action}}' + ttl: 0 + priority: high + notification_icon: '{{icon}}' + sticky: '{{sticky}}' + channel: '{{''alarm_stream'' if critical else channel}}' + car_ui: '{{android_auto}}' + subtitle: '{{subtitle}}' + url: '{{tap_action}}' + attachment: + url: '{{video if video else attachment }}' + content-type: '{{ ''application/vnd.apple.mpegurl'' if ''m3u8'' + in video else ''mp4'' if ''mp4'' in video else ''jpeg'' if ''jpg'' + in attachment else ''gif'' }}' + push: + sound: + name: '{{sound}}' + volume: '{{ iif(sound == ''none'', 0, volume) }}' + critical: '{{ iif(critical, 1, 0) }}' + entity_id: '{{ios_live_view}}' + actions: + - action: URI + title: '{{button_1}}' + uri: '{{url_1}}' + icon: '{{icon_1}}' + - action: URI + title: '{{button_2}}' + uri: '{{url_2}}' + icon: '{{icon_2}}' + - action: '{{ ''URI'' if ''/'' in url_3 else url_3 }}' + title: '{{button_3}}' + uri: '{{url_3}}' + icon: '{{icon_3}}' + destructive: true + - conditions: '{{ tv }}' + sequence: + - action: notify.{{ notify_group_target }} + data: + title: '{{title}}' + message: '{{message}}' + data: + tag: '{{ id }}' + group: '{{ group }}' + color: '{{color}}' + subject: '{{subtitle}}' + clickAction: '{{tap_action}}' + ttl: 0 + priority: high + notification_icon: '{{icon}}' + sticky: '{{sticky}}' + channel: '{{''alarm_stream'' if critical else channel}}' + car_ui: '{{android_auto}}' + image: + url: '{{attachment | replace(''review_preview.gif'',''snapshot.jpg'') + | replace(''event_preview.gif'',''snapshot.jpg'')}}' + fontsize: '{{tv_size}}' + position: '{{tv_position}}' + duration: '{{tv_duration}}' + transparency: '{{tv_transparency}}' + interrupt: '{{tv_interrupt}}' + timeout: 30 + subtitle: '{{subtitle}}' + url: '{{tap_action}}' + attachment: + url: '{{video if video else attachment }}' + content-type: '{{ ''application/vnd.apple.mpegurl'' if ''m3u8'' + in video else ''mp4'' if ''mp4'' in video else ''jpeg'' if + ''jpg'' in attachment else ''gif'' }}' + push: + sound: + name: '{{sound}}' + volume: '{{ iif(sound == ''none'', 0, volume) }}' + critical: '{{ iif(critical, 1, 0) }}' + entity_id: '{{ios_live_view}}' + actions: + - action: URI + title: '{{button_1}}' + uri: '{{url_1}}' + icon: '{{icon_1}}' + - action: URI + title: '{{button_2}}' + uri: '{{url_2}}' + icon: '{{icon_2}}' + - action: '{{ ''URI'' if ''/'' in url_3 else url_3 }}' + title: '{{button_3}}' + uri: '{{url_3}}' + icon: '{{icon_3}}' + destructive: true + default: + - action: notify.{{ notify_group_target }} + data: + title: '{{title}}' + message: '{{message}}' + data: + tag: '{{ id }}' + group: '{{ group }}' + color: '{{color}}' + subject: '{{subtitle}}' + image: '{{attachment}}' + video: '{{video}}' + clickAction: '{{tap_action}}' + ttl: 0 + priority: high + notification_icon: '{{icon}}' + sticky: '{{sticky}}' + channel: '{{''alarm_stream'' if critical else channel}}' + car_ui: '{{android_auto}}' + subtitle: '{{subtitle}}' + fontsize: '{{tv_size}}' + position: '{{tv_position}}' + duration: '{{tv_duration}}' + transparency: '{{tv_transparency}}' + interrupt: '{{tv_interrupt}}' + url: '{{tap_action}}' + attachment: + url: '{{video if video else attachment }}' + content-type: '{{ ''application/vnd.apple.mpegurl'' if ''m3u8'' + in video else ''mp4'' if ''mp4'' in video else ''jpeg'' if ''jpg'' + in attachment else ''gif'' }}' + push: + sound: + name: '{{sound}}' + volume: '{{ iif(sound == ''none'', 0, volume) }}' + critical: '{{ iif(critical, 1, 0) }}' + entity_id: '{{ios_live_view}}' + actions: + - action: URI + title: '{{button_1}}' + uri: '{{url_1}}' + icon: '{{icon_1}}' + - action: URI + title: '{{button_2}}' + uri: '{{url_2}}' + icon: '{{icon_2}}' + - action: '{{ ''URI'' if ''/'' in url_3 else url_3 }}' + title: '{{button_3}}' + uri: '{{url_3}}' + icon: '{{icon_3}}' + destructive: true + - if: '{{tts and (not tts_helper or not alert_once or (tts_helper and id + not in states(tts_helper)))}}' + then: + sequence: + - choose: + - conditions: '{{ not notify_group_target }}' + sequence: + - device_id: !input notify_device + domain: mobile_app + type: notify + message: '{{''TTS''}}' + data: + tag: '{{ id }}{{''-tts''}}' + channel: '{{''alarm_stream'' if critical else channel}}' + alert_once: '{{ alert_once }}' + tts_text: '{{message}}' + default: + - action: notify.{{ notify_group_target }} + data: + message: '{{''TTS''}}' + data: + tag: '{{ id }}{{''-tts''}}' + channel: '{{''alarm_stream'' if critical else channel}}' + alert_once: '{{ alert_once }}' + tts_text: '{{message}}' + - action: input_text.set_value + data: + value: '{% set newIds = id + ''|'' + states(tts_helper) %} + + {{ newIds[:250] }} + + ' + target: + entity_id: '{{tts_helper}}' + - repeat: + sequence: + - wait_for_trigger: + - trigger: mqtt + topic: '{{mqtt_topic}}' + payload: '{{ review_id }}' + value_template: '{{ value_json[''after''][''id''] }}' + timeout: + minutes: '{{timeout}}' + continue_on_timeout: false + - variables: + attachment_2: !input attachment_2 + attachment: '{{iif(attachment_2, attachment_2, attachment)}}' + event: '{{ wait.trigger.payload_json }}' + type: '{{event[''type'']}}' + initial_severity: '{{severity}}' + old_objects: '{{objects}}' + last_zones: '{{after_zones}}' + severity: '{{event[''after''][''severity'']}}' + severity_updated: '{{initial_severity != severity}}' + severity_satisfied: '{{((input_severity | select(''equalto'', severity) + | list | length) > 0) }}' + objects: '{{ event[''after''][''data''][''objects''] }}' + objects_satisfied: '{{ not labels|length or labels|select(''in'', objects)|list|length + > 0 or (''person-verified'' in objects and ''person'' in labels) }}' + home: '{{presence_entity |reject(''in'', '''') |select(''is_state'', ''home'') + |list |length != 0 }}' + presence_changed: '{{ presence_entity |reject(''in'', '''') |expand |map(attribute=''last_changed'') + |list |select(''gt'', as_datetime(event[''before''][''start_time''])) + |list |length != 0 }}' + before_zones: '{{ event[''before''][''data''][''zones''] | default([]) + }}' + after_zones: '{{ event[''after''][''data''][''zones''] | default([]) }}' + any_zones_entered: '{{ zones | length == 0 or ((zones | select(''in'', + after_zones) | list | length) > 0) }}' + zone_single_satisfied: '{{ any_zones_entered if zone_only else true}}' + all_zones_entered: '{{ zones | length == 0 or ((zones | reject(''in'', + after_zones) | list | length) == 0) }}' + zone_multi_satisfied: '{{ all_zones_entered if zone_only and zone_multi + else true}}' + ordered_zones_match: "{% set ns = namespace(intersection=[]) %} {% for + item in after_zones %}\n {% if item in zones %}\n {% set ns.intersection + = ns.intersection + [item] %}\n {% endif %}\n{% endfor %} {{ ns.intersection + == zones }}\n" + zone_order_satisfied: '{{ (zone_only and zone_multi and ordered_zones_match) + if zone_order_enforced else true }}' + zones_satisfied: '{{zone_single_satisfied and zone_multi_satisfied and + zone_order_satisfied}}' + new_entered_zones: '{{ zones | select(''in'', after_zones) | list }}' + last_entered_zones: '{{ zones | select(''in'', last_zones) | list }}' + entered_new_zones: '{{ not zone_only and after_zones | length > last_zones + | length }}' + entered_new_filter_zones: '{{ zone_only and zones | length > 0 and (new_entered_zones + | length > last_entered_zones | length) }}' + state_satisfied: '{{ not state_only or states(input_entity)|lower in states_filter + }}' + before_sub_labels: '{{ sub_labels }}' + sub_labels: '{{ event[''after''][''data''][''sub_labels''] | default([]) + }}' + label: "{% if update_sub_label %}\n {% set data = namespace(labels=[]) + %} \n {% if labels|length %}\n {% for obj in objects|select('in', + labels) %}\n {% if \"-verified\" in obj %}\n {% else %}\n + \ {% set data.labels = data.labels + [obj] %}\n {% endif + %}\n {% endfor %} {% set data.labels = data.labels + sub_labels %} + \n {{ data.labels | unique | list | sort | join(\", \") | title }}\n + \ {% else %}\n {% for obj in objects %}\n {% if \"-verified\" + in obj %}\n {% else %}\n {% set data.labels = data.labels + + [obj] %}\n {% endif %}\n {% endfor %} {% set data.labels = + data.labels + sub_labels %} \n {{ data.labels | unique | list | sort + | join(\", \") | title }}\n {% endif %}\n{% else %}\n {{objects | + list | join(', ') | title}}\n{% endif %}" + title: !input title + message: !input message + subtitle: !input subtitle + critical_input: !input critical + critical: '{{ true if critical_input == ''true'' else true if critical_input + == True else false }}' + tts: !input tts + sub_label_updated: '{{ update_sub_label and sub_labels != before_sub_labels + }}' + zone_updated: '{{ (entered_new_filter_zones and zones_satisfied) or entered_new_zones + }}' + object_updated: '{{ old_objects | select(''in'', labels) | list | length != + objects | select(''in'', labels) | list | length }}' + silent_update: '{{ alert_once or (not presence_changed and not zone_updated + and not object_updated and not sub_label_updated) }}' + custom_action_auto_multi: !input custom_action_auto_multi + - alias: 'Debug: Loop Output' + choose: + - conditions: + - '{{debug}}' + sequence: + - action: logbook.log + data_template: + name: Frigate Notification + message: "DEBUG (in loop):\n Send Notification: {{custom_filter and + not home and zones_satisfied and state_satisfied and objects_satisfied + and severity_satisfied and ((final_update and type == 'end') or + (severity_updated or presence_changed or zone_updated or object_updated + or sub_label_updated)) }}\n Info:\n Sub Label: {{sub_labels}},\n + \ Image: \"{{attachment if not redacted or not base_url else attachment + |replace(base_url, 'REDACTED')}}\"\n Title: {{title}}\n Message: + {{message}}\n iOS sound: {{'Critical' if critical else 'disabled + by alert once' if alert_once else 'Silent' if silent_update else + sound}},\n Android Sound: {{'disabled by alert once' if alert_once + else 'enabled'}},\n iOS url: \"{{(video if not redacted or not + base_url else video |replace(base_url, 'REDACTED')) if video else + attachment if not redacted or not base_url else attachment |replace(base_url, + 'REDACTED')}}\", \n Video: \"{{video if not redacted or not base_url + else video |replace(base_url, 'REDACTED')}}\", \n\n Critical: + {{critical}},\n TTS: {{tts}}\n Triggers:\n New Snapshot: + False (not functional with reviews)\n Severity Changed: {{severity_updated}},\n + \ Presence Changed: {{presence_changed}},\n Object changed: + {{object_updated}},\n Zones Changed: {{'True' if entered_new_filter_zones + and zones_satisfied else 'True - zone filter disabled' if entered_new_zones + and not zone_only else 'True - Filter Criteria not met' if entered_new_zones + else 'False'}},\n Sublabel changed: {{ sub_label_updated }}{{' + - Disabled' if not update_sub_label}},\n Final Update: {{final_update + and type == 'end'}}\n Conditions:\n Filters:\n Severity:\n + \ Required Severity: {{input_severity}}\n TEST: {{'PASS' + if severity_satisfied else 'FAIL'}} - {{severity}}, \n Zones:\n + \ Zone Filter toggle on: {{zone_only}},\n Multi-Zone + toggle on: {{zone_multi}},\n Required zones: {{input_zones}},\n + \ Zone Order toggle on: {{zone_order_enforced}}\n Last + Zones: {{ last_zones | list | length }} - {{last_zones}},\n New + Zones: {{ after_zones | list | length }} - {{after_zones}},\n TEST: + {{'PASS' if zones_satisfied else 'FAIL' }} {{'(Multi)' if zone_only + and zone_multi}} {{'(Order-Enforced)' if zone_only and zone_multi + and zone_order_enforced}},\n Object Filter:\n Input: + {{input_labels}},\n TEST: {{'PASS' if objects_satisfied else + 'FAIL'}} - {{objects}},\n Presence entity (not home):\n Entity: + {{presence_entity}},\n TEST: {{'PASS' if not home else 'FAIL'}},\n + \ Time Filter:\n Disabled times: {{disable_times}},\n + \ TEST: {{'PASS' if now().hour not in disable_times else 'FAIL'}}\n + \ State Filter:\n State Filter toggle on: {{state_only}},\n + \ State Filter Entity: {{input_entity}},\n Required + States: {{input_states}},\n TEST: {{'PASS' if state_satisfied + else 'FAIL'}},\n Custom Filter: {{'PASS' if custom_filter else + 'FAIL'}},\n" + - choose: + - conditions: + - and: + - alias: Severity Filter + condition: template + value_template: '{{severity_satisfied}}' + - alias: Object Filter + condition: template + value_template: '{{ objects_satisfied }}' + - alias: Zone Filter + condition: template + value_template: '{{zones_satisfied}}' + - alias: State Filter + condition: template + value_template: '{{state_satisfied}}' + - alias: Custom Filter + condition: template + value_template: '{{custom_filter}}' + - alias: Presence Filter + condition: template + value_template: '{{not home}}' + - or: + - alias: Presence Changed + condition: template + value_template: '{{presence_changed}}' + - alias: Zone Changed + condition: template + value_template: '{{zone_updated}}' + - alias: Sub Label Changed + condition: template + value_template: '{{sub_label_updated}}' + - alias: Object Changed + condition: template + value_template: '{{object_updated}}' + - alias: Severity Changed + condition: template + value_template: '{{severity_updated}}' + - and: + - alias: Final Update + condition: template + value_template: '{{final_update}}' + - alias: End of Event + condition: template + value_template: '{{event[''type''] == ''end''}}' + sequence: + - alias: Custom Action Auto Multi + choose: + - conditions: + - '{{ custom_action_auto_multi | length > 0 }}' + sequence: !input custom_action_auto_multi + - alias: Delay for Final Update + choose: + - conditions: + - '{{ event[''type''] == ''end'' }}' + - '{{ final_update }}' + sequence: + - delay: + seconds: '{{final_delay}}' + - alias: Update Notification + sequence: + - choose: + - conditions: '{{ telegram }}' + sequence: + - choose: + - conditions: + - '{{ event[''type''] == ''end'' }}' + - '{{ video | length > 0 }}' + sequence: + - action: telegram_bot.send_video + data: + target: '{{telegram_chat_id}}' + caption: '{{message}}' + url: '{{ video | replace(base_url, telegram_base_url) }}' + inline_keyboard: + - - - '{{button_1}}' + - '{{url_1}}' + - - '{{button_2}}' + - '{{url_2}}' + - - - '{{button_3}}' + - '{{url_3}}' + default: + - action: telegram_bot.send_photo + data: + target: '{{telegram_chat_id}}' + caption: '{{message}}' + url: '{{attachment | replace(base_url,telegram_base_url)}}' + inline_keyboard: + - - - '{{button_1}}' + - '{{url_1}}' + - - '{{button_2}}' + - '{{url_2}}' + - - - '{{button_3}}' + - '{{url_3}}' + - conditions: '{{ not notify_group_target }}' + sequence: + - device_id: !input notify_device + domain: mobile_app + type: notify + title: '{{title}}' + message: '{{message}}' + data: + tag: '{{ id }}' + group: '{{ group }}' + color: '{{color}}' + subject: '{{subtitle}}' + image: '{{attachment}}' + video: '{{video}}' + clickAction: '{{tap_action}}' + ttl: 0 + priority: high + alert_once: '{{ alert_once }}' + notification_icon: '{{icon}}' + sticky: '{{sticky}}' + channel: '{{''alarm_stream'' if critical else channel}}' + car_ui: '{{android_auto}}' + subtitle: '{{subtitle}}' + url: '{{tap_action}}' + attachment: + url: '{{video if video else attachment }}' + content-type: '{{ ''application/vnd.apple.mpegurl'' if ''m3u8'' + in video else ''mp4'' if ''mp4'' in video else ''jpeg'' + if ''jpg'' in attachment else ''gif'' }}' + push: + sound: + name: '{{ iif(silent_update, ''none'', sound) }}' + volume: '{{ iif((silent_update or sound == ''none''), 0, + volume) }}' + critical: '{{ iif(critical, 1, 0) }}' + entity_id: '{{ios_live_view}}' + actions: + - action: URI + title: '{{button_1}}' + uri: '{{url_1}}' + icon: '{{icon_1}}' + - action: URI + title: '{{button_2}}' + uri: '{{url_2}}' + icon: '{{icon_2}}' + - action: '{{ ''URI'' if ''/'' in url_3 else url_3 }}' + title: '{{button_3}}' + uri: '{{url_3}}' + icon: '{{icon_3}}' + destructive: true + - conditions: '{{ tv }}' + sequence: + - action: notify.{{ notify_group_target }} + data: + title: '{{title}}' + message: '{{message}}' + data: + tag: '{{ id }}' + group: '{{ group }}' + color: '{{color}}' + subject: '{{subtitle}}' + clickAction: '{{tap_action}}' + ttl: 0 + priority: high + alert_once: '{{ alert_once }}' + notification_icon: '{{icon}}' + sticky: '{{sticky}}' + channel: '{{''alarm_stream'' if critical else channel}}' + car_ui: '{{android_auto}}' + image: + url: '{{base_url}}/api/frigate{{client_id}}/notifications/{{id}}/snapshot.jpg' + video: '{{video}}' + fontsize: '{{tv_size}}' + position: '{{tv_position}}' + duration: '{{tv_duration}}' + transparency: '{{tv_transparency}}' + interrupt: '{{tv_interrupt}}' + timeout: 30 + subtitle: '{{subtitle}}' + url: '{{tap_action}}' + attachment: + url: '{{video if video else attachment }}' + content-type: '{{ ''application/vnd.apple.mpegurl'' if ''m3u8'' + in video else ''mp4'' if ''mp4'' in video else ''jpeg'' + if ''jpg'' in attachment else ''gif'' }}' + push: + sound: + name: '{{ iif(silent_update, ''none'', sound) }}' + volume: '{{ iif((silent_update or sound == ''none''), + 0, volume) }}' + critical: '{{ iif(critical, 1, 0) }}' + entity_id: '{{ios_live_view}}' + actions: + - action: URI + title: '{{button_1}}' + uri: '{{url_1}}' + icon: '{{icon_1}}' + - action: URI + title: '{{button_2}}' + uri: '{{url_2}}' + icon: '{{icon_2}}' + - action: '{{ ''URI'' if ''/'' in url_3 else url_3 }}' + title: '{{button_3}}' + uri: '{{url_3}}' + icon: '{{icon_3}}' + destructive: true + default: + - action: notify.{{ notify_group_target }} + data: + title: '{{title}}' + message: '{{message}}' + data: + tag: '{{ id }}' + group: '{{ group }}' + color: '{{color}}' + subject: '{{subtitle}}' + image: '{{attachment}}' + video: '{{video}}' + clickAction: '{{tap_action}}' + ttl: 0 + priority: high + alert_once: '{{ alert_once }}' + notification_icon: '{{icon}}' + sticky: '{{sticky}}' + channel: '{{''alarm_stream'' if critical else channel}}' + car_ui: '{{android_auto}}' + fontsize: '{{tv_size}}' + position: '{{tv_position}}' + duration: '{{tv_duration}}' + transparency: '{{tv_transparency}}' + interrupt: '{{tv_interrupt}}' + subtitle: '{{subtitle}}' + url: '{{tap_action}}' + attachment: + url: '{{video if video else attachment }}' + content-type: '{{ ''application/vnd.apple.mpegurl'' if ''m3u8'' + in video else ''mp4'' if ''mp4'' in video else ''jpeg'' + if ''jpg'' in attachment else ''gif'' }}' + push: + sound: + name: '{{ iif(silent_update, ''none'', sound) }}' + volume: '{{ iif((silent_update or sound == ''none''), 0, + volume) }}' + critical: '{{ iif(critical, 1, 0) }}' + entity_id: '{{ios_live_view}}' + actions: + - action: URI + title: '{{button_1}}' + uri: '{{url_1}}' + icon: '{{icon_1}}' + - action: URI + title: '{{button_2}}' + uri: '{{url_2}}' + icon: '{{icon_2}}' + - action: '{{ ''URI'' if ''/'' in url_3 else url_3 }}' + title: '{{button_3}}' + uri: '{{url_3}}' + icon: '{{icon_3}}' + destructive: true + - if: '{{tts and (not tts_helper or not alert_once or (tts_helper and + id not in states(tts_helper)))}}' + then: + sequence: + - choose: + - conditions: '{{ not notify_group_target }}' + sequence: + - device_id: !input notify_device + domain: mobile_app + type: notify + message: '{{''TTS''}}' + data: + tag: '{{ id }}{{''-loitering-tts'' if loitering}}' + channel: '{{''alarm_stream'' if critical else channel}}' + alert_once: '{{ alert_once }}' + tts_text: '{{message}}' + default: + - action: notify.{{ notify_group_target }} + data: + message: '{{''TTS''}}' + data: + tag: '{{ id }}{{''-loitering-tts'' if loitering}}' + channel: '{{''alarm_stream'' if critical else channel}}' + alert_once: '{{ alert_once }}' + tts_text: '{{message}}' + - action: input_text.set_value + data: + value: '{% set newIds = id + ''|'' + states(tts_helper) %} + + {{ newIds[:250] }} + + ' + target: + entity_id: '{{tts_helper}}' + until: '{{ not wait.trigger or wait.trigger.payload_json[''type''] == ''end'' + }}' diff --git a/blueprints/automation/hunterjm/frigate_notification.yaml b/blueprints/automation/hunterjm/frigate_notification.yaml deleted file mode 100644 index 326314f..0000000 --- a/blueprints/automation/hunterjm/frigate_notification.yaml +++ /dev/null @@ -1,225 +0,0 @@ -blueprint: - name: Frigate Notification - description: "## Frigate Mobile App Notification\n\nThis blueprint will send a notification\ - \ to your device when a Frigate event for the selected camera is fired. The notification\ - \ will initially include the thumbnail of the detection, but will update to include\ - \ actionable notifications allowing you to view the saved clip/snapshot when available,\ - \ or silence the notification for a configurable amount of time.\n\nWith this\ - \ blueprint, you may send the notification to multiple devices by leaving \"Device\"\ - \ blank and instead use a [notification group][1].\n\n### Required entities:\n\ - \ - Frigate Camera Name\n - Mobile App Device **or** the name of a Notification\ - \ Group\n\n### Optional features:\n - You can limit notifications to objects\ - \ entering **any** pre-defined [zones][2] in Frigate.\n - You can specify which\ - \ [zones][2] to be notified about. This must be a list (e.g.):\n ```yaml\n\ - \ - backyard\n ```\n - You can specify what type of [objects][3] to be\ - \ notified about. This must be a list (e.g.):\n ```yaml\n - person\n \ - \ - car\n ```\n - You can disable notifications if a presence entity or group\ - \ is \"home\".\n - You can configure a cooldown for the camera to reduce the\ - \ number of notifications when back-to-back events occur.\n - You can silence\ - \ future notifications for a defined amount of time through actionable notifications.\ - \ This is helpful in situations where you know you will be triggering detections\ - \ for an extended period of time, like when the kids are playing outside.\n\n\ - [1]: https://companion.home-assistant.io/docs/notifications/notifications-basic#sending-notifications-to-multiple-devices\n\ - [2]: https://blakeblackshear.github.io/frigate/configuration/cameras#zones\n[3]:\ - \ https://blakeblackshear.github.io/frigate/configuration/objects\n" - domain: automation - source_url: https://gist.github.com/hunterjm/23c1588a9f2b8b9c2a62ffc364e17f8c - input: - camera: - name: Frigate Camera - description: The name of the camera as defined in your frigate configuration. - notify_device: - name: Device - description: The device must run the official Home Assistant app to receive - notifications. - default: false - selector: - device: - integration: mobile_app - notify_group: - name: Notification Group - description: The name of the notification group to call. - default: '' - base_url: - name: (Optional) Base URL - description: 'The external url for your Home Assistant instance. This will default - to a relative URL and will open the clips in the app instead of the browser, - which may cause issues on some devices. - - ' - default: '' - zone_filter: - name: (Optional) Zone Filter - description: Only notify if object has entered a defined zone. - default: false - selector: - boolean: {} - zones: - name: (Optional) Trigger Zones - description: A list (-) of zones you wish to recieve notifications for. - default: [] - selector: - object: {} - labels: - name: (Optional) Trigger Objects - description: A list (-) of objects you wish to recieve notifications for. - default: [] - selector: - object: {} - presence_filter: - name: (Optional) Presence Filter - description: Only notify if selected presence entity is not "home". - default: '' - selector: - entity: {} - cooldown: - name: (Optional) Cooldown - description: Delay before sending another notification for this camera after - the last event. - default: 30 - selector: - number: - max: 300.0 - min: 0.0 - unit_of_measurement: seconds - step: 1.0 - mode: slider - silence_timer: - name: (Optional) Silence Notifications - description: 'How long to silence notifications for this camera when requested - as part of the actionable notification. - - ' - default: 30 - selector: - number: - max: 300.0 - min: 0.0 - unit_of_measurement: minutes - step: 1.0 - mode: slider -mode: single -max_exceeded: silent -trigger: - platform: mqtt - topic: frigate/events - payload: !input 'camera' - value_template: '{{ value_json[''after''][''camera''] }}' -variables: - id: '{{ trigger.payload_json[''after''][''id''] }}' - camera: '{{ trigger.payload_json[''after''][''camera''] }}' - camera_name: '{{ camera | replace(''_'', '' '') | title }}' - object: '{{ trigger.payload_json[''after''][''label''] }}' - label: '{{ object | title }}' - entered_zones: '{{ trigger.payload_json[''after''][''entered_zones''] }}' - type: '{{ trigger.payload_json[''type''] }}' - base_url: !input 'base_url' - group_target: !input 'notify_group' - zone_only: !input 'zone_filter' - input_zones: !input 'zones' - zones: '{{ input_zones | list }}' - input_labels: !input 'labels' - labels: '{{ input_labels | list }}' - presence_entity: !input 'presence_filter' -condition: -- '{{ type != ''end'' }}' -- '{{ not zone_only or entered_zones|length > 0 }}' -- '{{ not zones|length or zones|select(''in'', entered_zones)|list|length > 0 }}' -- '{{ not labels|length or object in labels }}' -- '{{ not presence_entity or not is_state(presence_entity, ''home'') }}' -action: -- choose: - - conditions: '{{ not group_target }}' - sequence: - - device_id: !input 'notify_device' - domain: mobile_app - type: notify - message: A {{ label }} was detected on the {{ camera_name }} camera. - data: - tag: '{{ id }}' - group: frigate-notification-{{ camera }} - image: /api/frigate/notifications/{{id}}/thumbnail.jpg?format=android - attachment: - url: /api/frigate/notifications/{{id}}/thumbnail.jpg - default: - - service: notify.{{ group_target }} - data: - message: A {{ label }} was detected on the {{ camera_name }} camera. - data: - tag: '{{ id }}' - group: frigate-notification-{{ camera }} - image: /api/frigate/notifications/{{id}}/thumbnail.jpg?format=android - attachment: - url: /api/frigate/notifications/{{id}}/thumbnail.jpg -- repeat: - sequence: - - wait_for_trigger: - - platform: mqtt - topic: frigate/events - payload: '{{ id }}' - value_template: '{{ value_json[''after''][''id''] }}' - timeout: - minutes: 2 - continue_on_timeout: false - - condition: template - value_template: '{{ wait.trigger.payload_json[''type''] == ''end'' }}' - - choose: - - conditions: '{{ not group_target }}' - sequence: - - device_id: !input 'notify_device' - domain: mobile_app - type: notify - message: A {{ label }} was detected on the {{ camera_name }} camera. - data: - tag: '{{ id }}' - group: frigate-notification-{{ camera }} - url: '{{base_url}}/api/frigate/notifications/{{id}}/{{camera}}/clip.mp4' - clickAction: '{{base_url}}/api/frigate/notifications/{{id}}/{{camera}}/clip.mp4' - image: /api/frigate/notifications/{{id}}/thumbnail.jpg?format=android - sound: none - attachment: - url: /api/frigate/notifications/{{id}}/thumbnail.jpg - actions: - - action: URI - title: View Clip - uri: '{{base_url}}/api/frigate/notifications/{{id}}/{{camera}}/clip.mp4' - - action: URI - title: View Snapshot - uri: '{{base_url}}/api/frigate/notifications/{{id}}/snapshot.jpg' - - action: silence-{{ camera }} - title: Silence Notifications - destructive: true - default: - - service: notify.{{ group_target }} - data: - message: A {{ label }} was detected on the {{ camera_name }} camera. - data: - tag: '{{ id }}' - group: frigate-notification-{{ camera }} - url: '{{base_url}}/api/frigate/notifications/{{id}}/{{camera}}/clip.mp4' - clickAction: '{{base_url}}/api/frigate/notifications/{{id}}/{{camera}}/clip.mp4' - image: /api/frigate/notifications/{{id}}/thumbnail.jpg?format=android - sound: none - attachment: - url: /api/frigate/notifications/{{id}}/thumbnail.jpg - actions: - - action: URI - title: View Clip - uri: '{{base_url}}/api/frigate/notifications/{{id}}/{{camera}}/clip.mp4' - - action: URI - title: View Snapshot - uri: '{{base_url}}/api/frigate/notifications/{{id}}/snapshot.jpg' - - action: silence-{{ camera }} - title: Silence Notifications - destructive: true - until: '{{ wait.trigger.payload_json[''type''] == ''end'' }}' -- wait_for_trigger: - - platform: event - event_type: mobile_app_notification_action - event_data: - action: silence-{{ camera }} - timeout: - seconds: !input 'cooldown' - continue_on_timeout: false -- delay: - minutes: !input 'silence_timer' diff --git a/components/packages/google_assistant.yaml b/components/packages/google_assistant.yaml index d01246e..ab1145a 100644 --- a/components/packages/google_assistant.yaml +++ b/components/packages/google_assistant.yaml @@ -329,6 +329,11 @@ google_assistant: aliases: - Master Bedroom Awake + input_boolean.master_bed_occupied: + name: Master Bed Occupied + room: Master Bedroom + expose: true + input_button.blue_room_bedtime: name: Teens Bedtime room: Blue Room diff --git a/esphome/bed-presence/base.yaml b/esphome/bed-presence/base.yaml new file mode 100644 index 0000000..9dec910 --- /dev/null +++ b/esphome/bed-presence/base.yaml @@ -0,0 +1,80 @@ +substitutions: + sensor_gpio_left: GPIO10 + sensor_gpio_right: GPIO20 + +packages: + diagnostics: !include + file: ../esphome-common/diagnostics.yaml + vars: + boot_gpio: GPIO9 + uptime_id: bed_presence_uptime + restart_id: btn_restart + status_id: bed_presence_status + + left_bed_sensor: !include + file: sensor.yaml + vars: + sensor_name: Left + sensor_id: left + sensor_gpio: ${sensor_gpio_left} + + right_bed_sensor: !include + file: sensor.yaml + vars: + sensor_name: Right + sensor_id: right + sensor_gpio: ${sensor_gpio_right} + +binary_sensor: + - platform: template + name: Bed Occupied Both (Fast) + id: bed_occupied_both_fast + device_class: occupancy + icon: mdi:bunk-bed + disabled_by_default: true + lambda: return id(bed_occupied_left_fast).state && id(bed_occupied_right_fast).state; + + - platform: template + name: Bed Occupied Either (Fast) + id: bed_occupied_either_fast + device_class: occupancy + icon: mdi:bunk-bed + disabled_by_default: true + lambda: return id(bed_occupied_left_fast).state || id(bed_occupied_right_fast).state; + + - platform: template + name: Bed Occupied Both + id: bed_occupied_both + device_class: occupancy + icon: mdi:bunk-bed + lambda: return id(bed_occupied_left).state && id(bed_occupied_right).state; + + - platform: template + name: Bed Occupied Either + id: bed_occupied_either + device_class: occupancy + icon: mdi:bunk-bed + lambda: return id(bed_occupied_left).state || id(bed_occupied_right).state; + +switch: + - platform: template + name: Full Range + id: full_range + optimistic: true + restore_mode: RESTORE_DEFAULT_OFF + entity_category: config + icon: mdi:arrow-expand + +select: + - platform: template + name: "Response Speed" + id: response_speed + icon: mdi:speedometer + optimistic: true + restore_value: true + options: + - "Fast" + - "Normal" + - "Slow" + initial_option: "Normal" + entity_category: config \ No newline at end of file diff --git a/esphome/bed-presence/bluetooth-proxy.yaml b/esphome/bed-presence/bluetooth-proxy.yaml new file mode 100644 index 0000000..5d388aa --- /dev/null +++ b/esphome/bed-presence/bluetooth-proxy.yaml @@ -0,0 +1,15 @@ +api: + on_client_connected: + - esp32_ble_tracker.start_scan: + continuous: true + on_client_disconnected: + - esp32_ble_tracker.stop_scan: + +bluetooth_proxy: + active: true + +esp32_ble_tracker: + id: ble_tracker + scan_parameters: + active: true + continuous: false \ No newline at end of file diff --git a/esphome/bed-presence/diagnostics.yaml b/esphome/bed-presence/diagnostics.yaml new file mode 100644 index 0000000..ef9d79b --- /dev/null +++ b/esphome/bed-presence/diagnostics.yaml @@ -0,0 +1,59 @@ +substitutions: + boot_gpio: GPIO9 + boot_id: boot_button + status_id: status_sensor + factory_reset_id: factory_reset_button + restart_id: restart_button + wifi_db_id: wifi_signal_db + wifi_percent_id: wifi_signal_percent + uptime_id: uptime_sensor + +binary_sensor: + - platform: gpio + pin: + number: ${boot_gpio} + mode: INPUT_PULLUP + inverted: true + id: ${boot_id} + internal: true + name: Boot Button + filters: + - delayed_on: 10s + on_press: + then: + - button.press: ${factory_reset_id} + + - platform: status + id: ${status_id} + name: Status + +button: + - platform: factory_reset + id: ${factory_reset_id} + internal: true + + - platform: restart + name: Restart + id: ${restart_id} + entity_category: diagnostic + +sensor: + - platform: wifi_signal # Reports the WiFi signal strength in dB + name: WiFi Signal dB + id: ${wifi_db_id} + update_interval: 60s + + - platform: copy # Reports the WiFi signal strength in % + source_id: ${wifi_db_id} + name: WiFi Signal Percent + id: ${wifi_percent_id} + filters: + - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0); + unit_of_measurement: '%' + entity_category: diagnostic + device_class: "" + + - platform: uptime + type: seconds + id: ${uptime_id} + name: Uptime \ No newline at end of file diff --git a/esphome/bed-presence/sensor.yaml b/esphome/bed-presence/sensor.yaml new file mode 100644 index 0000000..ebb9c0a --- /dev/null +++ b/esphome/bed-presence/sensor.yaml @@ -0,0 +1,240 @@ +substitutions: + # Calibrate Trigger Percentile + # This controls how the trigger threshold is set during calibration. During calibration, the unoccupied and occupied + # pressure values are determined. This is the percentage of the difference between those values required to trigger + # the "occupied" state. + # - 0.75 Requires 75% of the occupied pressure to trigger (DEFAULT) + # - 0.50 Set trigger exactly in the middle of unoccupied and occupied pressures + # - 0.25 More sensitive, likely to be triggered by partner + trigger_percentile: '0.75' + + # Window Averaging Samples + # Add a sliding window moving average to the incoming sensor samples. This specifies the number of samples to average + # over. Each sample is 1/2 second. + # - 1 Don't perform averaging + # - 5 Average over 5 samples (2.5 seconds) (DEFAULT) + # - 10 Average over 10 samples (5 seconds) + averaging_window_samples: '5' + + # Fast Sensor Delay + # This controls how long the "Fast" sensor must register "unoccupied" or "occupied" before reporting. Averaging or + # delay is encouraged to prevent frequent false negatives as you shift in bed. + # - 2s Same response as standard sensor + # - 500ms Good starting point for getting speed without too many false negatives + # - 0ms No delay (DEFAULT) + fast_delayed_on: '0ms' + fast_delayed_off: '0ms' + + # Standard Sensor Delay + # This controls how long the standard sensor must register "unoccupied" or "occupied" before reporting. Averaging or + # delay is enocuraged to ensure stability. + standard_delayed_on: '0s' + standard_delayed_off: '1s' + + # Slow Sensor Delay + # This controls how long the "Slow" sensor must register "unoccupied" or "occupied" before reporting. Averaging or + # delay is encouraged to ensure stability. + slow_delayed_on: '2s' + slow_delayed_off: '5s' + + # Reporting Delta + # The sensor must change by this amount before an update is sent (or the reporting_interval_max has been hit) + # - 10.0 Only report very large changes + # - 1.0 Relatively sensitive with much less reporting (DEFAULT) + # - 0.1 Very sensitive, will report frequently + reporting_delta: '1.0' + + # Reporting Interval (Max) + # The max amount of time between sensor reports (even if the value hasn't changed) + reporting_interval_max: '180s' + + # Linear Calibration Points + # Change the linear calibration points for the FSR sensor. These values correspond with the raw pulses per minute from + # the pulse_counter. Only mess with this if you know what you're doing. In standard mode (Full Range = False), the + # sensor is linearly calibrated between calibrate_0 (0%) and calibreate_100 (100%). When Full Range = True, + # calibrate_0 is set to 0. + calibrate_100: '408000' + calibrate_0: '276000' + +binary_sensor: + - platform: template + name: Bed Occupied ${sensor_name} (Fast) + id: bed_occupied_${sensor_id}_fast + device_class: occupancy + icon: mdi:speedometer + disabled_by_default: true + filters: + - delayed_on: ${fast_delayed_on} + - delayed_off: ${fast_delayed_off} + lambda: return id(bed_sensor_${sensor_id}).state > id(val_trigger_${sensor_id}).state; + + - platform: template + name: Bed Occupied ${sensor_name} (Normal) + id: bed_occupied_${sensor_id}_normal + device_class: occupancy + icon: mdi:speedometer-medium + disabled_by_default: true + filters: + - delayed_on: ${standard_delayed_on} + - delayed_off: ${standard_delayed_off} + lambda: return id(bed_sensor_${sensor_id}).state > id(val_trigger_${sensor_id}).state; + + - platform: template + id: bed_occupied_${sensor_id}_slow + name: Bed Occupied ${sensor_name} (Slow) + device_class: occupancy + icon: mdi:speedometer-slow + disabled_by_default: true + filters: + - delayed_on: ${slow_delayed_on} + - delayed_off: ${slow_delayed_off} + lambda: return id(bed_sensor_${sensor_id}).state > id(val_trigger_${sensor_id}).state; + + - platform: template + name: Bed Occupied ${sensor_name} + id: bed_occupied_${sensor_id} + device_class: occupancy + icon: mdi:bed + lambda: |- # Sensor response is user tunable via "Response Speed" + if (id(response_speed).state == "Fast") { + return id(bed_occupied_${sensor_id}_fast).state; + } else if (id(response_speed).state == "Slow") { + return id(bed_occupied_${sensor_id}_slow).state; + } else { + return id(bed_occupied_${sensor_id}_normal).state; + } + +sensor: + - platform: pulse_counter + pin: ${sensor_gpio} + name: ${sensor_name} Pressure + id: bed_sensor_${sensor_id} + update_interval: 0.5s + unit_of_measurement: '%' + icon: mdi:gauge + filters: + - lambda: |- # scale pulses/minute to 0%->100% + float cal_0 = id(full_range).state ? 0 : ${calibrate_0}; + + float val = (x - cal_0) * 100; + float range = ${calibrate_100} - cal_0; + + return val/range; + - clamp: + min_value: 0 + - sliding_window_moving_average: + window_size: ${averaging_window_samples} + send_every: 1 + - or: + - delta: ${reporting_delta} # only send if sensor changes by `reporting_delta` (eliminate sensor noise) + - throttle: ${reporting_interval_max} # but still update every `reporting_interval_max` + - platform: copy + source_id: bed_sensor_${sensor_id} + name: Calibrated ${sensor_name} Pressure + id: bed_sensor_${sensor_id}_calibrated + icon: mdi:scale-balance + disabled_by_default: true + filters: + - lambda: |- # scale between val_unoccupied and val_occupied + float cal_0 = id(val_unoccupied_${sensor_id}).state; + float cal_100 = id(val_occupied_${sensor_id}).state; + + float val = (x - cal_0) * 100; + float range = cal_100 - cal_0; + + return val/range; + - clamp: + max_value: 100 + min_value: 0 + +number: + - platform: template + name: ${sensor_name} Unoccupied Pressure + id: val_unoccupied_${sensor_id} + icon: mdi:gauge-empty + unit_of_measurement: '%' + entity_category: diagnostic + optimistic: true + restore_value: true + initial_value: 0 + min_value: 0 + max_value: 120 + step: 1.0 + mode: box + on_value: + then: + - lambda: |- # Update trigger + id(update_trigger_${sensor_id})->execute(); + - platform: template + name: ${sensor_name} Occupied Pressure + id: val_occupied_${sensor_id} + icon: mdi:gauge-full + unit_of_measurement: '%' + entity_category: diagnostic + optimistic: true + restore_value: true + initial_value: 100 + min_value: 0 + max_value: 120 + step: 1.0 + mode: box + on_value: + then: + - lambda: |- # Update trigger + id(update_trigger_${sensor_id})->execute(); + - platform: template + name: ${sensor_name} Trigger Pressure + id: val_trigger_${sensor_id} + optimistic: true + restore_value: true + initial_value: 50 + min_value: 0 + max_value: 120 + step: 1.0 + mode: box + icon: mdi:gauge + unit_of_measurement: '%' + entity_category: config + +button: + - platform: template + name: Calibrate ${sensor_name} Unoccupied + id: calibration_${sensor_id}_set_unoccupied + icon: mdi:bed-empty + entity_category: config + on_press: + then: + - number.set: + id: val_unoccupied_${sensor_id} + # round to 2 decimal places + value: !lambda return round(id(bed_sensor_${sensor_id}).state * 100)/100.0; + - platform: template + name: Calibrate ${sensor_name} Occupied + id: calibration_${sensor_id}_set_occupied + icon: mdi:bed + entity_category: config + on_press: + then: + - number.set: + id: val_occupied_${sensor_id} + # round to 2 decimal places + value: !lambda return round(id(bed_sensor_${sensor_id}).state * 100)/100.0; + +script: + - id: update_trigger_${sensor_id} + mode: queued + then: + - lambda: |- # Set trigger to x% of difference between min/max + float unoccupied_pressure = id(val_unoccupied_${sensor_id}).state; + float occupied_pressure = id(val_occupied_${sensor_id}).state; + + // calculate new trigger value + float trigger_pressure = unoccupied_pressure + ((occupied_pressure - unoccupied_pressure) * float(${trigger_percentile})); + + // round to 2 decimal places + trigger_pressure = round(trigger_pressure * 100)/100.0; + + // set value + auto call = id(val_trigger_${sensor_id}).make_call(); + call.set_value(trigger_pressure); + call.perform(); \ No newline at end of file diff --git a/glances/glances.conf b/glances/glances.conf deleted file mode 100644 index 64c3dd1..0000000 --- a/glances/glances.conf +++ /dev/null @@ -1,321 +0,0 @@ -############################################################################## -# Globals Glances parameters -############################################################################## - -[global] -# Does Glances should check if a newer version is available on PyPI ? -check_update=false -# History size (maximum number of values) -# Default glances history size to 0 -# https://github.com/hassio-addons/addon-glances/issues/61 -# https://github.com/nicolargo/glances/issues/1341 -history_size=0 - -############################################################################## -# User interface -############################################################################## - -[outputs] -# Theme name for the Curses interface: black or white -curse_theme=black -# Limit the number of processes to display in the WebUI -max_processes_display=30 - -############################################################################## -# plugins -############################################################################## - -[quicklook] -# Define CPU, MEM and SWAP thresholds in % -cpu_careful=50 -cpu_warning=70 -cpu_critical=90 -mem_careful=50 -mem_warning=70 -mem_critical=90 -swap_careful=50 -swap_warning=70 -swap_critical=90 - -[cpu] -# Default values if not defined: 50/70/90 (except for iowait) -user_careful=50 -user_warning=70 -user_critical=90 -#user_log=False -#user_critical_action=echo {{user}} {{value}} {{max}} > /tmp/cpu.alert -system_careful=50 -system_warning=70 -system_critical=90 -steal_careful=50 -steal_warning=70 -steal_critical=90 -#steal_log=True -# I/O wait percentage should be lower than 1/# (Logical CPU cores) -# Leave commented to just use the default config (1/#-20% / 1/#-10% / 1/#) -#iowait_careful=30 -#iowait_warning=40 -#iowait_critical=50 -# Context switch limit (core / second) -# Leave commented to just use the default config (critical is 50000*# (Logical CPU cores) -#ctx_switches_careful=10000 -#ctx_switches_warning=12000 -#ctx_switches_critical=14000 - -[percpu] -# Define CPU thresholds in % -# Default values if not defined: 50/70/90 -user_careful=50 -user_warning=70 -user_critical=90 -iowait_careful=50 -iowait_warning=70 -iowait_critical=90 -system_careful=50 -system_warning=70 -system_critical=90 - -[gpu] -# Default processor values if not defined: 50/70/90 -proc_careful=50 -proc_warning=70 -proc_critical=90 -# Default memory values if not defined: 50/70/90 -mem_careful=50 -mem_warning=70 -mem_critical=90 - -[mem] -# Define RAM thresholds in % -# Default values if not defined: 50/70/90 -careful=50 -#careful_action_repeat=echo {{percent}} >> /tmp/memory.alert -warning=70 -critical=90 - -[memswap] -# Define SWAP thresholds in % -# Default values if not defined: 50/70/90 -careful=50 -warning=70 -critical=90 - -[load] -# Define LOAD thresholds -# Value * number of cores -# Default values if not defined: 0.7/1.0/5.0 per number of cores -# Source: http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages -# http://www.linuxjournal.com/article/9001 -careful=0.7 -warning=1.0 -critical=5.0 -#log=False - -[network] -# Default bitrate thresholds in % of the network interface speed -# Default values if not defined: 70/80/90 -rx_careful=70 -rx_warning=80 -rx_critical=90 -tx_careful=70 -tx_warning=80 -tx_critical=90 -# Define the list of hidden network interfaces (comma-separated regexp) -#hide=docker.*,lo -# WLAN 0 alias -#wlan0_alias=Wireless IF -# It is possible to overwrite the bitrate thresholds per interface -# WLAN 0 Default limits (in bits per second aka bps) for interface bitrate -#wlan0_rx_careful=4000000 -#wlan0_rx_warning=5000000 -#wlan0_rx_critical=6000000 -#wlan0_rx_log=True -#wlan0_tx_careful=700000 -#wlan0_tx_warning=900000 -#wlan0_tx_critical=1000000 -#wlan0_tx_log=True - -[wifi] -# Define the list of hidden wireless network interfaces (comma-separated regexp) -hide=lo,docker.* -# Define SIGNAL thresholds in db (lower is better...) -# Based on: http://serverfault.com/questions/501025/industry-standard-for-minimum-wifi-signal-strength -careful=-65 -warning=-75 -critical=-85 - -[diskio] -# Define the list of hidden disks (comma-separated regexp) -#hide=sda2,sda5,loop.* -hide=loop.* -# Alias for sda1 -#sda1_alias=IntDisk - -[fs] -# Define the list of hidden file system (comma-separated regexp) -#hide=/boot.* -# Define filesystem space thresholds in % -# Default values if not defined: 50/70/90 -# It is also possible to define per mount point value -# Example: /_careful=40 -careful=50 -warning=70 -critical=90 -# Allow additional file system types (comma-separated FS type) -#allow=zfs - -[folders] -# Define a folder list to monitor -# The list is composed of items (list_#nb <= 10) -# An item is defined by: -# * path: absolute path -# * careful: optional careful threshold (in MB) -# * warning: optional warning threshold (in MB) -# * critical: optional critical threshold (in MB) -folder_1_path=/config -folder_1_careful=4096 -folder_1_warning=8196 -folder_1_critical=12228 -folder_2_path=/share -folder_2_careful=4096 -folder_2_warning=8196 -folder_2_critical=12228 -folder_3_path=/backup -folder_3_careful=4096 -folder_3_warning=8196 -folder_3_critical=12228 -folder_4_path=/media -folder_4_careful=4096 -folder_4_warning=8196 -folder_4_critical=12228 - -[sensors] -# Sensors core thresholds (in Celsius...) -# Default values if not defined: 60/70/80 -temperature_core_careful=60 -temperature_core_warning=70 -temperature_core_critical=80 -# Temperatures threshold in °C for hddtemp -# Default values if not defined: 45/52/60 -temperature_hdd_careful=45 -temperature_hdd_warning=52 -temperature_hdd_critical=60 -# Battery threshold in % -battery_careful=80 -battery_warning=90 -battery_critical=95 -# Sensors alias -#temp1_alias=Motherboard 0 -#temp2_alias=Motherboard 1 -#core 0_alias=CPU Core 0 -#core 1_alias=CPU Core 1 - -[processlist] -# Define CPU/MEM (per process) thresholds in % -# Default values if not defined: 50/70/90 -cpu_careful=50 -cpu_warning=70 -cpu_critical=90 -mem_careful=50 -mem_warning=70 -mem_critical=90 -# -# Nice priorities range from -20 to 19. -# Configure nice levels using a comma separated list. -# -# Nice: Example 1, non-zero is warning (default behavior) -nice_warning=-20,-19,-18,-17,-16,-15,-14,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19 -# -# Nice: Example 2, low priority processes escalate from careful to critical -#nice_careful=1,2,3,4,5,6,7,8,9 -#nice_warning=10,11,12,13,14 -#nice_critical=15,16,17,18,19 - -[ports] -# Ports scanner plugin configuration -# Interval in second between two scans -refresh=30 -# Set the default timeout (in second) for a scan (can be overwritten in the scan list) -timeout=3 -# If port_default_gateway is True, add the default gateway on top of the scan list -port_default_gateway=True -# -# Define the scan list (1 < x < 255) -# port_x_host (name or IP) is mandatory -# port_x_port (TCP port number) is optional (if not set, use ICMP) -# port_x_description is optional (if not set, define to host:port) -# port_x_timeout is optional and overwrite the default timeout value -# port_x_rtt_warning is optional and defines the warning threshold in ms -# -#port_1_host=192.168.0.1 -#port_1_port=80 -#port_1_description=Home Box -#port_1_timeout=1 -#port_2_host=www.free.fr -#port_2_description=My ISP -#port_3_host=www.google.com -#port_3_description=Internet ICMP -#port_3_rtt_warning=1000 -#port_4_description=Internet Web -#port_4_host=www.google.com -#port_4_port=80 -#port_4_rtt_warning=1000 -# -# Define Web (URL) monitoring list (1 < x < 255) -# web_x_url is the URL to monitor (example: http://my.site.com/folder) -# web_x_description is optional (if not set, define to URL) -# web_x_timeout is optional and overwrite the default timeout value -# web_x_rtt_warning is optional and defines the warning respond time in ms (approximatively) -# -#web_1_url=https://blog.nicolargo.com -#web_1_description=My Blog -#web_1_rtt_warning=3000 -#web_2_url=https://github.com -#web_3_url=http://www.google.fr -#web_3_description=Google Fr -#web_4_url=https://blog.nicolargo.com/nonexist -#web_4_description=Intranet - -[docker] -# Thresholds for CPU and MEM (in %) -cpu_careful=50 -cpu_warning=70 -cpu_critical=90 -mem_careful=20 -mem_warning=50 -mem_critical=70 -# -# Per container thresholds -#containername_cpu_careful=10 -#containername_cpu_warning=20 -#containername_cpu_critical=30 -# -# By default, Glances only display running containers -# Set the following key to True to display all containers -all=False - -############################################################################## -# Client/server -############################################################################## - -[serverlist] -# Define the static servers list -#server_1_name=localhost -#server_1_alias=My local PC -#server_1_port=61209 -#server_2_name=localhost -#server_2_port=61235 -#server_3_name=192.168.0.17 -#server_3_alias=Another PC on my network -#server_3_port=61209 -#server_4_name=pasbon -#server_4_port=61237 - -[passwords] -# Define the passwords list -# Syntax: host=password -# Where: host is the hostname -# password is the clear password -# Additionally (and optionally) a default password could be defined -#localhost=abc -#default=defaultpassword diff --git a/lovelace/view-ha-floorplan.yaml b/lovelace/view-ha-floorplan.yaml index 634a4b6..c48d5a0 100644 --- a/lovelace/view-ha-floorplan.yaml +++ b/lovelace/view-ha-floorplan.yaml @@ -707,7 +707,7 @@ cards: class: "light-unavailable" - entities: - - switch.shelly_projector + # - switch.shelly_projector - binary_sensor.computer_chair_contact_occupied # - switch.computer_area_pi_plug # - switch.computer_area_lighouse diff --git a/lovelace/view-overview.yaml b/lovelace/view-overview.yaml index 0bbeae6..7c25de4 100644 --- a/lovelace/view-overview.yaml +++ b/lovelace/view-overview.yaml @@ -1315,22 +1315,27 @@ cards: icon: mdi:cctv state_filter: - "not_home" - - entity: device_tracker.amcrest_technologies_32_ae_4e - name: Front Room - icon: mdi:cctv - state_filter: - - "not_home" - - entity: device_tracker.amcrest_technologies_36_1d_8a - name: Back Yard - icon: mdi:cctv - state_filter: - - "not_home" + # - entity: device_tracker.amcrest_technologies_32_ae_4e + # name: Front Room + # icon: mdi:cctv + # state_filter: + # - "not_home" + # - entity: device_tracker.amcrest_technologies_36_1d_8a + # name: Back Yard + # icon: mdi:cctv + # state_filter: + # - "not_home" # - entity: device_tracker.amcrest_technologies_36_22_3a # name: Back Yard # icon: mdi:cctv # state_filter: # - "not_home" - - entity: device_tracker.amcrest_technologies_35_5d_c3 + # - entity: device_tracker.amcrest_technologies_35_5d_c3 + # name: Front Yard + # icon: mdi:cctv + # state_filter: + # - "not_home" + - entity: device_tracker.nmap_tracker_f0_00_05_10_b2_ca name: Front Yard icon: mdi:cctv state_filter: