Template Sensor - Attribute filtering

Hi everyone,

I need help modifying the following template sensor to remove from the attribute devices, the duplicate entries which have the same MAC/IP, and node c8:7f:54:a1:c9:d8.

- sensor:
    - name: Asus Connected Devices
      unique_id: asus_connected_devices
      state_class: measurement
      icon: mdi:router-network
      state: >
        {{ states('sensor.router_connected_devices') }}
      attributes:
        devices: >
          {% set router_devices_list = state_attr('sensor.router_connected_devices', 'devices') | default([]) %}
          {% set kitchen_ap_devices_list = state_attr('sensor.kitchen_ap_connected_devices', 'devices') | default([]) %}
          {% set bathroom_2_ap_devices_list = state_attr('sensor.bathroom_2_ap_connected_devices', 'devices') | default([]) %}
          {% set combined_list = router_devices_list + kitchen_ap_devices_list + bathroom_2_ap_devices_list %}
          [
            {% for device in combined_list if device.connection_type == 'wired' or device.connected is defined %}
              {
                "mac": "{{ device.mac }}",
                "ip": "{{ device.ip }}",
                "name": "{{ device.name }}",
                "connection_type": "{{ device.connection_type }}",
                "node": "{{ device.node }}",
                "guest": "{{ device.guest }}",
                "guest_id": "{{ device.guest_id }}",
                "connected": "{{ device.connected }}"
              }{% if not loop.last %},{% endif %}
            {% endfor %}
          ]

Just to give some context:

I have the following 3 sensors created by the Asus router custom integration: sensor.router_connected_devices, sensor.kitchen_ap_connected_devices and sensor.bathroom_2_ap_connected_devices and they contain the attribute devices (devices connected to the router/APs) showing the IP, MAC, name, connection type, node, connected time, etc.

The Asus firmware has a bug and the router reports as connected over Ethernet (wired) a lot of the devices which are actually connected over WiFi to the APs (the APs being connected to the router over Ethernet).

In the below example Living Room TV Presence is actually connected over WiFi to another AP, Rain Sensor is connected to the Router over WiFi, BLE Gateway 1 is connected over Ethernet to the Router.

sensor.router_connected_devices

state_class: measurement
devices:
  - mac: 0c:b8:15:d5:c0:54
    ip: 192.168.45.120
    name: Living Room TV Presence
    connection_type: wired
    node: c8:7f:54:a1:c9:d8
  - mac: e8:68:e7:c7:e1:06
    ip: 192.168.45.101
    name: Rain Sensor
    connection_type: 2ghz
    node: c8:7f:54:a1:c9:d8
    guest: false
    guest_id: 0
    connected: "2024-06-17T07:29:07+00:00"
  - mac: e8:68:e7:c1:8c:cd
    name: Plug Monitor
    connection_type: disconnected
  - mac: c4:5b:be:93:1e:73
    ip: 192.168.45.17
    name: BLE Gateway 1
    connection_type: wired
    node: c8:7f:54:a1:c9:d8
icon: mdi:router-network
friendly_name: Router Connected Devices

Thanks in advance for your help.

So the rule is “if node is c8:7f:54:a1:c9:d8 AND both the mac and ip appear in another item, exclude this item” — correct?

That’s correct.

Try this addition to your for logic.

Device must be:

  • wired or connected
  • either not on that node, or the only entry for that MAC / IP combination
            {% for device in combined_list
                   if  (device.connection_type == 'wired'
                        or device.connected is defined)
                   and (device.node != 'c8:7f:54:a1:c9:d8'
                        or combined_list
                           |selectattr('mac','eq',device.mac)
                           |selectattr('ip','eq',device.ip)
                           |list|count == 1) %}
              {
                "mac": "{{ device.mac }}",
                "ip": "{{ device.ip }}",
                "name": "{{ device.name }}",
                "connection_type": "{{ device.connection_type }}",
                "node": "{{ device.node }}",
                "guest": "{{ device.guest }}",
                "guest_id": "{{ device.guest_id }}",
                "connected": "{{ device.connected }}"
              }{% if not loop.last %},{% endif %}
            {% endfor %}

I tried the following template but the end result is empty.

- sensor:
    - name: Asus Connected Devices
      unique_id: asus_connected_devices
      state_class: measurement
      icon: mdi:router-network
      state: >
        {{ states('sensor.router_connected_devices') }}
      attributes:
        devices: >
          {% set router_devices_list = state_attr('sensor.router_connected_devices', 'devices') | default([]) %}
          {% set kitchen_ap_devices_list = state_attr('sensor.kitchen_ap_connected_devices', 'devices') | default([]) %}
          {% set bathroom_2_ap_devices_list = state_attr('sensor.bathroom_2_ap_connected_devices', 'devices') | default([]) %}
          {% set combined_list = router_devices_list + kitchen_ap_devices_list + bathroom_2_ap_devices_list %}
          {% set unique_devices = [] %}
          {% set mac_set = [] %}
          {% for device in combined_list %}
            {% set mac = device.mac %}
            {% if mac not in mac_set %}
              {% set unique_devices = unique_devices + [device] %}
              {% set mac_set = mac_set + [mac] %}
            {% elif unique_devices | selectattr('mac', 'eq', mac) | first | attr('connection_type') == 'wired' and device.connection_type != 'wired' %}
              {% set unique_devices = unique_devices | rejectattr('mac', 'eq', mac) | list %}
              {% set unique_devices = unique_devices + [device] %}
            {% elif unique_devices | selectattr('mac', 'eq', mac) | first | attr('node') == 'c8:7f:54:a1:c9:d8' and device.node != 'c8:7f:54:a1:c9:d8' %}
              {% set unique_devices = unique_devices | rejectattr('mac', 'eq', mac) | list %}
              {% set unique_devices = unique_devices + [device] %}
            {% endif %}
          {% endfor %}
          [
            {% for device in filtered_list if device.connection_type == 'wired' or device.connected is defined %}
              {
                "mac": "{{ device.mac }}",
                "ip": "{{ device.ip }}",
                "name": "{{ device.name }}",
                "connection_type": "{{ device.connection_type }}",
                "node": "{{ device.node }}",
                "guest": "{{ device.guest }}",
                "guest_id": "{{ device.guest_id }}",
                "connected": "{{ device.connected }}"
              }{% if not loop.last %},{% endif %}
            {% endfor %}
          ]
sensor.asus_connected_devices

state_class: measurement
icon: mdi:router-network
friendly_name: Asus Connected Devices
devices: []

Amazing. Thanks a lot, that was spot on. :partying_face: :clap:

1 Like