automations.yaml
This commit is contained in:
+51
-24
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user