System Monitoring - How does yours look?

For the bar-char look for bar-card on HACS

type: custom:bar-card
name: HDD
positions:
  icon: outside
  name: inside
color: '#17A589'
entities:
  - entity: sensor.disk_use_percent_home

And this is the code for the router cards.

type: vertical-stack
cards:
  - type: horizontal-stack
    cards:
      - show_name: true
        show_icon: false
        type: custom:button-card
        tap_action:
          action: none
        name: ANTARES
        color_type: card
        color: rgb(50,78,78)
        hold_action:
          action: none
        styles:
          card:
            - height: 10px
  - type: entities
    entities:
      - type: custom:button-card
        entity: binary_sensor.velop_mesh_wan_status
        show_name: false
        icon: hass:web
        size: 75px
        tap_action:
          action: none
        custom_fields:
          attr_dns_servers: '[[[ return entity.attributes.dns ]]]'
          attr_public_ip: '[[[ return entity.attributes.ip ]]]'
          attr_speedtest_latest: |
            [[[
              var entity_speedtest = states['sensor.velop_mesh_speedtest_latest']          
              var d = new Date(entity_speedtest.state)
              return d.toLocaleString()
            ]]]
          attr_speedtest_details: |
            [[[
              var round2 = (num) => Math.round(num * 100) / 100
              var spacing_internal = 5
              var spacing_external = 30
              var icon_size = 22
              var entity_speedtest = states['sensor.velop_mesh_speedtest_latest']
              var latency = entity_speedtest.attributes.latency
              var download_bandwidth = round2(entity_speedtest.attributes.download_bandwidth / 1000)
              var upload_bandwidth = round2(entity_speedtest.attributes.upload_bandwidth / 1000)        

              return `<span style="margin-right: ${spacing_external}px;">
                        <ha-icon icon="hass:swap-horizontal" style="width: ${icon_size}px;"></ha-icon>
                        <span>${latency}ms</span>
                      </span>
                      <span style="margin-right: ${spacing_external}px;">
                        <ha-icon icon="hass:cloud-download-outline" style="width: ${icon_size}px;"></ha-icon>
                        <span>${download_bandwidth} Mbps</span>
                      </span>
                      <span>
                        <ha-icon icon="hass:cloud-upload-outline" style="width: ${icon_size}px;"></ha-icon>
                        <span>${upload_bandwidth} Mbps</span>
                      </span>
                      `
            ]]]
        state:
          - value: 'on'
            color: darkcyan
          - value: 'off'
            color: darkred
        styles:
          card:
            - box-shadow: none
            - padding: 16px 8px
          grid:
            - grid-template-areas: >-
                "attr_dns_servers . attr_public_ip" "i i i"
                "attr_speedtest_details attr_speedtest_details
                attr_speedtest_details" "attr_speedtest_latest
                attr_speedtest_latest attr_speedtest_latest"
            - grid-template-rows: 5% 1fr 15% 5%
            - grid-template-columns: 1fr min-content 1fr
          custom_fields:
            attr_dns_servers:
              - justify-self: self-start
            attr_public_ip:
              - justify-self: self-end
        extra_styles: >
          div[id^="attr_"] { font-size: smaller; color:
          var(--disabled-text-color);

          }

          div[id^="attr_speedtest_"] { margin-top: 10px; }

          #attr_speedtest_latest::before { content: 'As at:' }

          #attr_public_ip::before { content: 'Public IP: ' }

          #attr_dns_servers::before { content: 'DNS: ' }
      - type: conditional
        conditions:
          - entity: binary_sensor.velop_mesh_speedtest_status
            state: 'on'
        row:
          type: section
      - type: custom:template-entity-row
        condition: '{{ is_state(''binary_sensor.velop_mesh_speedtest_status'', ''on'') }}'
        name: >-
          {{ state_attr('binary_sensor.velop_mesh_speedtest_status', 'status')
          }}
        tap_action:
          action: none
        card_mod:
          style: >
            state-badge { display: none; } state-badge + div.info { margin-left:
            8px !important; margin-right: 8px; text-align: center; }
      - type: section
      - type: custom:auto-entities
        card:
          type: horizontal-stack
        card_param: cards
        sort:
          method: friendly_name
        filter:
          include:
            - entity_id: /^(button|switch)\.velop_mesh_/
              options:
                type: custom:button-card
                hold_action:
                  action: more-info
                tap_action:
                  action: >-
                    [[[ return (entity.entity_id.startsWith("button")) ?
                    "call-service" : "toggle" ]]]
                  service: >-
                    [[[ return (entity.entity_id.startsWith("button")) ?
                    "button.press" : undefined ]]]
                  service_data:
                    entity_id: entity
                name: |-
                  [[[
                    var friendly_name = entity.attributes.friendly_name.replace("Velop Mesh:", "").trim()
                    var idx = friendly_name.lastIndexOf(" ");
                    var ret = friendly_name.substring(0, idx) + "<br />" + friendly_name.substring(idx + 1)
                    return ret
                  ]]]
                styles:
                  card:
                    - box-shadow: none
                    - margin-bottom: 3px
                  icon:
                    - animation: |-
                        [[[
                          var ret
                          if (entity.entity_id == "button.velop_mesh_start_speedtest" && states["binary_sensor.velop_mesh_speedtest_status"].state == "on") {
                            ret = "rotating 2s linear infinite"
                          }
                          return ret
                        ]]]
                    - color: |-
                        [[[ 
                          var ret
                          var col_on = "darkcyan"
                          var col_off = "var(--primary-text-color)"
                          ret = (entity.state == "on") ? col_on : col_off
                          if (entity.entity_id == "button.velop_mesh_start_speedtest") {
                            ret = (states["binary_sensor.velop_mesh_speedtest_status"].state == "on") ? col_on : col_off
                          }
                          return ret
                        ]]]
                  name:
                    - font-size: smaller
                    - color: |-
                        [[[
                          var ret
                          var col_on = "darkcyan"
                          var col_off = "var(--primary-text-color)"
                          ret = (entity.state == "on") ? col_on : col_off
                          if (entity.entity_id == "button.velop_mesh_start_speedtest") {
                            ret = (states["binary_sensor.velop_mesh_speedtest_status"].state == "on") ? col_on : col_off
                          }
                          return ret
                        ]]]
      - type: section
      - type: custom:fold-entity-row
        padding: 0
        head:
          type: custom:template-entity-row
          entity: sensor.velop_mesh_online_devices
          tap_action:
            action: fire-dom-event
            fold_row: true
          name: >-
            {% set friendly_name = state_attr(config.entity, 'friendly_name') %}
            {% if friendly_name %}
              {{ friendly_name.split(':')[1].strip() }}
            {% endif %}
          card_mod:
            style: |
              .info.pointer { font-weight: 500; }
              .state { margin-right: 10px; }
        entities:
          - type: custom:hui-element
            card_type: markdown
            card_mod:
              style:
                .: |
                  ha-card { border-radius: 0px; box-shadow: none; }
                  ha-markdown { padding: 16px 0px 0px !important; }
                ha-markdown$: >
                  table { width: 100%; border-collapse: separate;
                  border-spacing: 0px; }

                  tbody tr:nth-child(2n+1) { background-color:
                  var(--table-row-background-color); }

                  thead tr th, tbody tr td { padding: 4px 10px; }
            content: >
              {% set devices = state_attr('sensor.velop_mesh_online_devices',
              'devices') %} | # | Name | IP | Type |

              |:---:|:---|---:|:---:| {%- for device in devices -%}
                {% set idx = loop.index %}
                {%- for device_name, device_details in device.items() -%}
                  {%- set device_ip = device_details.ip -%}
                  {%- set connection_type = device_details.connection | lower -%}
                  {%- set guest_network = device_details.guest_network -%}
                  {%- if connection_type == "wired" -%}
                    {%- set connection_icon = "ethernet" -%}
                  {% elif connection_type == "wireless" -%}
                    {%- set connection_icon = "wifi" -%}
                  {% elif connection_type == "unknown" -%}
                    {%- set connection_icon = "help" -%}
                  {% else -%}
                    {%- set connection_icon = "" -%}
                  {%- endif %}
              {{ "| {} | {}{} | {} | {} |".format(idx, device_name,
              '&nbsp;<ha-icon icon="hass:account-multiple"></ha-icon>' if
              guest_network else '', device_ip, '<ha-icon icon="hass:' ~
              connection_icon ~ '"></ha-icon>') }}
                {%- endfor %}
              {%- endfor %}
      - type: custom:fold-entity-row
        padding: 0
        head:
          type: custom:template-entity-row
          entity: sensor.velop_mesh_offline_devices
          tap_action:
            action: fire-dom-event
            fold_row: true
          name: >-
            {% set friendly_name = state_attr(config.entity, 'friendly_name') %}
            {% if friendly_name %}
              {{ friendly_name.split(':')[1].strip() }}
            {% endif %}
          card_mod:
            style: |
              .info.pointer { font-weight: 500; }
              .state { margin-right: 10px; }
        entities:
          - type: custom:hui-element
            card_type: markdown
            card_mod:
              style:
                .: |
                  ha-card { border-radius: 0px; box-shadow: none; }
                  ha-markdown { padding: 16px 0px 0px !important; }
                ha-markdown$: >
                  table { width: 100%; border-collapse: separate;
                  border-spacing: 0px; }

                  tbody tr:nth-child(2n+1) { background-color:
                  var(--table-row-background-color); }

                  thead tr th, tbody tr td { padding: 4px 10px; }
            content: >
              {% set devices = state_attr('sensor.velop_mesh_offline_devices',
              'devices') %}

              | # | Name |

              |:---:|:---|

              {% for device in devices %} {{ "| {} | {} |".format(loop.index,
              device) }}

              {% endfor %}
      - type: conditional
        conditions:
          - entity: sensor.velop_mesh_available_storage
            state_not: '0'
          - entity: sensor.velop_mesh_available_storage
            state_not: unavailable
        row:
          type: custom:fold-entity-row
          padding: 0
          head:
            type: section
            label: Storage
          entities:
            - type: custom:hui-element
              card_type: markdown
              card_mod:
                style:
                  .: |
                    ha-card { border-radius: 0px; box-shadow: none; }
                    ha-markdown { padding: 16px 0px 0px !important; }
                  ha-markdown$: >
                    table { width: 100%; border-collapse: separate;
                    border-spacing: 0px; }        

                    tbody tr:nth-child(2n+1) { background-color:
                    var(--table-row-background-color); }

                    thead tr th, tbody tr td { padding: 4px 10px; }
              content: >
                {% set partitions =
                state_attr('sensor.velop_mesh_available_storage', 'partitions')
                %}

                | Host | Label | %age used

                |:---:|:---:|:---:|

                {% for partition in partitions %} {{ "| {} | {} | {}
                |".format(partition.ip, partition.label, partition.used_percent)
                }}

                {% endfor %}
    state_color: false
    card_mod:
      style:
        .: |
          #states { padding-top: 0px; }
        fold-entity-row:
          $:
            template-entity-row:
              $: |
                state-badge { display: none; }
                state-badge + div { margin-left: 8px !important; }
                .info.pointer { font-weight: 500; }
                .state { margin-right: 10px; }
  - type: custom:auto-entities
    card:
      type: vertical-stack
    card_param: cards
    sort:
      method: friendly_name
      reverse: false
    filter:
      include:
        - entity_id: /^binary_sensor\.velop_(?!(mesh)).*_status/
          options:
            type: custom:config-template-card
            variables:
              BUTTONS: |
                () => {
                  var ret = []
                  var entity_prefix = "button." + "this.entity_id".split(".")[1].split("_").slice(0, -1).join("_")
                  for (var entity_id in states) {
                    if (entity_id.startsWith(entity_prefix)) {
                      var entity_action = states[entity_id].attributes.friendly_name.split(':')[1].trim()
                      var entity_name = states[entity_id].attributes.friendly_name.split(':')[0].replace('Velop', '').trim()
                      ret.push({
                        'entity': entity_id,
                        'name': entity_action,
                        'tap_action': {
                            'action': 'call-service',
                            'service': 'linksys_velop.' + entity_action.toLowerCase() + '_node',
                            'service_data': {
                              'node_name': entity_name,
                            },
                            'confirmation': {
                              'text': 'Are you sure you want to reboot the ' + entity_name + ' node?'
                          }
                        }
                      })
                    }
                  }
                  return ret
                }
              ID_CONNECTED_DEVICES: >
                "sensor." + "this.entity_id".split(".")[1].split("_").slice(0,
                -1).join("_") + "_connected_devices"
              ID_ENTITY_PICTURE: >
                "sensor." + "this.entity_id".split(".")[1].split("_").slice(0,
                -1).join("_") + "_image"
              ID_LAST_UPDATE_CHECK: >
                "sensor." + "this.entity_id".split(".")[1].split("_").slice(0,
                -1).join("_") + "_last_update_check"
              ID_MODEL: >
                "sensor." +
                "this.entity_id".split(".")[1].split("_").slice(0,-1).join("_")
                + "_model"
              ID_PARENT: >
                "sensor." +
                "this.entity_id".split(".")[1].split("_").slice(0,-1).join("_")
                + "_parent"
              ID_SERIAL: >
                "sensor." +
                "this.entity_id".split(".")[1].split("_").slice(0,-1).join("_")
                + "_serial"
              ID_UPDATE_AVAILABLE: >
                "update." +
                "this.entity_id".split(".")[1].split("_").slice(0,-1).join("_")
                + "_update"
              CONNECTED_DEVICES_TEXT: |
                (entity_id) => {
                  var ret = `
                | # | Name | IP | Type |
                |:---:|:---|---:|:---:|
                `
                  if (states[entity_id].attributes.devices) {
                    states[entity_id].attributes.devices.forEach((device, idx) => {
                      var connection_icon
                      switch (device.type.toLowerCase()) {
                        case "wireless":
                          connection_icon = "wifi"
                          break
                        case "wired":
                          connection_icon = "ethernet"
                          break
                        case "unknown":
                          connection_icon = "help"
                          break
                      }
                      ret += "| " + (idx + 1) + " | " + device.name + ((device.guest_network) ? "&nbsp;<ha-icon icon='hass:account-multiple'></ha-icon>" : "") + " | " + device.ip + " | <ha-icon icon='hass:" + connection_icon + "'></ha-icon> |\n"
                    })
                  }
                  return ret
                }
              getEntityPicture: |
                () => {
                  if (states[vars['ID_ENTITY_PICTURE']]) {
                    return states[vars['ID_ENTITY_PICTURE']].state
                  } else {
                    return '/local/velop_nodes/' + states[vars['ID_MODEL']].state + '.png'
                  }
                }
            entities:
              - this.entity_id
              - ${ID_CONNECTED_DEVICES}
              - ${ID_LAST_UPDATE_CHECK}
              - ${ID_MODEL}
              - ${ID_PARENT}
              - ${ID_SERIAL}
              - ${ID_UPDATE_AVAILABLE}
            card:
              type: entities
              card_mod:
                style:
                  .: |
                    #states { padding-top: 0px; }
                  fold-entity-row:
                    $:
                      template-entity-row:
                        $: |
                          state-badge { display: none; }
                          state-badge + div { margin-left: 8px !important; }
                          .info.pointer { font-weight: 500; }
                          .state { margin-right: 10px; }
              entities:
                - type: custom:button-card
                  entity: this.entity_id
                  size: 100%
                  show_entity_picture: true
                  show_last_changed: true
                  show_state: true
                  tap_action:
                    action: none
                  entity_picture: ${ getEntityPicture() }
                  name: |
                    [[[
                      var ret = entity.attributes.friendly_name
                      if (ret) {
                        ret = ret.replace("Velop", "").split(":")[0].trim()
                      }
                      return ret || "N/A"
                    ]]]
                  state_display: |
                    [[[
                      return `<ha-icon 
                        icon="hass:checkbox-blank-circle"
                        style="width: 24px; height: 24px;">
                        </ha-icon>`
                    ]]]
                  custom_fields:
                    attr_label_model: Model
                    attr_model: ${states[ID_MODEL].state}
                    attr_label_serial: Serial
                    attr_serial: ${states[ID_SERIAL].state}
                    attr_parent: >-
                      ${(states[ID_PARENT].state && states[ID_PARENT].state !=
                      'unknown') ? 'Connected to ' + states[ID_PARENT].state :
                      'N/A'}
                    attr_label_ip: IP Address
                    attr_ip: '[[[ return entity.attributes.ip || ''N/A'' ]]]'
                    attr_update: |
                      [[[
                        var ret
                        var entity_update = 'update.' + entity.entity_id.split('.')[1].split('_').slice(0, -1).join('_') + '_update'
                        var update_available = states[entity_update].state
                        if (update_available == 'on') {
                          ret = `<ha-icon
                              icon="hass:package-up"
                              style="width: 24px; height: 20px;"
                            >
                            </ha-icon>`
                        }
                        return ret
                      ]]]
                  extra_styles: >
                    div[id^="attr_"] { justify-self: start; }
                    div[id^="attr_label_"] { justify-self: start; margin-left:
                    20px; } #label, #attr_parent { padding-top: 25px; font-size:
                    smaller; }
                  styles:
                    card:
                      - box-shadow: none
                      - padding: 10px 8px
                    grid:
                      - grid-template-areas: >-
                          "n n attr_update s" "i attr_label_model
                          attr_label_model attr_model" "i attr_label_serial
                          attr_label_serial attr_serial" "i attr_label_ip
                          attr_label_ip attr_ip" "l l l attr_parent "
                      - grid-template-columns: 30% 1fr 30px 150px
                    name:
                      - font-size: large
                      - justify-self: start
                      - padding-bottom: 20px
                    label:
                      - justify-self: start
                    custom_fields:
                      attr_label_last_update_check:
                        - margin-left: 0px
                      attr_last_update_check:
                        - justify-self: end
                      attr_parent:
                        - justify-self: end
                      attr_update:
                        - color: darkred
                        - justify-self: end
                        - padding-bottom: 25px
                      attr_label_model:
                        - color: white
                        - font-size: 16px
                        - justify-self: start
                      attr_label_serial:
                        - color: white
                        - font-size: 16px
                        - justify-self: start
                      attr_label_ip:
                        - color: white
                        - font-size: 16px
                        - justify-self: start
                      attr_model:
                        - color: darkwhite
                        - font-size: 12px
                        - justify-self: end
                      attr_serial:
                        - color: darkwhite
                        - font-size: 12px
                        - justify-self: end
                      attr_ip:
                        - color: darkwhite
                        - font-size: 12px
                        - justify-self: end
                    state:
                      - justify-self: end
                      - padding-bottom: 20px
                      - color: |-
                          [[[
                            return (entity.state == 'on' ? 'darkcyan' : 'darkred')
                          ]]]
                - type: custom:auto-entities
                  show_empty: true
                  card:
                    type: custom:fold-entity-row
                    head:
                      type: section
                      label: Additional Information
                    padding: 0
                  filter:
                    include:
                      - entity_id: ${ID_LAST_UPDATE_CHECK}
                        options:
                          name: Last update check
                      - entity_id: ${ID_PARENT}
                        not:
                          state: unknown
                        options:
                          type: custom:template-entity-row
                          name: Backhaul
                          state: >-
                            {% set backhaul_info = state_attr(config.entity,
                            'backhaul') %} {% set backhaul_speed =
                            backhaul_info.speed_mbps | round(2) %} {% if
                            (backhaul_speed | string).split('.')[1] == '0' %}
                              {% set backhaul_speed = backhaul_speed | int %}
                            {% endif %} {{ backhaul_info.connection }} ({{
                            backhaul_speed }} Mbps)
                - type: custom:auto-entities
                  show_empty: false
                  filter:
                    include:
                      - domain: button
                        entity_id: >-
                          ${"/" +
                          "this.entity_id".split(".")[1].split("_").slice(0,-1).join("_")
                          + "/"}
                  card:
                    type: custom:fold-entity-row
                    padding: 0
                    head:
                      type: section
                      label: Actions
                    entities:
                      - type: buttons
                        entities: ${BUTTONS()}
                - type: section
                - type: custom:fold-entity-row
                  padding: 0
                  head:
                    type: custom:template-entity-row
                    tap_action:
                      action: fire-dom-event
                      fold_row: true
                    entity: ${ID_CONNECTED_DEVICES}
                    name: >-
                      {% set name = state_attr(config.entity, 'friendly_name')
                      %} {% if name %}
                        {{ name.split(':')[1].strip() }}
                      {% endif %}
                  entities:
                    - type: custom:hui-element
                      card_type: markdown
                      content: ${CONNECTED_DEVICES_TEXT(ID_CONNECTED_DEVICES)}
                      card_mod:
                        style:
                          .: |
                            ha-card { border-radius: 0px; box-shadow: none; }
                            ha-markdown { padding: 16px 0px 0px !important; }
                          ha-markdown$: >
                            table { width: 100%; border-collapse: collapse; }

                            tbody tr:nth-child(2n+1) { background-color:
                            var(--table-row-background-color); }

                            thead tr th, tbody tr td { padding: 4px 10px; }

1 Like

Thanks @RomanFdez, thats really helpful (great work too!)

1 Like

This setup for showing multiple temperature looks great. I was not able to find it on the repository. Is it available? Or even a sample code. I am using the card already for my server vitals and love it

Anyone knowing how to get disk throughput (read / write local disk) as a sensor? Like this which is from a virtual environment (outside HA):

Bild

Setup: Raspberry Pi with HA OS. Does the supervisor has this information?

Thanks all for the inspiration, now I just need to create a dashboard for everything else

type: custom:stack-in-card
keep:
  border_radius: true
  margin: true
cards:
  - type: custom:button-card
    name: Network Server
    entity_picture: /local/images/raspberry-pi.png
    show_name: true
    show_entity_picture: true
    styles:
      card:
        - padding: 5px
        - border: 0px
      grid:
        - grid-template-areas: '"n i"'
        - grid-template-columns: 3fr 1fr
      name:
        - justify-self: start
        - padding-left: 20px
        - font-size: 30px
        - font-weight: 300
  - type: horizontal-stack
    cards:
      - type: custom:mini-graph-card
        entities:
          - sensor.networkserver_cpu_usage
        hours_to_show: 24
        points_per_hour: 2
        hour24: true
        animate: true
        height: 150
        show:
          extrema: true
          icon: false
          name: false
        color_thresholds:
          - value: 100
            color: '#d32f2f'
          - value: 90
            color: '#ffa000'
          - value: 75
            color: '#388e3c'
        card_mod:
          style: |
            ha-card .states.flex{
              padding-bottom: 0px;
              }
            ha-card .graph{
              margin-top: 0px !important;
            }
            ha-card .graph .graph__legend{
              padding-bottom: 0px !important;
            }
            ha-card .info.flex{
              padding-bottom: 0px !important;
            }
      - type: custom:mini-graph-card
        entities:
          - sensor.networkserver_temperature
        hours_to_show: 24
        points_per_hour: 2
        hour24: true
        animate: true
        height: 150
        show:
          extrema: true
          icon: false
          name: false
        color_thresholds:
          - value: 100
            color: '#d32f2f'
          - value: 85
            color: '#ffa000'
          - value: 60
            color: '#388e3c'
        card_mod:
          style: |
            ha-card .states.flex{
              padding-bottom: 0px;
              }
            ha-card .graph{
              margin-top: 0px !important;
            }
            ha-card .graph .graph__legend{
              padding-bottom: 0px !important;
            }
            ha-card .info.flex{
              padding-bottom: 0px !important;
            }
  - type: horizontal-stack
    cards:
      - type: custom:bar-card
        entities:
          - sensor.networkserver_cpu_usage
        name: CPU Usage
        positions:
          icon: 'off'
          name: inside
          value: inside
          indicator: inside
        severity:
          - color: '#d32f2f'
            from: 90
            to: 100
          - color: '#ffa000'
            from: 75
            to: 90
          - color: '#388e3c'
            from: 0
            to: 75
        card_mod:
          style: |
            bar-card-backgroundbar {
              border-radius: 8px;
            }
            bar-card-currentbar {
              border-radius: 8px;
            }
      - type: custom:bar-card
        entities:
          - sensor.networkserver_temperature
        name: CPU Temp
        positions:
          icon: 'off'
          name: inside
          value: inside
          indicator: inside
        severity:
          - color: '#d32f2f'
            from: 85
            to: 100
          - color: '#ffa000'
            from: 60
            to: 85
          - color: '#388e3c'
            from: 0
            to: 60
        card_mod:
          style: |
            bar-card-backgroundbar {
              border-radius: 8px;
            }
            bar-card-currentbar {
              border-radius: 8px;
            }
  - type: horizontal-stack
    cards:
      - type: custom:bar-card
        entities:
          - entity: sensor.networkserver_load_1m
            name: Load 1m
          - entity: sensor.networkserver_load_5m
            name: Load 5m
          - entity: sensor.networkserver_load_15m
            name: Load 15m
        stack: horizontal
        max: 4
        severity:
          - color: '#d32f2f'
            from: 2
            to: 4
          - color: '#ffa000'
            from: 1
            to: 2
          - color: '#388e3c'
            from: 0
            to: 1
        positions:
          icon: 'off'
          name: inside
          value: inside
          indicator: inside
        card_mod:
          style: |
            bar-card-card{
              margin-right: 20px
            }
            bar-card-backgroundbar {
              border-radius: 8px;
            }
            bar-card-currentbar {
              border-radius: 8px;
            }
  - type: custom:bar-card
    entities:
      - sensor.networkserver_memory_use
    name: Memory Usage
    width: 70%
    positions:
      icon: 'off'
      name: inside
      value: inside
      indicator: inside
    severity:
      - color: '#d32f2f'
        from: 90
        to: 100
      - color: '#ffa000'
        from: 75
        to: 90
      - color: '#388e3c'
        from: 0
        to: 75
    card_mod:
      style: |
        bar-card-backgroundbar {
          border-radius: 8px;
        }
        bar-card-currentbar {
          border-radius: 8px;
        }
  - type: custom:bar-card
    entities:
      - sensor.networkserver_disk_use
    name: Disk Usage
    width: 70%
    positions:
      icon: 'off'
      name: inside
      value: inside
      indicator: inside
    severity:
      - color: '#d32f2f'
        from: 90
        to: 100
      - color: '#ffa000'
        from: 75
        to: 90
      - color: '#388e3c'
        from: 0
        to: 75
    card_mod:
      style: |
        bar-card-backgroundbar {
          border-radius: 8px;
        }
        bar-card-currentbar {
          border-radius: 8px;
        }
  - type: custom:mini-graph-card
    entities:
      - entity: sensor.networkserver_network_download
        color: '#91C0F8'
        name: Download
      - entity: sensor.networkserver_network_upload
        color: '#ffa000'
        name: Upload
        show_state: true
    hours_to_show: 24
    points_per_hour: 2
    height: 75
    animate: true
    line_width: 2.5
    show:
      name: false
      icon: false
    card_mod:
      style: |
        ha-card .graph{
          margin-top: -15px !important;
        }
        ha-card .graph .graph__legend{
          padding-bottom: 0px !important;
        }
  - type: entities
    entities:
      - entity: sensor.networkserver_uptime
        name: Uptime
      - entity: sensor.networkserver_updates
        name: Packages
      - type: custom:fold-entity-row
        head:
          type: section
          label: Server Details
        card_mod:
          style:
            hui-sensor-entity-row:
              $ hui-generic-entity-row $: |
                .pointer{
                  color: #91C0F8;
                }
                .text-content{
                  color: #e1e1e1;
                }
            hui-simple-entity-row:
              $ hui-generic-entity-row $: |
                .pointer{
                  color: #91C0F8;
                }
                .text-content{
                  color: #e1e1e1;
                }
        entities:
          - entity: sensor.networkserver_hostname
            name: Hostname
          - entity: sensor.networkserver_host_ip
            name: IP Address
          - entity: sensor.networkserver_host_os
            name: OS
          - entity: sensor.networkserver_host_kernel
            name: Kernel
          - entity: sensor.networkserver_host_platform
            name: Platform
          - entity: sensor.networkserver_host_architecture
            name: Architecture
          - entity: binary_sensor.networkserver_under_voltage
            name: Power
          - entity: sensor.networkserver_last_message
            name: Last Refresh
    card_mod:
      style:
        hui-sensor-entity-row:
          $ hui-generic-entity-row $: |
            .pointer{
              color: #91C0F8;
            }
            .text-content{
              color: #e1e1e1;
            }
14 Likes

Great looking dashboard, kudos for sharing the code.

me too, would love to see the code plz

You can grab the above code copy+paste it all for the Network Server. Then copy paste for your other 3 servers and change the entities. That’ll make the total of 4.

type: custom:stack-in-card
keep:
  border_radius: true
  margin: true
cards:
  - type: custom:button-card
    name: **Network Server**
    entity_picture: /local/images/raspberry-pi.png
    show_name: true
    show_entity_picture: true
    styles:
etc
etc
etc

Hope to be of some help. Good luck!

2 Likes

I know this old, but can you share how you use the pythonscripts for this?
want to do it with windows and linux systems.
thanks for your help

Sure for the setup you can check this post.

To get the actual sensors, I isolated things in separate configuration file stored in /config/sensors_sys_monitoring.yaml

# 1NUC (Linux machine)
- platform: systemmonitor
  resources:
    - type: disk_use_percent
      arg: /
    - type: disk_use
      arg: /
    - type: disk_free
      arg: /
    - type: memory_use_percent
    - type: memory_use
    - type: memory_free
    - type: swap_use_percent
    - type: swap_use
    - type: swap_free
    - type: processor_use
    - type: processor_temperature
    - type: last_boot

- platform: python_script
  name: 1NUC Updates
  unique_id: "1nuc_updates"
  icon: mdi:package-up
  scan_interval: 120
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    cat /home/amilino/updatestatus.log

- platform: python_script
  name: 1NUC Model
  unique_id: "1nuc_model"
  icon: mdi:desktop-tower
  scan_interval: 63072000 #2 Years in seconds
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    sudo dmidecode -s system-product-name

- platform: python_script
  name: 1NUC Distribution
  unique_id: "1nuc_distribution"
  icon: mdi:monitor
  scan_interval: 63072000 #2 Years in seconds
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    grep -Po "(?<=^PRETTY_NAME=).+" /etc/os-release | sed 's/"//g'

- platform: python_script
  name: 1NUC Kernel
  unique_id: "1nuc_kernel"
  icon: mdi:developer-board
  scan_interval: 63072000 #2 Years in seconds
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    uname -msr

- platform: python_script
  name: 1NUC Processor
  unique_id: "1nuc_processor"
  icon: mdi:chip
  scan_interval: 63072000 #2 Years in seconds
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    grep -m 1 "model name" /proc/cpuinfo | sed -e "s/^.*: //"

- platform: python_script
  name: 1NUC Processor speed
  unique_id: "1nuc_processor_speed"
  unit_of_measurement: MHz
  icon: mdi:rotate-360
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    lscpu | grep "CPU MHz" | sed -e "s/^.*: //" | awk '{printf("%.f \n",$1)}'

- platform: python_script
  name: 1NUC Processor voltage
  unique_id: "1nuc_processor_voltage"
  unit_of_measurement: V
  icon: mdi:lightning-bolt-outline
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    sudo dmidecode --type processor | grep "Voltage" | grep -Eo "[0-9]+\.[0-9]+"

- platform: python_script
  name: 1NUC Processor mem x86_64
  unique_id: "1nuc_processor_mem_x86_64"
  unit_of_measurement: MiB
  icon: mdi:memory
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    helper_functions -kb2mborgb $(grep "Slab" /proc/meminfo | grep -Eo "[0-9]+") | sed 's/M//' | awk '{printf("%.f \n",$1)}'

- platform: python_script
  name: 1NUC Processor mem gpu
  unique_id: "1nuc_processor_mem_gpu"
  unit_of_measurement: MiB
  icon: mdi:expansion-card
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    lspci -v -s 00:02.0 | grep " prefetchable" | grep -Eo "[0-9]+[0-9]+[0-9]M" | sed 's/M//'

- platform: python_script
  name: 1NUC Processor scaling governor
  unique_id: "1nuc_processor_scaling_governor"
  icon: mdi:scale-balance
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

- platform: python_script
  name: 1NUC Top Processes cpu usage
  unique_id: "1nuc_processes_cpu_usage"
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    top -b -n 1 | grep -ve "jq" -ve "top" | awk 'FNR>=6 && FNR<=10{print $12, $9}' | jq -nR '{"return": [inputs | split(" ") | { "proc": .[0], "usage": .[1] }]}'

- platform: python_script
  name: 1NUC Top Processes memory usage
  unique_id: "1nuc_processes_memory_usage"
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    top -o %MEM -b -n 1 | grep -ve "jq" -ve "top" | awk 'FNR>=6 && FNR<=10{print $12, $10}' | jq -nR '{"return": [inputs | split(" ") | { "proc": .[0], "usage": .[1] }]}'

- platform: python_script
  name: 1NUC Processes
  unique_id: "1nuc_processes"
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: >
    sudo ps -N --format comm,etime,cmd | grep -v grep | grep -w "/usr/bin/kodi\|webgrabplus" | awk '{print $1, $2}' | jq -nR '{"return": [inputs | split(" ") | { "proc": .[0], "etime": .[1] }]}'

- platform: python_script
  name: 1NUC Services
  unique_id: "1nuc_services"
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 1nuc_host
  port: !secret 1nuc_port
  user: "amilino"
  pass: !secret 1nuc_amilino_password
  cmd: > 
    for i in "smbd" "ssh" "xrdp"; do printf "$i\t"; sudo service "$i" status | grep "Active: " | sed -e "s/^.*; //"; done | jq -nR '{"return": [inputs | split("\t") | { "service": .[0], "etime": .[1] }]}'

# 2NUC (Windows machine)
- platform: python_script
  name: 2NUC Processor
  unique_id: "2nuc_processor"
  icon: mdi:chip
  scan_interval: 63072000 #2 Years in seconds
  file: scripts/remote_ssh_command.py
  host: !secret 2nuc_host
  port: !secret 2nuc_port
  user: "amilino"
  pass: !secret 2nuc_amilino_password
  cmd: >
    wmic CPU get NAME | more +1

- platform: python_script
  name: 2NUC Model
  unique_id: "2nuc_model"
  icon: mdi:desktop-tower
  scan_interval: 63072000 #2 Years in seconds
  file: scripts/remote_ssh_command.py
  host: !secret 2nuc_host
  port: !secret 2nuc_port
  user: "amilino"
  pass: !secret 2nuc_amilino_password
  cmd: >
    powershell (Get-WmiObject -Class:Win32_ComputerSystem).Model

- platform: python_script
  name: 2NUC Distribution
  unique_id: "2nuc_distribution"
  icon: mdi:monitor
  scan_interval: 63072000 #2 Years in seconds
  file: scripts/remote_ssh_command.py
  host: !secret 2nuc_host
  port: !secret 2nuc_port
  user: "amilino"
  pass: !secret 2nuc_amilino_password
  cmd: >
    powershell (Get-WmiObject -class Win32_OperatingSystem).Caption

- platform: python_script
  name: 2NUC Processor use
  unique_id: "2nuc_processor_use"
  icon: mdi:cpu-64-bit
  unit_of_measurement: '%'
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 2nuc_host
  port: !secret 2nuc_port
  user: "amilino"
  pass: !secret 2nuc_amilino_password
  cmd: >
    powershell c:\\SystemMonitoring\\processor_use.ps1

- platform: python_script
  name: 2NUC Processor temperature
  unique_id: "2nuc_processor_temperature"
  icon: mdi:thermometer
  unit_of_measurement: 'ºC'
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 2nuc_host
  port: !secret 2nuc_port
  user: "amilino"
  pass: !secret 2nuc_amilino_password
  cmd: >
    powershell c:\\SystemMonitoring\\processor_temperature.ps1

- platform: python_script
  name: 2NUC Memory use percent
  unique_id: "2nuc_memory_use_percent"
  icon: mdi:memory
  unit_of_measurement: '%'
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 2nuc_host
  port: !secret 2nuc_port
  user: "amilino"
  pass: !secret 2nuc_amilino_password
  cmd: >
    powershell c:\\SystemMonitoring\\memory_use_percent.ps1

- platform: python_script
  name: 2NUC Memory use
  unique_id: "2nuc_memory_use"
  icon: mdi:memory
  unit_of_measurement: 'MiB'
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 2nuc_host
  port: !secret 2nuc_port
  user: "amilino"
  pass: !secret 2nuc_amilino_password
  cmd: >
    powershell c:\\SystemMonitoring\\memory_use.ps1

- platform: python_script
  name: 2NUC Memory free
  unique_id: "2nuc_memory_free"
  icon: mdi:memory
  unit_of_measurement: 'MiB'
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 2nuc_host
  port: !secret 2nuc_port
  user: "amilino"
  pass: !secret 2nuc_amilino_password
  cmd: >
    powershell c:\\SystemMonitoring\\memory_free.ps1

- platform: python_script
  name: 2NUC Last boot
  unique_id: "2nuc_last_boot"
  icon: mdi:clock
  scan_interval: 15
  file: scripts/remote_ssh_command.py
  host: !secret 2nuc_host
  port: !secret 2nuc_port
  user: "amilino"
  pass: !secret 2nuc_amilino_password
  cmd: >
    powershell c:\\SystemMonitoring\\last_boot.ps1

After you created file you need to add this into /config/configuration.yaml
sensor sys monitoring: !include sensors_sys_monitoring.yaml

For windows machine I created powershell files on windows machine itself (you also need OpenHardwareMonitor running in the background).
processor_use.ps1

# Check if Open Hardware Monitor is running.
if ((Get-Process -Name OpenHardwareMonitor -ErrorAction SilentlyContinue) -eq $null) {
    write-host 'OpenHardwareMonitor.exe not running!'
    exit 3
}

# Get the temperatures from all the found sensors and check them
$temperatures = Get-WmiObject -Namespace "Root\OpenHardwareMonitor" -Query "SELECT value FROM Sensor WHERE Name LIKE '%CPU Total%' AND Sensortype='Load'" | sort-object Identifier | select -First 1

$temperature_string = foreach ($result in $temperatures){
    '{0}' -f [math]::Round($result.Value)
}
 
write-host "$temperature_string"
exit 00

processor_temperature.ps1

# Check if Open Hardware Monitor is running.
if ((Get-Process -Name OpenHardwareMonitor -ErrorAction SilentlyContinue) -eq $null) {
    write-host 'OpenHardwareMonitor.exe not running!'
    exit 3
}

# Get the temperatures from all the found sensors and check them
$temperatures = Get-WmiObject -Namespace "Root\OpenHardwareMonitor" -Query "SELECT value FROM Sensor WHERE Name LIKE '%CPU Core%' AND Sensortype='Temperature'" | sort-object Identifier | select -First 1

$temperature_string = foreach ($result in $temperatures){
    '{0}' -f $result.Value
}
 
write-host "$temperature_string"
exit 0

memory_use_percent.ps1

# Check if Open Hardware Monitor is running.
if ((Get-Process -Name OpenHardwareMonitor -ErrorAction SilentlyContinue) -eq $null) {
    write-host 'OpenHardwareMonitor.exe not running!'
    exit 3
}

# Get the temperatures from all the found sensors and check them
$values= Get-WmiObject -Namespace "Root\OpenHardwareMonitor" -Query "SELECT value FROM Sensor WHERE Name = 'Memory' AND Sensortype='Load'" | sort-object Identifier | select -First 1

$value_string = foreach ($result in $values){
    '{0}' -f [math]::Round($result.Value,1) -Replace ',','.'
}
 
write-host "$value_string"
exit 0

memory_use.ps1

# Check if Open Hardware Monitor is running.
if ((Get-Process -Name OpenHardwareMonitor -ErrorAction SilentlyContinue) -eq $null) {
    write-host 'OpenHardwareMonitor.exe not running!'
    exit 3
}

# Get the temperatures from all the found sensors and check them
$values= Get-WmiObject -Namespace "Root\OpenHardwareMonitor" -Query "SELECT value FROM Sensor WHERE Name = 'Used Memory' AND Sensortype='Data'" | sort-object Identifier | select -First 1

$value_string = foreach ($result in $values){
    '{0}' -f [math]::Round($result.Value*1024,1) -Replace ',','.'
}
 
write-host "$value_string"
exit 0

memory_free.ps1

# Check if Open Hardware Monitor is running.
if ((Get-Process -Name OpenHardwareMonitor -ErrorAction SilentlyContinue) -eq $null) {
    write-host 'OpenHardwareMonitor.exe not running!'
    exit 3
}

# Get the temperatures from all the found sensors and check them
$values= Get-WmiObject -Namespace "Root\OpenHardwareMonitor" -Query "SELECT value FROM Sensor WHERE Name = 'Available Memory' AND Sensortype='Data'" | sort-object Identifier | select -First 1

$value_string = foreach ($result in $values){
    '{0}' -f [math]::Round($result.Value*1024,1) -Replace ',','.'
}
 
write-host "$value_string"
exit 0

last_boot.ps1

$os = Get-WmiObject -Class win32_operatingsystem 
$os.ConvertToDateTime($os.LastBootUpTime).ToString('yyyy-MM-ddTHH:mm:ss+00:00')

Let me know if you need as well code for the lovelace card.

1 Like

I have been using similar to your code for several years. They always worked well until 2023.4.x (not sure which release caused it to fail. Does yours still work?

I’m afraid I can’t say. I don’t use that anymore and I haven’t for a long, long time!

1 Like

If have been using the following code for a couple of years with no issues until core 2023.4x was released. Not sure which of the updates cause it to fail.

  - type: markdown
    title: Are Updates Available?
    card_mod:
      style: |
        :host {
          --card-mod-icon-color: #42a5f5;
          font-size: 1.1em;
        }
    content: |
      <ha-icon icon="mdi:home-assistant"></ha-icon>&nbsp;&nbsp;&nbsp;Add-ons needing update: &nbsp;&nbsp; {{ states('sensor.supervisor_updates') | default }}
      > {% for addon in state_attr('sensor.supervisor_updates', 'addons') %}
      >   &nbsp;&nbsp;{{ addon.name }}&nbsp; {{ addon.version }} -> {{ addon.version_latest }}
      > {% endfor %}
      
      <ha-icon icon="hacs:hacs"></ha-icon>&nbsp;&nbsp;&nbsp;HACS updates available: &nbsp;&nbsp; {{ states('sensor.hacs') | default }}
      > {% for repo in state_attr('sensor.hacs', 'repositories') %}
      >   &nbsp;&nbsp;{{ repo.display_name }} {{ repo["installed_version"] }} -> {{ repo["available_version"] }}
      > {% endfor %}
      
      |          |    Current | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Latest |
      |--- |:---: |:---: |:---: |
      | **Supervisor**&nbsp;&nbsp;&nbsp; | {{ state_attr('sensor.supervisor_updates', 'current_version') }} | | {{ state_attr('sensor.supervisor_updates', 'newest_version') }} |
      | **HassOS** | {{ states('sensor.home_assistant_operating_system_version') }} | | {{ states('sensor.home_assistant_operating_system_newest_version') }} |
      | **CORE** | {{ states.sensor.updater_core.attributes.current_version }} | | {{ states.sensor.updater_core.attributes.newest_version }} |
      | **Audio** | {{ states.sensor.updater_audio.attributes.current_version }} | | {{ states.sensor.updater_audio.attributes.newest_version }} |
      | **CLI** | {{ states.sensor.updater_cli.attributes.current_version }} | | {{ states.sensor.updater_cli.attributes.newest_version }} |
      | **DNS** | {{ states.sensor.updater_dns.attributes.current_version }} | | {{ states.sensor.updater_dns.attributes.newest_version }} |
      | **Multicast** | {{ states.sensor.updater_multicast.attributes.current_version }} | | {{ states.sensor.updater_multicast.attributes.newest_version }} |
      | **Observer** | {{ states.sensor.updater_observer.attributes.current_version }} | | {{ states.sensor.updater_observer.attributes.newest_version }} |

As I used many of the examples in this and other forums to build this card, I am not sure what is wrong with the code now. There are no errors in the logs. Just noting but the title showing on my screen. Any ideas on how to fix it?
Thanks.

what does it show in dev templates ?

Personally, I did away with most of these templates, and just added an auto-entities on domain update being on…

the more info HA integrations provide out of the box, the less we need to write our own investigator/monitor.

Not working in dev template. What I liked about it was in a small marked down card I saw the status of everything. I think there was a change and the template sensor no longer gets the correct information. I was pointed yesterday in discord to a GitHub issue talking about this . I have looked at other examples and I have not seen any that are as close to this one.

can you chop it up and provide a smaller template that does not work?

seems a bit weird that templates stopped working all of a sudden, and I cant imagine the whole set doesnt work. Maybe a smaller detail?

first strip al the markdown and then try each template selectively?

I believe it is my template sensors that stopped working not the card. I’ll post them when I get home.

My sensor codes:

sensor:
  # Sensor to track available updates for supervisor & addons
  - 
    platform: command_line
    name: Supervisor updates
    command: 'curl http://supervisor/supervisor/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"newest_version":.data.version_latest,"current_version":.data.version,"update_available":.data.update_available,"addons":[.data.addons[] | select(.update_available)]}'''
    value_template: "{{ value_json.addons | length }}"
    unit_of_measurement: pending update(s)
    json_attributes:
    - update_available
    - newest_version
    - current_version
    - addons
    

#end of part 1
#=========================
#----- Command_Line
#========================= 
  - platform: command_line
    name: Updater CLI
    command: 'curl http://supervisor/cli/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"newest_version":.data.version_latest,"current_version":.data.version}'''
    value_template: "{% if value_json.newest_version != value_json.current_version %}on{% else %}off{% endif %}"
    json_attributes:
      - newest_version
      - current_version
#=========================
#----- DNS Update
#=========================    
  - platform: command_line
    name: Updater DNS
    command: 'curl http://supervisor/dns/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"newest_version":.data.version_latest,"current_version":.data.version}'''
    value_template: "{% if value_json.newest_version != value_json.current_version %}on{% else %}off{% endif %}"
    json_attributes:
    - newest_version
    - current_version
#=========================
#----- Audio Update
#=========================    
  - platform: command_line
    name: Updater Audio
    command: 'curl http://supervisor/audio/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"newest_version":.data.version_latest,"current_version":.data.version}'''
    value_template: "{% if value_json.newest_version != value_json.current_version %}on{% else %}off{% endif %}"
    json_attributes:
    - newest_version
    - current_version
#=========================
#----- Multicast Update
#=========================    
  - platform: command_line
    name: Updater Multicast
    command: 'curl http://supervisor/multicast/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"newest_version":.data.version_latest,"current_version":.data.version}'''
    value_template: "{% if value_json.newest_version != value_json.current_version %}on{% else %}off{% endif %}"
    json_attributes:
    - newest_version
    - current_version
#=========================
#----- Observer Update
#=========================    
  - platform: command_line
    name: Updater observer
    command: 'curl http://supervisor/observer/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"newest_version":.data.version_latest,"current_version":.data.version}'''
    value_template: "{% if value_json.newest_version != value_json.current_version %}on{% else %}off{% endif %}"
    json_attributes:
    - newest_version
    - current_version


#=========================
#----- Core Update
#=========================    
  - platform: command_line
    name: Updater Core
    command: 'curl http://supervisor/core/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq ''{"newest_version":.data.version_latest,"current_version":.data.version, "update_available":.data.update_available}'''
    value_template: "{% if value_json.update_available %}on{% else %}off{% endif %}"
    json_attributes:
    - update_available
    - newest_version
    - current_version
#========================
#    os_agent
#========================
#  - platform: command_line
#    name: Updater Core
#    command: 'curl http://supervisor/os_agent/info -H "Authorization: Bearer $(printenv SUPERVISOR_TOKEN)" | jq #''{"newest_version":.data.version_latest,"current_version":.data.version, "update_available":.data.update_available}'''

#========================
#Hacs Update
#=========================
binary_sensor:
  - platform: template
    sensors:
      # True if there's an update available for supervisor
      updater_supervisor:
        friendly_name: 'Updater - Supervisor'
        device_class: problem
#        entity_id:
#fix entity id error        - sensor.supervisor_updates
        value_template: "{{ state_attr('sensor.supervisor_updates', 'current_version') != state_attr('sensor.supervisor_updates', 'newest_version') }}"
        availability_template: "{{ (states('sensor.supervisor_updates') | int(-1)) > -1 }}"

      # True if there's updates available for any HACS components
      updater_hacs:
        friendly_name: 'Updater - HACS'
        device_class: problem
        value_template: "{{ states('sensor.hacs')| int(0) > 0 }}"

      # True if there's updates available for any addons
      updater_addons:
        friendly_name: 'Updater - Addons'
        device_class: problem
        value_template: "{{ states('sensor.supervisor_updates') | int(0) > 0 }}"
alert:

  ha_update_available:
    name: HA has an update
    entity_id: binary_sensor.updater
    state: 'on'
    can_acknowledge: false
    repeat: 
    - 5
    - 360
    title: 'Update for HA available'
    message: "New version is {{ state_attr('binary_sensor.updater', 'newest_version') }}. Currently on {{ states('sensor.current_version') }}"
    notifiers:
    - Pixel XL_4
    data:
      tag: 'ha-update-available'
      url: 'https://192.168.1.48:8123/hassio/addon/core_check_config'

  # Supervisor update is available - un-acknowledgeable, auto-dismiss, me only
  supervisor_update_available:
    name: Supervisor has an update
    entity_id: binary_sensor.updater_supervisor
    state: 'on'
    can_acknowledge: false
    repeat: 360
    title: 'Update for HA Supervisor available'
    message: "New version is {{ state_attr('sensor.supervisor_updates', 'newest_version') }}. Currently on {{ state_attr('sensor.supervisor_updates', 'current_version') }}"
    notifiers:
    - Pixel XL_4
    - 'me'
    data:
      tag: 'supervisor-update-available'
      url: 'https://192.168.1.48:8123/hassio/dashboard'

  # HACS repos have updates available - acknowledgeable, auto-dismiss, me only
  hacs_update_available:
    name: HACS repos have updates
    entity_id: binary_sensor.updater_hacs
    state: 'on'
    can_acknowledge: false
    repeat: 360
    title: "Updates available in {{ states('sensor.hacs') | default (0) }} HACS repo{% if states('sensor.hacs') | default (0) | int(default=0) > 1 %}s{% endif %}"
    message: ""
    notifiers:
    - Pixel XL_4
    - 'me'
    data:
      tag: 'hacs-update-available'
      url: 'https://192.168.1.48:8123/hassio//hacs/installed'
#      ttl: 21600

  # Addons have updates available - acknowledgeable, auto-dismiss, me only
  addon_update_available:
    name: Addons have updates
    entity_id: binary_sensor.updater_addons
    state: 'on'
    can_acknowledge: false
    repeat: 360
    title: "Updates available for {{ states('sensor.supervisor_updates') }} HA addon{% if states('sensor.supervisor_updates') | int(0) > 1 %}s{% endif %}"
    message: ""
    notifiers:
    - Pixel XL_4
    
    data:
      tag: 'addon-update-available'
      url: 'https://192.168.1.48:8123/hassio/hassio/dashboard'

No errors in the log files.

What is the output in developer tools → templates as Marius asked for / recommended? Put the content of your markdown there and just double-check the output.

Be aware some rest sensor issues were noted. Maybe some of these are based on those ?

I mean command_line uses the same resources so maybe related .

Can you at least confirm these sensors to return correct output . If not ofc there is no use templating those