Skip to content

Conversation

zanix
Copy link
Contributor

@zanix zanix commented Mar 16, 2024

This updates the call to yaml.dump() which preserves the order and indentation in .storage/lovelace so the generated ui-lovelace.yaml file more closely matches the content of the UI editor.

Here is an example:

UI
title: Home
views:
  - title: Living
    theme: Backend-selected
    path: living
    type: custom:masonry-layout
    layout:
      max_cols: 2
    icon: mdi:sofa-single
    badges: []
    cards:
      - type: custom:decluttering-card
        template: chip_header
        variables:
          - primary: Living Room
          - icon: mdi:sofa-single
          - icon_color: orange
          - chips:
              - type: template
                entity: binary_sensor.ecobee_occupancy
                icon: |-
                  {%- if is_state("binary_sensor.ecobee_motion", "on") -%}
                    mdi:motion-sensor
                  {%- elif is_state(entity, "on") -%}
                    mdi:walk
                  {%- else -%}
                    mdi:motion-sensor-off
                  {%- endif -%}
                icon_color: |-
                  {%- if is_state("binary_sensor.ecobee_motion", "on") -%}
                    orange
                  {%- elif is_state(entity, "on") -%}
                    light-green
                  {%- else -%}
                    disabled
                  {%- endif -%}
                tap_action:
                  action: more-info
                hold_action:
                  action: none
              - type: entity
                entity: sensor.ecobee_current_temperature
              - type: entity
                entity: sensor.ecobee_current_humidity
              - type: template
                icon: mdi:remote-tv
                icon_color: orange
                tap_action:
                  action: fire-dom-event
                  browser_mod:
                    service: browser_mod.popup
                    data:
                      title: Living Room Remote
                      style: |
                        --popup-min-width: 380px;
                        --popup-max-width: 380px;
                      content:
                        type: custom:decluttering-card
                        template: shield_remote
                        variables:
                          - remote: remote.androidtv_living_room
                          - media: media_player.universal_living_room
              - type: template
                icon: mdi:dots-horizontal-circle
                icon_color: blue
                tap_action:
                  action: fire-dom-event
                  browser_mod:
                    service: browser_mod.popup
                    data:
                      title: Send Message
                      right_button: Send
                      right_button_action:
                        service: script.media_play
                        data:
                          media_player: media_player.cast_living_room_speaker
                          volume: 80
                      content:
                        - name: message
                          label: Message
                          selector:
                            select:
                              custom_value: true
                              options:
                                - label: Snack Time
                                  value: It's time for snacks!
                                - label: Lunch Time
                                  value: Hey, come get some lunch!
                                - label: Dinner Time
                                  value: It's time for dinner.
                                - label: Breakfast Time
                                  value: It's time for breakfast.
      - type: vertical-stack
        cards:
          - type: custom:decluttering-card
            template: title_chips
            variables:
              - title: Lights
              - chips:
                  - type: template
                    entity: light.living_room_lights
                    content: >-
                      {{ expand(entity) | selectattr("state", "==", "on") | list
                      | count }} / {{ expand(entity) | list | count }}
                    tap_action:
                      action: more-info
                    hold_action:
                      action: toggle
          - type: custom:mushroom-light-card
            entity: light.living_room
            name: Main
            show_brightness_control: true
            layout: horizontal
          - type: custom:mushroom-light-card
            entity: light.living_room_lamp
            name: Lamp
            show_brightness_control: true
            layout: horizontal
          - type: custom:mushroom-light-card
            entity: light.living_room_floor_lamp
            name: Floor Lamp
            show_color_temp_control: true
            show_brightness_control: true
            layout: horizontal
            double_tap_action:
              action: more-info
            hold_action:
              action: fire-dom-event
              browser_mod:
                service: browser_mod.popup
                data:
                  title: Floor Lamp
                  content:
                    type: custom:decluttering-card
                    template: light_wb_popup
                    variables:
                      - light: light.living_room_floor_lamp
          - type: grid
            square: false
            columns: 3
            cards:
              - type: custom:mushroom-light-card
                entity: light.hallway
                name: Hallway
                layout: vertical
                secondary_info: none
              - type: custom:mushroom-light-card
                entity: light.front_entry
                name: Entry
                layout: vertical
                secondary_info: none
              - type: custom:mushroom-light-card
                entity: light.garage_entry
                name: Garage Entry
                layout: vertical
                secondary_info: none
          - type: custom:mushroom-fan-card
            entity: fan.living_room_ceiling
            icon_animation: true
            show_percentage_control: true
            name: Fan
            layout: horizontal
      - type: vertical-stack
        cards:
          - type: custom:mushroom-title-card
            title: Media
          - type: conditional
            conditions:
              - condition: or
                conditions:
                  - entity: remote.harmony_living_room
                    state: unavailable
                  - entity: remote.harmony_living_room
                    state: unknown
            card:
              type: custom:mushroom-template-card
              primary: Harmony Unavailable
              icon: mdi:progress-question
          - type: conditional
            conditions:
              - entity: remote.harmony_living_room
                state_not: unavailable
              - entity: remote.harmony_living_room
                state_not: unknown
            card:
              type: grid
              columns: 2
              square: false
              cards:
                - type: custom:mushroom-template-card
                  primary: Shield
                  icon: mdi:motion-play-outline
                  entity: remote.harmony_living_room
                  icon_color: >-
                    {%- if has_value(entity) and is_state_attr(entity,
                    "current_activity", "Shield TV") -%}
                      green
                    {%- else -%}
                      grey
                    {%- endif -%}
                  tap_action:
                    action: call-service
                    service: remote.turn_on
                    data:
                      activity: Shield TV
                    target:
                      entity_id: remote.harmony_living_room
                - type: conditional
                  conditions:
                    - entity: remote.harmony_living_room
                      state: 'on'
                  card:
                    type: custom:mushroom-template-card
                    primary: Power
                    icon: mdi:power
                    entity: remote.harmony_living_room
                    icon_color: red
                    tap_action:
                      action: call-service
                      service: remote.turn_off
                      target:
                        entity_id: remote.harmony_living_room
          - type: conditional
            conditions:
              - entity: media_player.universal_living_room
                state_not: 'off'
              - entity: media_player.universal_living_room
                state_not: unavailable
              - entity: media_player.universal_living_room
                state_not: unknown
            card:
              type: custom:decluttering-card
              template: media_card
              variables:
                - entity: media_player.universal_living_room
                - sound_buttons:
                    - id: Straight
                      type: sound_mode
                      name: Direct
                      icon: mdi:surround-sound-5-1
                    - id: Surround
                      type: sound_mode
                      name: Surround
                      icon: mdi:surround-sound-2-1
                    - id: MCh Stereo
                      type: sound_mode
                      name: Multi-Channel
                      icon: mdi:surround-sound
          - type: custom:mini-media-player
            entity: media_player.cast_living_room_speaker
            name: Google Home
            icon: mdi:dots-horizontal-circle
            info: scroll
            hide:
              power: true
ReadMe (Before Fix)
title: Home
views:
- badges: []
  cards:
  - template: chip_header
    type: custom:decluttering-card
    variables:
    - primary: Living Room
    - icon: mdi:sofa-single
    - icon_color: orange
    - chips:
      - entity: binary_sensor.ecobee_occupancy
        hold_action:
          action: none
        icon: "{%- if is_state(\"binary_sensor.ecobee_motion\", \"on\") -%}\n  mdi:motion-sensor\n\
          {%- elif is_state(entity, \"on\") -%}\n  mdi:walk\n{%- else -%}\n  mdi:motion-sensor-off\n\
          {%- endif -%}"
        icon_color: "{%- if is_state(\"binary_sensor.ecobee_motion\", \"on\") -%}\n\
          \  orange\n{%- elif is_state(entity, \"on\") -%}\n  light-green\n{%- else\
          \ -%}\n  disabled\n{%- endif -%}"
        tap_action:
          action: more-info
        type: template
      - entity: sensor.ecobee_current_temperature
        type: entity
      - entity: sensor.ecobee_current_humidity
        type: entity
      - icon: mdi:remote-tv
        icon_color: orange
        tap_action:
          action: fire-dom-event
          browser_mod:
            data:
              content:
                template: shield_remote
                type: custom:decluttering-card
                variables:
                - remote: remote.androidtv_living_room
                - media: media_player.universal_living_room
              style: '--popup-min-width: 380px;

                --popup-max-width: 380px;

                '
              title: Living Room Remote
            service: browser_mod.popup
        type: template
      - icon: mdi:dots-horizontal-circle
        icon_color: blue
        tap_action:
          action: fire-dom-event
          browser_mod:
            data:
              content:
              - label: Message
                name: message
                selector:
                  select:
                    custom_value: true
                    options:
                    - label: Snack Time
                      value: It's time for snacks!
                    - label: Lunch Time
                      value: Hey, come get some lunch!
                    - label: Dinner Time
                      value: It's time for dinner.
                    - label: Breakfast Time
                      value: It's time for breakfast.
              right_button: Send
              right_button_action:
                data:
                  media_player: media_player.cast_living_room_speaker
                  volume: 80
                service: script.media_play
              title: Send Message
            service: browser_mod.popup
        type: template
  - cards:
    - template: title_chips
      type: custom:decluttering-card
      variables:
      - title: Lights
      - chips:
        - content: '{{ expand(entity) | selectattr("state", "==", "on") | list | count
            }} / {{ expand(entity) | list | count }}'
          entity: light.living_room_lights
          hold_action:
            action: toggle
          tap_action:
            action: more-info
          type: template
    - entity: light.living_room
      layout: horizontal
      name: Main
      show_brightness_control: true
      type: custom:mushroom-light-card
    - entity: light.living_room_lamp
      layout: horizontal
      name: Lamp
      show_brightness_control: true
      type: custom:mushroom-light-card
    - double_tap_action:
        action: more-info
      entity: light.living_room_floor_lamp
      hold_action:
        action: fire-dom-event
        browser_mod:
          data:
            content:
              template: light_wb_popup
              type: custom:decluttering-card
              variables:
              - light: light.living_room_floor_lamp
            title: Floor Lamp
          service: browser_mod.popup
      layout: horizontal
      name: Floor Lamp
      show_brightness_control: true
      show_color_temp_control: true
      type: custom:mushroom-light-card
    - cards:
      - entity: light.hallway
        layout: vertical
        name: Hallway
        secondary_info: none
        type: custom:mushroom-light-card
      - entity: light.front_entry
        layout: vertical
        name: Entry
        secondary_info: none
        type: custom:mushroom-light-card
      - entity: light.garage_entry
        layout: vertical
        name: Garage Entry
        secondary_info: none
        type: custom:mushroom-light-card
      columns: 3
      square: false
      type: grid
    - entity: fan.living_room_ceiling
      icon_animation: true
      layout: horizontal
      name: Fan
      show_percentage_control: true
      type: custom:mushroom-fan-card
    type: vertical-stack
  - cards:
    - title: Media
      type: custom:mushroom-title-card
    - card:
        icon: mdi:progress-question
        primary: Harmony Unavailable
        type: custom:mushroom-template-card
      conditions:
      - condition: or
        conditions:
        - entity: remote.harmony_living_room
          state: unavailable
        - entity: remote.harmony_living_room
          state: unknown
      type: conditional
    - card:
        cards:
        - entity: remote.harmony_living_room
          icon: mdi:motion-play-outline
          icon_color: "{%- if has_value(entity) and is_state_attr(entity, \"current_activity\"\
            , \"Shield TV\") -%}\n  green\n{%- else -%}\n  grey\n{%- endif -%}"
          primary: Shield
          tap_action:
            action: call-service
            data:
              activity: Shield TV
            service: remote.turn_on
            target:
              entity_id: remote.harmony_living_room
          type: custom:mushroom-template-card
        - card:
            entity: remote.harmony_living_room
            icon: mdi:power
            icon_color: red
            primary: Power
            tap_action:
              action: call-service
              service: remote.turn_off
              target:
                entity_id: remote.harmony_living_room
            type: custom:mushroom-template-card
          conditions:
          - entity: remote.harmony_living_room
            state: 'on'
          type: conditional
        columns: 2
        square: false
        type: grid
      conditions:
      - entity: remote.harmony_living_room
        state_not: unavailable
      - entity: remote.harmony_living_room
        state_not: unknown
      type: conditional
    - card:
        template: media_card
        type: custom:decluttering-card
        variables:
        - entity: media_player.universal_living_room
        - sound_buttons:
          - icon: mdi:surround-sound-5-1
            id: Straight
            name: Direct
            type: sound_mode
          - icon: mdi:surround-sound-2-1
            id: Surround
            name: Surround
            type: sound_mode
          - icon: mdi:surround-sound
            id: MCh Stereo
            name: Multi-Channel
            type: sound_mode
      conditions:
      - entity: media_player.universal_living_room
        state_not: 'off'
      - entity: media_player.universal_living_room
        state_not: unavailable
      - entity: media_player.universal_living_room
        state_not: unknown
      type: conditional
    - entity: media_player.cast_living_room_speaker
      hide:
        power: true
      icon: mdi:dots-horizontal-circle
      info: scroll
      name: Google Home
      type: custom:mini-media-player
    type: vertical-stack
  icon: mdi:sofa-single
  layout:
    max_cols: 2
  path: living
  theme: Backend-selected
  title: Living
  type: custom:masonry-layout
ReadMe (After Fix)
title: Home
views:
  - title: Living
    theme: Backend-selected
    path: living
    type: custom:masonry-layout
    layout:
      max_cols: 2
    icon: mdi:sofa-single
    badges: []
    cards:
      - type: custom:decluttering-card
        template: chip_header
        variables:
          - primary: Living Room
          - icon: mdi:sofa-single
          - icon_color: orange
          - chips:
              - type: template
                entity: binary_sensor.ecobee_occupancy
                icon: "{%- if is_state(\"binary_sensor.ecobee_motion\", \"on\") -%}\n\
                  \  mdi:motion-sensor\n{%- elif is_state(entity, \"on\") -%}\n  mdi:walk\n\
                  {%- else -%}\n  mdi:motion-sensor-off\n{%- endif -%}"
                icon_color: "{%- if is_state(\"binary_sensor.ecobee_motion\", \"on\"\
                  ) -%}\n  orange\n{%- elif is_state(entity, \"on\") -%}\n  light-green\n\
                  {%- else -%}\n  disabled\n{%- endif -%}"
                tap_action:
                  action: more-info
                hold_action:
                  action: none
              - type: entity
                entity: sensor.ecobee_current_temperature
              - type: entity
                entity: sensor.ecobee_current_humidity
              - type: template
                icon: mdi:remote-tv
                icon_color: orange
                tap_action:
                  action: fire-dom-event
                  browser_mod:
                    service: browser_mod.popup
                    data:
                      title: Living Room Remote
                      style: '--popup-min-width: 380px;

                        --popup-max-width: 380px;

                        '
                      content:
                        type: custom:decluttering-card
                        template: shield_remote
                        variables:
                          - remote: remote.androidtv_living_room
                          - media: media_player.universal_living_room
              - type: template
                icon: mdi:dots-horizontal-circle
                icon_color: blue
                tap_action:
                  action: fire-dom-event
                  browser_mod:
                    service: browser_mod.popup
                    data:
                      title: Send Message
                      right_button: Send
                      right_button_action:
                        service: script.media_play
                        data:
                          media_player: media_player.cast_living_room_speaker
                          volume: 80
                      content:
                        - name: message
                          label: Message
                          selector:
                            select:
                              custom_value: true
                              options:
                                - label: Snack Time
                                  value: It's time for snacks!
                                - label: Lunch Time
                                  value: Hey, come get some lunch!
                                - label: Dinner Time
                                  value: It's time for dinner.
                                - label: Breakfast Time
                                  value: It's time for breakfast.
      - type: vertical-stack
        cards:
          - type: custom:decluttering-card
            template: title_chips
            variables:
              - title: Lights
              - chips:
                  - type: template
                    entity: light.living_room_lights
                    content: '{{ expand(entity) | selectattr("state", "==", "on")
                      | list | count }} / {{ expand(entity) | list | count }}'
                    tap_action:
                      action: more-info
                    hold_action:
                      action: toggle
          - type: custom:mushroom-light-card
            entity: light.living_room
            name: Main
            show_brightness_control: true
            layout: horizontal
          - type: custom:mushroom-light-card
            entity: light.living_room_lamp
            name: Lamp
            show_brightness_control: true
            layout: horizontal
          - type: custom:mushroom-light-card
            entity: light.living_room_floor_lamp
            name: Floor Lamp
            show_color_temp_control: true
            show_brightness_control: true
            layout: horizontal
            double_tap_action:
              action: more-info
            hold_action:
              action: fire-dom-event
              browser_mod:
                service: browser_mod.popup
                data:
                  title: Floor Lamp
                  content:
                    type: custom:decluttering-card
                    template: light_wb_popup
                    variables:
                      - light: light.living_room_floor_lamp
          - type: grid
            square: false
            columns: 3
            cards:
              - type: custom:mushroom-light-card
                entity: light.hallway
                name: Hallway
                layout: vertical
                secondary_info: none
              - type: custom:mushroom-light-card
                entity: light.front_entry
                name: Entry
                layout: vertical
                secondary_info: none
              - type: custom:mushroom-light-card
                entity: light.garage_entry
                name: Garage Entry
                layout: vertical
                secondary_info: none
          - type: custom:mushroom-fan-card
            entity: fan.living_room_ceiling
            icon_animation: true
            show_percentage_control: true
            name: Fan
            layout: horizontal
      - type: vertical-stack
        cards:
          - type: custom:mushroom-title-card
            title: Media
          - type: conditional
            conditions:
              - condition: or
                conditions:
                  - entity: remote.harmony_living_room
                    state: unavailable
                  - entity: remote.harmony_living_room
                    state: unknown
            card:
              type: custom:mushroom-template-card
              primary: Harmony Unavailable
              icon: mdi:progress-question
          - type: conditional
            conditions:
              - entity: remote.harmony_living_room
                state_not: unavailable
              - entity: remote.harmony_living_room
                state_not: unknown
            card:
              type: grid
              columns: 2
              square: false
              cards:
                - type: custom:mushroom-template-card
                  primary: Shield
                  icon: mdi:motion-play-outline
                  entity: remote.harmony_living_room
                  icon_color: "{%- if has_value(entity) and is_state_attr(entity,\
                    \ \"current_activity\", \"Shield TV\") -%}\n  green\n{%- else\
                    \ -%}\n  grey\n{%- endif -%}"
                  tap_action:
                    action: call-service
                    service: remote.turn_on
                    data:
                      activity: Shield TV
                    target:
                      entity_id: remote.harmony_living_room
                - type: conditional
                  conditions:
                    - entity: remote.harmony_living_room
                      state: 'on'
                  card:
                    type: custom:mushroom-template-card
                    primary: Power
                    icon: mdi:power
                    entity: remote.harmony_living_room
                    icon_color: red
                    tap_action:
                      action: call-service
                      service: remote.turn_off
                      target:
                        entity_id: remote.harmony_living_room
          - type: conditional
            conditions:
              - entity: media_player.universal_living_room
                state_not: 'off'
              - entity: media_player.universal_living_room
                state_not: unavailable
              - entity: media_player.universal_living_room
                state_not: unknown
            card:
              type: custom:decluttering-card
              template: media_card
              variables:
                - entity: media_player.universal_living_room
                - sound_buttons:
                    - id: Straight
                      type: sound_mode
                      name: Direct
                      icon: mdi:surround-sound-5-1
                    - id: Surround
                      type: sound_mode
                      name: Surround
                      icon: mdi:surround-sound-2-1
                    - id: MCh Stereo
                      type: sound_mode
                      name: Multi-Channel
                      icon: mdi:surround-sound
          - type: custom:mini-media-player
            entity: media_player.cast_living_room_speaker
            name: Google Home
            icon: mdi:dots-horizontal-circle
            info: scroll
            hide:
              power: true

@ludeeus ludeeus merged commit e636745 into custom-components:main Jul 23, 2024
3 checks passed
@zanix zanix deleted the preserve-dashboard-order-and-indentation branch August 9, 2024 17:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

2 participants