Hey guys,
After combining some ideas found in the community, i thought i should share my end result, in case it helps somebody.
Happy to provide any help (if i can )
Here is my final ui:
Hardware:
- Ender 3p
- Rpi3b
- D-link Smart plug W215
- Xiaomi Temp/Humidity sensor (with its gateway)
Setup:
I have a 3way socket on my d-link plug, which powers the printer, a desk lamp and the pi through a 5v usb charger (could have gone with buck converter and power it through the enderās PSU but i didnt bother)
Configuration:
(whole UI and Package file at the end)
octoprint:
host: !secret octoprint_host
api_key: !secret octoprint_api_key
bed: true
number_of_tools: 2
Shutdown scripts:
script:
3dprint_off:
alias: ĀØTurn off 3d printer after 10 minutesĀØ
sequence:
- delay:
minutes: 10 #release
# seconds: 10 #production
- condition: state
entity_id: sensor.octoprint_current_state
state: 'Operational'
- service: rest_command.shutdown_octoprint
- service: notify.mobile_app_sm_g975f
data:
message: "Octopi is Down, Printer is next"
- delay:
seconds: 30
- service: switch.turn_off
data:
entity_id: switch.d_link_smart_plug
octopi_off:
alias: "Soft Shutdown Octopi"
sequence:
- delay:
seconds: 30 #added to avoid accidental clics
- service: rest_command.shutdown_octoprint
#shutdown octopi RPI
rest_command:
shutdown_octoprint:
url: http://octopi.local/api/system/commands/core/shutdown #use numeric IP alternatively
method: POST
headers:
X-Api-Key: !secret octoprint_api_key
I added a 30sec delay to the octopi soft-off because, yes i managed to ruin a print by accidentally clicking it.
This delay also turns the ui from āexecuteā into a toggle and allows me to add a lock to it.
Custom sensors rewriting time to be readable as octoprint component reads them in seconds (stolen from these forums / dont remember the user to quote, sorry):
sensor: #fix time display
- platform: template
sensors:
octoprint_time_elapsed_format:
friendly_name: 'Printing Time Elapsed'
value_template: >-
{% set etime = states.sensor.octoprint_time_elapsed.state | int %}
{% set seconds = etime % 60 %}
{% set minutes = ((etime % 3600) / 60) | int %}
{% set hours = ((etime % 86400) / 3600) | int %}
{% set days = (etime / 86400) | int %}
{%- if days > 0 -%}
{%- if days == 1 -%}
1 day
{%- else -%}
{{ days }} days
{%- endif -%}
{{ ', ' }}
{%- endif -%}
{%- if hours > 0 -%}
{%- if hours == 1 -%}
1 hour
{%- else -%}
{{ hours }} hours
{%- endif -%}
{{ ', ' }}
{%- endif -%}
{%- if minutes > 0 -%}
{%- if minutes == 1 -%}
1 minute
{%- else -%}
{{ minutes }} minutes
{%- endif -%}
{%- endif -%}
octoprint_time_remaining_format:
friendly_name: 'Printing Time Remaining'
value_template: >-
{% set rtime = states.sensor.octoprint_time_remaining.state | int %}
{% set seconds = rtime % 60 %}
{% set minutes = ((rtime % 3600) / 60) | int %}
{% set hours = ((rtime % 86400) / 3600) | int %}
{% set days = (rtime / 86400) | int %}
{%- if days > 0 -%}
{%- if days == 1 -%}
1 day
{%- else -%}
{{ days }} days
{%- endif -%}
{{ ', ' }}
{%- endif -%}
{%- if hours > 0 -%}
{%- if hours == 1 -%}
1 hour
{%- else -%}
{{ hours }} hours
{%- endif -%}
{{ ', ' }}
{%- endif -%}
{%- if minutes > 0 -%}
{%- if minutes == 1 -%}
1 minute
{%- else -%}
{{ minutes }} minutes
{%- endif -%}
{%- endif -%}
Automations to handle print start / progress / end and printer idle, along with android actionable notifications for canceling shutdown:
automation:
#print start
- alias: 3DP Send me a notification when the print starts
trigger:
platform: state
entity_id: sensor.octoprint_current_state
from: 'Operational'
to: 'Printing'
action:
- service: notify.mobile_app_sm_g975f
data:
message: "Printing Started"
#print 50%
- alias: 3DP Send me a notification when the print is above 50%
trigger:
platform: numeric_state
entity_id: sensor.octoprint_job_percentage
above: 50
action:
service: notify.mobile_app_sm_g975f
data:
message: "Print is at {{states.sensor.octoprint_job_percentage.state}}%"
#print finish
- alias: 3DP Send me a notification when the print is finished AND TURN OFF PRINTER
trigger:
platform: state
entity_id: sensor.octoprint_current_state
from: 'Printing'
to: 'Operational'
action:
- service: notify.mobile_app_sm_g975f
data:
message: "Print finished, Shutting down in 10"
data:
actions:
- action: kill_script_3dprint_off
title: Cancel Shutdown
- service: homeassistant.turn_on
entity_id: script.3dprint_off
#print Idle
- alias: 3DP Send me a notification when the printer is idle AND TURN OFF PRINTER
trigger:
platform: state
entity_id: sensor.octoprint_current_state
to: 'Operational'
for: 01:20:00
action:
- service: notify.mobile_app_sm_g975f
data:
message: "Printer Idle, Shutting down in 10"
data:
actions:
- action: kill_script_3dprint_off
title: Cancel Shutdown
- service: homeassistant.turn_on
entity_id: script.3dprint_off
#handle actionable notification replies
- alias: 3DP Action from Notify - Cancel 3DP shutdown
id: kill_scrip_3dprint_off_after_actionable_notification
trigger:
platform: event
event_type: mobile_app_notification_action
event_data:
action: kill_script_3dprint_off
action:
- service: script.turn_off
entity_id: script.3dprint_off
#Cancel shutdown if the printer has changed status since last print finished
- id: 'kill_script_if_im_playing'
alias: Cancel printer shutdown if im playing
trigger:
- entity_id: sensor.octoprint_current_state
from: Operational
platform: state
condition:
- condition: state
entity_id: script.3dprint_off
state: 'on'
action:
- entity_id: script.3dprint_off
service: script.turn_off
Lovelace UI:
- auto-entities card (HACS) that shows up only if thereās some error. (i actually use this on my main ui page to display alerts like doors open or devices low bat, itās pretty useful)
- Main switches locked with toggle-lock-entity-row (HACS) to avoid banging my head on the desk after turning stuff off mid-print
- A link to open octoprint in a new tab
- Camera stream from octoprint
- Several info from the octoprint plug in - job percentage, time remaining etc.
- Printer sensors displayed nicely with mini-graph-card(HACS) with nice colors and stuff ^^
- Filament box, filled with silica to preserve filaments. Its sensors also displayed with mini-graph-card
- Power consumption data from the smart plug (which also reports temperature but itās internal, so no practical data there, besides safety i guess?)
Here is my whole tab, copied from the raw config section:
- badges: []
cards:
- card:
title: Octoprint ERROR
type: entities
filter:
include:
- entity_id: binary_sensor.octopr*error*
state: 'on'
show_empty: false
show_header_toggle: false
type: 'custom:auto-entities'
- entities:
- entity: switch.d_link_smart_plug
type: 'custom:toggle-lock-entity-row'
- entity: script.octopi_off
type: 'custom:toggle-lock-entity-row'
- entity: script.3dprint_off
name: Shutdown Octopi then Printer (10m)
type: 'custom:toggle-lock-entity-row'
- icon: 'mdi:printer-3d'
name: OctoPrint
type: weblink
url: 'http://octopi.local'
show_header_toggle: false
type: entities
- aspect_ratio: 50%
camera_image: camera.octoprint
entity: camera.octoprint
image: 'http://octopi.local/webcam/?action=snapshot'
show_name: false
show_state: false
type: picture-entity
- entities:
- entity: sensor.octoprint_job_percentage
- entity: sensor.octoprint_time_remaining_format
- entity: sensor.octoprint_time_elapsed_format
title: Job
type: entities
- entities:
- entity: sensor.octoprint_current_state
- entity: binary_sensor.octoprint_printing
- entity: binary_sensor.octoprint_printing_error
- entity: sensor.d_link_plug_temperature
title: Status
type: entities
- entities:
- entity: sensor.d_link_plug_current_power_w
name: Current Power
- entity: sensor.d_link_plug_total_consumption
name: Total Power
color: gray
y_axis: secondary
hours_to_show: 24
color_thresholds:
- value: 50
color: green
- value: 100
color: orange
- value: 150
color: red
line_width: 3
show:
labels: true
legend: false
labels_secondary: true
icon: 'mdi:printer-3d'
name: Power Consumption
type: 'custom:mini-graph-card'
- entities:
- entity: sensor.humidity_158d00046546d8
name: Box Humidity
- entity: sensor.temperature_158d00046546d8
name: Box Temp
color: gray
y_axis: secondary
hours_to_show: 24
line_width: 3
color_thresholds:
- value: 18
color: green
- value: 22
color: orange
- value: 100
color: red
show:
labels: true
legend: false
name_adaptive_color: false
labels_secondary: true
icon: 'mdi:water-percent'
name: Filament Box Humidity / Temp
type: 'custom:mini-graph-card'
- entities:
- entity: sensor.octoprint_actual_bed_temp
name: Current Temp
color: orange
- entity: sensor.octoprint_target_bed_temp
color: skyblue
name: Target Temp
hours_to_show: 24
line_width: 3
color_thresholds:
- value: 35
color: white
- value: 40
color: green
- value: 49
color: orange
- value: 70
color: red
show:
labels: hover
legend: false
name_adaptive_color: false
icon: 'mdi:temperature-celsius'
name: Bed Temp
type: 'custom:mini-graph-card'
- entities:
- entity: sensor.octoprint_actual_tool0_temp
name: Current Temp
color: orange
- entity: sensor.octoprint_target_tool0_temp
color: darkred
name: Target Temp
hours_to_show: 24
line_width: 3
color_thresholds:
- value: 35
color: white
- value: 179
color: green
- value: 220
color: orange
- value: 300
color: red
show:
labels: hover
legend: false
name_adaptive_color: false
icon: 'mdi:temperature-celsius'
name: Hotend Temp
type: 'custom:mini-graph-card'
icon: 'mdi:printer-3d'
path: 3dp
title: 3DP
The whole file octoprint.yaml is in my packages folder:
octoprint:
host: !secret octoprint_host
api_key: !secret octoprint_api_key
bed: true
number_of_tools: 2
#shutdown octopi RPI
rest_command:
shutdown_octoprint:
url: http://octopi.local/api/system/commands/core/shutdown
method: POST
headers:
X-Api-Key: !secret octoprint_api_key
#notifications and commands regarding printer
automation:
- alias: 3DP Send me a notification when the print starts
trigger:
platform: state
entity_id: sensor.octoprint_current_state
from: 'Operational'
to: 'Printing'
action:
- service: notify.mobile_app_sm_g975f
data:
message: "Printing Started"
- alias: 3DP Send me a notification when the print is above 50%
trigger:
platform: numeric_state
entity_id: sensor.octoprint_job_percentage
above: 50
action:
service: notify.mobile_app_sm_g975f
data:
message: "Print is at {{states.sensor.octoprint_job_percentage.state}}%"
- alias: 3DP Send me a notification when the print is finished AND TURN OFF PRINTER
trigger:
platform: state
entity_id: sensor.octoprint_current_state
from: 'Printing'
to: 'Operational'
action:
- service: notify.mobile_app_sm_g975f
data:
message: "Print finished, Shutting down in 10"
data:
actions:
- action: kill_script_3dprint_off
title: Cancel Shutdown
- service: homeassistant.turn_on
entity_id: script.3dprint_off
- alias: 3DP Send me a notification when the printer is idle AND TURN OFF PRINTER
trigger:
platform: state
entity_id: sensor.octoprint_current_state
to: 'Operational'
for: 01:20:00
action:
- service: notify.mobile_app_sm_g975f
data:
message: "Printer Idle, Shutting down in 10"
data:
actions:
- action: kill_script_3dprint_off
title: Cancel Shutdown
- service: homeassistant.turn_on
entity_id: script.3dprint_off
- alias: 3DP Action from Notify - Cancel 3DP shutdown
id: kill_scrip_3dprint_off_after_actionable_notification
trigger:
platform: event
event_type: mobile_app_notification_action
event_data:
action: kill_script_3dprint_off
action:
- service: script.turn_off
entity_id: script.3dprint_off
- id: 'kill_script_if_im_playing'
alias: Cancel printer shutdown if im playing
trigger:
- entity_id: sensor.octoprint_current_state
from: Operational
platform: state
condition:
- condition: state
entity_id: script.3dprint_off
state: 'on'
action:
- entity_id: script.3dprint_off
service: script.turn_off
script:
3dprint_off:
alias: ĀØTurn off 3d printer after 10 minutesĀØ
sequence:
- delay:
minutes: 10 #release
# seconds: 10 #production
- condition: state
entity_id: sensor.octoprint_current_state
state: 'Operational'
- service: rest_command.shutdown_octoprint
- service: notify.mobile_app_sm_g975f
data:
message: "Octopi is Down, Printer is next"
- delay:
seconds: 30
- service: switch.turn_off
data:
entity_id: switch.d_link_smart_plug
octopi_off:
alias: "Soft Shutdown Octopi"
sequence:
- delay:
seconds: 30
- service: rest_command.shutdown_octoprint
sensor: #fix time display
- platform: template
sensors:
octoprint_time_elapsed_format:
friendly_name: 'Printing Time Elapsed'
value_template: >-
{% set etime = states.sensor.octoprint_time_elapsed.state | int %}
{% set seconds = etime % 60 %}
{% set minutes = ((etime % 3600) / 60) | int %}
{% set hours = ((etime % 86400) / 3600) | int %}
{% set days = (etime / 86400) | int %}
{%- if days > 0 -%}
{%- if days == 1 -%}
1 day
{%- else -%}
{{ days }} days
{%- endif -%}
{{ ', ' }}
{%- endif -%}
{%- if hours > 0 -%}
{%- if hours == 1 -%}
1 hour
{%- else -%}
{{ hours }} hours
{%- endif -%}
{{ ', ' }}
{%- endif -%}
{%- if minutes > 0 -%}
{%- if minutes == 1 -%}
1 minute
{%- else -%}
{{ minutes }} minutes
{%- endif -%}
{%- endif -%}
octoprint_time_remaining_format:
friendly_name: 'Printing Time Remaining'
value_template: >-
{% set rtime = states.sensor.octoprint_time_remaining.state | int %}
{% set seconds = rtime % 60 %}
{% set minutes = ((rtime % 3600) / 60) | int %}
{% set hours = ((rtime % 86400) / 3600) | int %}
{% set days = (rtime / 86400) | int %}
{%- if days > 0 -%}
{%- if days == 1 -%}
1 day
{%- else -%}
{{ days }} days
{%- endif -%}
{{ ', ' }}
{%- endif -%}
{%- if hours > 0 -%}
{%- if hours == 1 -%}
1 hour
{%- else -%}
{{ hours }} hours
{%- endif -%}
{{ ', ' }}
{%- endif -%}
{%- if minutes > 0 -%}
{%- if minutes == 1 -%}
1 minute
{%- else -%}
{{ minutes }} minutes
{%- endif -%}
{%- endif -%}