336 lines
14 KiB
YAML
336 lines
14 KiB
YAML
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
|