SNMP Bandwidth Monitor

If you want to monitor current bandwidth on a SNMP accessible network device, such as routers and wifi access points. Here is a tutorial on how to configure it in Home Assistant. Hopefully someone else will find it useful. :slight_smile:

SNMP Sensor

Grabs data via SNMP from my router addressing the WAN port IN/OUT traffic via the OID:

  - platform: snmp
    name: snmp_wan_in
    host: 10.0.1.1
    baseoid: 1.3.6.1.2.1.2.2.1.10.2

  - platform: snmp
    name: snmp_wan_out
    host: 10.0.1.1
    baseoid: 1.3.6.1.2.1.2.2.1.16.2

Automations

Where the magic happens. Here’s a breakdown:

  1. Grab trigger.to_state and trigger.from_state values.
  2. Subtract those two values to get the delta.
  3. Multiply that delta by 8 to get the total number of bits transmitted between the time interval.
  4. Grab the time interval delta using the last_updated time from the to_state and from_state entities.
  5. We now have our bits per second.

- alias: Monitor Traffic

  trigger:
    platform: state
    entity_id: sensor.snmp_wan_in

  action:
    - service: input_slider.select_value
      data_template:
        entity_id: input_slider.internet_traffic_delta_in
        value: '{{ ((trigger.to_state.state | int - trigger.from_state.state | int) * 8 ) / ( as_timestamp(trigger.to_state.last_updated) - as_timestamp(trigger.from_state.last_updated) ) }}'

- alias: Monitor Traffic

  trigger:
    platform: state
    entity_id: sensor.snmp_wan_out

  action:
    - service: input_slider.select_value
      data_template:
        entity_id: input_slider.internet_traffic_delta_out
        value: '{{ ((trigger.to_state.state | int - trigger.from_state.state | int) * 8 ) / ( as_timestamp(trigger.to_state.last_updated) - as_timestamp(trigger.from_state.last_updated) ) }}'

Formatting

Next we want to make it look good in the Home Assistant UI.

The code here was used to take the data in the input slider, and first create a sensor that shows us Mbps by coverting bps to Mbps. Then, I choose to setup a statistics sensor for the IN/OUT.

  - platform: template
    sensors:
        internet_speed_in:
          friendly_name: 'Internet Speed'
          value_template: '{{ ((states.input_slider.internet_traffic_delta_in.state | float ) / 1000000 ) | round(2) }}'
          unit_of_measurement: 'Mbps'

  - platform: template
    sensors:
        internet_speed_out:
          friendly_name: 'Internet Speed'
          value_template: '{{ ((states.input_slider.internet_traffic_delta_out.state | float ) / 1000000 ) | round(2) }}'
          unit_of_measurement: 'Mbps'

  - platform: statistics
    name: 'WAN Traffic IN'
    entity_id: sensor.internet_speed_in

  - platform: statistics
    name: 'WAN Traffic OUT'
    entity_id: sensor.internet_speed_out

Make it look good.

Just a few customizations:

sensor.download_speed_mean:
  friendly_name: 'Speedtest Download Average'
  icon: mdi:speedometer

sensor.upload_speed_mean:
  friendly_name: 'Spedtest Upload Average'
  icon: mdi:speedometer

sensor.ping_time_mean:
  friendly_name: 'Speedtest Ping Average'
  icon: mdi:clock-fast

sensor.wan_traffic_in_mean:
  friendly_name: 'WAN Download Average'
  icon: mdi:download

sensor.wan_traffic_out_mean:
  friendly_name: 'WAN Upload Average'
  icon: mdi:upload
22 Likes

Really usefull !!! really nice and clear “how to” Thanks !! I am using it right now.

1 Like

Found it helpful to add this to configuration.yaml:

input_slider: internet_traffic_delta_in: name: "Traffic IN Delta" initial: 0 min: 0 max: 1000000000000

internet_traffic_delta_out:
name: “Traffic OUT Delta”
initial: 0
min: 0
max: 1000000000000

Is this now broken as of 2.8? finding difficulty getting it to work :frowning:

I haven’t had any issues all the way to HA version 0.39.2

Finally got around to setting this up, works perfectly!!

If anyone is wanting to set this up and needs to find their OID’s I can recommend an Android app called: SNMP Traffic Grapher. Made it really easy to find the internet VLAN OID’s for my Asus router running MerlinWRT.

Am i missing something, i just get loads of errors when i have set this up…
Im using HA 0.41
Sensors:

- platform: snmp
  name: snmp_wan_in
  host: !secret snmp_host
  community: !secret snmp_community
  baseoid: 1.3.6.1.2.1.2.2.1.10.10
- platform: snmp
  name: snmp_wan_out
  host: !secret snmp_host
  community: !secret snmp_community
  baseoid: 1.3.6.1.2.1.2.2.1.16.10
- platform: template
  sensors:
    internet_speed_in:
      friendly_name: 'Internet Speed'
      value_template: '{{ ((states.input_slider.internet_traffic_delta_in.state | float ) / 1000000 ) | round(2) }}'
      unit_of_measurement: 'Mbps'
- platform: template
  sensors:
    internet_speed_out:
      friendly_name: 'Internet Speed'
      value_template: '{{ ((states.input_slider.internet_traffic_delta_out.state | float ) / 1000000 ) | round(2) }}'
      unit_of_measurement: 'Mbps'
- platform: statistics
  name: 'WAN Traffic IN'
  entity_id: sensor.internet_speed_in
- platform: statistics
  name: 'WAN Traffic OUT'
  entity_id: sensor.internet_speed_out

automations:

- alias: Monitor Traffic in
  trigger:
    platform: state
    entity_id: sensor.snmp_wan_in
  action:
    - service: input_slider.select_value
      data_template:
        entity_id: input_slider.internet_traffic_delta_in
        value: '{{ ((trigger.to_state.state | int - trigger.from_state.state | int) * 8 ) / ( as_timestamp(trigger.to_state.last_updated) - as_timestamp(trigger.from_state.last_updated) ) }}'
- alias: Monitor Traffic out
  trigger:
    platform: state
    entity_id: sensor.snmp_wan_out
  action:
    - service: input_slider.select_value
      data_template:
        entity_id: input_slider.internet_traffic_delta_out
        value: '{{ ((trigger.to_state.state | int - trigger.from_state.state | int) * 8 ) / ( as_timestamp(trigger.to_state.last_updated) - as_timestamp(trigger.from_state.last_updated) ) }}'

Error log:

WARNING (MainThread) [homeassistant.components.sensor.statistics] mean requires at least one data point
ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "C:\Users\xbmc\AppData\Local\Programs\Python\Python36-32\lib\site-packages\homeassistant\helpers\template.py", line 99, in async_render
    return self._compiled.render(kwargs).strip()
  File "C:\Users\xbmc\AppData\Local\Programs\Python\Python36-32\lib\site-packages\jinja2\asyncsupport.py", line 76, in render
    return original_render(self, *args, **kwargs)
  File "C:\Users\xbmc\AppData\Local\Programs\Python\Python36-32\lib\site-packages\jinja2\environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "C:\Users\xbmc\AppData\Local\Programs\Python\Python36-32\lib\site-packages\jinja2\environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\xbmc\AppData\Local\Programs\Python\Python36-32\lib\site-packages\jinja2\_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "<template>", line 1, in top-level template code
  File "C:\Users\xbmc\AppData\Local\Programs\Python\Python36-32\lib\site-packages\jinja2\filters.py", line 542, in do_int
    return int(value)
jinja2.exceptions.UndefinedError: 'None' has no attribute 'state'
WARNING (MainThread) [homeassistant.components.sensor.template] Could not render template Internet Speed, the state is unknown.
WARNING (MainThread) [homeassistant.core] Unable to find service input_slider/select_value

If i just run the snmp sensors it works, they display a huge number.

One thing that hits me is that we are referring to some input_slider's but never define them? (i added them like @firstof9 wrote but sadly that didn’t solve the issue).

I usually get those errors on HA startup, but it only happens once since the values get populated shortly after.

configuration.yaml (with formatting now):

input_slider:
  internet_traffic_delta_in:
   name: "Traffic IN Delta"
   initial: 0
   min: 0
   max: 1000000000000

  internet_traffic_delta_out:
   name: "Traffic OUT Delta"
   initial: 0
   min: 0
   max: 1000000000000
1 Like

It seems to work now, the values seem a bit low but time will tell, i did a network speed test and it maxed my line at about 100 Mbps both in and out but the Home assistant only showed 20 Mbps.

Neat! Would you mind sharing how you did the configuration for the status of the network devices? (i.e. online/offline)? I was looking to do a similar thing.

Thanks!

Example:

 - platform: template
    sensors:
     xbox:
      friendly_name: "XBox One"
      value_template: "{{ 'Online' if is_state('device_tracker.xbox_one', 'home') else 'Offline' }}"
     router:
      friendly_name: "Router"
      value_template: "{{ 'Online' if is_state('device_tracker.router', 'home') else 'Offline' }}"

1 Like

Ah! Didn’t think of using the template component. Thanks!

1 Like

Might be the wrong baseoid. I know mine is different from the one in the example. I used a SNMP Walker to verify my WAN interface.

I use a Netgear AC1900/R7000 with advanced tomato and for me the baseoid’s where:

IN:  1.3.6.1.2.1.2.2.1.10.10
OUT: 1.3.6.1.2.1.2.2.1.16.10

Im a Windows user and used Getif (Enable windows XP compatibility mode to make it work) to query my router’s snmp.

Really nice! Will try to implement soon.

From yesterday i keep getting:
WARNING (MainThread) [homeassistant.components.input_slider] Invalid value: -1085498964.4708297 (range 0.0 - 1000000000000.0)
and the up speed seem to have stuck.
I did update to 0.42.4 yesterday, could that have made it?
Is there a way to reset the values?

This is great. Took a bit of work as my OID for my router is different. Had to change the last number to a 4 for my ASUS RT-AC87U.

Also had to make a few alterations as some items were named differently.

The problem I’m having now is that my Speedtest Upload Average value is reporting results that are impossible for me. I have 100/40 internet, and I just down a test on speedtest.net (which gave correct values), but this sensor gave me 68 for my upload speed when 40 is my max. The result is very close to the download average. So maybe I’ve crossed my wires somewhere, but I can’t see it.

Any help would be appreciated.

Here is my config from configuration.yaml

  - platform: snmp
    name: snmp_wan_in
    host: 192.168.1.1
    baseoid: 1.3.6.1.2.1.2.2.1.10.4

  - platform: snmp
    name: snmp_wan_out
    host: 192.168.1.1
    baseoid: 1.3.6.1.2.1.2.2.1.16.4
    
  - platform: template
    sensors:
        internet_speed_in:
          friendly_name: 'Internet Speed'
          value_template: '{{ ((states.input_slider.internet_traffic_delta_in.state | float ) / 1000000 ) | round(2) }}'
          unit_of_measurement: 'Mbps'

  - platform: template
    sensors:
        internet_speed_out:
          friendly_name: 'Internet Speed'
          value_template: '{{ ((states.input_slider.internet_traffic_delta_out.state | float ) / 1000000 ) | round(2) }}'
          unit_of_measurement: 'Mbps'

  - platform: statistics
    name: 'WAN Traffic IN'
    entity_id: sensor.internet_speed_in

  - platform: statistics
    name: 'WAN Traffic OUT'
    entity_id: sensor.internet_speed_out

input_slider:
  internet_traffic_delta_in:
   name: "Traffic IN Delta"
   initial: 0
   min: 0
   max: 1000000000000

  internet_traffic_delta_out:
   name: "Traffic OUT Delta"
   initial: 0
   min: 0
   max: 1000000000000

and now automations.yaml

- alias: Monitor Traffic

  trigger:
    platform: state
    entity_id: sensor.snmp_wan_in

  action:
    - service: input_slider.select_value
      data_template:
        entity_id: input_slider.internet_traffic_delta_in
        value: '{{ ((trigger.to_state.state | int - trigger.from_state.state | int) * 8 ) / ( as_timestamp(trigger.to_state.last_updated) - as_timestamp(trigger.from_state.last_updated) ) }}'

- alias: Monitor Traffic

  trigger:
    platform: state
    entity_id: sensor.snmp_wan_out

  action:
    - service: input_slider.select_value
      data_template:
        entity_id: input_slider.internet_traffic_delta_out
        value: '{{ ((trigger.to_state.state | int - trigger.from_state.state | int) * 8 ) / ( as_timestamp(trigger.to_state.last_updated) - as_timestamp(trigger.from_state.last_updated) ) }}'

and now customize.yaml

sensor.internet_speed_in:
  friendly_name: 'Speedtest Download Average'
  icon: mdi:speedometer

sensor.internet_speed_out:
  friendly_name: 'Spedtest Upload Average'
  icon: mdi:speedometer

sensor.ping_time_mean:
  friendly_name: 'Speedtest Ping Average'
  icon: mdi:clock-fast

sensor.wan_traffic_in_mean:
  friendly_name: 'WAN Download Average'
  icon: mdi:download

sensor.wan_traffic_out_mean:
  friendly_name: 'WAN Upload Average'
  icon: mdi:upload

I also have an Asus router. RT-N66U
You may have the SNMP oid wrong and be monitoring the br0 interface, which is EVERYTHING which might explain different figures

Bear in mind its probably different across certain routers, especially the DSL and cable variants
For me:
eth0 = WAN
br0 = Bridge
eth1 = Wifi 2.4G
eth2 = Wifi 5G
vlan1 = LAN switch

I dont know what their oids would be and cant figure that out at the moment as Im at work, but definitely worth checking out

My RT-AC87U has 9 interfaces. Number 4 is eth0 and is what I’m using and I’ve confirmed that by SSH’ing into my router and looking at ifconfig, eth0 has the correct IP address, so it’s definatly my WAN interface.

1: ifDescr.1 lo
2: ifDescr.2 ifb0
3: ifDescr.3 ifb1
4: ifDescr.4 eth0
5: ifDescr.5 eth1
6: ifDescr.6 vlan1
7: ifDescr.7 vlan2
8: ifDescr.8 br0
9: ifDescr.9 tun21

Now that I look at it, the data for the SNMP sensors is correct, so there must be something in the automations that isn’t liked. I don’t get why when downloading a file the up is counting so much data.

Maybe I made a mistake in my config posted earlier.