initial commmit

This commit is contained in:
Joshua
2025-06-24 12:12:01 -04:00
commit b6e5bf47fe
12 changed files with 1982 additions and 0 deletions

View File

@@ -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

View File

@@ -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 }}"

View File

@@ -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 > 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

View File

@@ -0,0 +1,86 @@
blueprint:
name: Confirmable Notification
description: >-
A script that sends an actionable notification with a confirmation before
running the specified action.
domain: script
source_url: https://github.com/home-assistant/core/blob/master/homeassistant/components/script/blueprints/confirmable_notification.yaml
author: Home Assistant
input:
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
title:
name: "Title"
description: "The title of the button shown in the notification."
default: ""
selector:
text:
message:
name: "Message"
description: "The message body"
selector:
text:
confirm_text:
name: "Confirmation Text"
description: "Text to show on the confirmation button"
default: "Confirm"
selector:
text:
confirm_action:
name: "Confirmation Action"
description: "Action to run when notification is confirmed"
default: []
selector:
action:
dismiss_text:
name: "Dismiss Text"
description: "Text to show on the dismiss button"
default: "Dismiss"
selector:
text:
dismiss_action:
name: "Dismiss Action"
description: "Action to run when notification is dismissed"
default: []
selector:
action:
mode: restart
sequence:
- alias: "Set up variables"
variables:
action_confirm: "{{ 'CONFIRM_' ~ context.id }}"
action_dismiss: "{{ 'DISMISS_' ~ context.id }}"
- alias: "Send notification"
domain: mobile_app
type: notify
device_id: !input notify_device
title: !input title
message: !input message
data:
actions:
- action: "{{ action_confirm }}"
title: !input confirm_text
- action: "{{ action_dismiss }}"
title: !input dismiss_text
- alias: "Awaiting response"
wait_for_trigger:
- platform: event
event_type: mobile_app_notification_action
event_data:
action: "{{ action_confirm }}"
- platform: event
event_type: mobile_app_notification_action
event_data:
action: "{{ action_dismiss }}"
- choose:
- conditions: "{{ wait.trigger.event.data.action == action_confirm }}"
sequence: !input confirm_action
- conditions: "{{ wait.trigger.event.data.action == action_dismiss }}"
sequence: !input dismiss_action