SNMP bandwidth monitor using statistics

hi,
shall you share the lovelace code of this graph?

Tnx

if someone have the same problem with pppoe interface on a Ubiquiti USG, that change the OID randomly every time it restart, I created an appdaemon app to retrieve the data via SNMP and put on 2 HA entities

You can find at: https://github.com/twproject/homeassistant/tree/main/appdaemon/snmp%20query/hassio_unifi_internet_interface

OIDs don’t change. Otherwise people would not be able to do this for their USG: https://www.reddit.com/r/homelab/comments/bepzkk/was_able_to_add_a_usg_bandwidth_monitor_and_some/

OID change with pppoe virtual interfaces, it’s about 6 month that i change my configuration.yaml config with the new values

On october it was 1.3.6.1.2.1.31.1.1.1.6.5 after few weeks after a pppoe restart 1.3.6.1.2.1.31.1.1.1.6.18, now is 1.3.6.1.2.1.31.1.1.1.6.308

As I said at beginning it happen only at pppoe virtual interfaces, It doesn’t change with physical interfaces

1 Like

Ah ok, that makes sense.

I had the same issue with snmp trying to read snmp from a dd-wrt router. I solved it like this (there is probably a shorter version to this, but for me it works). DD-wrt seems to change oids after a reboot… This quite large sensor code avoids this by checking the name of the network interface and based on that reads other oids.

# Determine interface names
- platform: snmp
  name: ddwrt_ifname_1
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.1.1
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_ifname_2
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.1.2
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_ifname_3
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.1.3
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_ifname_4
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.1.4
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_ifname_5
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.1.5
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_ifname_6
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.1.6
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_ifname_7
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.1.7
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_ifname_8
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.1.8
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_ifname_9
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.1.9
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_ifname_10
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.1.10
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_ifname_11
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.1.11
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_ifname_12
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.1.12
  community: 'public'
  version: 2c
  scan_interval: 3600

# Read all interface counters
- platform: snmp
  name: ddwrt_if_1_rx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.6.1
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_1_tx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.10.1
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_2_rx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.6.2
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_2_tx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.10.2
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_3_rx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.6.3
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_3_tx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.10.3
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_4_rx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.6.4
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_4_tx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.10.4
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_5_rx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.6.5
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_5_tx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.10.5
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_6_rx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.6.6
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_6_tx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.10.6
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_7_rx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.6.7
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_7_tx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.10.7
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_8_rx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.6.8
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_8_tx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.10.8
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_9_rx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.6.9
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_9_tx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.10.9
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_10_rx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.6.10
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_10_tx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.10.10
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_11_rx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.6.11
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_11_tx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.10.11
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_12_rx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.6.12
  community: 'public'
  version: 2c
  scan_interval: 3600
- platform: snmp
  name: ddwrt_if_12_tx
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.31.1.1.1.10.12
  community: 'public'
  version: 2c
  scan_interval: 3600

# Read correct rx/tx values for interfaces
- platform: template
  sensors:
    ddwrt_crap2_rx:
      value_template: >
        {% if   is_state('sensor.ddwrt_ifname_1' , 'eth1') %}
          {{ states('sensor.ddwrt_if_1_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_2' , 'eth1') %}
          {{ states('sensor.ddwrt_if_2_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_3' , 'eth1') %}
          {{ states('sensor.ddwrt_if_3_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_4' , 'eth1') %}
          {{ states('sensor.ddwrt_if_4_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_5' , 'eth1') %}
          {{ states('sensor.ddwrt_if_5_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_6' , 'eth1') %}
          {{ states('sensor.ddwrt_if_6_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_7' , 'eth1') %}
          {{ states('sensor.ddwrt_if_7_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_8' , 'eth1') %}
          {{ states('sensor.ddwrt_if_8_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_9' , 'eth1') %}
          {{ states('sensor.ddwrt_if_9_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_10' , 'eth1') %}
          {{ states('sensor.ddwrt_if_10_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_11' , 'eth1') %}
          {{ states('sensor.ddwrt_if_11_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_12' , 'eth1') %}
          {{ states('sensor.ddwrt_if_12_rx') }}
        {% endif %}
- platform: template
  sensors:
    ddwrt_crap2_tx:
      value_template: >
        {% if   is_state('sensor.ddwrt_ifname_1' , 'eth1') %}
          {{ states('sensor.ddwrt_if_1_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_2' , 'eth1') %}
          {{ states('sensor.ddwrt_if_2_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_3' , 'eth1') %}
          {{ states('sensor.ddwrt_if_3_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_4' , 'eth1') %}
          {{ states('sensor.ddwrt_if_4_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_5' , 'eth1') %}
          {{ states('sensor.ddwrt_if_5_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_6' , 'eth1') %}
          {{ states('sensor.ddwrt_if_6_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_7' , 'eth1') %}
          {{ states('sensor.ddwrt_if_7_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_8' , 'eth1') %}
          {{ states('sensor.ddwrt_if_8_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_9' , 'eth1') %}
          {{ states('sensor.ddwrt_if_9_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_10' , 'eth1') %}
          {{ states('sensor.ddwrt_if_10_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_11' , 'eth1') %}
          {{ states('sensor.ddwrt_if_11_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_12' , 'eth1') %}
          {{ states('sensor.ddwrt_if_12_tx') }}
        {% endif %}

- platform: template
  sensors:
    ddwrt_crap5_rx:
      value_template: >
        {% if   is_state('sensor.ddwrt_ifname_1' , 'eth2') %}
          {{ states('sensor.ddwrt_if_1_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_2' , 'eth2') %}
          {{ states('sensor.ddwrt_if_2_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_3' , 'eth2') %}
          {{ states('sensor.ddwrt_if_3_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_4' , 'eth2') %}
          {{ states('sensor.ddwrt_if_4_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_5' , 'eth2') %}
          {{ states('sensor.ddwrt_if_5_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_6' , 'eth2') %}
          {{ states('sensor.ddwrt_if_6_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_7' , 'eth2') %}
          {{ states('sensor.ddwrt_if_7_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_8' , 'eth2') %}
          {{ states('sensor.ddwrt_if_8_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_9' , 'eth2') %}
          {{ states('sensor.ddwrt_if_9_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_10' , 'eth2') %}
          {{ states('sensor.ddwrt_if_10_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_11' , 'eth2') %}
          {{ states('sensor.ddwrt_if_11_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_12' , 'eth2') %}
          {{ states('sensor.ddwrt_if_12_rx') }}
        {% endif %}
- platform: template
  sensors:
    ddwrt_crap5_tx:
      value_template: >
        {% if   is_state('sensor.ddwrt_ifname_1' , 'eth2') %}
          {{ states('sensor.ddwrt_if_1_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_2' , 'eth2') %}
          {{ states('sensor.ddwrt_if_2_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_3' , 'eth2') %}
          {{ states('sensor.ddwrt_if_3_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_4' , 'eth2') %}
          {{ states('sensor.ddwrt_if_4_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_5' , 'eth2') %}
          {{ states('sensor.ddwrt_if_5_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_6' , 'eth2') %}
          {{ states('sensor.ddwrt_if_6_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_7' , 'eth2') %}
          {{ states('sensor.ddwrt_if_7_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_8' , 'eth2') %}
          {{ states('sensor.ddwrt_if_8_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_9' , 'eth2') %}
          {{ states('sensor.ddwrt_if_9_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_10' , 'eth2') %}
          {{ states('sensor.ddwrt_if_10_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_11' , 'eth2') %}
          {{ states('sensor.ddwrt_if_11_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_12' , 'eth2') %}
          {{ states('sensor.ddwrt_if_12_tx') }}
        {% endif %}

- platform: template
  sensors:
    ddwrt_crap6_rx:
      value_template: >
        {% if   is_state('sensor.ddwrt_ifname_1' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_1_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_2' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_2_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_3' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_3_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_4' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_4_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_5' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_5_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_6' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_6_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_7' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_7_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_8' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_8_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_9' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_9_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_10' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_10_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_11' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_11_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_12' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_12_rx') }}
        {% endif %}
- platform: template
  sensors:
    ddwrt_crap6_tx:
      value_template: >
        {% if   is_state('sensor.ddwrt_ifname_1' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_1_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_2' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_2_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_3' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_3_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_4' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_4_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_5' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_5_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_6' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_6_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_7' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_7_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_8' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_8_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_9' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_9_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_10' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_10_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_11' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_11_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_12' , 'wl0.1') %}
          {{ states('sensor.ddwrt_if_12_tx') }}
        {% endif %}

- platform: template
  sensors:
    ddwrt_crap7_rx:
      value_template: >
        {% if   is_state('sensor.ddwrt_ifname_1' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_1_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_2' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_2_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_3' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_3_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_4' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_4_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_5' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_5_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_6' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_6_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_7' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_7_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_8' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_8_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_9' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_9_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_10' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_10_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_11' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_11_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_12' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_12_rx') }}
        {% endif %}
- platform: template
  sensors:
    ddwrt_crap7_tx:
      value_template: >
        {% if   is_state('sensor.ddwrt_ifname_1' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_1_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_2' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_2_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_3' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_3_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_4' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_4_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_5' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_5_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_6' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_6_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_7' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_7_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_8' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_8_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_9' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_9_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_10' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_10_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_11' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_11_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_12' , 'wl0.2') %}
          {{ states('sensor.ddwrt_if_12_tx') }}
        {% endif %}

- platform: template
  sensors:
    ddwrt_br0_rx:
      value_template: >
        {% if   is_state('sensor.ddwrt_ifname_1' , 'br0') %}
          {{ states('sensor.ddwrt_if_1_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_2' , 'br0') %}
          {{ states('sensor.ddwrt_if_2_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_3' , 'br0') %}
          {{ states('sensor.ddwrt_if_3_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_4' , 'br0') %}
          {{ states('sensor.ddwrt_if_4_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_5' , 'br0') %}
          {{ states('sensor.ddwrt_if_5_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_6' , 'br0') %}
          {{ states('sensor.ddwrt_if_6_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_7' , 'br0') %}
          {{ states('sensor.ddwrt_if_7_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_8' , 'br0') %}
          {{ states('sensor.ddwrt_if_8_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_9' , 'br0') %}
          {{ states('sensor.ddwrt_if_9_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_10' , 'br0') %}
          {{ states('sensor.ddwrt_if_10_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_11' , 'br0') %}
          {{ states('sensor.ddwrt_if_11_rx') }}
        {% elif is_state('sensor.ddwrt_ifname_12' , 'br0') %}
          {{ states('sensor.ddwrt_if_12_rx') }}
        {% endif %}
- platform: template
  sensors:
    ddwrt_br0_tx:
      value_template: >
        {% if   is_state('sensor.ddwrt_ifname_1' , 'br0') %}
          {{ states('sensor.ddwrt_if_1_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_2' , 'bro') %}
          {{ states('sensor.ddwrt_if_2_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_3' , 'br0') %}
          {{ states('sensor.ddwrt_if_3_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_4' , 'br0') %}
          {{ states('sensor.ddwrt_if_4_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_5' , 'br0') %}
          {{ states('sensor.ddwrt_if_5_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_6' , 'br0') %}
          {{ states('sensor.ddwrt_if_6_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_7' , 'br0') %}
          {{ states('sensor.ddwrt_if_7_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_8' , 'br0') %}
          {{ states('sensor.ddwrt_if_8_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_9' , 'br0') %}
          {{ states('sensor.ddwrt_if_9_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_10' , 'br0') %}
          {{ states('sensor.ddwrt_if_10_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_11' , 'br0') %}
          {{ states('sensor.ddwrt_if_11_tx') }}
        {% elif is_state('sensor.ddwrt_ifname_12' , 'br0') %}
          {{ states('sensor.ddwrt_if_12_tx') }}
        {% endif %}

# Do the math
- platform: template
  sensors:
    ddwrt_crap2_rx_mb:
      value_template: "{{ (states('sensor.ddwrt_crap2_rx') | float / 1024 / 1024 ) | round(2) }}"
      unit_of_measurement: MB
- platform: template
  sensors:
    ddwrt_crap2_tx_mb:
      value_template: "{{ (states('sensor.ddwrt_crap2_tx') | float / 1024 / 1024 ) | round(2) }}"
      unit_of_measurement: MB
- platform: template
  sensors:
    ddwrt_crap5_rx_mb:
      value_template: "{{ (states('sensor.ddwrt_crap5_rx') | float / 1024 / 1024 ) | round(2) }}"
      unit_of_measurement: MB
- platform: template
  sensors:
    ddwrt_crap5_tx_mb:
      value_template: "{{ (states('sensor.ddwrt_crap5_tx') | float / 1024 / 1024 ) | round(2) }}"
      unit_of_measurement: MB
- platform: template
  sensors:
    ddwrt_crap6_rx_mb:
      value_template: "{{ (states('sensor.ddwrt_crap6_rx') | float / 1024 / 1024 ) | round(2) }}"
      unit_of_measurement: MB
- platform: template
  sensors:
    ddwrt_crap6_tx_mb:
      value_template: "{{ (states('sensor.ddwrt_crap6_tx') | float / 1024 / 1024 ) | round(2) }}"
      unit_of_measurement: MB
- platform: template
  sensors:
    ddwrt_crap7_rx_mb:
      value_template: "{{ (states('sensor.ddwrt_crap7_rx') | float / 1024 / 1024 ) | round(2) }}"
      unit_of_measurement: MB
- platform: template
  sensors:
    ddwrt_crap7_tx_mb:
      value_template: "{{ (states('sensor.ddwrt_crap7_tx') | float / 1024 / 1024 ) | round(2) }}"
      unit_of_measurement: MB
- platform: template
  sensors:
    ddwrt_br0_rx_mb:
      value_template: "{{ (states('sensor.ddwrt_br0_rx') | float / 1024 / 1024 ) | round(2) }}"
      unit_of_measurement: MB
- platform: template
  sensors:
    ddwrt_br0_tx_mb:
      value_template: "{{ (states('sensor.ddwrt_br0_tx') | float / 1024 / 1024 ) | round(2) }}"
      unit_of_measurement: MB
- platform: template
  sensors:
    ddwrt_br0_rx_gb:
      value_template: "{{ (states('sensor.ddwrt_br0_rx') | float / 1024 / 1024 / 1024 ) | round(2) }}"
      unit_of_measurement: GB
- platform: template
  sensors:
    ddwrt_br0_tx_gb:
      value_template: "{{ (states('sensor.ddwrt_br0_tx') | float / 1024 / 1024 / 1024 ) | round(2) }}"
      unit_of_measurement: GB

# Get the uptime
- platform: snmp
  name: ddwrt_uptime
  host: 192.168.0.253
  baseoid: 1.3.6.1.2.1.25.1.1.0
  scan_interval: 3600
  community: public
  version: 2c
  value_template: >
    {% set timetick = value | int %}
    {% set minutes = ((timetick % 360000) / 6000) | int%}
    {% set hours = ((timetick % 8640000) / 360000) | int %}
    {% set days = (timetick / 8640000) | int %}
    {%- if timetick < 6000 -%}
      Less than a minute
    {%- else -%}
      {%- if days > 0 -%}
        {%- if days == 1 -%}
          1 day
        {%- else -%}
          {{ days }} days
        {%- endif -%}
      {%- endif -%}
      {%- if hours > 0 -%}
        {%- if days > 0 -%}
          {{ ', ' }}
        {%- endif -%}
        {%- if hours == 1 -%}
          1 hr
        {%- else -%}
          {{ hours }} hrs
        {%- endif -%}
      {%- endif -%}
      {%- if minutes > 0 -%}
        {%- if days > 0 or hours > 0 -%}
          {{ ', ' }}
        {%- endif -%}
        {%- if minutes == 1 -%}
          1 min
        {%- else -%}
          {{ minutes }} min
        {%- endif -%}
      {%- endif -%}
    {%- endif -%}

Hi tom_l, where did you configure this? I have tried both ‘configuration.yaml’ and ‘Raw configuration editor’ neither one works. Also how did you add the sensor for ERX? Trying to do this for my UDM Pro but not having any luck. SNMPv2 is enabled.

Please advise and thank you

Can you please show what you added to configuration.yaml? Did you add it to the section sensor:. Also make sure that you only have one sensor: section in configuration.yaml

Hi, I have done the same way but get quite a lot of drops, does anyone know what it is due to or if you can set so it does not show any negative values?
negative_reading (Small)

For those interested, here’s why there are big drops.

The type of OID that keeps track of the the usage is a counter. it counts bits (octets) from 0 to a very big number, and then resets back to 0 when it gets to its maximum value and starts counting all over again.

To calculate the various values from the counter (were you to do it manually), you’d take a look at the counter and write down the number. Then, you’d take another reading some amount of time later, and write it down. Subtract the first number from the second and then divide by the number of seconds between readings. That’ll get you the average speed utilized during that timeframe.

Now, imagine if you’re near the end of the counter range. You calculate a value, and then all of a sudden, you’re subtracting whatever 2^64-5 is from 27. You’re going to get a very low negative number because of the way these numbers are. The way I usually deal with that is to add 2^64-1 to the later value, and then subtract the earlier one from that sum. (2^32-1 for older gear with 32 bit counters)

That having been said, I’m not sure how to mitigate it in jinja. But it can be fixed. We’ll just have to mess around with the templates to figure out what the syntax is.

Technically true, but I doubt you’re exhausting a 64 bit counter within your lifetime, or the lifetime of any router.

The problem is more that there are older OIDs which are only 32 bit (4 GByte) but usually there are also newer OIDs that are 64 bit (18446744073 GByte). So you just need to find and use the 64 bit OIDs and the problem is solved.

No, you’re correct… Coming from an ISP Engineering background, it usually takes 40 or 50 residential services to exhaust a 64 bit counter in any shortish timeframe. It is technically possible for a single residential service, but you’d have to have a big plan, and you’d have to have something using a lot of bandwidth for a long time.

32 bit counters, OTOH, are easily exhausted, as you say. I once wrote a “realtime” bandwidth monitor and had to use the 32 bit counters for some of the hardware (because the older Ubiquiti Airmax equipment doesn’t do 64 bit counters) and counter resets were definitely a problem.

Some things I’ve run across that have impacted reporting for me in the past, regardless of the counters being 32 or 64 bit:

  1. Equipment power cycle – resets everything back to 0
  2. Equipment watchdog reboots when error is detected – resets everything back back to 0
  3. Equipment firmware bugs – may erroneously report back garbage (or zeros)
  4. Equipment overwhelmed – may just stop reporting all together (usually the device is undersized for the work being asked of it)
  5. Equipment OID Update interval is longer than polling interval – can be fixed by extending the polling interval out. (This will make graphs spiky, with the line oscillating from zero to what the actual number is and back)

Not everyone runs ISP-grade or corporate-grade gear at their houses like I do, and I have found that many of the cheaper residential router-gateways have issues with being underpowered or having buggy SNMP stacks.

It should be possible to add some light error checking in templates to mitigate the strange data issues.

You’re right, any of these events will reset the counter and you’ll likely get a spike in the traffic.

My point about 64 bit is still valid, as it would take approximately 4679 years to transfer 2^64 bytes of data at 1 Gigabit/second. Not likely to be exhausted in any relevant time frame even with 40-50 residential services. Not sure which speed you are looking at. Even 5000 users using 1Gbit/s at full rate would take almost a whole year to exhaust a 64 bit counter.

I had a deep dive into the NPM server, and it looks like someone didn’t enable the 64 bit counters.

[facepalm]

So, everything I said about exhausting 64 bit counters? Ignore it.

Worked like a charm for me, but after installing the HA core update from october stopped working. Anyone else having issues?

Nope. Still working for me.

Thanks,
I’ll digg in to it later then, maybe delete sensors and restart HA and configure them again will do the trick

For anybody with Float = None errors etc… (p.s. not an expert just FYI)

Worked today (Core 10.3) on it, graphing IN/OUT Mbps of a Unifi USG router:
Confirmed working:

configuration.yaml

sensor:
  - platform: snmp
    name: 'USG WAN in'
    host: <IP router>
    baseoid: 1.3.6.1.2.1.31.1.1.1.6.2
    community: 'public'
    version: '2c'
    scan_interval: 10
  - platform: snmp
    name: 'USG WAN out'
    host: <IP router>
    baseoid: 1.3.6.1.2.1.31.1.1.1.10.2
    community: 'public'
    version: '2c'
    scan_interval: 10
    #-----
  - platform: derivative
    name: wan_in_der
    source: sensor.usg_wan_in
    unit_time: s
    unit: B
  - platform: derivative
    name: wan_out_der
    source: sensor.usg_wan_out
    unit_time: s
    unit: B
  - platform: template
    sensors:
      wan_in_mbps:
        value_template:  "{{ [((states('sensor.wan_in_der')|float(0)*8)/1000000)|round(2),0]|max }}"
        unit_of_measurement: 'Mbps'
        friendly_name: "WAN In der"
      wan_out_mbps:
        value_template:  "{{ [((states('sensor.wan_out_der')|float(0)*8)/1000000)|round(2),0]|max }}"
        unit_of_measurement: 'Mbps'
        friendly_name: "WAN Out der"

Well that will return 0 when sensor.wan_in_der is unknown, like the last version of Home Assistant did.

A better option would be

value_template:  "{{ [((states('sensor.wan_in_der')|float(none)*8)/1000000)|round(2, default=none),0]|max }}"

So you know when there is an issue with your sensor.

See here for more:

1 Like

Thanks @tom_l

After reading the template info page I am testing your suggestion (in configuration.yaml):

sensor:
    - platform: snmp
      name: 'USG WAN in'
      host: <IProuter IP>
      baseoid: 1.3.6.1.2.1.31.1.1.1.6.2
      community: 'public'
      version: '2c'
      scan_interval: 10
    - platform: snmp
      name: 'USG WAN out'
      host: <IProuter IP>
      baseoid: 1.3.6.1.2.1.31.1.1.1.10.2
      community: 'public'
      version: '2c'
      scan_interval: 10
    - platform: derivative
      name: wan_in_der
      source: sensor.usg_wan_in
      unit_time: s
      unit: B
    - platform: derivative
      name: wan_out_der
      source: sensor.usg_wan_out
      unit_time: s
      unit: B
   - platform: template
     sensors:
        wan_in_mbps:
             value_template:  "{{ [((states('sensor.wan_in_der')|float(none)*8)/1000000)|round(2, default=none),0]|max }}"
            unit_of_measurement: 'Mbps'
            friendly_name: "WAN In der Alex"
       wan_out_mbps:
            value_template:  "{{ [((states('sensor.wan_out_der')|float(none)*8)/1000000)|round(2, default=none),0]|max }}"
           unit_of_measurement: 'Mbps'
           friendly_name: "WAN Out der Alex"
1 Like