initial commit

This commit is contained in:
root
2026-06-28 14:27:20 -04:00
commit ae0f1f559e
115 changed files with 30411 additions and 0 deletions
@@ -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