My Bambu Lab X1C Dashboard & Automations

This is what mine looks like for my P1S, I did try to yoink @sendorm 's fancy layer preview, but I am holding it wrong.

code

views:
  - title: Main
    cards:
      - type: horizontal-stack
        cards:
          - type: custom:mushroom-title-card
            title: Bambu Lab P1S
            alignment: start
          - type: custom:mod-card
            card:
              type: custom:mushroom-chips-card
              chips:
                - type: entity
                  entity: button.p1s_01p00c470401372_stop_printing
                  icon: mdi:stop
                  content_info: false
                - type: entity
                  entity: button.p1s_01p00c470401372_pause_printing
                  icon: mdi:pause
                  content_info: false
                - type: entity
                  entity: button.p1s_01p00c470401372_resume_printing
                  icon: mdi:play
                  content_info: false
              card_mod:
                style: |
                  ha-card {
                    display: flex;
                    justify-content: end;
                    align-items: center;
                    height: 80px;
                  }
      - type: custom:mod-card
        card:
          type: picture
          image_entity: image.p1s_01p00c470401372_camera
      - type: custom:mod-card
        card:
          type: vertical-stack
          cards:
            - type: custom:mushroom-title-card
              title: AMS STATUS
              subtitle: Current environmental stats
              icon: mdi:warehouse
              card_mod:
                style: |
                  ha-card {
                    background: linear-gradient(90deg, #004a7c, #007acc) !important;
                    color: white !important;
                    border-radius: 10px;
                    text-align: center;
                    font-size: 1.5rem;
                    font-weight: bold;
                    box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.2);
                  }
            - type: grid
              columns: 2
              square: false
              cards:
                - type: custom:mushroom-entity-card
                  entity: sensor.p1s_01p00c470401372_ams_1_humidity_index
                  name: AMS Humidity (Main)
                  icon: mdi:water-percent
                  layout: vertical
                  primary_info: name
                  secondary_info: state
                  card_mod:
                    style: |
                      ha-card {
                        background: linear-gradient(135deg, #003366, #336699) !important;
                        color: white !important;
                        border-radius: 10px;
                        font-size: 1.2rem;
                        text-align: center;
                      }
                - type: custom:mushroom-entity-card
                  entity: sensor.ams_temp_and_humid_titty_humidity
                  name: AMS Humidity (Silica)
                  icon: mdi:water-opacity
                  layout: vertical
                  primary_info: name
                  secondary_info: state
                  card_mod:
                    style: |
                      ha-card {
                        background: linear-gradient(135deg, #004d00, #228b22) !important;
                        color: white !important;
                        border-radius: 10px;
                        font-size: 1.2rem;
                        text-align: center;
                      }
                - type: custom:mushroom-entity-card
                  entity: sensor.ams_lid_temp_and_humid_titty_humidity
                  name: AMS Humidity (Lid)
                  icon: mdi:water-opacity
                  layout: vertical
                  primary_info: name
                  secondary_info: state
                  card_mod:
                    style: |
                      ha-card {
                        background: linear-gradient(135deg, #4b0082, #8a2be2) !important;
                        color: white !important;
                        border-radius: 10px;
                        font-size: 1.2rem;
                        text-align: center;
                      }
                - type: custom:mushroom-entity-card
                  entity: sensor.p1s_01p00c470401372_active_tray_index
                  name: Active Tray
                  icon: mdi:tray
                  layout: vertical
                  primary_info: name
                  secondary_info: state
                  card_mod:
                    style: |
                      ha-card {
                        background: linear-gradient(135deg, #005757, #008b8b) !important;
                        color: white !important;
                        border-radius: 10px;
                        font-size: 1.2rem;
                        text-align: center;
                      }
      - chart_type: line
        period: hour
        type: statistics-graph
        entities:
          - sensor.ams_lid_temp_and_humid_titty_humidity
          - sensor.ams_temp_and_humid_titty_humidity
        stat_types:
          - mean
          - min
          - max
        days_to_show: 7
      - type: horizontal-stack
        cards:
          - type: custom:button-card
            entity: sensor.p1s_01p00c470401372_ams_1_tray_1
            icon: mdi:circle-slice-8
            name: Bambu PLA Basic
            show_icon: true
            show_name: true
            custom_fields:
              percentage: |
                [[[
                  return states['sensor.tray_1_remaining_filament_percentage'].state + '%';
                ]]]
            styles:
              card:
                - height: 130px
                - font-size: 12px
              grid:
                - grid-template-areas: '"i" "n" "percentage"'
                - grid-template-rows: 1fr auto auto
                - grid-template-columns: 1fr
              custom_fields:
                percentage:
                  - justify-self: center
                  - font-size: 10px
                  - color: var(--primary-text-color)
              icon:
                - color: |
                    [[[
                      return states['sensor.p1s_01p00c470401372_ams_1_tray_1'].attributes.color;
                    ]]]
          - type: custom:button-card
            entity: sensor.p1s_01p00c470401372_ams_1_tray_2
            icon: mdi:circle-slice-8
            name: Bambu PLA Basic
            show_icon: true
            show_name: true
            custom_fields:
              percentage: |
                [[[
                  return states['sensor.tray_2_remaining_filament_percentage'].state + '%';
                ]]]
            styles:
              card:
                - height: 130px
                - font-size: 12px
              grid:
                - grid-template-areas: '"i" "n" "percentage"'
                - grid-template-rows: 1fr auto auto
                - grid-template-columns: 1fr
              custom_fields:
                percentage:
                  - justify-self: center
                  - font-size: 10px
                  - color: var(--primary-text-color)
              icon:
                - color: |
                    [[[
                      return states['sensor.p1s_01p00c470401372_ams_1_tray_2'].attributes.color;
                    ]]]
          - type: custom:button-card
            entity: sensor.p1s_01p00c470401372_ams_1_tray_3
            icon: mdi:circle-slice-8
            name: Bambu PLA Basic
            show_icon: true
            show_name: true
            custom_fields:
              percentage: |
                [[[
                  return states['sensor.tray_3_remaining_filament_percentage'].state + '%';
                ]]]
            styles:
              card:
                - height: 130px
                - font-size: 12px
              grid:
                - grid-template-areas: '"i" "n" "percentage"'
                - grid-template-rows: 1fr auto auto
                - grid-template-columns: 1fr
              custom_fields:
                percentage:
                  - justify-self: center
                  - font-size: 10px
                  - color: var(--primary-text-color)
              icon:
                - color: |
                    [[[
                      return states['sensor.p1s_01p00c470401372_ams_1_tray_3'].attributes.color;
                    ]]]
          - type: custom:button-card
            entity: sensor.p1s_01p00c470401372_ams_1_tray_4
            icon: mdi:circle-slice-8
            name: Bambu PLA Basic
            show_icon: true
            show_name: true
            custom_fields:
              percentage: |
                [[[
                  return states['sensor.tray_4_remaining_filament_percentage'].state + '%';
                ]]]
            styles:
              card:
                - height: 130px
                - font-size: 12px
              grid:
                - grid-template-areas: '"i" "n" "percentage"'
                - grid-template-rows: 1fr auto auto
                - grid-template-columns: 1fr
              custom_fields:
                percentage:
                  - justify-self: center
                  - font-size: 10px
                  - color: var(--primary-text-color)
              icon:
                - color: |
                    [[[
                      return states['sensor.p1s_01p00c470401372_ams_1_tray_4'].attributes.color;
                    ]]]
      - type: custom:mod-card
        card:
          type: custom:mushroom-chips-card
          chips:
            - type: template
              entity: binary_sensor.p1s_01p00c470401372
              content: Printer
              card_mod:
                style: |
                  ha-card {
                    background: none !important;
                    border: none;
                    font-size: 4rem !important;
                  }
            - type: spacer
            - type: entity
              entity: sensor.p1s_01p00c470401372_current_stage
            - type: light
              icon: mdi:lightbulb
              entity: light.p1s_01p00c470401372_chamber_light
            - type: entity
              entity: sensor.p1s_01p00c470401372_wi_fi_signal
            - type: entity
              entity: binary_sensor.p1s_01p00c470401372_hms_errors
              icon: mdi:alert-circle
            - type: entity
              entity: sensor.p1s_01p00c470401372_nozzle_size
            - type: entity
              entity: sensor.p1s_01p00c470401372_nozzle_type
            - type: light
              entity: switch.p1s_01p00c470401372_enable_camera
              icon: mdi:camera
      - type: custom:mod-card
        card:
          show_name: false
          show_icon: true
          show_state: true
          type: glance
          entities:
            - entity: sensor.p1s_01p00c470401372_nozzle_temperature
              icon: mdi:printer-3d-nozzle-heat
            - entity: sensor.p1s_01p00c470401372_bed_temperature
              icon: mdi:train-car-flatbed
            - entity: sensor.p1s_01p00c470401372_chamber_fan_speed
              icon: mdi:minus-box-outline
            - entity: sensor.p1s_01p00c470401372_speed_profile
          state_color: false
      - type: custom:mushroom-chips-card
        chips:
          - type: entity
            entity: sensor.p1s_01p00c470401372_print_progress
            icon: mdi:progress-helper
          - type: entity
            entity: sensor.p1s_01p00c470401372_end_time
            icon: mdi:progress-check
          - type: entity
            entity: sensor.p1s_01p00c470401372_remaining_time
        alignment: justify
      - type: vertical-stack
        cards:
          - type: custom:config-template-card
            entities:
              - sensor.p1s_01p00c470401372_task_name
              - sensor.p1s_01p00c470401372_current_layer
              - sensor.p1s_01p00c470401372_total_layer_count
              - sensor.p1s_01p00c470401372_print_progress
              - sensor.p1s_01p00c470401372_remaining_time
            card:
              type: custom:html-template-card
              content: >
                <font size="5">{{
                states.sensor.p1s_01p00c470401372_task_name.state }}</font>

                <table width="100%">
                  <tr>
                    <td align="left">Printed layers</td>
                    <td align="right">
                      <font color="#77fc54" size="4">
                        {{ states.sensor.p1s_01p00c470401372_current_layer.state }}
                      </font> /
                      {{ states.sensor.p1s_01p00c470401372_total_layer_count.state }}
                    </td>
                  </tr>
                </table>

                <table width="100%">
                  <tr>
                    <td align="left">
                      <font size="5" color="#77fc54">
                        {{ states.sensor.p1s_01p00c470401372_print_progress.state }}%
                      </font>
                    </td>
                    <td align="right">
                      {% if (states.sensor.p1s_01p00c470401372_remaining_time.state | int) == 0 %}
                        <font color="#77fc54">Success</font>
                      {% else %}
                        <font color="#959595">
                          -{{ (states.sensor.p1s_01p00c470401372_remaining_time.state | int / 60) | int }}h{{ states.sensor.p1s_01p00c470401372_remaining_time.state | int % 60 }}m
                        </font>
                      {% endif %}
                    </td>
                  </tr>
                </table>
          - type: custom:bar-card
            entity: sensor.p1s_01p00c470401372_print_progress
            icon: 'off'
            name: Progress
            positions:
              icon: 'off'
              indicator: 'off'
              title: inside
              value: inside
            severity:
              - color: green
                from: 0
                to: 100

2 Likes

Looks nice! Can you share your config?

hello I am trying to use your code but I have many errors… I can’t save the section. maybe it is missing os some parts?

maybe I should put a disclaimer. The code is for an A1 printer. What kind of errors are you getting? Are you sure that the code in your yaml is the same as the code posted here?

A friendly reminder from Bambu Labs:

unauthorized third-party software will be prohibited from executing critical operations

After updating to the latest firmware with enhanced security controls, full control of printers via Home Assistant will no longer be possible.

In other words: You don’t own it…

https://wiki.rossmanngroup.com/wiki/Bambu_Lab_Authorization_Control_System

1 Like

Errore di configurazione

  • Cannot read properties of undefined (reading ‘startsWith’)
No card type configured
- icon: mdi:alpha-a-box-outline
  title: Bambu A1
  id: bambua1
  cards:
    - type: vertical-stack
      cards:
        - type: horizontal-stack
          cards:
            - type: custom:mushroom-title-card
              title: '{{ states.sensor.a1_printer_name.state }}'
              alignment: start
        - type: custom:mod-card
          card:
            type: picture-glance
            entities: []
            camera_image: camera.a1_camera
        - type: horizontal-stack
          cards:
            - type: custom:mod-card
              card:
                type: picture-entity
                entity: image.a1_cover_image
                camera_view: auto
                show_name: false
                show_state: false
            - type: vertical-stack
              cards:
                - type: markdown
                  content: >
                    <font size="5">{{ states.sensor.a1_task_name.state }}</font>

                    <table width=100%><tr><td align=left>Printed layers<td
                    align=right><font color=#77fc54 ; size="4">{{
                    states.sensor.a1_current_layer.state}}</font>/{{states.sensor.a1_total_layer_count.state}}</td></tr></table>

                    <table width=100%><tr> <td align=left><font
                    size="5";color=#77fc54>{{
                    states.sensor.a1_print_progress.state}}%<td align=right>   
                    {% if (states.sensor.a1_remaining_time.state | int) == 0 %}
                      Success  
                    {% else %}
                      <font color=#959595>-{{(states.sensor.a1_remaining_time.state | int/60) | int  }}h{{ states.sensor.a1_remaining_time.state| int % 60 }}m 
                    {% endif %} </td> </tr></table>
                - type: custom:bar-card
                  entity: sensor.a1_print_progress
                  icon: 'off'
                  name: Progress
                  positions:
                    icon: 'off'
                    indicator: 'off'
                    title: inside
                    value: inside
                  severity:
                    - color: green
                      from: 0
                      to: 100
        - type: horizontal-stack
          cards:
            - type: custom:button-card
              color_type: icon
              entity: button.a1_resume_printing
              icon: mdi:play
              name: Resume
              layout: icon_name
              card_mod:
                style: |
                  :host {
                      --paper-item-icon-color: green}
                  ha-card {
                    height: 60px;
                  }    
            - type: custom:button-card
              color_type: icon
              entity: button.a1_pause_printing
              icon: mdi:pause
              name: Pause
              card_mod:
                style: |
                  :host {
                      --paper-item-icon-color: rgreen}
                  ha-card {
                    height: 60px;
                  }       
              layout: icon_name_state
              confirmation:
                text: '[[[ return `Are you sure you want to pause the print?` ]]]'
            - type: custom:button-card
              color: rgb(255, 0, 0)
              color_type: icon
              entity: button.a1_stop_printing
              icon: mdi:stop
              name: Stop
              card_mod:
                style: |
                  :host {
                      --paper-item-icon-color: red}
                  ha-card {
                    height: 60px;
                  }
              layout: icon_name_state
              confirmation:
                text: '[[[ return `Are you sure you want to stop the print?` ]]]'
        - type: custom:mod-card
          card_mod:
            style:
              hui-horizontal-stack-card $: |
                div#root > :first-child {
                  width: 20%;
                  flex: auto; 
                }
                div#root > :last-child {
                  width: 80%;
                  flex: auto; 
                }
          card:
            type: horizontal-stack
            cards:
              - type: custom:mushroom-chips-card
                chips:
                  - type: template
                    entity: binary_sensor.a1_online
                    content: EXT.
                    card_mod:
                      style: |
                        ha-card {
                          background: none !important;
                          border: none;
                          font-size: 4rem !important;
                        }
              - type: custom:mushroom-chips-card
                chips:
                  - type: template
                    entity: binary_sensor.a1_online
                    content: AMS
                    card_mod:
                      style: |
                        ha-card {
                          background: none !important;
                          border: none;
                          font-size: 4rem !important;
                        }
                  - type: spacer
                  - type: entity
                    entity: sensor.a1_ams_1_humidity_index
                    icon: mdi:water-opacity
        - type: custom:mod-card
          card_mod:
            style:
              hui-horizontal-stack-card $: |
                div#root > :first-child {
                  width: 20%;
                  flex: auto; 
                }
                div#root > :last-child {
                  width: 80%;
                  flex: auto; 
                }
          card:
            type: horizontal-stack
            cards:
              - type: custom:mod-card
                card_mod:
                  style: |
                    ha-card {
                      font-size: 10px;
                      --external_spool_color: {{state_attr('sensor.a1_externalspool_external_spool', 'color') }};
                      --tray_1_color: {{state_attr('sensor.a1_ams_1_tray_1', 'color') }};
                      --tray_2_color: {{state_attr('sensor.a1_ams_1_tray_2', 'color') }};
                      --tray_3_color: {{state_attr('sensor.a1_ams_1_tray_3', 'color') }};
                      --tray_4_color: {{state_attr('sensor.a1_ams_1_tray_4', 'color') }};
                      --external_spool_bg: {% if is_state_attr('sensor.a1_externalspool_external_spool', 'active', true) %} rgba(255,254,249, 0.25); {% else %} rgba(111,111,111, 0.2) {% endif %};
                      --tray_1_bg: {% if is_state_attr('sensor.a1_ams_1_tray_1', 'active', true) %} rgba(255,254,249, 0.25); {% else %} rgba(111,111,111, 0.2) {% endif %};
                      --tray_2_bg: {% if is_state_attr('sensor.a1_ams_1_tray_2', 'active', true) %} rgba(255,254,249, 0.25); {% else %} rgba(111,111,111, 0.2) {% endif %};
                      --tray_3_bg: {% if is_state_attr('sensor.a1_ams_1_tray_3', 'active', true) %} rgba(255,254,249, 0.25); {% else %} rgba(111,111,111, 0.2) {% endif %};
                      --tray_4_bg: {% if is_state_attr('sensor.a1_ams_1_tray_4', 'active', true) %} rgba(255,254,249, 0.25); {% else %} rgba(111,111,111, 0.2) {% endif %};
                    }
                card:
                  card_mod:
                    style: |
                      .entities {
                        align-items: start !important;
                      }
                  show_name: false
                  show_icon: true
                  show_state: true
                  type: glance
                  entities:
                    - entity: sensor.a1_externalspool_external_spool
                      icon: mdi:circle-slice-8
                      card_mod:
                        style: |
                          :host {
                            --paper-item-icon-color: var(--external_spool_color);
                          }
                          state-badge {
                            background-color: var(--external_spool_bg);
                            border-radius: 50%;
                          }
                          div {
                            white-space: unset !important;
                            text-wrap: balance !important;
                          }
              - type: custom:mod-card
                card_mod:
                  style: |
                    ha-card {
                      font-size: 10px;
                      --external_spool_color: {{state_attr('sensor.a1_externalspool_external_spool', 'color') }};
                      --tray_1_color: {{state_attr('sensor.a1_ams_1_tray_1', 'color') }};
                      --tray_2_color: {{state_attr('sensor.a1_ams_1_tray_2', 'color') }};
                      --tray_3_color: {{state_attr('sensor.a1_ams_1_tray_3', 'color') }};
                      --tray_4_color: {{state_attr('sensor.a1_ams_1_tray_4', 'color') }};
                      --external_spool_bg: {% if is_state_attr('sensor.a1_externalspool_external_spool', 'active', true) %} rgba(255,254,249, 0.25); {% else %} rgba(111,111,111, 0.2) {% endif %};
                      --tray_1_bg: {% if is_state_attr('sensor.a1_ams_1_tray_1', 'active', true) %} rgba(255,254,249, 0.25); {% else %} rgba(111,111,111, 0.2) {% endif %};
                      --tray_2_bg: {% if is_state_attr('sensor.a1_ams_1_tray_2', 'active', true) %} rgba(255,254,249, 0.25); {% else %} rgba(111,111,111, 0.2) {% endif %};
                      --tray_3_bg: {% if is_state_attr('sensor.a1_ams_1_tray_3', 'active', true) %} rgba(255,254,249, 0.25); {% else %} rgba(111,111,111, 0.2) {% endif %};
                      --tray_4_bg: {% if is_state_attr('sensor.a1_ams_1_tray_4', 'active', true) %} rgba(255,254,249, 0.25); {% else %} rgba(111,111,111, 0.2) {% endif %};
                    }
                card:
                  card_mod:
                    style: |
                      .entities {
                        align-items: start !important;
                      }
                  show_name: false
                  show_icon: true
                  show_state: true
                  type: glance
                  entities:
                    - entity: sensor.a1_ams_1_tray_1
                      icon: mdi:circle-slice-8
                      card_mod:
                        style: |
                          :host {
                            --paper-item-icon-color: var(--tray_1_color);
                          }
                          state-badge {
                            background-color: var(--tray_1_bg);
                            border-radius: 50%;
                          }
                          div {
                            white-space: unset !important;
                            text-wrap: balance !important;
                          }
                    - entity: sensor.a1_ams_1_tray_2
                      icon: mdi:circle-slice-8
                      card_mod:
                        style: |
                          :host {
                            --paper-item-icon-color: var(--tray_2_color);
                          }
                          state-badge {
                            background-color: var(--tray_2_bg);
                            border-radius: 50%;
                          }
                          div {
                            white-space: unset !important;
                            text-wrap: balance !important;
                          }
                    - entity: sensor.a1_ams_1_tray_3
                      icon: mdi:circle-slice-8
                      card_mod:
                        style: |
                          :host {
                            --paper-item-icon-color: var(--tray_3_color);
                          }
                          state-badge {
                            background-color: var(--tray_3_bg);
                            border-radius: 50%;
                          }
                          div {
                            white-space: unset !important;
                            text-wrap: balance !important;
                          }
                    - entity: sensor.a1_ams_1_tray_4
                      icon: mdi:circle-slice-8
                      card_mod:
                        style: |
                          :host {
                            --paper-item-icon-color: var(--tray_4_color);
                          }
                          state-badge {
                            background-color: var(--tray_4_bg);
                            border-radius: 50%;
                          }
                          div {
                            white-space: unset !important;
                            text-wrap: balance !important;
                          }
        - type: custom:mod-card
          card:
            type: custom:mushroom-chips-card
            chips:
              - type: template
                entity: binary_sensor.a1_online
                content: Printer
                card_mod:
                  style: |
                    ha-card {
                      background: none !important;
                      border: none;
                      font-size: 4rem !important;
                    }
              - type: spacer
              - type: entity
                entity: sensor.a1_current_stage
              - type: light
                icon: mdi:lightbulb
                entity: light.a1_chamber_light
              - type: entity
                entity: sensor.a1_wi_fi_signal
              - type: entity
                entity: binary_sensor.a1_hms_errors
                icon: mdi:alert-circle
        - type: custom:mod-card
          card:
            show_name: false
            show_icon: true
            show_state: true
            type: glance
            entities:
              - entity: sensor.a1_nozzle_temperature
                icon: mdi:printer-3d-nozzle-heat
              - entity: sensor.a1_bed_temperature
                icon: mdi:radiator
              - entity: sensor.a1_speed_profile
                icon: mdi:speedometer
            state_color: false
        - type: custom:mushroom-chips-card
          chips:
            - type: entity
              entity: sensor.a1_end_time
          alignment: justify
1 Like

Let’s hope Bambu Lab doesn’t use the leaked :key: as an lame argument to soft brick :brick: all devices that don’t update (to cloud only), seems buyers might have agreed to that according their TOS: :point_down:

Terms of Use - Bambu Lab

7.3 … you decide not to download and use an update provided by Bambu Lab, you understand that you may place the Product under serious security risk or cause the Product to be unusable or unstable. Some of the functions of the Product may be limited based on the version.

Might just need to change brains on the long run… :brain:

They got (silently) rid of this passage… Doesn’t look good. :-1:

Also word is out that downgrades are not possible once the new (cloud only) firmware is installed. :put_litter_in_its_place:

Now silently changed to:

“Due to the importance of these updates, your product may block new print job before the updates is installed

Because this is a view. If you want this inside a view, you should copy the parts after the first “cards:”

fixed up my filament display a bit

type: horizontal-stack
cards:
  - type: custom:button-card
    entity: sensor.p1s_01p00c470401372_ams_1_tray_1
    icon: mdi:circle-slice-8
    name: Bambu PLA Basic
    show_icon: true
    show_name: true
    custom_fields:
      status: |
        [[[
          let percentage = parseFloat(states['sensor.tray_1_remaining_filament_percentage'].state) || 0;
          let remainingMeters = (percentage / 100) * 335;
          return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
        ]]]
    styles:
      card:
        - height: 130px
        - font-size: 12px
      grid:
        - grid-template-areas: "\"i\" \"n\" \"status\""
        - grid-template-rows: 1fr auto auto
        - grid-template-columns: 1fr
      custom_fields:
        status:
          - justify-self: center
          - font-size: 10px
          - color: var(--primary-text-color)
      icon:
        - color: |
            [[[
              return states['sensor.p1s_01p00c470401372_ams_1_tray_1'].attributes.color;
            ]]]
  - type: custom:button-card
    entity: sensor.p1s_01p00c470401372_ams_1_tray_2
    icon: mdi:circle-slice-8
    name: Bambu PLA Basic
    show_icon: true
    show_name: true
    custom_fields:
      status: |
        [[[
          let percentage = parseFloat(states['sensor.tray_2_remaining_filament_percentage'].state) || 0;
          let remainingMeters = (percentage / 100) * 335;
          return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
        ]]]
    styles:
      card:
        - height: 130px
        - font-size: 12px
      grid:
        - grid-template-areas: "\"i\" \"n\" \"status\""
        - grid-template-rows: 1fr auto auto
        - grid-template-columns: 1fr
      custom_fields:
        status:
          - justify-self: center
          - font-size: 10px
          - color: var(--primary-text-color)
      icon:
        - color: |
            [[[
              return states['sensor.p1s_01p00c470401372_ams_1_tray_2'].attributes.color;
            ]]]
  - type: custom:button-card
    entity: sensor.p1s_01p00c470401372_ams_1_tray_3
    icon: mdi:circle-slice-8
    name: Bambu PLA Basic
    show_icon: true
    show_name: true
    custom_fields:
      status: |
        [[[
          let percentage = parseFloat(states['sensor.tray_3_remaining_filament_percentage'].state) || 0;
          let remainingMeters = (percentage / 100) * 335;
          return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
        ]]]
    styles:
      card:
        - height: 130px
        - font-size: 12px
      grid:
        - grid-template-areas: "\"i\" \"n\" \"status\""
        - grid-template-rows: 1fr auto auto
        - grid-template-columns: 1fr
      custom_fields:
        status:
          - justify-self: center
          - font-size: 10px
          - color: var(--primary-text-color)
      icon:
        - color: |
            [[[
              return states['sensor.p1s_01p00c470401372_ams_1_tray_3'].attributes.color;
            ]]]
  - type: custom:button-card
    entity: sensor.p1s_01p00c470401372_ams_1_tray_4
    icon: mdi:circle-slice-8
    name: Bambu PLA Basic
    show_icon: true
    show_name: true
    custom_fields:
      status: |
        [[[
          let percentage = parseFloat(states['sensor.tray_4_remaining_filament_percentage'].state) || 0;
          let remainingMeters = (percentage / 100) * 335;
          return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
        ]]]
    styles:
      card:
        - height: 130px
        - font-size: 12px
      grid:
        - grid-template-areas: "\"i\" \"n\" \"status\""
        - grid-template-rows: 1fr auto auto
        - grid-template-columns: 1fr
      custom_fields:
        status:
          - justify-self: center
          - font-size: 10px
          - color: var(--primary-text-color)
      icon:
        - color: |
            [[[
              return states['sensor.p1s_01p00c470401372_ams_1_tray_4'].attributes.color;
            ]]]

1 Like

oh, I hardcoded the name, derp.

fixed card

type: horizontal-stack
cards:
  - type: custom:button-card
    entity: sensor.p1s_01p00c470401372_ams_1_tray_1
    icon: mdi:printer-3d-nozzle
    name: |
      [[[
        return states['sensor.p1s_01p00c470401372_ams_1_tray_1'].attributes.name || 'Unknown Filament';
      ]]]
    show_icon: true
    show_name: true
    custom_fields:
      status: |
        [[[
          let percentage = parseFloat(states['sensor.p1s_01p00c470401372_ams_1_tray_1'].attributes.remain) || 0;
          let remainingMeters = (percentage / 100) * 335;
          return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
        ]]]
    styles:
      card:
        - height: 130px
        - font-size: 12px
      grid:
        - grid-template-areas: "\"i\" \"n\" \"status\""
        - grid-template-rows: 1fr auto auto
        - grid-template-columns: 1fr
      custom_fields:
        status:
          - justify-self: center
          - font-size: 10px
          - color: var(--primary-text-color)
      icon:
        - color: |
            [[[
              return states['sensor.p1s_01p00c470401372_ams_1_tray_1'].attributes.color || '#FFFFFF';
            ]]]
  - type: custom:button-card
    entity: sensor.p1s_01p00c470401372_ams_1_tray_2
    icon: mdi:printer-3d-nozzle
    name: |
      [[[
        return states['sensor.p1s_01p00c470401372_ams_1_tray_2'].attributes.name || 'Unknown Filament';
      ]]]
    show_icon: true
    show_name: true
    custom_fields:
      status: |
        [[[
          let percentage = parseFloat(states['sensor.p1s_01p00c470401372_ams_1_tray_2'].attributes.remain) || 0;
          let remainingMeters = (percentage / 100) * 335;
          return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
        ]]]
    styles:
      card:
        - height: 130px
        - font-size: 12px
      grid:
        - grid-template-areas: "\"i\" \"n\" \"status\""
        - grid-template-rows: 1fr auto auto
        - grid-template-columns: 1fr
      custom_fields:
        status:
          - justify-self: center
          - font-size: 10px
          - color: var(--primary-text-color)
      icon:
        - color: |
            [[[
              return states['sensor.p1s_01p00c470401372_ams_1_tray_2'].attributes.color || '#FFFFFF';
            ]]]
  - type: custom:button-card
    entity: sensor.p1s_01p00c470401372_ams_1_tray_3
    icon: mdi:printer-3d-nozzle
    name: |
      [[[
        return states['sensor.p1s_01p00c470401372_ams_1_tray_3'].attributes.name || 'Unknown Filament';
      ]]]
    show_icon: true
    show_name: true
    custom_fields:
      status: |
        [[[
          let percentage = parseFloat(states['sensor.p1s_01p00c470401372_ams_1_tray_3'].attributes.remain) || 0;
          let remainingMeters = (percentage / 100) * 335;
          return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
        ]]]
    styles:
      card:
        - height: 130px
        - font-size: 12px
      grid:
        - grid-template-areas: "\"i\" \"n\" \"status\""
        - grid-template-rows: 1fr auto auto
        - grid-template-columns: 1fr
      custom_fields:
        status:
          - justify-self: center
          - font-size: 10px
          - color: var(--primary-text-color)
      icon:
        - color: |
            [[[
              return states['sensor.p1s_01p00c470401372_ams_1_tray_3'].attributes.color || '#FFFFFF';
            ]]]
  - type: custom:button-card
    entity: sensor.p1s_01p00c470401372_ams_1_tray_4
    icon: mdi:printer-3d-nozzle
    name: |
      [[[
        return states['sensor.p1s_01p00c470401372_ams_1_tray_4'].attributes.name || 'Unknown Filament';
      ]]]
    show_icon: true
    show_name: true
    custom_fields:
      status: |
        [[[
          let percentage = parseFloat(states['sensor.p1s_01p00c470401372_ams_1_tray_4'].attributes.remain) || 0;
          let remainingMeters = (percentage / 100) * 335;
          return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
        ]]]
    styles:
      card:
        - height: 130px
        - font-size: 12px
      grid:
        - grid-template-areas: "\"i\" \"n\" \"status\""
        - grid-template-rows: 1fr auto auto
        - grid-template-columns: 1fr
      custom_fields:
        status:
          - justify-self: center
          - font-size: 10px
          - color: var(--primary-text-color)
      icon:
        - color: |
            [[[
              return states['sensor.p1s_01p00c470401372_ams_1_tray_4'].attributes.color || '#FFFFFF';
            ]]]

1 Like

Great addition. I will probably steal this and merge it with the op gist.

Final :tm: version

type: horizontal-stack
cards:
  - type: custom:button-card
    entity: sensor.p1s_01p00c470401372_ams_1_tray_1
    icon: mdi:printer-3d-nozzle
    name: |
      [[[
        let tray = "Tray 1";
        let filamentType = states['sensor.p1s_01p00c470401372_ams_1_tray_1'].attributes.type || 'Unknown Type';
        return tray + " | " + filamentType;
      ]]]
    show_icon: true
    show_name: true
    custom_fields:
      filament_name: |
        [[[
          return states['sensor.p1s_01p00c470401372_ams_1_tray_1'].attributes.name || 'Unknown Filament';
        ]]]
      status: |
        [[[
          let percentage = parseFloat(states['sensor.p1s_01p00c470401372_ams_1_tray_1'].attributes.remain) || 0;
          let remainingMeters = (percentage / 100) * 335;
          return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
        ]]]
    styles:
      card:
        - height: 130px
        - font-size: 12px
      grid:
        - grid-template-areas: "\"i\" \"n\" \"filament_name\" \"status\""
        - grid-template-rows: auto auto auto auto
        - grid-template-columns: 1fr
      custom_fields:
        filament_name:
          - justify-self: center
          - font-size: 12px
          - font-weight: bold
          - color: var(--primary-text-color)
          - white-space: normal
          - text-align: center
          - overflow: hidden
      status:
        - justify-self: center
        - font-size: 10px
        - color: var(--primary-text-color)
      icon:
        - color: |
            [[[
              return states['sensor.p1s_01p00c470401372_ams_1_tray_1'].attributes.color || '#FFFFFF';
            ]]]
  - type: custom:button-card
    entity: sensor.p1s_01p00c470401372_ams_1_tray_2
    icon: mdi:printer-3d-nozzle
    name: |
      [[[
        let tray = "Tray 2";
        let filamentType = states['sensor.p1s_01p00c470401372_ams_1_tray_2'].attributes.type || 'Unknown Type';
        return tray + " | " + filamentType;
      ]]]
    show_icon: true
    show_name: true
    custom_fields:
      filament_name: |
        [[[
          return states['sensor.p1s_01p00c470401372_ams_1_tray_2'].attributes.name || 'Unknown Filament';
        ]]]
      status: |
        [[[
          let percentage = parseFloat(states['sensor.p1s_01p00c470401372_ams_1_tray_2'].attributes.remain) || 0;
          let remainingMeters = (percentage / 100) * 335;
          return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
        ]]]
    styles:
      card:
        - height: 130px
        - font-size: 12px
      grid:
        - grid-template-areas: "\"i\" \"n\" \"filament_name\" \"status\""
        - grid-template-rows: auto auto auto auto
        - grid-template-columns: 1fr
      custom_fields:
        filament_name:
          - justify-self: center
          - font-size: 12px
          - font-weight: bold
          - color: var(--primary-text-color)
          - white-space: normal
          - text-align: center
          - overflow: hidden
      status:
        - justify-self: center
        - font-size: 10px
        - color: var(--primary-text-color)
      icon:
        - color: |
            [[[
              return states['sensor.p1s_01p00c470401372_ams_1_tray_2'].attributes.color || '#FFFFFF';
            ]]]
  - type: custom:button-card
    entity: sensor.p1s_01p00c470401372_ams_1_tray_3
    icon: mdi:printer-3d-nozzle
    name: |
      [[[
        let tray = "Tray 3";
        let filamentType = states['sensor.p1s_01p00c470401372_ams_1_tray_3'].attributes.type || 'Unknown Type';
        return tray + " | " + filamentType;
      ]]]
    show_icon: true
    show_name: true
    custom_fields:
      filament_name: |
        [[[
          return states['sensor.p1s_01p00c470401372_ams_1_tray_3'].attributes.name || 'Unknown Filament';
        ]]]
      status: |
        [[[
          let percentage = parseFloat(states['sensor.p1s_01p00c470401372_ams_1_tray_3'].attributes.remain) || 0;
          let remainingMeters = (percentage / 100) * 335;
          return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
        ]]]
    styles:
      card:
        - height: 130px
        - font-size: 12px
      grid:
        - grid-template-areas: "\"i\" \"n\" \"filament_name\" \"status\""
        - grid-template-rows: auto auto auto auto
        - grid-template-columns: 1fr
      custom_fields:
        filament_name:
          - justify-self: center
          - font-size: 12px
          - font-weight: bold
          - color: var(--primary-text-color)
          - white-space: normal
          - text-align: center
          - overflow: hidden
      status:
        - justify-self: center
        - font-size: 10px
        - color: var(--primary-text-color)
      icon:
        - color: |
            [[[
              return states['sensor.p1s_01p00c470401372_ams_1_tray_3'].attributes.color || '#FFFFFF';
            ]]]
  - type: custom:button-card
    entity: sensor.p1s_01p00c470401372_ams_1_tray_4
    icon: mdi:printer-3d-nozzle
    name: |
      [[[
        let tray = "Tray 4";
        let filamentType = states['sensor.p1s_01p00c470401372_ams_1_tray_4'].attributes.type || 'Unknown Type';
        return tray + " | " + filamentType;
      ]]]
    show_icon: true
    show_name: true
    custom_fields:
      filament_name: |
        [[[
          return states['sensor.p1s_01p00c470401372_ams_1_tray_4'].attributes.name || 'Unknown Filament';
        ]]]
      status: |
        [[[
          let percentage = parseFloat(states['sensor.p1s_01p00c470401372_ams_1_tray_4'].attributes.remain) || 0;
          let remainingMeters = (percentage / 100) * 335;
          return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
        ]]]
    styles:
      card:
        - height: 130px
        - font-size: 12px
      grid:
        - grid-template-areas: "\"i\" \"n\" \"filament_name\" \"status\""
        - grid-template-rows: auto auto auto auto
        - grid-template-columns: 1fr
      custom_fields:
        filament_name:
          - justify-self: center
          - font-size: 12px
          - font-weight: bold
          - color: var(--primary-text-color)
          - white-space: normal
          - text-align: center
          - overflow: hidden
      status:
        - justify-self: center
        - font-size: 10px
        - color: var(--primary-text-color)
      icon:
        - color: |
            [[[
              return states['sensor.p1s_01p00c470401372_ams_1_tray_4'].attributes.color || '#FFFFFF';
            ]]]

can you share your code please?

Sure thing.

views:
  - type: sections
    title: Bambu Lab P1S
    path: bambu-lab-p1s
    sections:
      - type: grid
        cards:
          - type: heading
            heading: Bambu Lab P1S
            heading_style: title
            badges: []
          - type: custom:mushroom-chips-card
            chips:
              - type: entity
                entity: sensor.p1s_01p00c470300106_nozzle_temperature
                icon: mdi:printer-3d-nozzle-heat
              - type: entity
                entity: sensor.p1s_01p00c470300106_bed_temperature
                icon: mdi:train-car-flatbed
              - type: entity
                entity: sensor.p1s_01p00c470300106_remaining_time
                content_info: state
              - type: template
                content: >-
                  {{
                  time_since((states('sensor.p1s_01p00c470300106_start_time')|as_datetime).astimezone(),
                  precision=2)}}
                icon: mdi:timer-sand-complete
                tap_action:
                  action: none
                hold_action:
                  action: none
              - type: entity
                entity: sensor.p1s_01p00c470300106_speed_profile
                icon: mdi:speedometer
              - type: template
                tap_action:
                  action: none
                hold_action:
                  action: none
                double_tap_action:
                  action: none
                icon: mdi:lightning-bolt
                content: >-
                  {{ (states('sensor.0xa4c138c1ddcf344d_energy')|float(0) -
                  states('sensor.print_start_energy')|float(0))|round(2) }} kWh
          - type: custom:mushroom-template-card
            primary: '{{ state_translated(''sensor.p1s_01p00c470300106_current_stage'') }}'
            secondary: >-
              {{ states(entity) }}% (layer {{
              states('sensor.p1s_01p00c470300106_current_layer') }} of {{
              states('sensor.p1s_01p00c470300106_total_layer_count') }})
            icon: mdi:printer-3d-nozzle
            icon_color: '{{ state_attr(entity, ''color'') }}'
            entity: sensor.p1s_01p00c470300106_print_progress
            fill_container: false
            grid_options:
              columns: 12
              rows: 1
          - type: picture-elements
            elements:
              - type: state-icon
                entity: button.p1s_01p00c470300106_resume_printing
                style:
                  left: 90%
                  top: 80%
                  '--mdc-icon-size': 70px
              - type: state-icon
                entity: button.p1s_01p00c470300106_stop_printing
                style:
                  left: 80%
                  top: 80%
                  '--mdc-icon-size': 70px
              - type: state-icon
                entity: button.p1s_01p00c470300106_pause_printing
                style:
                  left: 70%
                  top: 80%
                  '--mdc-icon-size': 70px
            camera_view: live
            camera_image: camera.p1s_01p00c470300106_camera
          - type: horizontal-stack
            cards:
              - type: vertical-stack
                cards:
                  - type: heading
                    icon: mdi:palette-outline
                    heading: EXT
                    heading_style: title
                  - type: custom:mushroom-chips-card
                    chips:
                      - type: template
                        icon_color: >-
                          {{
                          state_attr('sensor.p1s_01p00c470300106_externalspool_external_spool',
                          'color')[:7] }}
                        icon: >-
                          {% if
                          state_attr('sensor.p1s_01p00c470300106_externalspool_external_spool',
                          'active') == true %}mdi:check-circle {% else
                          %}mdi:circle{% endif %}
                        picture: ''
                        content: ''
                    alignment: start
              - type: vertical-stack
                cards:
                  - type: heading
                    icon: mdi:palette-outline
                    heading: AMS
                    heading_style: title
                    badges:
                      - type: entity
                        show_state: true
                        show_icon: true
                        entity: sensor.p1s_01p00c470300106_ams_1_humidity_index
                  - type: custom:mushroom-chips-card
                    chips:
                      - type: template
                        icon_color: >-
                          {{
                          state_attr('sensor.p1s_01p00c470300106_ams_1_tray_1',
                          'color') }}
                        icon: >-
                          {% if
                          state_attr('sensor.p1s_01p00c470300106_ams_1_tray_1',
                          'active') == true %}mdi:check-circle {% else
                          %}mdi:circle{% endif %}
                        picture: ''
                        content: ''
                      - type: template
                        icon_color: >-
                          {{
                          state_attr('sensor.p1s_01p00c470300106_ams_1_tray_2',
                          'color') }}
                        icon: >-
                          {% if
                          state_attr('sensor.p1s_01p00c470300106_ams_1_tray_2',
                          'active') == true %}mdi:check-circle {% else
                          %}mdi:circle{% endif %}
                        picture: ''
                        content: ''
                      - type: template
                        icon_color: >-
                          {{
                          state_attr('sensor.p1s_01p00c470300106_ams_1_tray_3',
                          'color') }}
                        icon: >-
                          {% if
                          state_attr('sensor.p1s_01p00c470300106_ams_1_tray_3',
                          'active') == true %}mdi:check-circle {% else
                          %}mdi:circle{% endif %}
                        picture: ''
                        content: ''
                      - type: template
                        icon_color: >-
                          {{
                          state_attr('sensor.p1s_01p00c470300106_ams_1_tray_4',
                          'color') }}
                        icon: >-
                          {% if
                          state_attr('sensor.p1s_01p00c470300106_ams_1_tray_4',
                          'active') == true %}mdi:check-circle {% else
                          %}mdi:circle{% endif %}
                        picture: ''
                        content: ''
                    alignment: justify
          - type: horizontal-stack
            cards:
              - show_name: true
                show_icon: true
                type: button
                tap_action:
                  action: toggle
                entity: light.p1s_01p00c470300106_chamber_light
                name: Light
              - show_name: true
                show_icon: true
                type: button
                entity: select.p1s_01p00c470300106_printing_speed
                name: Speed
                show_state: false
              - show_name: true
                show_icon: true
                type: button
                tap_action:
                  action: more-info
                entity: switch.0xa4c138c1ddcf344d
                icon: mdi:power
                name: Power
              - show_name: true
                show_icon: true
                type: button
                entity: number.p1s_01p00c470300106_bed_target_temperature
                icon: mdi:train-car-flatbed
                name: Bed
                show_state: true
              - show_name: true
                show_icon: true
                type: button
                entity: number.p1s_01p00c470300106_nozzle_target_temperature
                name: Nozzle
                show_state: true
            title: Control
        column_span: 1
        visibility:
          - condition: state
            entity: switch.0xa4c138c1ddcf344d
            state: 'on'
      - type: grid
        cards:
          - type: heading
            heading: Bambu Lab P1S
            heading_style: title
            badges: []
          - show_name: false
            show_icon: true
            type: button
            tap_action:
              action: toggle
            entity: switch.0xa4c138c1ddcf344d
            grid_options:
              columns: 12
              rows: 2
            icon: mdi:power
        visibility:
          - condition: state
            entity: switch.0xa4c138c1ddcf344d
            state: 'off'
    cards: []
    max_columns: 1

Thank you :slight_smile:

I have one suggetion to your code, to avoid negative value on custom filament change it to this:

    [[[
      let percentage = parseFloat(states['sensor.p1s_ams_1_slot_1'].attributes.remain) || 0;
      let remainingMeters = (percentage / 100) * 335;
      if (remainingMeters > 0) {
      return percentage.toFixed(1) + '% | ' + remainingMeters.toFixed(1) + 'm';
      }
    ]]]