šŸ“ 100% Templatable Lovelace Configurations

Here 2 templates:

  1. ā€œExcellentā€ etc in "secondary_info".
  2. In a separate column.
decluttering_templates:
  decl_test_david:
    card:
      type: 'custom:config-template-card'
      variables:
        varDEVICE: 'parseFloat(states[''[[SENSOR_DEVICE]]''].state)'
      entities:
        - '[[SENSOR_DEVICE]]'
        - '[[VALUE_DEVICE_NAME]]'
        - '[[SENSOR_DEVICE_STATUS]]'
        - '[[SENSOR_DEVICE_WIFI_CONNECT_COUNT]]'
        - '[[SENSOR_DEVICE_SIGNAL]]'
        - '[[SENSOR_DEVICE_RSSI]]'
      card:
        type: 'custom:mod-card'
        style:
          multiple-entity-row:
            $:
              hui-generic-entity-row:
                $: |
                  .info.pointer .secondary {
                    {% if states('[[SENSOR_DEVICE]]')|int >= 100 %}
                    color: green;
                    {% elif states('[[SENSOR_DEVICE]]')|int >= 80 %}
                    color: orange;
                    {% elif states('[[SENSOR_DEVICE]]')|int >= 60 %}
                    color: red;
                    {% else %}
                    color: magenta;
                    {% endif %}
                  }
        card:
          type: 'custom:multiple-entity-row'
          entity: '[[SENSOR_DEVICE]]'
          show_state: false
          name: '[[VALUE_DEVICE_NAME]]'
          icon: >-
            ${varDEVICE >= 100 ? "mdi:wifi" : (varDEVICE >= 80 ?
            "mdi:wifi-strength-3" : (varDEVICE >= 60 ? "mdi:wifi-strength-2" :
            "mdi:wifi-strength-1")) }
          secondary_info: >-
            ${ varDEVICE >= 100 ? "Excellent" : (varDEVICE >= 80 ? "Good" :
            (varDEVICE >= 60 ? "Fair" : "Weak"))}
          entities:
            - entity: '[[SENSOR_DEVICE_STATUS]]'
              name: MQTT
              styles:
                width: 23px
            - entity: '[[SENSOR_DEVICE_WIFI_CONNECT_COUNT]]'
              name: WiFi
              styles:
                width: 23px
            - entity: '[[SENSOR_DEVICE_SIGNAL]]'
              name: Signal
              styles:
                width: 48px
            - entity: '[[SENSOR_DEVICE_RSSI]]'
              name: RSSI
              styles:
                width: 38px
  decl_test_david_2:
    card:
      type: 'custom:config-template-card'
      variables:
        varDEVICE: 'parseFloat(states[''[[SENSOR_DEVICE]]''].state)'
      entities:
        - '[[SENSOR_DEVICE]]'
        - '[[VALUE_DEVICE_NAME]]'
        - '[[SENSOR_DEVICE_STATUS]]'
        - '[[SENSOR_DEVICE_WIFI_CONNECT_COUNT]]'
        - '[[SENSOR_DEVICE_SIGNAL]]'
        - '[[SENSOR_DEVICE_RSSI]]'
      card:
        type: 'custom:mod-card'
        style:
          multiple-entity-row:
            $:
              hui-generic-entity-row: |
                .entities-row div.entity:nth-child(1) div::before {
                  {% if states('[[SENSOR_DEVICE]]')|int >= 100 %}
                  color: green;
                  content: "Excellent\A";
                  {% elif states('[[SENSOR_DEVICE]]')|int >= 80 %}
                  color: orange;
                  content: "Good\A";
                  {% elif states('[[SENSOR_DEVICE]]')|int >= 60 %}
                  color: red;
                  content: "Fair\A";
                  {% else %}
                  color: magenta;
                  content: "Weak\A";
                  {% endif %}
                  line-height: var(--mdc-typography-body1-line-height, 1.5rem);
                  text-align: center;
                  white-space: pre;
                }
                .entities-row div.entity:nth-child(1) div {
                  color: transparent;
                  line-height: 0px;
                }
        card:
          type: 'custom:multiple-entity-row'
          entity: '[[SENSOR_DEVICE]]'
          show_state: false
          name: '[[VALUE_DEVICE_NAME]]'
          icon: >-
            ${varDEVICE >= 100 ? "mdi:wifi" : (varDEVICE >= 80 ?
            "mdi:wifi-strength-3" : (varDEVICE >= 60 ? "mdi:wifi-strength-2" :
            "mdi:wifi-strength-1")) }
          secondary_info: last-changed
          entities:
            - entity: '[[SENSOR_DEVICE]]'
              name: Quality
              styles:
                width: 55px
            - entity: '[[SENSOR_DEVICE_STATUS]]'
              name: MQTT
              styles:
                width: 23px
            - entity: '[[SENSOR_DEVICE_WIFI_CONNECT_COUNT]]'
              name: WiFi
              styles:
                width: 23px
            - entity: '[[SENSOR_DEVICE_SIGNAL]]'
              name: Signal
              styles:
                width: 48px
            - entity: '[[SENSOR_DEVICE_RSSI]]'
              name: RSSI
              styles:
                width: 38px

Both templates use the "config-template-card":

  1. For displaying an icon dependingly on the state.
  2. For displaying those ā€œExcellentā€ etc words in the "secondary-info" section (the 1st template).

Alternatively you may change the icon in the Config in an "icon_template" section (if possible).

How to use the templates:

type: entities
entities:
  - type: 'custom:decluttering-card'
    template: decl_test_david
    variables:
      - SENSOR_DEVICE: sensor.test_david_1_device
      - VALUE_DEVICE_NAME: Coffee
      - SENSOR_DEVICE_STATUS: sensor.test_david_1_device_status
      - SENSOR_DEVICE_WIFI_CONNECT_COUNT: sensor.test_david_1_wifi_connect_count
      - SENSOR_DEVICE_SIGNAL: sensor.test_david_1_signal
      - SENSOR_DEVICE_RSSI: sensor.test_david_1_rssi

How it looks like on desktop (Chrome) for both templates:
image

How it looks like in iPhone 5s (Safari):

Since the 2nd option is a kind of trick, I would recommend you to use the 1st option - it is more reliable.
Of course, those "::before" & "content" CSS things are supported with many browsers, but you decide yourself which option to choose.

P.S. I really like the "multiple-entity-row" - but it does not show "last-changed" for every item, this is rather important for me.

Omg!!!

I will give it a whirl. I do like the look of the second one and I donā€™t need secondary_info but can just leave that offā€¦ I will report back

THANK YOU

David, welcome!

If you decide to proceed with the 2nd option - consider changing the icon in the sensor itself (Config ā†’ icon_template) and then do not use the "config-template-card".
You may even decide to create a new template sensor with values ā€œExcellentā€ etc instead of using those "::before" & "content" CSS things. Then the "card-mod" will be used only for colourizing the ā€œExcellentā€ etc column.
The simpler - the better, I thinkā€¦

Ummmā€¦ why? I donā€™t see an option to do that. The sensor is created by the Tasmota integration.

Hmm yes but why?

Tried this:

decluttering_templates:
  dec_sonoff:
    card:
      type: 'custom:config-template-card'
      variables:
        varDEVICE: 'parseFloat(states[''[[SENSOR_DEVICE_RSSI]]''].state)'
      entities:
        - '[[SENSOR_DEVICE]]'
        - '[[VALUE_DEVICE_NAME]]'
        - '[[SENSOR_DEVICE_STATUS]]'
        - '[[SENSOR_DEVICE_WIFI_CONNECT_COUNT]]'
        - '[[SENSOR_DEVICE_SIGNAL]]'
        - '[[SENSOR_DEVICE_RSSI]]'
      card:
        type: 'custom:mod-card'
        style:
          multiple-entity-row:
            $:
              hui-generic-entity-row: |
                .entities-row div.entity:nth-child(1) div::before {
                  {% if states('[[SENSOR_DEVICE_RSSI]]')|int >= 100 %}
                  color: green;
                  content: "Excellent\A";
                  {% elif states('[[SENSOR_DEVICE_RSSI]]')|int >= 80 %}
                  color: orange;
                  content: "Good\A";
                  {% elif states('[[SENSOR_DEVICE_RSSI]]')|int >= 60 %}
                  color: red;
                  content: "Fair\A";
                  {% else %}
                  color: magenta;
                  content: "Weak\A";
                  {% endif %}
                  line-height: var(--mdc-typography-body1-line-height, 1.5rem);
                  text-align: center;
                  white-space: pre;
                }
                .entities-row div.entity:nth-child(1) div {
                  color: transparent;
                  line-height: 0px;
                }
        card:
          type: 'custom:multiple-entity-row'
          entity: '[[SENSOR_DEVICE]]'
          show_state: false
          name: '[[VALUE_DEVICE_NAME]]'
          icon: >-
            ${varDEVICE >= 100 ? "mdi:wifi" : (varDEVICE >= 80 ?
            "mdi:wifi-strength-3" : (varDEVICE >= 60 ? "mdi:wifi-strength-2" :
            "mdi:wifi-strength-1")) }
          secondary_info: last-changed
          entities:
            - entity: '[[SENSOR_DEVICE]]'
              name: Quality
              styles:
                width: 55px
            - entity: '[[SENSOR_DEVICE_STATUS]]'
              name: MQTT
              styles:
                width: 23px
            - entity: '[[SENSOR_DEVICE_WIFI_CONNECT_COUNT]]'
              name: WiFi
              styles:
                width: 23px
            - entity: '[[SENSOR_DEVICE_SIGNAL]]'
              name: Signal
              styles:
                width: 48px
            - entity: '[[SENSOR_DEVICE_RSSI]]'
              name: RSSI
              styles:
                width: 38px
type: entities
entities:
  - type: 'custom:decluttering-card'
    template: dec_sonoff
    variables:
      - SENSOR_DEVICE: sensor.coffee_maker_firmware
      - VALUE_DEVICE_NAME: Coffee
      - SENSOR_DEVICE_STATUS: sensor.coffee_maker_status
      - SENSOR_DEVICE_WIFI_CONNECT_COUNT: sensor.sonoff1_2914_wifi_connect_count
      - SENSOR_DEVICE_SIGNAL: sensor.sonoff1_2914_signal
      - SENSOR_DEVICE_RSSI: sensor.sonoff1_2914_rssi

And get this:
image

I cut and pasted all those entities into dev-tools states and they are all there





image

I seeā€¦ Of course, you may create a template sensor which repeats the original one. But may be using the "config-template-card" is better - you decide!
I heard that using custom cards with templating based on JS, Ninjia2 needs more CPU usage, and this may be crucial on slow systems.

This is just an option.
Iā€™m afraid that using "card-mod" for some particular card one day may stop working - just because an internal structure of the card is changed. So I prefer to choose a ā€œusualā€ way of doing something rather than those CSS tricks with "::after", "::before" & "content".

Regarding ā€œCannot read propertyā€.
Do you have the "decluttering-card" & "card-mod" installed?

Also, I see that the template & the card are in one ā€œcode pageā€ - are they in one file?
In GUI mode (which is not yaml mode) the template must be before the ā€œdashboardā€ section, and the code for a card must be inside some ā€œviewā€ section.

Ah that will explain it. I have them exactly as shown and both are installed. So I need to move the template to the top?
I use GUI mode but store and edit the raw file.
So I need to move the template above view:

title: Home
swipe_nav:
  wrap: true
  animate: swipe        # could also use fade or flip
  swipe_amount: 15
views:

Here?

Oh yeah that worksā€¦
Template 1

I probably need to adjust the spacing for portrait mode but I will have a go at this tomorrow and template 2 as wellā€¦

Like this:

decluttering_templates:
  decl_test_david:
    card:
      type: 'custom:config-template-card'
      .................
views:
  - title: '-----'
    path: '-----'
    badges: []
    cards:
      - type: entities
        entities:
          - entity: sensor.test_timestamp
            format: total
            ...................
1 Like

Also, David, if you like, you may display "last-changed" for every item:

Thanks but itā€™s not really useful for my use hereā€¦ the signal and RSSI jump around like a drunken sailorā€¦

I have actually a question hereā€¦ Where (or how) did you get that _firmware entity?
Iā€™ve checked my Tasmota Integration and I donā€™t have such entity (not even in the disabled list).

Iā€™m trying to replicate your same config (the goal was to provide you an even more shorter amount of code), but I am struggling to find that piece (not really important, but now Iā€™m curious :smiley: )

Thanks

Hahaha! Itā€™s a hack. I think itā€™s STATUS2 and I publish that to the group topic and then use a mqtt sensor with json_attributes to read it it. Itā€™s an upper PITA compared to the old MQTT discovery method. Check my github for the githun_sensors package. home-assistant/github_version_sensors.yaml at 81d01e00944884a724ef5deaa5af0a2a0f41c056 Ā· DavidFW1960/home-assistant Ā· GitHub Line 111ā€¦

Ah! Thatā€™s what I thought!

Thanks!

I do a status 11 as well because that returns interesting info as wellā€¦ even though the state Iā€™m getting is the same as one of the ones provided by the integration - but if I use that then when I click on the row I get all the other info as well in the pop up as I showed way up aboveā€¦ (Iā€™m only saying this because itā€™s not immediately obvious why Iā€™m doing that so if you suggest a new config just remember my end goal is the information in the pop ups as well as the formatting of the rssi etc)

So, basically what Iā€™m trying to do to reduce the code is this:
decluttering_card:

tasmota_info:
  card:
    type: 'custom:config-template-card'
    variables:
      - varDEVICE: parseFloat(states['sensor.[[device]]_rssi'].state)
    entities:
      - sensor.[[device]]_mqtt_connect_count
      - sensor.[[device]]_wifi_connect_count
      - sensor.[[device]]_signal
      - sensor.[[device]]_rssi
    card:
      type: 'custom:mod-card'
      style:
        multiple-entity-row:
          $:
            hui-generic-entity-row: |
              .entities-row div.entity:nth-child(1) div::before {
                {% if states(sensor.[[device]]_rssi)|int >= 100 %}
                color: green;
                content: "Excellent\A";
                {% elif states(sensor.[[device]]_rssi)|int >= 80 %}
                color: orange;
                content: "Good\A";
                {% elif states(sensor.[[device]]_rssi)|int >= 60 %}
                color: red;
                content: "Fair\A";
                {% else %}
                color: magenta;
                content: "Weak\A";
                {% endif %}
                line-height: var(--mdc-typography-body1-line-height, 1.5rem);
                text-align: center;
                white-space: pre;
              }
              .entities-row div.entity:nth-child(1) div {
                color: transparent;
                line-height: 0px;
              }
      card:
        type: 'custom:multiple-entity-row'
        entity: sensor.time
        show_state: false
        name: '[[device_name]]'
        icon: >-
          ${varDEVICE >= 100 ? "mdi:wifi" : (varDEVICE >= 80 ?
          "mdi:wifi-strength-3" : (varDEVICE >= 60 ? "mdi:wifi-strength-2" :
          "mdi:wifi-strength-1")) }
        secondary_info: last-changed
        entities:
          - entity: sensor.[[device]]_rssi
            name: Quality
            styles:
              width: 55px
          - entity: sensor.[[device]]_mqtt_connect_count
            name: MQTT
            styles:
              width: 23px
          - entity: sensor.[[device]]_wifi_connect_count
            name: WiFi
            styles:
              width: 23px
          - entity: sensor.[[device]]_signal
            name: Signal
            styles:
              width: 48px
          - entity: sensor.[[device]]_rssi
            name: RSSI
            styles:
              width: 38px

Entity code:

  - type: 'custom:decluttering-card'
    template: tasmota_info
    variables:
      - device: studio_desk_andrea_lamp
      - device_name: Lamp

So, the idea is that you provide the device and itā€™s name, and thatā€™s it, the rest is in the template so that you really need just to add 2 things for each item you want to be visualized.

Right now tho, it is not yet working.
Iā€™m pretty sure it should be possible because I use this on other templates, maybe @Ildar_Gabdullin spot something I did wrong?

Thatā€™s very nice indeed, would be even better if HA expose those two entities and related info automatically :stuck_out_tongue:

Ok, got it working! @DavidFW1960

Decluttering template:

tasmota_info:
  card:
    type: 'custom:config-template-card'
    variables:
      varDEVICE: 'parseFloat(states[''sensor.[[device]]_rssi''].state)'
    entities:
      - 'sensor.[[device]]_rssi'
      - 'sensor.[[device]]_signal'
      - 'sensor.[[device]]_mqtt_connect_count'
      - 'sensor.[[device]]_wifi_connect_count'
    card:
      type: 'custom:mod-card'
      style:
        multiple-entity-row:
          $:
            hui-generic-entity-row: |
              .entities-row div.entity:nth-child(1) div::before {
                {% if states('sensor.[[device]]_rssi')|int >= 100 %}
                color: green;
                content: "Excellent\A";
                {% elif states('sensor.[[device]]_rssi')|int >= 80 %}
                color: orange;
                content: "Good\A";
                {% elif states('sensor.[[device]]_rssi')|int >= 60 %}
                color: red;
                content: "Fair\A";
                {% else %}
                color: magenta;
                content: "Weak\A";
                {% endif %}
                line-height: var(--mdc-typography-body1-line-height, 1.5rem);
                text-align: center;
                white-space: pre;
              }
              .entities-row div.entity:nth-child(1) div {
                color: transparent;
                line-height: 0px;
              }
      card:
        type: 'custom:multiple-entity-row'
        entity: sensor.[[device]]_rssi
        show_state: false
        name: '[[device_name]]'
        icon: >-
          ${varDEVICE >= 100 ? "mdi:wifi-strength-4" : (varDEVICE >= 80 ?
          "mdi:wifi-strength-3" : (varDEVICE >= 60 ? "mdi:wifi-strength-2" :
          "mdi:wifi-strength-1")) }
        secondary_info: last-changed
        entities:
          - entity: sensor.[[device]]_rssi
            name: Quality
            styles:
              width: 55px
          - entity: sensor.[[device]]_mqtt_connect_count
            name: MQTT
            styles:
              width: 23px
          - entity: sensor.[[device]]_wifi_connect_count
            name: WiFi
            styles:
              width: 23px
          - entity: sensor.[[device]]_signal
            name: Signal
            styles:
              width: 48px
          - entity: sensor.[[device]]_rssi
            name: RSSI
            styles:
              width: 38px

Entitiy card:

  - type: entities
    entities:
      - type: 'custom:decluttering-card'
        template: tasmota_info
        variables:
          - device: studio_desk_andrea_lamp
          - device_name: Lamp Andrea
      - type: 'custom:decluttering-card'
        template: tasmota_info
        variables:
          - device: studio_desk_sonia_lamp
          - device_name: Lamp Sonia

Outcome:

Please note, I also changed ā€œmdi:wifiā€ to ā€œmdi:wifi-strength-4ā€ so that the icon always use the same format, it looks better that way in my own opinion, feel free to revert it if you prefer the other :slight_smile:

There is only 1 thing that I can see it might need to be improved which is the ā€œUnavailableā€ handling, so that if something is Unavailable it shows N/A instead of that long text :slight_smile:

I like this too.

Usually I do this kind of decluttering only if I am absolutely sure that names of these auto-generated entities will be always in the same format.

Could be done by using template sensor in Config.

OK, these things may be done:
image

  decl_test_david_4:
    card:
      type: 'custom:config-template-card'
      variables:
        varDEVICE: 'parseFloat(states[''sensor.[[DEVICE]]_rssi''].state)'
      entities:
        - 'sensor.[[DEVICE]]_rssi'
        - 'sensor.[[DEVICE]]_signal'
        - 'sensor.[[DEVICE]]_mqtt_connect_count'
        - 'sensor.[[DEVICE]]_wifi_connect_count'
      card:
        type: 'custom:mod-card'
        style:
          multiple-entity-row:
            $:
              hui-generic-entity-row: |
                .entities-row div.entity:nth-child(1) div::before {
                  {% if states('sensor.[[DEVICE]]_rssi')|int >= 100 %}
                  color: green;
                  content: "Excellent\A";
                  {% elif states('sensor.[[DEVICE]]_rssi')|int >= 80 %}
                  color: orange;
                  content: "Good\A";
                  {% elif states('sensor.[[DEVICE]]_rssi')|int >= 60 %}
                  color: red;
                  content: "Fair\A";
                  {% elif states('sensor.[[DEVICE]]_rssi') in ['unavailable','unknown'] %}
                  color: brown;
                  content: "N/A\A";
                  {% else %}
                  color: magenta;
                  content: "Weak\A";
                  {% endif %}
                  line-height: var(--mdc-typography-body1-line-height, 1.5rem);
                  text-align: center;
                  white-space: pre;
                }
                .entities-row div.entity:nth-child(1) div {
                  color: transparent;
                  line-height: 0px;
                }
                .entities-row div.entity:nth-child(2) div::before {
                  {% if states('sensor.[[DEVICE]]_mqtt_connect_count') in ['unavailable','unknown'] %}
                  color: brown;
                  content: "N/A\A";
                  line-height: var(--mdc-typography-body1-line-height, 1.5rem);
                  {% endif %}
                }
                .entities-row div.entity:nth-child(2) div {
                  {% if states('sensor.[[DEVICE]]_mqtt_connect_count') in ['unavailable','unknown'] %}
                  color: transparent;
                  line-height: 0px;
                  {% endif %}
                }
                .entities-row div.entity:nth-child(3) div::before {
                  {% if states('sensor.[[DEVICE]]_wifi_connect_count') in ['unavailable','unknown'] %}
                  color: brown;
                  content: "N/A\A";
                  line-height: var(--mdc-typography-body1-line-height, 1.5rem);
                  {% endif %}
                }
                .entities-row div.entity:nth-child(3) div {
                  {% if states('sensor.[[DEVICE]]_wifi_connect_count') in ['unavailable','unknown'] %}
                  color: transparent;
                  line-height: 0px;
                  {% endif %}
                }
                .entities-row div.entity:nth-child(4) div::before {
                  {% if states('sensor.[[DEVICE]]_signal') in ['unavailable','unknown'] %}
                  color: brown;
                  content: "N/A\A";
                  line-height: var(--mdc-typography-body1-line-height, 1.5rem);
                  {% endif %}
                }
                .entities-row div.entity:nth-child(4) div {
                  {% if states('sensor.[[DEVICE]]_signal') in ['unavailable','unknown'] %}
                  color: transparent;
                  line-height: 0px;
                  {% endif %}
                }
                .entities-row div.entity:nth-child(5) div::before {
                  {% if states('sensor.[[DEVICE]]_rssi') in ['unavailable','unknown'] %}
                  color: brown;
                  content: "N/A\A";
                  line-height: var(--mdc-typography-body1-line-height, 1.5rem);
                  {% endif %}
                }
                .entities-row div.entity:nth-child(5) div {
                  {% if states('sensor.[[DEVICE]]_rssi') in ['unavailable','unknown'] %}
                  color: transparent;
                  line-height: 0px;
                  {% endif %}
                }
                .entities-row {
                  justify-content: flex-start;
                  align-items: unset;
                }
        card:
          type: 'custom:multiple-entity-row'
          entity: 'sensor.[[DEVICE]]_rssi'
          show_state: false
          name: '[[DEVICE_NAME]]'
          icon: >-
            ${varDEVICE >= 100 ? "mdi:wifi-strength-4" : (varDEVICE >= 80 ?
            "mdi:wifi-strength-3" : (varDEVICE >= 60 ? "mdi:wifi-strength-2" :
            "mdi:wifi-strength-1")) }
          entities:
            - entity: 'sensor.[[DEVICE]]_rssi'
              name: Quality
              styles:
                width: 55px
            - entity: 'sensor.[[DEVICE]]_mqtt_connect_count'
              name: MQTT
              styles:
                width: 23px
            - entity: 'sensor.[[DEVICE]]_wifi_connect_count'
              name: WiFi
              styles:
                width: 23px
            - entity: 'sensor.[[DEVICE]]_signal'
              name: Signal
              styles:
                width: 48px
            - entity: 'sensor.[[DEVICE]]_rssi'
              name: RSSI
              styles:
                width: 38px

BUT - once again I propose you to use template sensors in the Config.
Otherwise you have to use a lot of CSS tricks & a lot of code - not sure it is really worth it.

Also, there is one thing here: using that "::before" etc method anyway causes a little horizontal misalignment. It is a little but it is there. So, that could be a nice trick but so far I do not recommend it.

Yeah I donā€™t like thatā€¦ Iā€™d actually prefer all the icons to use the wifi style with lines instead of fill. Iā€™m going to move the quality to be next to the RSSI as well instead of first column.
Will have a go in a bit and show result and code.