# ha_mcp_backup schema_version: 1 domain: dashboard entity_id: sparkx-i7 captured: '2026-10-09T00:29:25.128399+00:00' tool: ha_config_set_dashboard config: views: - max_columns: 4 path: print sections: - cards: - bed: sensor.sparkx_i7_bed_temperature camera: camera.sparkx_i7_printer_camera grid_options: columns: full layer: sensor.sparkx_i7_working_layer light: light.sparkx_i7_light name: SparkX i7 nozzle: sensor.sparkx_i7_nozzle_temperature pause_btn: button.sparkx_i7_pause_print progress: sensor.sparkx_i7_print_progress resume_btn: button.sparkx_i7_resume_print status: sensor.sparkx_i7_print_status stop_btn: button.sparkx_i7_stop_print time_left: sensor.sparkx_i7_print_time_left total_layers: sensor.sparkx_i7_total_layers type: custom:k-printer-card - grid_options: columns: full type: custom:webrtc-camera ui: true url: octoprint - grid_options: columns: full type: custom:webrtc-camera ui: true url: octoprint2 - camera_image: camera.sparkx_i7_printer_camera camera_view: live entity: camera.sparkx_i7_printer_camera fit_mode: cover grid_options: columns: full show_name: true show_state: true type: picture-entity - cards: - grid_options: columns: 6 image_entity: image.sparkx_i7_current_print_preview show_name: false type: picture - entity: sensor.sparkx_i7_active_filament_slot icon: mdi:palette icon_color: '{% set color = state_attr(''sensor.sparkx_i7_active_filament_slot'', ''color'') | default('''') | string %}{% set core = color | replace(''#'', '''') %}{% if core | length >= 6 %}#{{ core[-6:] }}{% else %}var(--primary-text-color){% endif %}' multiline_secondary: true name: Active Color primary: '{% set slot = states(''sensor.sparkx_i7_active_filament_slot'') %}{% if ''Slot 1'' in slot %}{{ states(''sensor.sparkx_i7_slot_1_color_name'') }}{% elif ''Slot 2'' in slot %}{{ states(''sensor.sparkx_i7_slot_2_color_name'') }}{% elif ''Slot 3'' in slot %}{{ states(''sensor.sparkx_i7_slot_3_color_name'') }}{% elif ''Slot 4'' in slot %}{{ states(''sensor.sparkx_i7_slot_4_color_name'') }}{% elif slot == ''External'' %}{{ states(''sensor.sparkx_i7_external_color_name'') }}{% else %}Unknown{% endif %}' secondary: "{% set slot = states('sensor.sparkx_i7_active_filament_slot')\ \ %}{{ slot }}{% if state_attr('sensor.sparkx_i7_active_filament_slot',\ \ 'filament') %} \xB7 {{ state_attr('sensor.sparkx_i7_active_filament_slot',\ \ 'filament') }}{% endif %}" type: custom:mushroom-template-card grid_options: columns: full type: horizontal-stack - entity: sensor.sparkx_i7_print_status grid_options: columns: 12 icon: mdi:state-machine name: Status type: tile - entity: sensor.sparkx_i7_position_z_2_decimals grid_options: columns: 4 icon: mdi:axis-z-arrow name: Current Z type: tile - entity: sensor.sparkx_i7_position_x grid_options: columns: 4 icon: mdi:axis-x-arrow name: X type: tile - entity: sensor.sparkx_i7_position_y grid_options: columns: 4 icon: mdi:axis-y-arrow name: Y type: tile - entity: sensor.sparkx_i7_print_status grid_options: columns: 6 icon: mdi:message-alert-outline multiline_secondary: true name: Printer Message primary: '{{ states("sensor.sparkx_i7_print_status") | replace("_", " ") | title }}' secondary: '{% set err = state_attr("sensor.sparkx_i7_print_status", "err") or {} %}{% set code = err.get("errcode", 0) | int(0) %}{% set msg = err.get("value", "") %}{% if state_attr("sensor.sparkx_i7_print_status", "paused_flag") | default(false) %}Print paused{% elif msg %}ERROR {{ code }}: {{ msg }}{% elif code %}Printer error {{ code }}{% else %}No printer error{% endif %}' type: custom:mushroom-template-card - entity: sensor.sparkx_i7_print_status grid_options: columns: 6 icon: mdi:file-document-outline multiline_secondary: true name: Current File primary: Current File secondary: '{% set file = state_attr("sensor.sparkx_i7_print_status", "file") or "" %}{% if file %}{{ file.split("/")[-1] | replace(".gcode", "") }}{% else %}No active file{% endif %}' type: custom:mushroom-template-card type: grid - cards: - heading: Print Progress icon: mdi:progress-clock type: heading - entity: sensor.sparkx_i7_print_progress grid_options: columns: 6 rows: 3 max: 100 min: 0 name: Progress severity: green: 0 red: 90 yellow: 40 type: gauge unit: '%' - grid_options: columns: 6 icon: mdi:clock-start multiline_secondary: true name: Elapsed primary: Elapsed secondary: '{% set s = states(''sensor.sparkx_i7_print_job_time'') | float(0) %}{% set h = (s / 3600) | int %}{% set m = ((s % 3600) / 60) | int %}{% if h %}{{ h }} hr {{ m }} min{% else %}{{ m }} min{% endif %}' type: custom:mushroom-template-card - grid_options: columns: 6 icon: mdi:clock-end multiline_secondary: true name: Remaining primary: Remaining secondary: '{% set s = states(''sensor.sparkx_i7_print_time_left'') | float(-1) %}{% if s <= 0 %}No estimate{% else %}{% set h = (s / 3600) | int %}{% set m = ((s % 3600) / 60) | int %}{% if h %}{{ h }} hr {{ m }} min{% else %}{{ m }} min{% endif %}{% endif %}' type: custom:mushroom-template-card - grid_options: columns: 6 icon: mdi:clock-outline multiline_secondary: true primary: Est. Finish secondary: "{% set left = states('sensor.sparkx_i7_print_time_left') | int(0)\ \ %}{% if left > 0 %}{{ (now() + timedelta(seconds=left)).strftime('%I:%M\ \ %p').lstrip('0') }}{% else %}\u2014{% endif %}" type: custom:mushroom-template-card - grid_options: columns: 6 icon: mdi:layers multiline_secondary: true name: Layer primary: Layer secondary: '{% set c = states(''sensor.sparkx_i7_working_layer'') | int(0) %}{% set t = states(''sensor.sparkx_i7_total_layers'') | int(0) %}{{ c }} of {{ t }}' type: custom:mushroom-template-card - entity: light.sparkx_i7_light grid_options: columns: 6 icon: mdi:lightbulb name: Printer Light type: tile - detail: 1 entity: sensor.sparkx_i7_print_progress graph: line grid_options: columns: full hours_to_show: 24 name: Progress History type: sensor - entity: number.sparkx_i7_print_tuning grid_options: columns: 6 icon: mdi:speedometer name: Print Tuning type: tile - entity: sensor.sparkx_i7_print_speed grid_options: columns: 6 icon: mdi:speedometer name: Speed type: tile - entity: sensor.sparkx_i7_real_time_flow grid_options: columns: 6 icon: mdi:cube-send name: Real-Time Flow type: tile - entity: sensor.sparkx_i7_flow_rate grid_options: columns: 6 icon: mdi:chart-gantt name: Flow Rate type: tile - entity: sensor.sparkx_i7_current_object grid_options: columns: 6 icon: mdi:cube-outline name: Object type: tile - entity: sensor.sparkx_i7_object_count grid_options: columns: 6 icon: mdi:counter name: Object Count type: tile type: grid - cards: - heading: Temperatures icon: mdi:thermometer type: heading - entity: sensor.sparkx_i7_nozzle_temperature grid_options: columns: 4 max: 300 min: 0 name: Nozzle severity: green: 0 red: 240 yellow: 180 type: gauge unit: "\xB0C" - entity: sensor.sparkx_i7_bed_temperature grid_options: columns: 4 max: 100 min: 0 name: Bed severity: green: 0 red: 100 yellow: 60 type: gauge unit: "\xB0C" - entity: number.sparkx_i7_nozzle_target grid_options: columns: 6 icon: mdi:printer-3d-nozzle name: Nozzle Target type: tile - entity: number.sparkx_i7_bed_target grid_options: columns: 6 icon: mdi:radiator name: Bed Target type: tile - entities: - color: '#ef5350' entity: sensor.sparkx_i7_nozzle_temperature name: Actual - color: '#4caf50' entity: number.sparkx_i7_nozzle_target name: Target expand_legend: true grid_options: columns: full hours_to_show: 24 show_names: true title: Nozzle Temperature type: history-graph - entities: - color: '#42a5f5' entity: sensor.sparkx_i7_bed_temperature name: Actual - color: '#4caf50' entity: number.sparkx_i7_bed_target name: Target expand_legend: true grid_options: columns: full hours_to_show: 24 show_names: true title: Bed Temperature type: history-graph type: grid - cards: - heading: Controls icon: mdi:gesture-tap-button type: heading - entity: button.sparkx_i7_pause_print grid_options: columns: 4 icon: mdi:pause name: Pause tap_action: action: perform-action perform_action: button.press target: entity_id: button.sparkx_i7_pause_print type: tile - entity: button.sparkx_i7_resume_print grid_options: columns: 4 icon: mdi:play name: Resume tap_action: action: perform-action perform_action: button.press target: entity_id: button.sparkx_i7_resume_print type: tile - entity: button.sparkx_i7_reconnect grid_options: columns: 4 icon: mdi:lan-connect name: Connect tap_action: action: perform-action perform_action: button.press target: entity_id: button.sparkx_i7_reconnect type: tile - entity: button.sparkx_i7_stop_print grid_options: columns: 4 icon: mdi:cancel name: Cancel Print tap_action: action: perform-action perform_action: button.press target: entity_id: button.sparkx_i7_stop_print type: tile - entity: button.sparkx_i7_home_xy_then_z grid_options: columns: 4 icon: mdi:home-circle name: Home tap_action: action: perform-action perform_action: button.press target: entity_id: button.sparkx_i7_home_xy_then_z type: tile type: grid - cards: - heading: Filament icon: mdi:printer-3d-nozzle-outline type: heading - entity: sensor.sparkx_i7_filament_weight_estimated grid_options: columns: 6 icon: '{% set st = states(''sensor.sparkx_i7_print_status'') %}{% if st in [''printing'', ''paused''] %}mdi:printer-3d-nozzle{% else %}mdi:calendar-today{% endif %}' multiline_secondary: true name: Filament Used primary: '{% set st = states(''sensor.sparkx_i7_print_status'') %}{% if st in [''printing'', ''paused''] %}{{ states(''sensor.sparkx_i7_filament_weight_estimated'') | round(1) }} g{% else %}No active job{% endif %}' secondary: "{% set st = states('sensor.sparkx_i7_print_status') %}{% if st\ \ in ['printing', 'paused'] %}{{ states('sensor.sparkx_i7_used_material_length')\ \ | round(0) }} cm this job{% else %}{{ states('sensor.sparkx_i7_filament_weight_daily')\ \ | round(1) }} g \xB7 {{ states('sensor.sparkx_i7_filament_cost_daily')\ \ | round(2) }} $ today{% endif %}" type: custom:mushroom-template-card - entity: input_number.sparkx_i7_filament_g_cm grid_options: columns: 6 icon: mdi:weight-kilogram name: g/cm type: tile - entity: sensor.sparkx_i7_used_material_length grid_options: columns: 6 icon: mdi:counter multiline_secondary: true name: Used Length primary: '{% set st = states(''sensor.sparkx_i7_print_status'') %}{% if st in [''printing'', ''paused''] %}{{ states(''sensor.sparkx_i7_used_material_length'') | round(0) }} cm{% else %}{{ (states(''sensor.sparkx_i7_filament_weight_daily'') | float(0) / states(''input_number.sparkx_i7_filament_g_cm'') | float(0.0298)) | round(0) }} cm{% endif %}' secondary: '{% set st = states(''sensor.sparkx_i7_print_status'') %}{% if st in [''printing'', ''paused''] %}this job (printer-reported){% else %}today, from today''s weight{% endif %}' type: custom:mushroom-template-card - entity: sensor.sparkx_i7_filament_cost grid_options: columns: 3 icon: mdi:cash name: Job Cost (total) type: tile - entity: sensor.sparkx_i7_filament_cost_daily grid_options: columns: 3 icon: mdi:cash-multiple name: Today type: tile - entity: sensor.sparkx_i7_filament_cost_weekly grid_options: columns: 3 icon: mdi:cash-multiple name: This Week type: tile - entity: sensor.sparkx_i7_filament_cost_monthly grid_options: columns: 3 icon: mdi:cash-multiple name: This Month type: tile type: grid title: Print type: sections - max_columns: 2 path: history sections: - cards: - heading: Temperature History icon: mdi:chart-line-variant type: heading - entities: - color: '#ef5350' entity: sensor.sparkx_i7_nozzle_temperature name: Nozzle - color: '#ffab91' entity: number.sparkx_i7_nozzle_target name: Nozzle Target - color: '#42a5f5' entity: sensor.sparkx_i7_bed_temperature name: Bed - color: '#90caf9' entity: number.sparkx_i7_bed_target name: Bed Target expand_legend: true grid_options: columns: full hours_to_show: 24 show_names: true title: Temperatures (24h) type: history-graph - entities: - color: '#ef5350' entity: sensor.sparkx_i7_nozzle_temperature name: Nozzle - color: '#42a5f5' entity: sensor.sparkx_i7_bed_temperature name: Bed expand_legend: true grid_options: columns: full hours_to_show: 168 show_names: true title: Temperatures (7 days) type: history-graph type: grid - cards: - heading: Print Activity icon: mdi:chart-box-outline type: heading - apex_config: chart: height: 300 stroke: width: 1 graph_span: 24h grid_options: columns: full header: colorize_states: true show: true show_states: true title: Z Position (24h) series: - color: '#ab47bc' curve: straight entity: sensor.sparkx_i7_position_z fill_raw: last name: Current Z type: line type: custom:apexcharts-card - entities: - color: '#66bb6a' entity: sensor.sparkx_i7_print_progress name: Progress grid_options: columns: full hours_to_show: 24 show_names: true title: Print Progress (24h) type: history-graph - entities: - color: '#26c6da' entity: sensor.sparkx_i7_print_job_time name: Elapsed - color: '#ffa726' entity: sensor.sparkx_i7_print_time_left name: Remaining grid_options: columns: full hours_to_show: 24 show_names: true title: Print Duration (24h) type: history-graph type: grid title: History type: sections - icon: mdi:printer-3d-nozzle-outline max_columns: 4 path: cfs-fans sections: - cards: - heading: CFS Box 1 icon: mdi:file-cabinet type: heading - entity: sensor.sparkx_i7_cfs_box_1_temperature grid_options: columns: 6 icon: mdi:thermometer name: Temperature type: tile - entity: sensor.sparkx_i7_cfs_box_1_humidity grid_options: columns: 6 icon: mdi:water-percent name: Humidity type: tile - grid_options: columns: 6 icon: mdi:printer-3d-nozzle icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_1_color'')|default('''')|string %}{% set core = c|replace(''#'','''') %}{% if core|length >= 6 %}#{{ core[-6:] }}{% endif %}' multiline_secondary: true name: Slot 1 primary: '{{ states(''sensor.sparkx_i7_cfs_box_1_slot_1_filament'') }}' secondary: "{% set col = states('sensor.sparkx_i7_slot_1_color_name') %}{%\ \ if col %}{{ col }} \xB7 {% endif %}{{ states('sensor.sparkx_i7_cfs_box_1_slot_1_remaining')\ \ }}% left" type: custom:mushroom-template-card - grid_options: columns: 6 icon: mdi:printer-3d-nozzle icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_2_color'')|default('''')|string %}{% set core = c|replace(''#'','''') %}{% if core|length >= 6 %}#{{ core[-6:] }}{% endif %}' multiline_secondary: true name: Slot 2 primary: '{{ states(''sensor.sparkx_i7_cfs_box_1_slot_2_filament'') }}' secondary: "{% set col = states('sensor.sparkx_i7_slot_2_color_name') %}{%\ \ if col %}{{ col }} \xB7 {% endif %}{{ states('sensor.sparkx_i7_cfs_box_1_slot_2_remaining')\ \ }}% left" type: custom:mushroom-template-card - grid_options: columns: 6 icon: mdi:printer-3d-nozzle icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_3_color'')|default('''')|string %}{% set core = c|replace(''#'','''') %}{% if core|length >= 6 %}#{{ core[-6:] }}{% endif %}' multiline_secondary: true name: Slot 3 primary: '{{ states(''sensor.sparkx_i7_cfs_box_1_slot_3_filament'') }}' secondary: "{% set col = states('sensor.sparkx_i7_slot_3_color_name') %}{%\ \ if col %}{{ col }} \xB7 {% endif %}{{ states('sensor.sparkx_i7_cfs_box_1_slot_3_remaining')\ \ }}% left" type: custom:mushroom-template-card - grid_options: columns: 6 icon: mdi:printer-3d-nozzle icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_4_color'')|default('''')|string %}{% set core = c|replace(''#'','''') %}{% if core|length >= 6 %}#{{ core[-6:] }}{% endif %}' multiline_secondary: true name: Slot 4 primary: '{{ states(''sensor.sparkx_i7_cfs_box_1_slot_4_filament'') }}' secondary: "{% set col = states('sensor.sparkx_i7_slot_4_color_name') %}{%\ \ if col %}{{ col }} \xB7 {% endif %}{{ states('sensor.sparkx_i7_cfs_box_1_slot_4_remaining')\ \ }}% left" type: custom:mushroom-template-card type: grid - cards: - heading: External / Active icon: mdi:printer-3d type: heading - cards: - entity: sensor.sparkx_i7_active_filament_slot grid_options: columns: 6 icon: mdi:swap-horizontal name: Active Slot type: tile - entity: sensor.sparkx_i7_active_filament_slot icon: mdi:palette icon_color: '{% set color = state_attr(''sensor.sparkx_i7_active_filament_slot'', ''color'') | default('''') | string %}{% set core = color | replace(''#'', '''') %}{% if core | length >= 6 %}#{{ core[-6:] }}{% else %}var(--primary-text-color){% endif %}' multiline_secondary: true name: Active Color primary: '{% set slot = states(''sensor.sparkx_i7_active_filament_slot'') %}{% if ''Slot 1'' in slot %}{{ states(''sensor.sparkx_i7_slot_1_color_name'') }}{% elif ''Slot 2'' in slot %}{{ states(''sensor.sparkx_i7_slot_2_color_name'') }}{% elif ''Slot 3'' in slot %}{{ states(''sensor.sparkx_i7_slot_3_color_name'') }}{% elif ''Slot 4'' in slot %}{{ states(''sensor.sparkx_i7_slot_4_color_name'') }}{% elif slot == ''External'' %}{{ states(''sensor.sparkx_i7_external_color_name'') }}{% else %}Unknown{% endif %}' secondary: "{% set slot = states('sensor.sparkx_i7_active_filament_slot')\ \ %}{{ slot }}{% if state_attr('sensor.sparkx_i7_active_filament_slot',\ \ 'filament') %} \xB7 {{ state_attr('sensor.sparkx_i7_active_filament_slot',\ \ 'filament') }}{% endif %}" type: custom:mushroom-template-card grid_options: columns: full type: horizontal-stack - grid_options: columns: 6 icon: mdi:lan-outline icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_external_color'')|default('''')|string %}{% set core = c|replace(''#'','''') %}{% if core|length >= 6 %}#{{ core[-6:] }}{% endif %}' multiline_secondary: true name: External Filament primary: '{{ states(''sensor.sparkx_i7_cfs_external_filament'') }}' secondary: "{% set col = states('sensor.sparkx_i7_external_color_name') %}{%\ \ if col %}{{ col }} \xB7 {% endif %}{{ states('sensor.sparkx_i7_cfs_external_remaining')\ \ }}% left" type: custom:mushroom-template-card - entity: sensor.sparkx_i7_filament_status grid_options: columns: 6 icon: mdi:printer-3d-nozzle-alert name: Filament Status type: tile type: grid - cards: - heading: Fans icon: mdi:fan type: heading - entity: fan.sparkx_i7_model_fan features: - type: fan-speed grid_options: columns: 4 icon: mdi:fan name: Model Fan type: tile - entity: fan.sparkx_i7_case_fan features: - type: fan-speed grid_options: columns: 4 icon: mdi:fan name: Case Fan type: tile - entity: fan.sparkx_i7_side_fan features: - type: fan-speed grid_options: columns: 4 icon: mdi:fan name: Side Fan type: tile type: grid title: CFS / Fans type: sections - title: Spoolman path: spoolman icon: mdi:package-variant-closed type: sections max_columns: 4 sections: - type: grid cards: - type: heading heading: "CFS Slots \u2014 per-color deduction" icon: mdi:printer-filament - type: custom:mushroom-template-card entity: sensor.sparkx_i7_cfs_box_1_slot_1_color name: Slot 1 icon: mdi:printer-filament icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_1_color'') | replace(''#'', '''') | lower %}{% if c | length == 6 %}#{{ c }}{% else %}var(--primary-color){% endif %}' primary: '{{ states(''sensor.sparkx_i7_slot_1_color_name'') }} (#{{ states(''sensor.sparkx_i7_cfs_box_1_slot_1_color'') | replace(''#'', '''') | upper }})' secondary: "{% set color = states('sensor.sparkx_i7_cfs_box_1_slot_1_color')\ \ | replace('#', '') | lower %}{% set ns = namespace(id='') %}{% for e in\ \ integration_entities('spoolman') %}{% if e.endswith('_color_hex') and\ \ (states(e) | replace('#', '') | lower) == color and (state_attr(e[:-10],\ \ 'location') | default('', true) | lower) == 'cfs lite' %}{% set b = e[:-10]\ \ %}{% if (states(b) | float(0)) > 0 and ns.id == '' %}{% set ns.id = states(b\ \ ~ '_id') %}{% endif %}{% endif %}{% endfor %}{% if ns.id %}\u2022 Spool\ \ {{ ns.id }} \xB7 {{ states('sensor.spoolman_spool_' ~ ns.id ~ '_vendor')\ \ | default('?', true) }} \xB7 {{ states('sensor.spoolman_spool_' ~ ns.id\ \ ~ '_material') | default('?', true) }} \xB7 {{ (states('sensor.spoolman_spool_'\ \ ~ ns.id) | float(0)) | round(1) }} g left{% elif color in ['', 'unknown',\ \ 'unavailable'] %}\u2022 Slot color unavailable{% else %}\u2022 No spool\ \ with stock matches this color{% endif %}\n\u2022 This print: {{ (states('input_number.sparkx_i7_slot_1_grams')\ \ | float(0)) | round(1) }} g" multiline_secondary: true grid_options: columns: full picture: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_1_color'') | replace(''#'','''') | lower %}{% set svg = '''' %}{{ ''data:image/svg+xml;base64,'' ~ svg | base64_encode if c | length == 6 else '''' }}' - type: custom:mushroom-template-card entity: sensor.sparkx_i7_cfs_box_1_slot_2_color name: Slot 2 icon: mdi:printer-filament icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_2_color'') | replace(''#'', '''') | lower %}{% if c | length == 6 %}#{{ c }}{% else %}var(--primary-color){% endif %}' primary: '{{ states(''sensor.sparkx_i7_slot_2_color_name'') }} (#{{ states(''sensor.sparkx_i7_cfs_box_1_slot_2_color'') | replace(''#'', '''') | upper }})' secondary: "{% set color = states('sensor.sparkx_i7_cfs_box_1_slot_2_color')\ \ | replace('#', '') | lower %}{% set ns = namespace(id='') %}{% for e in\ \ integration_entities('spoolman') %}{% if e.endswith('_color_hex') and\ \ (states(e) | replace('#', '') | lower) == color and (state_attr(e[:-10],\ \ 'location') | default('', true) | lower) == 'cfs lite' %}{% set b = e[:-10]\ \ %}{% if (states(b) | float(0)) > 0 and ns.id == '' %}{% set ns.id = states(b\ \ ~ '_id') %}{% endif %}{% endif %}{% endfor %}{% if ns.id %}\u2022 Spool\ \ {{ ns.id }} \xB7 {{ states('sensor.spoolman_spool_' ~ ns.id ~ '_vendor')\ \ | default('?', true) }} \xB7 {{ states('sensor.spoolman_spool_' ~ ns.id\ \ ~ '_material') | default('?', true) }} \xB7 {{ (states('sensor.spoolman_spool_'\ \ ~ ns.id) | float(0)) | round(1) }} g left{% elif color in ['', 'unknown',\ \ 'unavailable'] %}\u2022 Slot color unavailable{% else %}\u2022 No spool\ \ with stock matches this color{% endif %}\n\u2022 This print: {{ (states('input_number.sparkx_i7_slot_2_grams')\ \ | float(0)) | round(1) }} g" multiline_secondary: true grid_options: columns: full picture: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_2_color'') | replace(''#'','''') | lower %}{% set svg = '''' %}{{ ''data:image/svg+xml;base64,'' ~ svg | base64_encode if c | length == 6 else '''' }}' - type: custom:mushroom-template-card entity: sensor.sparkx_i7_cfs_box_1_slot_3_color name: Slot 3 icon: mdi:printer-filament icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_3_color'') | replace(''#'', '''') | lower %}{% if c | length == 6 %}#{{ c }}{% else %}var(--primary-color){% endif %}' primary: '{{ states(''sensor.sparkx_i7_slot_3_color_name'') }} (#{{ states(''sensor.sparkx_i7_cfs_box_1_slot_3_color'') | replace(''#'', '''') | upper }})' secondary: "{% set color = states('sensor.sparkx_i7_cfs_box_1_slot_3_color')\ \ | replace('#', '') | lower %}{% set ns = namespace(id='') %}{% for e in\ \ integration_entities('spoolman') %}{% if e.endswith('_color_hex') and\ \ (states(e) | replace('#', '') | lower) == color and (state_attr(e[:-10],\ \ 'location') | default('', true) | lower) == 'cfs lite' %}{% set b = e[:-10]\ \ %}{% if (states(b) | float(0)) > 0 and ns.id == '' %}{% set ns.id = states(b\ \ ~ '_id') %}{% endif %}{% endif %}{% endfor %}{% if ns.id %}\u2022 Spool\ \ {{ ns.id }} \xB7 {{ states('sensor.spoolman_spool_' ~ ns.id ~ '_vendor')\ \ | default('?', true) }} \xB7 {{ states('sensor.spoolman_spool_' ~ ns.id\ \ ~ '_material') | default('?', true) }} \xB7 {{ (states('sensor.spoolman_spool_'\ \ ~ ns.id) | float(0)) | round(1) }} g left{% elif color in ['', 'unknown',\ \ 'unavailable'] %}\u2022 Slot color unavailable{% else %}\u2022 No spool\ \ with stock matches this color{% endif %}\n\u2022 This print: {{ (states('input_number.sparkx_i7_slot_3_grams')\ \ | float(0)) | round(1) }} g" multiline_secondary: true grid_options: columns: full picture: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_3_color'') | replace(''#'','''') | lower %}{% set svg = '''' %}{{ ''data:image/svg+xml;base64,'' ~ svg | base64_encode if c | length == 6 else '''' }}' - type: custom:mushroom-template-card entity: sensor.sparkx_i7_cfs_box_1_slot_4_color name: Slot 4 icon: mdi:printer-filament icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_4_color'') | replace(''#'', '''') | lower %}{% if c | length == 6 %}#{{ c }}{% else %}var(--primary-color){% endif %}' primary: '{{ states(''sensor.sparkx_i7_slot_4_color_name'') }} (#{{ states(''sensor.sparkx_i7_cfs_box_1_slot_4_color'') | replace(''#'', '''') | upper }})' secondary: "{% set color = states('sensor.sparkx_i7_cfs_box_1_slot_4_color')\ \ | replace('#', '') | lower %}{% set ns = namespace(id='') %}{% for e in\ \ integration_entities('spoolman') %}{% if e.endswith('_color_hex') and\ \ (states(e) | replace('#', '') | lower) == color and (state_attr(e[:-10],\ \ 'location') | default('', true) | lower) == 'cfs lite' %}{% set b = e[:-10]\ \ %}{% if (states(b) | float(0)) > 0 and ns.id == '' %}{% set ns.id = states(b\ \ ~ '_id') %}{% endif %}{% endif %}{% endfor %}{% if ns.id %}\u2022 Spool\ \ {{ ns.id }} \xB7 {{ states('sensor.spoolman_spool_' ~ ns.id ~ '_vendor')\ \ | default('?', true) }} \xB7 {{ states('sensor.spoolman_spool_' ~ ns.id\ \ ~ '_material') | default('?', true) }} \xB7 {{ (states('sensor.spoolman_spool_'\ \ ~ ns.id) | float(0)) | round(1) }} g left{% elif color in ['', 'unknown',\ \ 'unavailable'] %}\u2022 Slot color unavailable{% else %}\u2022 No spool\ \ with stock matches this color{% endif %}\n\u2022 This print: {{ (states('input_number.sparkx_i7_slot_4_grams')\ \ | float(0)) | round(1) }} g" multiline_secondary: true grid_options: columns: full picture: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_4_color'') | replace(''#'','''') | lower %}{% set svg = '''' %}{{ ''data:image/svg+xml;base64,'' ~ svg | base64_encode if c | length == 6 else '''' }}' - type: tile entity: input_number.sparkx_i7_spoolman_length_checkpoint name: Length Checkpoint (cm) icon: mdi:ruler-measure grid_options: columns: full - type: tile entity: input_text.sparkx_i7_print_spool_latch name: Latched CFS Slot icon: mdi:link-variant grid_options: columns: full - type: tile entity: sensor.sparkx_i7_used_material_length name: Used Material Total (cm) icon: mdi:plus-minus grid_options: columns: full - type: tile entity: sensor.sparkx_i7_filament_weight_estimated name: Current Job Weight (est.) icon: mdi:weight-gram grid_options: columns: 12 rows: 1 - type: custom:mushroom-template-card entity: sensor.sparkx_i7_active_filament_slot name: Next Deduction Match icon: mdi:magnet icon_color: '{% set slot = states(''sensor.sparkx_i7_active_filament_slot'') %}{% set c = states(''sensor.sparkx_i7_cfs_'' ~ (slot | lower | replace('' '', ''_'')) ~ ''_color'') | replace(''#'', '''') | lower %}{% if c | length == 6 %}#{{ c }}{% else %}var(--primary-color){% endif %}' primary: '{{ states(''sensor.sparkx_i7_active_filament_slot'') }}' secondary: "{% set slot = states('sensor.sparkx_i7_active_filament_slot')\ \ %}{% set ce = 'sensor.sparkx_i7_cfs_' ~ (slot | lower | replace(' ', '_'))\ \ ~ '_color' %}{% set color = states(ce) | replace('#', '') | lower %}{%\ \ set ns = namespace(id='') %}{% for e in integration_entities('spoolman')\ \ %}{% if e.endswith('_color_hex') and (states(e) | replace('#', '') | lower)\ \ == color and (state_attr(e[:-10], 'location') | default('', true) | lower)\ \ == 'cfs lite' %}{% set b = e[:-10] %}{% if (states(b) | float(0)) > 0\ \ and ns.id == '' %}{% set ns.id = states(b ~ '_id') %}{% endif %}{% endif\ \ %}{% endfor %}{% if ns.id %}Color #{{ color | upper }} \u2192 spool {{\ \ ns.id }} ({{ states('sensor.spoolman_spool_' ~ ns.id ~ '_filament_name')\ \ }} \xB7 {{ (states('sensor.spoolman_spool_' ~ ns.id) | float(0)) | round(1)\ \ }} g left){% elif slot in ['', 'unknown', 'unavailable'] %}No slot latched{%\ \ elif color in ['', 'unknown', 'unavailable'] %}Slot color unavailable{%\ \ else %}Color #{{ color | upper }} \u2014 no spool with stock{% endif %}" multiline_secondary: true grid_options: columns: full - type: markdown content: "**Spoolman UI:** [http://2c829f0e-spoolman.local.hass.io:7912](http://2c829f0e-spoolman.local.hass.io:7912)\n\ \nEach CFS slot is matched to the Spoolman spool with the same **color hex**\ \ that still has stock (remaining > 0). All 4 rolls live in the **CFS Lite**\ \ location in Spoolman.\n\n**Replaced a roll?** Register the new roll in\ \ Spoolman with the same color hex (location CFS Lite). No Home Assistant\ \ changes needed \u2014 exhausted spools are skipped automatically." grid_options: columns: full - type: grid cards: - type: heading heading: "Spool Details \u2014 CFS Lite" icon: mdi:spool - type: custom:mushroom-template-card entity: sensor.sparkx_i7_cfs_box_1_slot_1_color name: Slot 1 icon: mdi:spool icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_1_color'') | replace(''#'', '''') | lower %}{% if c | length == 6 %}#{{ c }}{% else %}var(--primary-color){% endif %}' picture: '{% set color = states(''sensor.sparkx_i7_cfs_box_1_slot_1_color'') | replace(''#'', '''') | lower %}{% set ns = namespace(id='''') %}{% for e in integration_entities(''spoolman'') %}{% if e.endswith(''_color_hex'') and (states(e) | replace(''#'', '''') | lower) == color and (state_attr(e[:-10], ''location'') | default('''', true) | lower) == ''cfs lite'' %}{% set b = e[:-10] %}{% if (states(b) | float(0)) > 0 and ns.id == '''' %}{% set ns.id = states(b ~ ''_id'') %}{% endif %}{% endif %}{% endfor %}{{ state_attr(''sensor.spoolman_spool_'' ~ ns.id, ''entity_picture'') if ns.id and state_attr(''sensor.spoolman_spool_'' ~ ns.id, ''entity_picture'') else '''' }}' primary: "{% set color = states('sensor.sparkx_i7_cfs_box_1_slot_1_color')\ \ | replace('#', '') | lower %}{% set ns = namespace(id='') %}{% for e in\ \ integration_entities('spoolman') %}{% if e.endswith('_color_hex') and\ \ (states(e) | replace('#', '') | lower) == color and (state_attr(e[:-10],\ \ 'location') | default('', true) | lower) == 'cfs lite' %}{% set b = e[:-10]\ \ %}{% if (states(b) | float(0)) > 0 and ns.id == '' %}{% set ns.id = states(b\ \ ~ '_id') %}{% endif %}{% endif %}{% endfor %}{% if ns.id %}Spool {{ ns.id\ \ }} \xB7 {{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_name')\ \ | default('?', true) }} \xB7 {{ (states('sensor.spoolman_spool_' ~ ns.id)\ \ | float(0)) | round(1) }} g left{% elif color in ['', 'unknown', 'unavailable']\ \ %}Slot color unavailable{% else %}No spool with stock matches this color{%\ \ endif %}" secondary: "{% set color = states('sensor.sparkx_i7_cfs_box_1_slot_1_color')\ \ | replace('#', '') | lower %}{% set ns = namespace(id='') %}{% for e in\ \ integration_entities('spoolman') %}{% if e.endswith('_color_hex') and\ \ (states(e) | replace('#', '') | lower) == color and (state_attr(e[:-10],\ \ 'location') | default('', true) | lower) == 'cfs lite' %}{% set b = e[:-10]\ \ %}{% if (states(b) | float(0)) > 0 and ns.id == '' %}{% set ns.id = states(b\ \ ~ '_id') %}{% endif %}{% endif %}{% endfor %}{% if ns.id %}\u2022 {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_vendor_name') | default('?', true) }} \xB7 {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_material') | default('?', true) }} \xB7 #{{ color |\ \ upper }}\n\u2022 Remaining: {{ (states('sensor.spoolman_spool_' ~ ns.id)\ \ | float(0)) | round(1) }} g \xB7 used {{ (state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'used_weight') | float(0)) | round(1) }} g ({{ (state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'used_percentage') | float(0)) | round(1) }}%)\n\u2022 Remaining\ \ length: {{ ((state_attr('sensor.spoolman_spool_' ~ ns.id, 'remaining_length')\ \ | float(0)) / 1000) | round(1) }} m \xB7 used {{ ((state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'used_length') | float(0)) / 1000) | round(1) }} m\n\u2022 Spool:\ \ \xD8{{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_diameter')\ \ | default('?', true) }} mm \xB7 {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_density') | default('?', true) }} g/cm\xB3 \xB7 {{\ \ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_weight') | default('?',\ \ true) }} g \xB7 art. {{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_article_number')\ \ | default('?', true) }}\n\u2022 Temps: bed {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_settings_bed_temp') | default('?', true) }}\xB0C \xB7\ \ hotend {{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_settings_extruder_temp')\ \ | default('?', true) }}\xB0C\n\u2022 Flow: {{ states('sensor.spoolman_spool_'\ \ ~ ns.id ~ '_flow_rate') }} \xB7 Runout est.: {{ states('sensor.spoolman_spool_'\ \ ~ ns.id ~ '_estimated_runout') }}\n\u2022 Registered: {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'registered') | default('?', true) }} \xB7 Location: {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'location') | default('?', true) }} \xB7 Price: {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_price') | default('?', true) }}{% elif color in ['',\ \ 'unknown', 'unavailable'] %}\u2022 Slot color unavailable{% else %}\u2022\ \ No spool with stock matches this color{% endif %}" multiline_secondary: true grid_options: columns: full - type: custom:mushroom-template-card entity: sensor.sparkx_i7_cfs_box_1_slot_2_color name: Slot 2 icon: mdi:spool icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_2_color'') | replace(''#'', '''') | lower %}{% if c | length == 6 %}#{{ c }}{% else %}var(--primary-color){% endif %}' picture: '{% set color = states(''sensor.sparkx_i7_cfs_box_1_slot_2_color'') | replace(''#'', '''') | lower %}{% set ns = namespace(id='''') %}{% for e in integration_entities(''spoolman'') %}{% if e.endswith(''_color_hex'') and (states(e) | replace(''#'', '''') | lower) == color and (state_attr(e[:-10], ''location'') | default('''', true) | lower) == ''cfs lite'' %}{% set b = e[:-10] %}{% if (states(b) | float(0)) > 0 and ns.id == '''' %}{% set ns.id = states(b ~ ''_id'') %}{% endif %}{% endif %}{% endfor %}{{ state_attr(''sensor.spoolman_spool_'' ~ ns.id, ''entity_picture'') if ns.id and state_attr(''sensor.spoolman_spool_'' ~ ns.id, ''entity_picture'') else '''' }}' primary: "{% set color = states('sensor.sparkx_i7_cfs_box_1_slot_2_color')\ \ | replace('#', '') | lower %}{% set ns = namespace(id='') %}{% for e in\ \ integration_entities('spoolman') %}{% if e.endswith('_color_hex') and\ \ (states(e) | replace('#', '') | lower) == color and (state_attr(e[:-10],\ \ 'location') | default('', true) | lower) == 'cfs lite' %}{% set b = e[:-10]\ \ %}{% if (states(b) | float(0)) > 0 and ns.id == '' %}{% set ns.id = states(b\ \ ~ '_id') %}{% endif %}{% endif %}{% endfor %}{% if ns.id %}Spool {{ ns.id\ \ }} \xB7 {{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_name')\ \ | default('?', true) }} \xB7 {{ (states('sensor.spoolman_spool_' ~ ns.id)\ \ | float(0)) | round(1) }} g left{% elif color in ['', 'unknown', 'unavailable']\ \ %}Slot color unavailable{% else %}No spool with stock matches this color{%\ \ endif %}" secondary: "{% set color = states('sensor.sparkx_i7_cfs_box_1_slot_2_color')\ \ | replace('#', '') | lower %}{% set ns = namespace(id='') %}{% for e in\ \ integration_entities('spoolman') %}{% if e.endswith('_color_hex') and\ \ (states(e) | replace('#', '') | lower) == color and (state_attr(e[:-10],\ \ 'location') | default('', true) | lower) == 'cfs lite' %}{% set b = e[:-10]\ \ %}{% if (states(b) | float(0)) > 0 and ns.id == '' %}{% set ns.id = states(b\ \ ~ '_id') %}{% endif %}{% endif %}{% endfor %}{% if ns.id %}\u2022 {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_vendor_name') | default('?', true) }} \xB7 {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_material') | default('?', true) }} \xB7 #{{ color |\ \ upper }}\n\u2022 Remaining: {{ (states('sensor.spoolman_spool_' ~ ns.id)\ \ | float(0)) | round(1) }} g \xB7 used {{ (state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'used_weight') | float(0)) | round(1) }} g ({{ (state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'used_percentage') | float(0)) | round(1) }}%)\n\u2022 Remaining\ \ length: {{ ((state_attr('sensor.spoolman_spool_' ~ ns.id, 'remaining_length')\ \ | float(0)) / 1000) | round(1) }} m \xB7 used {{ ((state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'used_length') | float(0)) / 1000) | round(1) }} m\n\u2022 Spool:\ \ \xD8{{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_diameter')\ \ | default('?', true) }} mm \xB7 {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_density') | default('?', true) }} g/cm\xB3 \xB7 {{\ \ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_weight') | default('?',\ \ true) }} g \xB7 art. {{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_article_number')\ \ | default('?', true) }}\n\u2022 Temps: bed {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_settings_bed_temp') | default('?', true) }}\xB0C \xB7\ \ hotend {{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_settings_extruder_temp')\ \ | default('?', true) }}\xB0C\n\u2022 Flow: {{ states('sensor.spoolman_spool_'\ \ ~ ns.id ~ '_flow_rate') }} \xB7 Runout est.: {{ states('sensor.spoolman_spool_'\ \ ~ ns.id ~ '_estimated_runout') }}\n\u2022 Registered: {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'registered') | default('?', true) }} \xB7 Location: {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'location') | default('?', true) }} \xB7 Price: {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_price') | default('?', true) }}{% elif color in ['',\ \ 'unknown', 'unavailable'] %}\u2022 Slot color unavailable{% else %}\u2022\ \ No spool with stock matches this color{% endif %}" multiline_secondary: true grid_options: columns: full - type: custom:mushroom-template-card entity: sensor.sparkx_i7_cfs_box_1_slot_3_color name: Slot 3 icon: mdi:spool icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_3_color'') | replace(''#'', '''') | lower %}{% if c | length == 6 %}#{{ c }}{% else %}var(--primary-color){% endif %}' picture: '{% set color = states(''sensor.sparkx_i7_cfs_box_1_slot_3_color'') | replace(''#'', '''') | lower %}{% set ns = namespace(id='''') %}{% for e in integration_entities(''spoolman'') %}{% if e.endswith(''_color_hex'') and (states(e) | replace(''#'', '''') | lower) == color and (state_attr(e[:-10], ''location'') | default('''', true) | lower) == ''cfs lite'' %}{% set b = e[:-10] %}{% if (states(b) | float(0)) > 0 and ns.id == '''' %}{% set ns.id = states(b ~ ''_id'') %}{% endif %}{% endif %}{% endfor %}{{ state_attr(''sensor.spoolman_spool_'' ~ ns.id, ''entity_picture'') if ns.id and state_attr(''sensor.spoolman_spool_'' ~ ns.id, ''entity_picture'') else '''' }}' primary: "{% set color = states('sensor.sparkx_i7_cfs_box_1_slot_3_color')\ \ | replace('#', '') | lower %}{% set ns = namespace(id='') %}{% for e in\ \ integration_entities('spoolman') %}{% if e.endswith('_color_hex') and\ \ (states(e) | replace('#', '') | lower) == color and (state_attr(e[:-10],\ \ 'location') | default('', true) | lower) == 'cfs lite' %}{% set b = e[:-10]\ \ %}{% if (states(b) | float(0)) > 0 and ns.id == '' %}{% set ns.id = states(b\ \ ~ '_id') %}{% endif %}{% endif %}{% endfor %}{% if ns.id %}Spool {{ ns.id\ \ }} \xB7 {{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_name')\ \ | default('?', true) }} \xB7 {{ (states('sensor.spoolman_spool_' ~ ns.id)\ \ | float(0)) | round(1) }} g left{% elif color in ['', 'unknown', 'unavailable']\ \ %}Slot color unavailable{% else %}No spool with stock matches this color{%\ \ endif %}" secondary: "{% set color = states('sensor.sparkx_i7_cfs_box_1_slot_3_color')\ \ | replace('#', '') | lower %}{% set ns = namespace(id='') %}{% for e in\ \ integration_entities('spoolman') %}{% if e.endswith('_color_hex') and\ \ (states(e) | replace('#', '') | lower) == color and (state_attr(e[:-10],\ \ 'location') | default('', true) | lower) == 'cfs lite' %}{% set b = e[:-10]\ \ %}{% if (states(b) | float(0)) > 0 and ns.id == '' %}{% set ns.id = states(b\ \ ~ '_id') %}{% endif %}{% endif %}{% endfor %}{% if ns.id %}\u2022 {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_vendor_name') | default('?', true) }} \xB7 {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_material') | default('?', true) }} \xB7 #{{ color |\ \ upper }}\n\u2022 Remaining: {{ (states('sensor.spoolman_spool_' ~ ns.id)\ \ | float(0)) | round(1) }} g \xB7 used {{ (state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'used_weight') | float(0)) | round(1) }} g ({{ (state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'used_percentage') | float(0)) | round(1) }}%)\n\u2022 Remaining\ \ length: {{ ((state_attr('sensor.spoolman_spool_' ~ ns.id, 'remaining_length')\ \ | float(0)) / 1000) | round(1) }} m \xB7 used {{ ((state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'used_length') | float(0)) / 1000) | round(1) }} m\n\u2022 Spool:\ \ \xD8{{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_diameter')\ \ | default('?', true) }} mm \xB7 {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_density') | default('?', true) }} g/cm\xB3 \xB7 {{\ \ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_weight') | default('?',\ \ true) }} g \xB7 art. {{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_article_number')\ \ | default('?', true) }}\n\u2022 Temps: bed {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_settings_bed_temp') | default('?', true) }}\xB0C \xB7\ \ hotend {{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_settings_extruder_temp')\ \ | default('?', true) }}\xB0C\n\u2022 Flow: {{ states('sensor.spoolman_spool_'\ \ ~ ns.id ~ '_flow_rate') }} \xB7 Runout est.: {{ states('sensor.spoolman_spool_'\ \ ~ ns.id ~ '_estimated_runout') }}\n\u2022 Registered: {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'registered') | default('?', true) }} \xB7 Location: {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'location') | default('?', true) }} \xB7 Price: {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_price') | default('?', true) }}{% elif color in ['',\ \ 'unknown', 'unavailable'] %}\u2022 Slot color unavailable{% else %}\u2022\ \ No spool with stock matches this color{% endif %}" multiline_secondary: true grid_options: columns: full - type: custom:mushroom-template-card entity: sensor.sparkx_i7_cfs_box_1_slot_4_color name: Slot 4 icon: mdi:spool icon_color: '{% set c = states(''sensor.sparkx_i7_cfs_box_1_slot_4_color'') | replace(''#'', '''') | lower %}{% if c | length == 6 %}#{{ c }}{% else %}var(--primary-color){% endif %}' picture: '{% set color = states(''sensor.sparkx_i7_cfs_box_1_slot_4_color'') | replace(''#'', '''') | lower %}{% set ns = namespace(id='''') %}{% for e in integration_entities(''spoolman'') %}{% if e.endswith(''_color_hex'') and (states(e) | replace(''#'', '''') | lower) == color and (state_attr(e[:-10], ''location'') | default('''', true) | lower) == ''cfs lite'' %}{% set b = e[:-10] %}{% if (states(b) | float(0)) > 0 and ns.id == '''' %}{% set ns.id = states(b ~ ''_id'') %}{% endif %}{% endif %}{% endfor %}{{ state_attr(''sensor.spoolman_spool_'' ~ ns.id, ''entity_picture'') if ns.id and state_attr(''sensor.spoolman_spool_'' ~ ns.id, ''entity_picture'') else '''' }}' primary: "{% set color = states('sensor.sparkx_i7_cfs_box_1_slot_4_color')\ \ | replace('#', '') | lower %}{% set ns = namespace(id='') %}{% for e in\ \ integration_entities('spoolman') %}{% if e.endswith('_color_hex') and\ \ (states(e) | replace('#', '') | lower) == color and (state_attr(e[:-10],\ \ 'location') | default('', true) | lower) == 'cfs lite' %}{% set b = e[:-10]\ \ %}{% if (states(b) | float(0)) > 0 and ns.id == '' %}{% set ns.id = states(b\ \ ~ '_id') %}{% endif %}{% endif %}{% endfor %}{% if ns.id %}Spool {{ ns.id\ \ }} \xB7 {{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_name')\ \ | default('?', true) }} \xB7 {{ (states('sensor.spoolman_spool_' ~ ns.id)\ \ | float(0)) | round(1) }} g left{% elif color in ['', 'unknown', 'unavailable']\ \ %}Slot color unavailable{% else %}No spool with stock matches this color{%\ \ endif %}" secondary: "{% set color = states('sensor.sparkx_i7_cfs_box_1_slot_4_color')\ \ | replace('#', '') | lower %}{% set ns = namespace(id='') %}{% for e in\ \ integration_entities('spoolman') %}{% if e.endswith('_color_hex') and\ \ (states(e) | replace('#', '') | lower) == color and (state_attr(e[:-10],\ \ 'location') | default('', true) | lower) == 'cfs lite' %}{% set b = e[:-10]\ \ %}{% if (states(b) | float(0)) > 0 and ns.id == '' %}{% set ns.id = states(b\ \ ~ '_id') %}{% endif %}{% endif %}{% endfor %}{% if ns.id %}\u2022 {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_vendor_name') | default('?', true) }} \xB7 {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_material') | default('?', true) }} \xB7 #{{ color |\ \ upper }}\n\u2022 Remaining: {{ (states('sensor.spoolman_spool_' ~ ns.id)\ \ | float(0)) | round(1) }} g \xB7 used {{ (state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'used_weight') | float(0)) | round(1) }} g ({{ (state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'used_percentage') | float(0)) | round(1) }}%)\n\u2022 Remaining\ \ length: {{ ((state_attr('sensor.spoolman_spool_' ~ ns.id, 'remaining_length')\ \ | float(0)) / 1000) | round(1) }} m \xB7 used {{ ((state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'used_length') | float(0)) / 1000) | round(1) }} m\n\u2022 Spool:\ \ \xD8{{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_diameter')\ \ | default('?', true) }} mm \xB7 {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_density') | default('?', true) }} g/cm\xB3 \xB7 {{\ \ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_weight') | default('?',\ \ true) }} g \xB7 art. {{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_article_number')\ \ | default('?', true) }}\n\u2022 Temps: bed {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_settings_bed_temp') | default('?', true) }}\xB0C \xB7\ \ hotend {{ state_attr('sensor.spoolman_spool_' ~ ns.id, 'filament_settings_extruder_temp')\ \ | default('?', true) }}\xB0C\n\u2022 Flow: {{ states('sensor.spoolman_spool_'\ \ ~ ns.id ~ '_flow_rate') }} \xB7 Runout est.: {{ states('sensor.spoolman_spool_'\ \ ~ ns.id ~ '_estimated_runout') }}\n\u2022 Registered: {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'registered') | default('?', true) }} \xB7 Location: {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'location') | default('?', true) }} \xB7 Price: {{ state_attr('sensor.spoolman_spool_'\ \ ~ ns.id, 'filament_price') | default('?', true) }}{% elif color in ['',\ \ 'unknown', 'unavailable'] %}\u2022 Slot color unavailable{% else %}\u2022\ \ No spool with stock matches this color{% endif %}" multiline_secondary: true grid_options: columns: full - type: grid cards: - type: heading heading: Adjust Remaining icon: mdi:pencil-outline - type: entities title: Set value (g) show_header_toggle: false entities: - input_number.spoolman_set_remaining grid_options: columns: full - type: tile entity: input_number.spoolman_set_remaining name: Apply to Slot 1 icon: mdi:content-save-outline grid_options: columns: 3 tap_action: action: perform-action perform_action: script.spoolman_set_spool_remaining data: slot: 1 confirmation: text: Overwrite remaining weight of the spool matching Slot 1 (by color hex) in Spoolman? - type: tile entity: input_number.spoolman_set_remaining name: Apply to Slot 2 icon: mdi:content-save-outline grid_options: columns: 3 tap_action: action: perform-action perform_action: script.spoolman_set_spool_remaining data: slot: 2 confirmation: text: Overwrite remaining weight of the spool matching Slot 2 (by color hex) in Spoolman? - type: tile entity: input_number.spoolman_set_remaining name: Apply to Slot 3 icon: mdi:content-save-outline grid_options: columns: 3 tap_action: action: perform-action perform_action: script.spoolman_set_spool_remaining data: slot: 3 confirmation: text: Overwrite remaining weight of the spool matching Slot 3 (by color hex) in Spoolman? - type: tile entity: input_number.spoolman_set_remaining name: Apply to Slot 4 icon: mdi:content-save-outline grid_options: columns: 3 tap_action: action: perform-action perform_action: script.spoolman_set_spool_remaining data: slot: 4 confirmation: text: Overwrite remaining weight of the spool matching Slot 4 (by color hex) in Spoolman? - type: markdown content: "**1.** Type the new remaining grams above. **2.** Tap **Apply to\ \ Slot N** for the slot holding that roll \u2014 it resolves the spool by\ \ the slot's color hex, so it also works when the spool is exhausted (e.g.\ \ right after replacing a roll). **3.** The value is **absolute** \u2014\ \ it replaces Spoolman's remaining weight; print deductions continue from\ \ there. Avoid adjusting during a running print." grid_options: columns: full - type: grid cards: - type: heading heading: Print Linkage icon: mdi:printer-3d-nozzle - type: tile entity: automation.sparkx_i7_latch_print_spool_for_spoolman name: Latch + Segment Deduction icon: mdi:link-variant grid_options: columns: 3 - type: tile entity: automation.sparkx_i7_deduct_filament_in_spoolman_on_print_complete name: Print Complete Deduction icon: mdi:minus-circle-outline grid_options: columns: 3 - type: tile entity: sensor.sparkx_i7_filament_weight_estimated name: Current Job Weight (est.) icon: mdi:weight-gram grid_options: columns: 3 - type: tile entity: input_number.sparkx_i7_filament_g_cm name: Filament g/cm icon: mdi:ruler grid_options: columns: 3 - type: tile entity: sensor.sparkx_i7_active_filament_slot name: Active CFS Slot icon: mdi:palette-swatch-variant grid_options: columns: 3 - type: tile entity: sensor.sparkx_i7_used_material_length name: Used Material Total (cm) icon: mdi:plus-minus grid_options: columns: 6 rows: 1 - type: grid cards: - type: heading heading: "Spool History \u2014 CFS Lite (auto)" icon: mdi:history - type: custom:auto-entities filter: include: - entity_id: sensor.spoolman_spool_* attributes: location: CFS Lite sort: method: attribute attribute: id numeric: true card: type: history-graph title: Remaining weight (7 days) hours_to_show: 168 show_names: true show_empty: false grid_options: columns: full - type: markdown content: "Every spool with location **CFS Lite** joins this graph automatically\ \ \u2014 register a new roll in Spoolman (same color hex, location CFS Lite)\ \ and it appears without dashboard edits. History follows the spool entity;\ \ a replaced roll keeps its own history under its own spool id." grid_options: columns: full