automations.yaml

This commit is contained in:
Home Assistant Version Control
2026-10-14 17:28:43 +00:00
parent bac81fd7cd
commit 9dc8b9f5a4
+51 -24
View File
@@ -4776,11 +4776,12 @@
- id: '1791477238799'
alias: SparkX i7 - Filament sufficiency check at print start
description: >-
When a print starts and stays printing for 45 s, compares the loaded CFS Lite
spools against the slicer's filament requirement. A single-material job is
checked exactly against its reported weight; a multi-material job has no
per-colour figure, so each loaded spool is compared against the whole job
total (worst case). Always sends a notification.
When a print starts and stays printing for 45 s, reports how much filament the
job needs, how much has already been used and how much is left, then compares
the loaded CFS Lite spools against that. A single-colour job whose colour is in
a loaded slot is checked exactly against that slot's spool; otherwise the
slicer gives no per-colour figure, so each loaded spool is compared against the
whole job total. Always sends a notification.
triggers:
- trigger: state
entity_id: sensor.sparkx_i7_print_status
@@ -4793,49 +4794,75 @@
length_cm: "{{ states('sensor.sparkx_i7_expected_material_length') | float(0) }}"
weight_g: "{{ states('sensor.sparkx_i7_expected_material_weight') | float(0) }}"
job_g: "{{ ((weight_g | float) if (weight_g | float) > 0 else (length_cm | float) * (gcm | float)) | round(1) }}"
gcol: "{{ state_attr('sensor.sparkx_i7_expected_material_length', 'color') | default('', true) | string | replace('#', '') | lower }}"
mono: "{{ (weight_g | float) > 0 and (gcol | length) <= 6 }}"
used_len: "{{ states('sensor.sparkx_i7_used_material_length') | float(0) }}"
used_g: "{{ (((used_len | float) * (gcm | float)) | round(1)) }}"
gcode_file: "{{ state_attr('sensor.sparkx_i7_expected_material_length', 'gcode_file') | default('', true) }}"
- variables:
report: |-
{% set ns = namespace(req=[], short=[], missing=[], loaded=[], avail=0) %}
{% set cols = namespace(list=[]) %}
{% for n in ['1','2','3','4'] %}{% set cc = states('sensor.sparkx_i7_cfs_box_1_slot_' ~ n ~ '_color') | replace('#','') | lower %}{% if cc not in ['','none','unknown','unavailable'] %}{% set cols.list = cols.list + [cc] %}{% endif %}{% endfor %}
{% set per_slot = gcol if (mono and gcol != '' and gcol in cols.list) else '' %}
{% set mono_offline = mono and gcol != '' and gcol not in cols.list %}
{% set gc = namespace(list=[]) %}
{% for p in (state_attr('sensor.sparkx_i7_expected_material_length','color') | default('', true) | string).split(';') %}{% set q = p | replace('#','') | lower | trim %}{% if q not in ['','none','unknown','unavailable'] %}{% set gc.list = gc.list + [q] %}{% endif %}{% endfor %}
{% set mc = namespace(list=[]) %}
{% for p in (state_attr('sensor.sparkx_i7_expected_material_length','material') | default('', true) | string).split(';') %}{% set q = p | trim %}{% if q not in ['','none','unknown','unavailable'] %}{% set mc.list = mc.list + [q] %}{% endif %}{% endfor %}
{% set single = (gc.list | length) == 1 %}
{% set gcol = gc.list[0] if single else '' %}
{% set rem_g = ([((job_g | float) - (used_g | float)), 0] | max) | round(1) %}
{% set ns = namespace(cover=[], below=[], short=[], ok=[], missing=[], loaded=[], match_label='', match_rem=0) %}
{% for n in ['1','2','3','4'] %}
{% set c = states('sensor.sparkx_i7_cfs_box_1_slot_' ~ n ~ '_color') | replace('#','') | lower %}
{% if c not in ['','none','unknown','unavailable'] %}
{% set cname = states('sensor.sparkx_i7_slot_' ~ n ~ '_color_name') %}
{% set flabel = states('sensor.sparkx_i7_cfs_box_1_slot_' ~ n ~ '_filament') %}
{% set label = 'Slot ' ~ n ~ ' ' ~ (cname if cname not in ['','unknown','unavailable'] else (flabel if flabel not in ['','unknown','unavailable'] else ('#' ~ (c | upper)))) %}
{% set sp = namespace(id='', rem=0) %}
{% set sp = namespace(id='', rem=0, fw=0) %}
{% for e in integration_entities('spoolman') if e.endswith('_color_hex') %}
{% if sp.id == '' and (states(e) | replace('#','') | lower) == c and (state_attr(e[:-10],'location') | default('', true) | lower) == 'cfs lite' %}
{% set sp.id = e[:-10] %}
{% set sp.rem = states(e[:-10]) | float(0) %}
{% set sp.fw = state_attr(e[:-10],'filament_weight') | float(0) %}
{% endif %}
{% endfor %}
{% if sp.id != '' %}{% set ns.avail = ns.avail + sp.rem %}{% set ns.loaded = ns.loaded + [label ~ ': ' ~ (sp.rem | round(1)) ~ ' g'] %}{% endif %}
{% if job_g > 0 %}
{% set req = job_g if (per_slot == '' or c == per_slot) else 0 %}
{% if req > 0 %}
{% if sp.id == '' %}{% set ns.missing = ns.missing + [label ~ ' (#' ~ (c | upper) ~ ')'] %}
{% elif sp.rem < req %}{% set ns.short = ns.short + [label ~ ': ' ~ (sp.rem | round(1)) ~ ' g left, up to ' ~ req ~ ' g needed'] %}
{% else %}{% set ns.req = ns.req + [label ~ ': ' ~ (sp.rem | round(1)) ~ ' g left, up to ' ~ req ~ ' g needed'] %}{% endif %}
{% set pct = ((((sp.rem | float) / (sp.fw | float)) * 100) | round(0) | int) if (sp.fw | float) > 0 else 0 %}
{% if sp.id != '' %}{% set ns.loaded = ns.loaded + [label ~ ': ' ~ (sp.rem | round(1)) ~ ' g (' ~ pct ~ '%)'] %}{% endif %}
{% if sp.id != '' and single and c == gcol %}{% set ns.match_label = label %}{% set ns.match_rem = sp.rem %}{% endif %}
{% if sp.id != '' %}
{% if single and c == gcol %}
{% if (sp.rem | float) < (job_g | float) %}{% set ns.short = ns.short + [label ~ ': ' ~ (sp.rem | round(1)) ~ ' g (' ~ pct ~ '%) left, ' ~ job_g ~ ' g needed'] %}
{% else %}{% set ns.ok = ns.ok + [label ~ ': ' ~ (sp.rem | round(1)) ~ ' g (' ~ pct ~ '%) left, ' ~ job_g ~ ' g needed'] %}{% endif %}
{% elif single %}
{% if (sp.rem | float) >= (job_g | float) %}{% set ns.cover = ns.cover + [label ~ ': ' ~ (sp.rem | round(1)) ~ ' g (' ~ pct ~ '%)'] %}
{% else %}{% set ns.below = ns.below + [label ~ ': ' ~ (sp.rem | round(1)) ~ ' g (' ~ pct ~ '%)'] %}{% endif %}
{% else %}
{% if (sp.rem | float) < (job_g | float) %}{% set ns.short = ns.short + [label ~ ': ' ~ (sp.rem | round(1)) ~ ' g (' ~ pct ~ '%) left, up to ' ~ job_g ~ ' g needed'] %}
{% else %}{% set ns.ok = ns.ok + [label ~ ': ' ~ (sp.rem | round(1)) ~ ' g (' ~ pct ~ '%) left, up to ' ~ job_g ~ ' g needed'] %}{% endif %}
{% endif %}
{% elif job_g > 0 %}
{% set ns.missing = ns.missing + [label ~ ' (#' ~ (c | upper) ~ ')'] %}
{% endif %}
{% endif %}
{% endfor %}
Job: {{ gcode_file if gcode_file not in ['','unknown','unavailable'] else (state_attr('sensor.sparkx_i7_print_status','file') | default('', true) | string).split('/')[-1] }}
Needs {{ job_g | round(1) }} g ({{ length_cm | round(1) }} cm) · used {{ used_g }} g · {{ rem_g }} g left to print
Slicer: {{ (mc.list | join(', ')) if mc.list else 'material unknown' }} · {{ ('single colour #' ~ (gcol | upper)) if single else ((gc.list | length) ~ ' colours') }}
{% if job_g <= 0 %}Cannot verify: slicer filament estimate not available yet.{% if ns.loaded %} Loaded: {{ ns.loaded | join('; ') }}.{% endif %}
{% elif mono_offline %}Cannot verify: this looks like a single-colour print of #{{ gcol | upper }}, which is not in a loaded CFS slot.
{% elif single and gcol in cols.list %}
{% if ns.short %}NOT ENOUGH filament:
{{ ns.short | join('\n') }}
{% elif ns.match_label %}Enough filament: {{ ns.match_label }}: {{ ns.match_rem | round(1) }} g left, {{ job_g }} g needed.
{% else %}Matched slot {{ gcol | upper }} has no Spoolman spool at CFS Lite, so remaining cannot be checked.{% endif %}
{% elif single %}No exact colour match for the print colour #{{ gcol | upper }} in a loaded CFS slot, so the exact spool cannot be identified.{% if ns.cover %}
Would cover {{ job_g }} g: {{ ns.cover | join('; ') }}{% endif %}{% if ns.below %}
Below {{ job_g }} g: {{ ns.below | join('; ') }}{% endif %}{% if not ns.cover and not ns.below %}
No loaded CFS slot has a matching Spoolman spool to compare.{% endif %}
{% elif ns.short %}NOT ENOUGH filament - possible shortfall:
{{ ns.short | join('\n') }}{% if ns.req %}
OK: {{ ns.req | join('; ') }}{% endif %}{% if ns.missing %}
{{ ns.short | join('\n') }}{% if ns.ok %}
OK (would still cover the whole job): {{ ns.ok | join('; ') }}{% endif %}{% if ns.missing %}
No Spoolman spool matched for: {{ ns.missing | join(', ') }}{% endif %}
{% elif ns.req %}Enough filament:
{{ ns.req | join('\n') }}{% if ns.missing %}
{% elif ns.ok %}Enough filament:
{{ ns.ok | join('\n') }}{% if ns.missing %}
No Spoolman spool matched for: {{ ns.missing | join(', ') }}{% endif %}
{% else %}Cannot verify: could not match this job's filament to a loaded CFS slot.{% endif %}
{% elif ns.missing %}Could not match any loaded CFS slot to a Spoolman spool.{% endif %}
- action: notify.persistent_notification
data:
title: Print started - filament check