initial commit
This commit is contained in:
@@ -0,0 +1,213 @@
|
||||
blueprint:
|
||||
name: ESPHome Device Auto Bulk Update
|
||||
description: 'Automatically updates ESPHome devices when a specified number of them
|
||||
|
||||
have pending updates. Optionally sends a notification before updating.
|
||||
|
||||
DEVICE FIRMWARE ENTITIES MUST BE ENABLED
|
||||
|
||||
FLOW:
|
||||
|
||||
1. Triggers when device update count exceeds the threshold, or daily sweep at
|
||||
the start of the time window.
|
||||
|
||||
2. Checks the time window and device count conditions are met.
|
||||
|
||||
3. Sends a notification listing devices to be updated with Update Now and Cancel
|
||||
buttons.
|
||||
|
||||
4. Waits for the delay period listening for a button response.
|
||||
|
||||
5. If Cancel is tapped - sends a cancellation notification and stops.
|
||||
|
||||
6. If Update Now is tapped or delay expires - proceeds with updates.
|
||||
|
||||
7. Updates all devices at once or sequentially depending on mode selected.
|
||||
|
||||
8. Sends a completion notification listing updated devices.
|
||||
|
||||
9. Waits out the cooldown period before the automation can trigger again.
|
||||
|
||||
'
|
||||
domain: automation
|
||||
source_url: https://github.com/bferd/homeassistant-blueprints/blob/main/esphome_auto_bulk_update.yaml
|
||||
input:
|
||||
update_threshold:
|
||||
name: Device Update Threshold
|
||||
description: How many devices need a pending update before updates are pushed.
|
||||
default: 1
|
||||
selector:
|
||||
number:
|
||||
min: 1.0
|
||||
max: 20.0
|
||||
step: 1.0
|
||||
mode: slider
|
||||
update_delay:
|
||||
name: Delay Before Updating
|
||||
description: How many minutes to wait before pushing updates.
|
||||
default: 30
|
||||
selector:
|
||||
number:
|
||||
min: 0.0
|
||||
max: 60.0
|
||||
step: 1.0
|
||||
mode: slider
|
||||
unit_of_measurement: minutes
|
||||
cooldown:
|
||||
name: Cooldown After Update
|
||||
description: Minutes to wait after updates complete before the automation can
|
||||
trigger again.
|
||||
default: 30
|
||||
selector:
|
||||
number:
|
||||
min: 0.0
|
||||
max: 120.0
|
||||
step: 1.0
|
||||
mode: slider
|
||||
unit_of_measurement: minutes
|
||||
time_window_start:
|
||||
name: Update Window Start
|
||||
description: Earliest time of day updates can be triggered.
|
||||
default: 08:00:00
|
||||
selector:
|
||||
time: {}
|
||||
time_window_end:
|
||||
name: Update Window End
|
||||
description: Latest time of day updates can be triggered.
|
||||
default: '21:00:00'
|
||||
selector:
|
||||
time: {}
|
||||
notify_device:
|
||||
name: Notification Device
|
||||
description: Device to notify before updates are pushed.
|
||||
selector:
|
||||
device:
|
||||
integration: mobile_app
|
||||
multiple: false
|
||||
update_mode:
|
||||
name: Update Mode
|
||||
description: Update all devices at once or one at a time sequentially.
|
||||
default: all_at_once
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- label: All at once
|
||||
value: all_at_once
|
||||
- label: One at a time (Sequential)
|
||||
value: sequential
|
||||
custom_value: false
|
||||
multiple: false
|
||||
sort: false
|
||||
sequential_delay:
|
||||
name: Delay Between Sequential Updates
|
||||
description: Minutes to wait between each device when using sequential mode.
|
||||
default: 0
|
||||
selector:
|
||||
number:
|
||||
min: 0.0
|
||||
max: 10.0
|
||||
step: 1.0
|
||||
mode: slider
|
||||
unit_of_measurement: minutes
|
||||
variables:
|
||||
update_threshold: !input update_threshold
|
||||
update_delay: !input update_delay
|
||||
cooldown: !input cooldown
|
||||
update_mode: !input update_mode
|
||||
sequential_delay: !input sequential_delay
|
||||
device_list: "{{ expand(integration_entities('esphome'))\n | selectattr(\"entity_id\",
|
||||
\"contains\", \"update\")\n | selectattr(\"state\", \"eq\", \"on\")\n | map(attribute='entity_id')
|
||||
| list }}\n"
|
||||
device_names: "{{ expand(integration_entities('esphome'))\n | selectattr(\"entity_id\",
|
||||
\"contains\", \"update\")\n | selectattr(\"state\", \"eq\", \"on\")\n | map(attribute='name')
|
||||
| join(', ') }}\n"
|
||||
device_count: "{{ expand(integration_entities('esphome'))\n | selectattr(\"entity_id\",
|
||||
\"contains\", \"update\")\n | selectattr(\"state\", \"eq\", \"on\")\n | list
|
||||
| count }}\n"
|
||||
trigger:
|
||||
- platform: template
|
||||
value_template: "{{ expand(integration_entities('esphome'))\n | selectattr(\"entity_id\",
|
||||
\"contains\", \"update\")\n | selectattr(\"state\", \"eq\", \"on\")\n | list
|
||||
| count > update_threshold }}\n"
|
||||
- platform: time
|
||||
at: !input time_window_start
|
||||
- platform: time_pattern
|
||||
hours: /1
|
||||
condition:
|
||||
- condition: time
|
||||
after: !input time_window_start
|
||||
before: !input time_window_end
|
||||
- condition: template
|
||||
value_template: "{{ expand(integration_entities('esphome'))\n | selectattr(\"entity_id\",
|
||||
\"contains\", \"update\")\n | selectattr(\"state\", \"eq\", \"on\")\n | list
|
||||
| count > update_threshold }}\n"
|
||||
action:
|
||||
- domain: mobile_app
|
||||
type: notify
|
||||
device_id: !input notify_device
|
||||
title: ESPHome Device Update(s)
|
||||
message: '{{ device_count }} device(s) need updating: {{ device_names }}. Updates
|
||||
will begin in {{ update_delay }} minute(s).
|
||||
|
||||
'
|
||||
data:
|
||||
sticky: 'true'
|
||||
persistent: 'true'
|
||||
actions:
|
||||
- action: UPDATE_NOW_ESPHOME
|
||||
title: Update Now
|
||||
- action: CANCEL_ESPHOME_UPDATE
|
||||
title: Cancel
|
||||
- wait_for_trigger:
|
||||
- platform: event
|
||||
event_type: mobile_app_notification_action
|
||||
event_data:
|
||||
action: CANCEL_ESPHOME_UPDATE
|
||||
- platform: event
|
||||
event_type: mobile_app_notification_action
|
||||
event_data:
|
||||
action: UPDATE_NOW_ESPHOME
|
||||
timeout:
|
||||
minutes: '{{ update_delay }}'
|
||||
continue_on_timeout: true
|
||||
- if:
|
||||
- condition: template
|
||||
value_template: "{{ wait.trigger is not none and\n wait.trigger.event.data.action
|
||||
== 'CANCEL_ESPHOME_UPDATE' }}\n"
|
||||
then:
|
||||
- domain: mobile_app
|
||||
type: notify
|
||||
device_id: !input notify_device
|
||||
title: ESPHome Update Cancelled
|
||||
message: ESPHome device updates have been cancelled.
|
||||
else:
|
||||
- if:
|
||||
- condition: template
|
||||
value_template: '{{ update_mode == ''sequential'' }}'
|
||||
then:
|
||||
- repeat:
|
||||
for_each: '{{ device_list }}'
|
||||
sequence:
|
||||
- action: update.install
|
||||
continue_on_error: true
|
||||
data: {}
|
||||
target:
|
||||
entity_id: '{{ repeat.item }}'
|
||||
- delay:
|
||||
minutes: '{{ 0 if repeat.last else sequential_delay }}'
|
||||
else:
|
||||
- action: update.install
|
||||
continue_on_error: true
|
||||
data: {}
|
||||
target:
|
||||
entity_id: '{{ device_list }}'
|
||||
- domain: mobile_app
|
||||
type: notify
|
||||
device_id: !input notify_device
|
||||
title: ESPHome Updates Complete
|
||||
message: '{{ device_count }} device(s) have been updated: {{ device_names }}.
|
||||
|
||||
'
|
||||
- delay:
|
||||
minutes: '{{ cooldown }}'
|
||||
mode: single
|
||||
@@ -0,0 +1,335 @@
|
||||
blueprint:
|
||||
name: Elegoo Printer Progress Notification (v4)
|
||||
description: Sends notifications for printer progress, status changes, and error
|
||||
states.
|
||||
author: Daniel Cherubini
|
||||
homeassistant:
|
||||
min_version: 2024.6.0
|
||||
domain: automation
|
||||
input:
|
||||
percent_complete_entity:
|
||||
name: Percent Complete Entity
|
||||
description: The percent complete sensor for the Elegoo printer (look for entities
|
||||
ending in '_percent_complete').
|
||||
selector:
|
||||
entity:
|
||||
domain:
|
||||
- sensor
|
||||
integration: elegoo_printer
|
||||
multiple: false
|
||||
reorder: false
|
||||
print_status_entity:
|
||||
name: Print Status Entity
|
||||
description: The print status sensor (should end with '_print_status').
|
||||
selector:
|
||||
entity:
|
||||
domain:
|
||||
- sensor
|
||||
integration: elegoo_printer
|
||||
device_class:
|
||||
- enum
|
||||
multiple: false
|
||||
reorder: false
|
||||
current_status_entity:
|
||||
name: Current Status Entity
|
||||
description: The current status sensor (should end with '_current_status').
|
||||
selector:
|
||||
entity:
|
||||
domain:
|
||||
- sensor
|
||||
integration: elegoo_printer
|
||||
device_class:
|
||||
- enum
|
||||
multiple: false
|
||||
reorder: false
|
||||
error_status_reason_entity:
|
||||
name: Error Status Reason Entity
|
||||
description: The error status reason sensor (should end with '_current_print_error_status_reason').
|
||||
selector:
|
||||
entity:
|
||||
domain:
|
||||
- sensor
|
||||
integration: elegoo_printer
|
||||
device_class:
|
||||
- enum
|
||||
multiple: false
|
||||
reorder: false
|
||||
notify_device:
|
||||
name: Notification Device
|
||||
description: The device to send notifications to.
|
||||
selector:
|
||||
device:
|
||||
integration: mobile_app
|
||||
multiple: false
|
||||
percentage_divisor:
|
||||
name: Notification Frequency
|
||||
description: Notify when the percentage complete is divisible by this number.
|
||||
Use 1 to be notified on every percentage change.
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- '1'
|
||||
- '2'
|
||||
- '5'
|
||||
sort: false
|
||||
custom_value: false
|
||||
multiple: false
|
||||
default: '5'
|
||||
camera_entity:
|
||||
name: Printer Camera (Optional)
|
||||
description: Override the default camera entity for the printer. Leave blank
|
||||
to use the default camera from the printer device.
|
||||
default: ''
|
||||
selector:
|
||||
entity:
|
||||
domain:
|
||||
- camera
|
||||
multiple: false
|
||||
reorder: false
|
||||
dashboard_url:
|
||||
name: Dashboard URL (Optional)
|
||||
description: The path to open when the notification is clicked (e.g., '/dashboard-example/example',
|
||||
not the full URL).
|
||||
default: ''
|
||||
enable_status_notifications:
|
||||
name: Enable Status Change Notifications
|
||||
description: Send notifications when printer status changes (e.g., homing, heating,
|
||||
etc.)
|
||||
default: true
|
||||
selector:
|
||||
boolean: {}
|
||||
source_url: https://github.com/danielcherubini/elegoo-homeassistant/blob/main/blueprints/automation/elegoo_printer/elegoo_printer_progress.yaml
|
||||
mode: single
|
||||
max_exceeded: silent
|
||||
variables:
|
||||
percent_complete_entity: !input percent_complete_entity
|
||||
notify_device: !input notify_device
|
||||
percentage_divisor: !input percentage_divisor
|
||||
camera_entity_input: !input camera_entity
|
||||
dashboard_url: !input dashboard_url
|
||||
enable_status_notifications: !input enable_status_notifications
|
||||
print_status_entity: !input print_status_entity
|
||||
current_status_entity: !input current_status_entity
|
||||
error_status_reason_entity: !input error_status_reason_entity
|
||||
printer_device: '{{ device_id(percent_complete_entity) }}'
|
||||
notification_group: '{{ device_attr(printer_device, ''name'') | slugify }}'
|
||||
end_time_entity: '{{ device_entities(printer_device) | select(''search'', ''_end_time'')
|
||||
| first }}'
|
||||
file_name_entity: '{{ device_entities(printer_device) | select(''search'', ''_file_name'')
|
||||
| first }}'
|
||||
current_layer_entity: '{{ device_entities(printer_device) | select(''search'', ''_current_layer'')
|
||||
| first }}'
|
||||
total_layers_entity: '{{ device_entities(printer_device) | select(''search'', ''_total_layers'')
|
||||
| first }}'
|
||||
camera_entity: "{{ (camera_entity_input\n if camera_entity_input != ''\n else
|
||||
(device_entities(printer_device) | select('match', '^camera\\.') | first))\n |
|
||||
default('', true) }}"
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: !input percent_complete_entity
|
||||
- platform: state
|
||||
entity_id: !input print_status_entity
|
||||
- platform: state
|
||||
entity_id: !input current_status_entity
|
||||
- platform: state
|
||||
entity_id: !input error_status_reason_entity
|
||||
condition: []
|
||||
action:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: '{{ trigger.entity_id == percent_complete_entity }}'
|
||||
- condition: template
|
||||
value_template: '{{ states(percent_complete_entity) not in [''unknown'', ''unavailable'']
|
||||
}}'
|
||||
- condition: template
|
||||
value_template: '{{ states(percent_complete_entity) | int(0) < 100 }}'
|
||||
- condition: template
|
||||
value_template: '{{ states(percent_complete_entity) | int(0) % (percentage_divisor
|
||||
| int) == 0 }}'
|
||||
- condition: template
|
||||
value_template: '{{ current_status_entity != none and states(current_status_entity)
|
||||
== ''printing'' }}'
|
||||
- condition: template
|
||||
value_template: '{{ notify_device != '''' }}'
|
||||
sequence:
|
||||
- device_id: !input notify_device
|
||||
domain: mobile_app
|
||||
type: notify
|
||||
title: 'Printing: {{ states(percent_complete_entity) | int(0) }}%
|
||||
|
||||
Layer: {{ (states(current_layer_entity)|default(''?'', true)) }}/{{ (states(total_layers_entity)|default(''?'',
|
||||
true)) }}'
|
||||
message: '{{ states(file_name_entity)|default(''Unknown file'', true) }}'
|
||||
data:
|
||||
chronometer: true
|
||||
when: '{{ as_timestamp(states(end_time_entity))|int if end_time_entity !=
|
||||
none and states(end_time_entity) not in [''unknown'', ''unavailable''] else
|
||||
0 }}'
|
||||
progress: '{{ states(percent_complete_entity)|int(0) }}'
|
||||
progress_max: 100
|
||||
image: '{{ (''/api/camera_proxy/'' ~ camera_entity) if (camera_entity|default('''',
|
||||
true)) != '''' else '''' }}'
|
||||
url: '{{ dashboard_url }}'
|
||||
clickAction: '{{ dashboard_url }}'
|
||||
group: '{{ notification_group }}'
|
||||
channel: '{{ notification_group }}'
|
||||
tag: '{{ notification_group }}'
|
||||
alert_once: true
|
||||
sticky: true
|
||||
push:
|
||||
interruption-level: passive
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: '{{ notify_device != '''' }}'
|
||||
- condition: template
|
||||
value_template: '{{ states(print_status_entity) == ''complete'' }}'
|
||||
- condition: or
|
||||
conditions:
|
||||
- condition: and
|
||||
conditions:
|
||||
- condition: template
|
||||
value_template: '{{ trigger.entity_id == print_status_entity }}'
|
||||
- condition: template
|
||||
value_template: '{{ trigger.from_state.state != ''complete'' }}'
|
||||
- condition: and
|
||||
conditions:
|
||||
- condition: template
|
||||
value_template: '{{ trigger.entity_id == percent_complete_entity }}'
|
||||
sequence:
|
||||
- device_id: !input notify_device
|
||||
domain: mobile_app
|
||||
type: notify
|
||||
title: "\U0001F389 Print Complete!"
|
||||
message: Print has finished successfully
|
||||
data:
|
||||
image: '{{ (''/api/camera_proxy/'' ~ camera_entity) if (camera_entity|default('''',
|
||||
true)) != '''' else '''' }}'
|
||||
url: '{{ dashboard_url }}'
|
||||
clickAction: '{{ dashboard_url }}'
|
||||
group: '{{ notification_group }}'
|
||||
channel: '{{ notification_group }}'
|
||||
tag: '{{ notification_group }}'
|
||||
sticky: true
|
||||
alert_once: true
|
||||
push:
|
||||
interruption-level: time-sensitive
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: '{{ trigger.entity_id == print_status_entity }}'
|
||||
- condition: template
|
||||
value_template: '{{ notify_device != '''' }}'
|
||||
- condition: template
|
||||
value_template: '{{ enable_status_notifications }}'
|
||||
- condition: template
|
||||
value_template: '{{ states(print_status_entity) not in [''complete'', ''stopped'',
|
||||
''stopping'', ''idle'', ''unknown'', ''unavailable''] }}'
|
||||
sequence:
|
||||
- device_id: !input notify_device
|
||||
domain: mobile_app
|
||||
type: notify
|
||||
title: Printer Status Update
|
||||
message: "{% set status = states(print_status_entity) %} {% set file_name =
|
||||
states(file_name_entity)|default('Unknown file', true) %} {% if status ==
|
||||
'homing' %}\n \U0001F3E0 Printer is homing\n{% elif status == 'printing'
|
||||
%}\n \U0001F5A8️ Started printing: {{ file_name }}\n{% elif status == 'paused'
|
||||
or status == 'pausing' %}\n ⏸️ Print paused: {{ file_name }}\n{% elif status
|
||||
== 'loading' %}\n \U0001F4E5 Loading filament\n{% elif status == 'dropping'
|
||||
%}\n \U0001F53D Platform dropping\n{% elif status == 'lifting' %}\n \U0001F53C
|
||||
Platform lifting\n{% elif status == 'file_checking' %}\n \U0001F4C1 Checking
|
||||
print file\n{% elif status == 'recovery' or status == 'printing_recovery'
|
||||
%}\n \U0001F504 Print recovery in progress\n{% elif status == 'preheating'
|
||||
%}\n \U0001F525 Preheating for print\n{% elif status == 'leveling' %}\n \U0001F4D0
|
||||
Bed leveling in progress\n{% else %}\n \U0001F4CA Status: {{ status }}\n{%
|
||||
endif %}"
|
||||
data:
|
||||
url: '{{ dashboard_url }}'
|
||||
clickAction: '{{ dashboard_url }}'
|
||||
group: '{{ notification_group }}'
|
||||
channel: '{{ notification_group }}'
|
||||
tag: '{{ notification_group }}_status'
|
||||
alert_once: true
|
||||
push:
|
||||
interruption-level: passive
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: '{{ trigger.entity_id == current_status_entity }}'
|
||||
- condition: template
|
||||
value_template: '{{ notify_device != '''' }}'
|
||||
- condition: template
|
||||
value_template: '{{ enable_status_notifications }}'
|
||||
- condition: template
|
||||
value_template: '{{ states(current_status_entity) not in [''idle'', ''printing'',
|
||||
''unknown'', ''unavailable''] }}'
|
||||
sequence:
|
||||
- device_id: !input notify_device
|
||||
domain: mobile_app
|
||||
type: notify
|
||||
title: Machine Status Update
|
||||
message: "{% set status = states(current_status_entity) %} {% set file_name
|
||||
= states(file_name_entity)|default('Unknown file', true) %} {% if status ==
|
||||
'file_transferring' %}\n \U0001F4C1 File transfer in progress\n{% elif status
|
||||
== 'exposure_testing' %}\n \U0001F52C Exposure test running\n{% elif status
|
||||
== 'devices_testing' %}\n \U0001F527 Device self-check running\n{% elif status
|
||||
== 'leveling' %}\n \U0001F4D0 Bed leveling in progress\n{% elif status ==
|
||||
'loading_unloading' %}\n \U0001F4E5\U0001F4E4 Loading/unloading filament\n{%
|
||||
else %}\n \U0001F4CA Machine status: {{ status }}\n{% endif %}"
|
||||
data:
|
||||
url: '{{ dashboard_url }}'
|
||||
clickAction: '{{ dashboard_url }}'
|
||||
group: '{{ notification_group }}'
|
||||
channel: '{{ notification_group }}'
|
||||
tag: '{{ notification_group }}_machine_status'
|
||||
alert_once: true
|
||||
push:
|
||||
interruption-level: passive
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: '{{ trigger.entity_id == error_status_reason_entity }}'
|
||||
- condition: template
|
||||
value_template: '{{ notify_device != '''' }}'
|
||||
- condition: template
|
||||
value_template: '{{ states(error_status_reason_entity) not in [''ok'', ''none'',
|
||||
''unknown'', ''unavailable''] }}'
|
||||
sequence:
|
||||
- device_id: !input notify_device
|
||||
domain: mobile_app
|
||||
type: notify
|
||||
title: "\U0001F6A8 Critical Printer Error!"
|
||||
message: "{% set error = states(error_status_reason_entity) %} {% set file_name
|
||||
= states(file_name_entity)|default('current print', true) %} {% if error ==
|
||||
'filament_runout' %}\n \U0001F9F5 Filament runout detected during {{ file_name
|
||||
}}! Please load new filament.\n{% elif error == 'filament_about_to_runout'
|
||||
%}\n ⚠️ Filament runout imminent for {{ file_name }}! Please prepare new
|
||||
filament.\n{% elif error == 'filament_jam' %}\n \U0001F6AB Filament jam detected
|
||||
during {{ file_name }}! Please check the extruder.\n{% elif error == 'temp_error'
|
||||
%}\n \U0001F321️ Temperature error detected! Please check nozzle and bed
|
||||
temperatures.\n{% elif error == 'level_failed' %}\n \U0001F4D0 Bed leveling
|
||||
failed! Please check the bed leveling system.\n{% elif error == 'home_failed'
|
||||
or error == 'home_failed_x' or error == 'home_failed_y' or error == 'home_failed_z'
|
||||
%}\n \U0001F3E0 Homing failed! Please check the printer axes and endstops.\n{%
|
||||
elif error == 'bed_adhesion_failed' %}\n \U0001F6CF️ Print detached from
|
||||
bed during {{ file_name }}!\n{% elif error == 'move_abnormal' %}\n ⚙️ Motor
|
||||
movement abnormality detected!\n{% elif error == 'file_error' %}\n \U0001F4C1
|
||||
Print file error during {{ file_name }}!\n{% elif error == 'udisk_remove'
|
||||
%}\n \U0001F4BE USB drive was removed during printing!\n{% elif error ==
|
||||
'nozzle_temp_sensor_offline' %}\n \U0001F321️ Nozzle temperature sensor is
|
||||
offline!\n{% elif error == 'bed_temp_sensor_offline' %}\n \U0001F321️ Bed
|
||||
temperature sensor is offline!\n{% elif error == 'camera_error' %}\n \U0001F4F7
|
||||
Camera connection error!\n{% elif error == 'network_error' %}\n \U0001F310
|
||||
Network connection error!\n{% elif error == 'server_connect_failed' %}\n \U0001F5A5️
|
||||
Server connection failed!\n{% elif error == 'disconnect_app' %}\n \U0001F4F1
|
||||
Controlling app disconnected during print!\n{% else %}\n ⚠️ Error: {{ error
|
||||
}}\n{% endif %}"
|
||||
data:
|
||||
image: '{{ (''/api/camera_proxy/'' ~ camera_entity) if (camera_entity|default('''',
|
||||
true)) != '''' else '''' }}'
|
||||
url: '{{ dashboard_url }}'
|
||||
clickAction: '{{ dashboard_url }}'
|
||||
group: '{{ notification_group }}'
|
||||
channel: '{{ notification_group }}'
|
||||
tag: '{{ notification_group }}_critical_error'
|
||||
sticky: true
|
||||
alert_once: false
|
||||
push:
|
||||
interruption-level: time-sensitive
|
||||
@@ -0,0 +1,66 @@
|
||||
blueprint:
|
||||
name: Duck area players volume while assist in progress
|
||||
description: 'Temporarily lowers the volume of media players in the same area when
|
||||
any selected Assist Satellite starts listening, then restores their volume after
|
||||
the interaction ends.
|
||||
|
||||
'
|
||||
domain: automation
|
||||
input:
|
||||
satellites:
|
||||
name: Assist Satellites
|
||||
description: List of Assist Satellite entities to monitor.
|
||||
selector:
|
||||
entity:
|
||||
domain:
|
||||
- assist_satellite
|
||||
multiple: true
|
||||
reorder: false
|
||||
duck_volume:
|
||||
name: Duck Volume Level
|
||||
description: Volume level to set while assist is listening (e.g. 0.2 = 20%).
|
||||
default: 0.2
|
||||
selector:
|
||||
number:
|
||||
min: 0.0
|
||||
max: 1.0
|
||||
step: 0.01
|
||||
unit_of_measurement: fraction (0–1)
|
||||
mode: slider
|
||||
source_url: https://raw.githubusercontent.com/formatBCE/Respeaker-Lite-ESPHome-integration/refs/heads/main/blueprints/automation/formatbce/duck_players_on_satellite_working.yaml
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: !input satellites
|
||||
to: listening
|
||||
variables:
|
||||
v_duck_volume: !input duck_volume
|
||||
v_players: "{{ states.media_player\n | selectattr('state', 'equalto', 'playing')\n
|
||||
\ | selectattr('attributes.volume_level', 'defined')\n | selectattr('entity_id',
|
||||
'in', area_entities(area_id(trigger.entity_id)))\n | rejectattr('entity_id',
|
||||
'in', device_entities(device_id(trigger.entity_id)))\n | rejectattr('attributes.active_queue',
|
||||
'in', device_entities(device_id(trigger.entity_id)))\n | map(attribute='entity_id')\n
|
||||
\ | list\n}}"
|
||||
v_volumes: "{% set vol = namespace(umes = []) %} {% for i in v_players %}\n {%
|
||||
set vol.umes = vol.umes + [{'id': i, 'volume_diff': state_attr(i, 'volume_level')
|
||||
- v_duck_volume }] %}\n{% endfor %} {{ vol.umes }}"
|
||||
action:
|
||||
- service: media_player.volume_set
|
||||
data:
|
||||
volume_level: '{{ v_duck_volume }}'
|
||||
target:
|
||||
entity_id: '{{ v_players }}'
|
||||
- wait_for_trigger:
|
||||
- platform: template
|
||||
value_template: '{{ is_state(trigger.entity_id, ''idle'') }}'
|
||||
timeout: 00:03:00
|
||||
- repeat:
|
||||
for_each: '{{ v_volumes }}'
|
||||
sequence:
|
||||
- service: media_player.volume_set
|
||||
data:
|
||||
volume_level: '{{ state_attr(repeat.item.id, ''volume_level'') + repeat.item.volume_diff
|
||||
}}'
|
||||
target:
|
||||
entity_id: '{{ repeat.item.id }}'
|
||||
mode: parallel
|
||||
max: 10
|
||||
@@ -0,0 +1,44 @@
|
||||
blueprint:
|
||||
name: Play TTS URI via Media Player
|
||||
description: Listen for a TTS URI event from an ESPHome device and play it using
|
||||
a selected media player.
|
||||
domain: automation
|
||||
input:
|
||||
tts_device:
|
||||
name: ESPHome TTS Device
|
||||
description: Select the ESPHome device that sends the TTS URI event.
|
||||
selector:
|
||||
device:
|
||||
entity:
|
||||
- domain:
|
||||
- assist_satellite
|
||||
filter:
|
||||
- manufacturer: formatbce
|
||||
model: Respeaker Lite Satellite
|
||||
- manufacturer: formatbce
|
||||
model: Koala Satellite
|
||||
multiple: false
|
||||
target_media_player:
|
||||
name: Target Media Player
|
||||
description: Media player entity that should play the TTS URI.
|
||||
selector:
|
||||
entity:
|
||||
domain:
|
||||
- media_player
|
||||
multiple: false
|
||||
reorder: false
|
||||
source_url: https://raw.githubusercontent.com/formatBCE/Respeaker-Lite-ESPHome-integration/refs/heads/main/blueprints/automation/formatbce/redirect_respeaker_tts.yaml
|
||||
trigger:
|
||||
- platform: event
|
||||
event_type: esphome.tts_uri
|
||||
event_data:
|
||||
device_id: !input tts_device
|
||||
action:
|
||||
- service: media_player.play_media
|
||||
target:
|
||||
entity_id: !input target_media_player
|
||||
data:
|
||||
announce: true
|
||||
media_content_type: music
|
||||
media_content_id: '{{ trigger.event.data.uri }}'
|
||||
mode: single
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
blueprint:
|
||||
name: Set Respeaker Alarm Time from Time Helper
|
||||
domain: automation
|
||||
input:
|
||||
datetime_helper:
|
||||
name: Datetime Helper
|
||||
description: The input_datetime helper that triggers the alarm time update.
|
||||
Must have time.
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
- domain:
|
||||
- input_datetime
|
||||
multiple: false
|
||||
reorder: false
|
||||
esphome_device:
|
||||
name: Respeaker Device
|
||||
description: The ESPHome device with set_alarm_time service
|
||||
selector:
|
||||
device:
|
||||
entity:
|
||||
- domain:
|
||||
- assist_satellite
|
||||
filter:
|
||||
- manufacturer: formatbce
|
||||
model: Respeaker Lite Satellite
|
||||
- manufacturer: formatbce
|
||||
model: Koala Satellite
|
||||
- manufacturer: formatbce
|
||||
model: Respeaker XVF3800 Satellite
|
||||
multiple: false
|
||||
source_url: https://raw.githubusercontent.com/formatBCE/Respeaker-Lite-ESPHome-integration/refs/heads/main/blueprints/automation/formatbce/set_respeaker_alarm_time_from_input_datetime_helper.yaml
|
||||
variables:
|
||||
esphome_device: !input esphome_device
|
||||
triggers:
|
||||
- trigger: state
|
||||
entity_id: !input datetime_helper
|
||||
actions:
|
||||
- action: esphome.{{ device_attr(esphome_device, 'name') | slugify }}_set_alarm_time
|
||||
data:
|
||||
alarm_time_hh_mm: '{{ trigger.to_state.attributes.hour }}:{{ trigger.to_state.attributes.minute
|
||||
}}'
|
||||
mode: single
|
||||
@@ -0,0 +1,58 @@
|
||||
blueprint:
|
||||
name: Motion-activated Light
|
||||
description: Turn on a light when motion is detected.
|
||||
domain: automation
|
||||
source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/motion_light.yaml
|
||||
author: Home Assistant
|
||||
input:
|
||||
motion_entity:
|
||||
name: Motion Sensor
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
- device_class: occupancy
|
||||
domain: binary_sensor
|
||||
- device_class: motion
|
||||
domain: binary_sensor
|
||||
light_target:
|
||||
name: Light
|
||||
selector:
|
||||
target:
|
||||
entity:
|
||||
domain: light
|
||||
no_motion_wait:
|
||||
name: Wait time
|
||||
description: Time to leave the light on after last motion is detected.
|
||||
default: 120
|
||||
selector:
|
||||
number:
|
||||
min: 0
|
||||
max: 3600
|
||||
unit_of_measurement: seconds
|
||||
|
||||
# If motion is detected within the delay,
|
||||
# we restart the script.
|
||||
mode: restart
|
||||
max_exceeded: silent
|
||||
|
||||
triggers:
|
||||
trigger: state
|
||||
entity_id: !input motion_entity
|
||||
from: "off"
|
||||
to: "on"
|
||||
|
||||
actions:
|
||||
- alias: "Turn on the light"
|
||||
action: light.turn_on
|
||||
target: !input light_target
|
||||
- alias: "Wait until there is no motion from device"
|
||||
wait_for_trigger:
|
||||
trigger: state
|
||||
entity_id: !input motion_entity
|
||||
from: "on"
|
||||
to: "off"
|
||||
- alias: "Wait the number of seconds that has been set"
|
||||
delay: !input no_motion_wait
|
||||
- alias: "Turn off the light"
|
||||
action: light.turn_off
|
||||
target: !input light_target
|
||||
@@ -0,0 +1,50 @@
|
||||
blueprint:
|
||||
name: Zone Notification
|
||||
description: Send a notification to a device when a person leaves a specific zone.
|
||||
domain: automation
|
||||
source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/notify_leaving_zone.yaml
|
||||
author: Home Assistant
|
||||
input:
|
||||
person_entity:
|
||||
name: Person
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
domain: person
|
||||
zone_entity:
|
||||
name: Zone
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
domain: zone
|
||||
notify_device:
|
||||
name: Device to notify
|
||||
description: Device needs to run the official Home Assistant app to receive notifications.
|
||||
selector:
|
||||
device:
|
||||
filter:
|
||||
integration: mobile_app
|
||||
|
||||
triggers:
|
||||
trigger: state
|
||||
entity_id: !input person_entity
|
||||
|
||||
variables:
|
||||
zone_entity: !input zone_entity
|
||||
# This is the state of the person when it's in this zone.
|
||||
zone_state: "{{ states[zone_entity].name }}"
|
||||
person_entity: !input person_entity
|
||||
person_name: "{{ states[person_entity].name }}"
|
||||
|
||||
conditions:
|
||||
condition: template
|
||||
# The first case handles leaving the Home zone which has a special state when zoning called 'home'.
|
||||
# The second case handles leaving all other zones.
|
||||
value_template: "{{ zone_entity == 'zone.home' and trigger.from_state.state == 'home' and trigger.to_state.state != 'home' or trigger.from_state.state == zone_state and trigger.to_state.state != zone_state }}"
|
||||
|
||||
actions:
|
||||
- alias: "Notify that a person has left the zone"
|
||||
domain: mobile_app
|
||||
type: notify
|
||||
device_id: !input notify_device
|
||||
message: "{{ person_name }} has left {{ zone_state }}"
|
||||
@@ -0,0 +1,514 @@
|
||||
blueprint:
|
||||
name: Bambu Lab - Spaghetti Detection
|
||||
description: Bambu Lab - Spaghetti Detection
|
||||
domain: automation
|
||||
input:
|
||||
home_assistant_host:
|
||||
name: Home Assistant Host
|
||||
description: Home Assistant host
|
||||
default: http://192.168.1.123:8123
|
||||
obico_host:
|
||||
name: Obico ML API Host
|
||||
description: Obico ML API host
|
||||
default: http://192.168.1.123:3333
|
||||
obico_auth_token:
|
||||
name: Obico ML API Auth Token
|
||||
description: Obico ML API authentication token
|
||||
default: obico_api_secret
|
||||
detection_frequency:
|
||||
name: Detection Frequency
|
||||
description: The detection algorithm will run in every defined seconds
|
||||
default: /5
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- label: Every second
|
||||
value: /1
|
||||
- label: Every 5 seconds
|
||||
value: /5
|
||||
- label: Every 10 seconds
|
||||
value: /10
|
||||
- label: Every 30 seconds
|
||||
value: /30
|
||||
- label: Every 60 seconds
|
||||
value: /59
|
||||
multiple: false
|
||||
mode: dropdown
|
||||
sort: false
|
||||
custom_value: false
|
||||
auto_turn_on_light:
|
||||
name: Automatically Turn On Printer Lights
|
||||
description: Turns on printer lights before spaghetti detection operation
|
||||
default: true
|
||||
selector:
|
||||
boolean: {}
|
||||
notification_settings:
|
||||
name: Notification Settings
|
||||
description: Type of notification to send after detecting a failure
|
||||
default: standard
|
||||
selector:
|
||||
select:
|
||||
mode: dropdown
|
||||
options:
|
||||
- label: Critical Notification
|
||||
value: critical
|
||||
- label: Standard Notification
|
||||
value: standard
|
||||
- label: None
|
||||
value: none
|
||||
sort: false
|
||||
multiple: false
|
||||
custom_value: false
|
||||
failure_action:
|
||||
name: On Failure Action
|
||||
description: What to do after detecting a failure
|
||||
default: pause
|
||||
selector:
|
||||
select:
|
||||
mode: dropdown
|
||||
options:
|
||||
- label: Pause
|
||||
value: pause
|
||||
- label: Stop
|
||||
value: stop
|
||||
- label: Warn
|
||||
value: warn
|
||||
sort: false
|
||||
multiple: false
|
||||
custom_value: false
|
||||
notification_service:
|
||||
name: Mobile devices notification service
|
||||
description: The notification service for mobile devices (eg. notify.mobile_app_<your_device_id_here>).
|
||||
You can provide both a notify group or a single notify device here.
|
||||
default: notify.notify
|
||||
selector:
|
||||
text: {}
|
||||
printer_print_status_sensor:
|
||||
name: Printer Print Status Sensor
|
||||
description: Bambu Lab printer print status sensor
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
- integration: bambu_lab
|
||||
domain:
|
||||
- sensor
|
||||
device_class:
|
||||
- enum
|
||||
multiple: false
|
||||
printer_current_stage_sensor:
|
||||
name: Printer Current Stage Sensor
|
||||
description: Bambu Lab printer current stage sensor
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
- integration: bambu_lab
|
||||
domain:
|
||||
- sensor
|
||||
device_class:
|
||||
- enum
|
||||
multiple: false
|
||||
printer_camera:
|
||||
name: Printer Camera Entity
|
||||
description: Bambu Lab printer camera entity
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
- domain:
|
||||
- camera
|
||||
multiple: false
|
||||
printer_pause_button:
|
||||
name: Printer Pause Button Entity
|
||||
description: Bambu Lab printer pause button entity
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
- integration: bambu_lab
|
||||
domain:
|
||||
- button
|
||||
multiple: false
|
||||
printer_resume_button:
|
||||
name: Printer Resume Button Entity
|
||||
description: Bambu Lab printer resume button entity
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
- integration: bambu_lab
|
||||
domain:
|
||||
- button
|
||||
multiple: false
|
||||
printer_stop_button:
|
||||
name: Printer Stop Button Entity
|
||||
description: Bambu Lab printer stop button entity
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
- integration: bambu_lab
|
||||
domain:
|
||||
- button
|
||||
multiple: false
|
||||
printer_chamber_light:
|
||||
name: Printer Chamber Light
|
||||
description: Bambu Lab printer chamber light
|
||||
selector:
|
||||
entity:
|
||||
filter:
|
||||
- integration: bambu_lab
|
||||
domain:
|
||||
- light
|
||||
multiple: false
|
||||
source_url: https://github.com/nberktumer/ha-bambu-lab-p1-spaghetti-detection/blob/main/blueprints/spaghetti_detection.yaml
|
||||
variables:
|
||||
HOME_ASSISTANT_HOST_VAR: !input home_assistant_host
|
||||
PRINTER_CAMERA_VAR: !input printer_camera
|
||||
FAILURE_ACTION_VAR: !input failure_action
|
||||
NOTIFICATION_SETTINGS_VAR: !input notification_settings
|
||||
DETECTION_FREQUENCY_VAR: !input detection_frequency
|
||||
mode: single
|
||||
max_exceeded: silent
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id:
|
||||
- !input printer_current_stage_sensor
|
||||
to: printing
|
||||
id: BAMBU_LAB_PRINTER_STAGE_CHANGE
|
||||
- platform: event
|
||||
event_type: mobile_app_notification_action
|
||||
id: BAMBU_LAB_PAUSE_PRINTING
|
||||
event_data:
|
||||
action: BAMBU_LAB_PAUSE_PRINTING
|
||||
- platform: event
|
||||
event_type: mobile_app_notification_action
|
||||
id: BAMBU_LAB_RESUME_PRINTING
|
||||
event_data:
|
||||
action: BAMBU_LAB_RESUME_PRINTING
|
||||
- platform: event
|
||||
event_type: mobile_app_notification_action
|
||||
id: BAMBU_LAB_STOP_PRINTING
|
||||
event_data:
|
||||
action: BAMBU_LAB_STOP_PRINTING
|
||||
- trigger: time_pattern
|
||||
id: BAMBU_LAB_DETECTION_TRIGGER
|
||||
seconds: !input detection_frequency
|
||||
condition: []
|
||||
action:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: trigger
|
||||
id: BAMBU_LAB_PRINTER_STAGE_CHANGE
|
||||
sequence:
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: 0
|
||||
target:
|
||||
entity_id:
|
||||
- number.bambu_lab_p1_spaghetti_detection_current_frame_number
|
||||
- number.bambu_lab_p1_spaghetti_detection_ewm_mean
|
||||
- number.bambu_lab_p1_spaghetti_detection_rolling_mean_short
|
||||
- number.bambu_lab_p1_spaghetti_detection_rolling_mean_long
|
||||
- number.bambu_lab_p1_spaghetti_detection_normalized_p
|
||||
- number.bambu_lab_p1_spaghetti_detection_adjusted_ewm_mean
|
||||
- number.bambu_lab_p1_spaghetti_detection_p_sum
|
||||
- if:
|
||||
- condition: and
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: !input printer_chamber_light
|
||||
state: 'off'
|
||||
- condition: template
|
||||
value_template: !input auto_turn_on_light
|
||||
then:
|
||||
- service: light.turn_on
|
||||
target:
|
||||
entity_id:
|
||||
- !input printer_chamber_light
|
||||
- conditions:
|
||||
- condition: trigger
|
||||
id:
|
||||
- BAMBU_LAB_PAUSE_PRINTING
|
||||
- BAMBU_LAB_RESUME_PRINTING
|
||||
- BAMBU_LAB_STOP_PRINTING
|
||||
sequence:
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: trigger
|
||||
id:
|
||||
- BAMBU_LAB_PAUSE_PRINTING
|
||||
sequence:
|
||||
- service: button.press
|
||||
data: {}
|
||||
target:
|
||||
entity_id: !input printer_pause_button
|
||||
- conditions:
|
||||
- condition: trigger
|
||||
id: BAMBU_LAB_RESUME_PRINTING
|
||||
sequence:
|
||||
- service: button.press
|
||||
data: {}
|
||||
target:
|
||||
entity_id: !input printer_resume_button
|
||||
- conditions:
|
||||
- condition: trigger
|
||||
id: BAMBU_LAB_STOP_PRINTING
|
||||
sequence:
|
||||
- service: button.press
|
||||
data: {}
|
||||
target:
|
||||
entity_id: !input printer_stop_button
|
||||
- conditions:
|
||||
- condition: trigger
|
||||
id: BAMBU_LAB_DETECTION_TRIGGER
|
||||
sequence:
|
||||
- if:
|
||||
- condition: not
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: !input printer_print_status_sensor
|
||||
state: running
|
||||
then:
|
||||
- stop: ''
|
||||
- if:
|
||||
- condition: template
|
||||
value_template: '{{ now().second % (DETECTION_FREQUENCY_VAR | replace(''/'', '''') | int(0)) > 0 }}'
|
||||
then:
|
||||
- stop: ''
|
||||
- if:
|
||||
- condition: and
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id: !input printer_chamber_light
|
||||
state: 'off'
|
||||
- condition: template
|
||||
value_template: !input auto_turn_on_light
|
||||
then:
|
||||
- service: light.turn_on
|
||||
target:
|
||||
entity_id:
|
||||
- !input printer_chamber_light
|
||||
- service: bambu_lab_p1_spaghetti_detection.predict
|
||||
data:
|
||||
obico_host: !input obico_host
|
||||
obico_auth_token: !input obico_auth_token
|
||||
image_url: '{{ HOME_ASSISTANT_HOST_VAR }}{{ state_attr(PRINTER_CAMERA_VAR,
|
||||
''entity_picture'') }}'
|
||||
response_variable: result
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ result.result.detections | map(attribute=1) | sum | float }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_p_sum
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ states(''number.bambu_lab_p1_spaghetti_detection_current_frame_number'')
|
||||
| float + 1 }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_current_frame_number
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ states(''number.bambu_lab_p1_spaghetti_detection_lifetime_frame_number'')
|
||||
| float + 1 }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_lifetime_frame_number
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ (states(''number.bambu_lab_p1_spaghetti_detection_p_sum'') | float)
|
||||
* (2 / (12 + 1)) + (states(''number.bambu_lab_p1_spaghetti_detection_ewm_mean'')
|
||||
| float) * (1 - (2 / (12 + 1))) }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_ewm_mean
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ (states(''number.bambu_lab_p1_spaghetti_detection_rolling_mean_short'')
|
||||
| float) + ((states(''number.bambu_lab_p1_spaghetti_detection_p_sum'') |
|
||||
float) - (states(''number.bambu_lab_p1_spaghetti_detection_rolling_mean_short'')
|
||||
| float)) / (310 if 310 <= (states(''number.bambu_lab_p1_spaghetti_detection_current_frame_number'')
|
||||
| float) else (states(''number.bambu_lab_p1_spaghetti_detection_current_frame_number'')
|
||||
| float) + 1) }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_rolling_mean_short
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ (states(''number.bambu_lab_p1_spaghetti_detection_rolling_mean_long'')
|
||||
| float) + ((states(''number.bambu_lab_p1_spaghetti_detection_p_sum'') |
|
||||
float) - (states(''number.bambu_lab_p1_spaghetti_detection_rolling_mean_long'')
|
||||
| float)) / (7200 if 7200 <= (states(''number.bambu_lab_p1_spaghetti_detection_lifetime_frame_number'')
|
||||
| float) else (states(''number.bambu_lab_p1_spaghetti_detection_lifetime_frame_number'')
|
||||
| float) + 1) }}'
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_rolling_mean_long
|
||||
- if:
|
||||
- condition: numeric_state
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_current_frame_number
|
||||
below: 30
|
||||
then:
|
||||
- stop: ''
|
||||
alias: if current_frame_num < 30
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ (states(''number.bambu_lab_p1_spaghetti_detection_ewm_mean'') |
|
||||
float) - (states(''number.bambu_lab_p1_spaghetti_detection_rolling_mean_long'')
|
||||
| float) }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_adjusted_ewm_mean
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ ((states(''number.bambu_lab_p1_spaghetti_detection_rolling_mean_short'')
|
||||
| float) - (states(''number.bambu_lab_p1_spaghetti_detection_rolling_mean_long'')
|
||||
| float)) * 3.8 }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_rolling_mean_diff
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ min(0.78, max(0.33, (states(''number.bambu_lab_p1_spaghetti_detection_rolling_mean_diff'')
|
||||
| float))) }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_thresh_warning
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ (states(''number.bambu_lab_p1_spaghetti_detection_thresh_warning'')
|
||||
| float) * 1.75 }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_thresh_failure
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ (states(''number.bambu_lab_p1_spaghetti_detection_ewm_mean'') |
|
||||
float) - (states(''number.bambu_lab_p1_spaghetti_detection_rolling_mean_long'')
|
||||
| float) }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_p
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: numeric_state
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_p
|
||||
above: number.bambu_lab_p1_spaghetti_detection_thresh_failure
|
||||
sequence:
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ min(1.0, max(2.0 / 3.0, ((((states(''number.bambu_lab_p1_spaghetti_detection_p'')
|
||||
| float) - (states(''number.bambu_lab_p1_spaghetti_detection_thresh_failure'')
|
||||
| float)) * (1.0 - 2.0 / 3.0)) / ((states(''number.bambu_lab_p1_spaghetti_detection_thresh_failure'')
|
||||
| float) * 1.5 - (states(''number.bambu_lab_p1_spaghetti_detection_thresh_failure'')
|
||||
| float))) + 2.0 / 3.0)) }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_normalized_p
|
||||
- conditions:
|
||||
- condition: numeric_state
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_p
|
||||
above: number.bambu_lab_p1_spaghetti_detection_thresh_warning
|
||||
sequence:
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ min(2.0 / 3.0, max(1.0 / 3.0, ((((states(''number.bambu_lab_p1_spaghetti_detection_p'')
|
||||
| float) - (states(''number.bambu_lab_p1_spaghetti_detection_thresh_warning'')
|
||||
| float)) * (2.0 / 3.0 - 1.0 / 3.0)) / ((states(''number.bambu_lab_p1_spaghetti_detection_thresh_failure'')
|
||||
| float) - (states(''number.bambu_lab_p1_spaghetti_detection_thresh_warning'')
|
||||
| float))) + 1.0 / 3.0)) }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_normalized_p
|
||||
default:
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: '{{ min(1.0 / 3.0, max(0, ((states(''number.bambu_lab_p1_spaghetti_detection_p'')
|
||||
| float) * 1.0 / 3.0) / (states(''number.bambu_lab_p1_spaghetti_detection_thresh_warning'')
|
||||
| float))) }}'
|
||||
target:
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_normalized_p
|
||||
- if:
|
||||
- condition: numeric_state
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_adjusted_ewm_mean
|
||||
below: 0.38
|
||||
then:
|
||||
- stop: ''
|
||||
- if:
|
||||
- condition: and
|
||||
conditions:
|
||||
- condition: numeric_state
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_adjusted_ewm_mean
|
||||
below: 0.78
|
||||
- condition: numeric_state
|
||||
entity_id: number.bambu_lab_p1_spaghetti_detection_adjusted_ewm_mean
|
||||
below: number.bambu_lab_p1_spaghetti_detection_rolling_mean_diff
|
||||
then:
|
||||
- stop: ''
|
||||
- if:
|
||||
- condition: template
|
||||
value_template: '{{ now() - states(''datetime.bambu_lab_p1_spaghetti_detection_last_notify_time'')
|
||||
| as_datetime | as_local < timedelta(minutes=1) }}'
|
||||
then:
|
||||
- stop: ''
|
||||
alias: if now() - last_notify_time < 1min
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: '{{ FAILURE_ACTION_VAR == ''pause'' }}'
|
||||
sequence:
|
||||
- service: button.press
|
||||
data: {}
|
||||
target:
|
||||
entity_id: !input printer_pause_button
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: '{{ FAILURE_ACTION_VAR == ''stop'' }}'
|
||||
sequence:
|
||||
- service: button.press
|
||||
data: {}
|
||||
target:
|
||||
entity_id: !input printer_stop_button
|
||||
- choose:
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: '{{ NOTIFICATION_SETTINGS_VAR == ''critical'' }}'
|
||||
sequence:
|
||||
- service: !input notification_service
|
||||
data:
|
||||
title: Bambu Lab - Spaghetti Detected
|
||||
message: 'Confidence: {{ (states(''number.bambu_lab_p1_spaghetti_detection_normalized_p'')
|
||||
| float * 100) | int }}%'
|
||||
data:
|
||||
image: '{{ HOME_ASSISTANT_HOST_VAR }}{{ state_attr(PRINTER_CAMERA_VAR,
|
||||
''entity_picture'') }}'
|
||||
ttl: 0
|
||||
priority: high
|
||||
channel: alarm_stream
|
||||
push:
|
||||
sound:
|
||||
name: default
|
||||
critical: 1
|
||||
volume: 0.75
|
||||
actions:
|
||||
- action: BAMBU_LAB_RESUME_PRINTING
|
||||
title: Resume Printing
|
||||
- action: BAMBU_LAB_STOP_PRINTING
|
||||
title: Stop Printing
|
||||
- conditions:
|
||||
- condition: template
|
||||
value_template: '{{ NOTIFICATION_SETTINGS_VAR == ''standard'' }}'
|
||||
sequence:
|
||||
- service: !input notification_service
|
||||
data:
|
||||
title: Bambu Lab - Spaghetti Detected
|
||||
message: 'Confidence: {{ (states(''number.bambu_lab_p1_spaghetti_detection_normalized_p'')
|
||||
| float * 100) | int }}%'
|
||||
data:
|
||||
image: '{{ HOME_ASSISTANT_HOST_VAR }}{{ state_attr(PRINTER_CAMERA_VAR,
|
||||
''entity_picture'') }}'
|
||||
actions:
|
||||
- action: BAMBU_LAB_RESUME_PRINTING
|
||||
title: Resume Printing
|
||||
- action: BAMBU_LAB_STOP_PRINTING
|
||||
title: Stop Printing
|
||||
- service: number.set_value
|
||||
data:
|
||||
value: 0
|
||||
target:
|
||||
entity_id:
|
||||
- number.bambu_lab_p1_spaghetti_detection_current_frame_number
|
||||
- number.bambu_lab_p1_spaghetti_detection_ewm_mean
|
||||
- number.bambu_lab_p1_spaghetti_detection_rolling_mean_short
|
||||
- number.bambu_lab_p1_spaghetti_detection_rolling_mean_long
|
||||
- number.bambu_lab_p1_spaghetti_detection_normalized_p
|
||||
- number.bambu_lab_p1_spaghetti_detection_adjusted_ewm_mean
|
||||
- number.bambu_lab_p1_spaghetti_detection_p_sum
|
||||
- service: datetime.set_value
|
||||
data:
|
||||
datetime: '{{ now() }}'
|
||||
target:
|
||||
entity_id: datetime.bambu_lab_p1_spaghetti_detection_last_notify_time
|
||||
Reference in New Issue
Block a user