Ubiquiti EdgeRouter with dual internet, stats and failover notifications

I have an EdgeRouter ERLite‑3 with two internet pipes, a primary via AT&T fiber and a secondary via Google Fi LTE on a Netgear modem. I initially setup the secondary LTE just because I had a modem laying around and Google Fi has free data sims, which was no extra cost. But this did save me some trouble while working from home when AT&T decided to be flaky a few times.

I’ve broken this up in to two parts. The first will be the failover status and notifications, and second will be HA pulling bandwidth info via SNMP.

Failover

I followed https://help.ui.com/hc/en-us/articles/205145990-EdgeRouter-WAN-Load-Balancing#3 to setup the dual WAN setup initially. My load-balance sections looks like the following. eth2 is the primary fiber, and eth1 is the secondary lte interface (note the failover-only option). I’m pinging cloudflare’s 1.1.1.1 to check for liveliness.

load-balance {
    group wan-group {
        exclude-local-dns disable
        flush-on-active enable
        gateway-update-interval 20
        interface eth1 {
            failover-only
            route {
                default
            }
            route-test {
                count {
                    failure 3
                    success 3
                }
                initial-delay 60
                interval 10
                type {
                    ping {
                        target 1.1.1.1
                    }
                }
            }
        }
        interface eth2 {
            route {
                default
            }
            route-test {
                count {
                    failure 3
                    success 3
                }
                initial-delay 60
                interval 10
                type {
                    ping {
                        target 1.1.1.1
                    }
                }
            }
        }
        lb-local enable
        lb-local-metric-change enable
        transition-script /config/scripts/wan_failover.sh
    }
}

Whenever a failover transition occurs, the EdgeRouter will invoke the script with several arguments, and will do so for each interface. I have the script to invoke a webhook on HA which configures the status.

#!/bin/bash
curl --request POST --header "Content-Type: application/json" --data "{\"group\":\"$1\",\"interface\":\"$2\",\"status\":\"$3\"}" http://hass.home/api/webhook/wan_failover
input_text:
  wan_status:
    name: "WAN Status"
  lte_status:
    name: "LTE Status"

sensor:
  - platform: template
    sensors:
      wan_status:
        friendly_name: "WAN Status"
        value_template: "{{ states('input_text.wan_status') | capitalize }}"
        icon_template: >-
          {% if is_state("input_text.wan_status", "active") %}
            mdi:lan-connect
          {% elif is_state("input_text.wan_status", "inactive") %}
            mdi:lan-disconnect
          {% else %}
            mdi:lan-pending
          {% endif %}
      lte_status:
        friendly_name: "LTE Status"
        value_template: "{{ states('input_text.lte_status') | capitalize }}"
        icon_template: >-
          {% if is_state("input_text.lte_status", "active") %}
            mdi:lan-connect
          {% elif is_state("input_text.lte_status", "inactive") %}
            mdi:lan-disconnect
          {% else %}
            mdi:lan-pending
          {% endif %}
- alias: WAN Failover Webhook
  description: ''
  trigger:
  - platform: webhook
    webhook_id: wan_failover
  condition: []
  action:
  - data_template:
      entity_id: '{{ ''input_text.wan_status'' if trigger.json.interface == ''eth2'' else ''input_text.lte_status'' }}'
      value: '{{ trigger.json.status }}'
    service: input_text.set_value
  - delay: 00:00:10
  - data_template:
      message: '{{ ''WAN'' if trigger.json.interface == ''eth2'' else ''LTE'' }} interface
        is now {{ trigger.json.status }}'
      title: WAN Failover
    service: notify.pushover
  mode: parallel
  max: 10

The webhook will both set the input_text for wan/lte status, and also send me a notification. (although I can’t remember why I have a 10s delay between them :thinking:). Having this webhook to be in parallel mode is important, because edgerouter will invoke the transition-script once for each interface more or less at the same time.

Bandwidth

To query the bandwidth, I have SNMP enabled on the EdgeRouter and the following HA configuration.

sensor:
  - platform: time_date
    display_options:
      - 'date_time'
  - platform: snmp
    name: wan_in
    baseoid: 1.3.6.1.2.1.2.2.1.10.4
    host: !secret zeus_hostname
    version: !secret zeus_snmp_version
    accept_errors: true
    scan_interval: 10
  - platform: snmp
    name: wan_out
    baseoid: 1.3.6.1.2.1.2.2.1.16.4
    host: !secret zeus_hostname
    version: !secret zeus_snmp_version
    accept_errors: true
    scan_interval: 10
  - platform: derivative
    name: wan_in_der
    source: sensor.wan_in
    unit_time: s
    unit: B
  - platform: derivative
    name: wan_out_der
    source: sensor.wan_out
    unit_time: s
    unit: B
  - platform: template
    sensors:
      wan_in_mbps:
        value_template: "{{ [((states('sensor.wan_in_der')|float*8)/1000000)|round(2),0]|max }}"
        unit_of_measurement: 'Mbps'
        friendly_name: "WAN In"
      wan_out_mbps:
        value_template: "{{ [((states('sensor.wan_out_der')|float*8)/1000000)|round(2),0]|max }}"
        unit_of_measurement: 'Mbps'
        friendly_name: "WAN Out"
  - platform: snmp
    name: lte_in
    baseoid: 1.3.6.1.2.1.2.2.1.10.3
    host: !secret zeus_hostname
    version: !secret zeus_snmp_version
    accept_errors: true
    scan_interval: 10
  - platform: snmp
    name: lte_out
    baseoid: 1.3.6.1.2.1.2.2.1.16.3
    host: !secret zeus_hostname
    version: !secret zeus_snmp_version
    accept_errors: true
    scan_interval: 10
  - platform: derivative
    name: lte_in_der
    source: sensor.lte_in
    unit_time: s
    unit: B
  - platform: derivative
    name: lte_out_der
    source: sensor.lte_out
    unit_time: s
    unit: B
  - platform: template
    sensors:
      lte_in_mbps:
        value_template: "{{ [((states('sensor.lte_in_der')|float*8)/1000000)|round(2),0]|max }}"
        unit_of_measurement: 'Mbps'
        friendly_name: "LTE In"
      lte_out_mbps:
        value_template: "{{ [((states('sensor.lte_out_der')|float*8)/1000000)|round(2),0]|max }}"
        unit_of_measurement: 'Mbps'
        friendly_name: "LTE Out"
6 Likes

This is nice, would I be able to do this just for one internet connection, I like to see the stats and notify me when down.

Yeah, certainly. If you have an EdgeRouter Lite-3, you can do the following. The baseoid’s last digit corresponds to the interface, so change accordingly, in my case .4 == eth2.

sensor:
  - platform: time_date
    display_options:
      - 'date_time'
  - platform: snmp
    name: wan_in
    baseoid: 1.3.6.1.2.1.2.2.1.10.4
    host: !secret zeus_hostname
    version: !secret zeus_snmp_version
    accept_errors: true
    scan_interval: 10
  - platform: snmp
    name: wan_out
    baseoid: 1.3.6.1.2.1.2.2.1.16.4
    host: !secret zeus_hostname
    version: !secret zeus_snmp_version
    accept_errors: true
    scan_interval: 10
  - platform: derivative
    name: wan_in_der
    source: sensor.wan_in
    unit_time: s
    unit: B
  - platform: derivative
    name: wan_out_der
    source: sensor.wan_out
    unit_time: s
    unit: B
  - platform: template
    sensors:
      wan_in_mbps:
        value_template: "{{ [((states('sensor.wan_in_der')|float*8)/1000000)|round(2),0]|max }}"
        unit_of_measurement: 'Mbps'
        friendly_name: "WAN In"
      wan_out_mbps:
        value_template: "{{ [((states('sensor.wan_out_der')|float*8)/1000000)|round(2),0]|max }}"
        unit_of_measurement: 'Mbps'
        friendly_name: "WAN Out"

If you have something other than EdgeRouter Lite-3, then you will need to figure out the oid that corresponds to the bytes in/out (you can use snmpwalk for example to query the device), and some may even have the bandwidth as a value directly (no need to do all the derivatives and calculations). There’s quite a few other writeups for pulling bandwidth via SNMP in the forum as well https://community.home-assistant.io/search?q=snmp%20bandwidth

Sorry, haven’t got a chance to see your response, for some reason I wasn’t notified by email. anyway
thanks for your response, I have Ubuiquiti Gateway Router 3P, will that work?

I wasn’t able to find a product named Gateway Router 3P, did you mean UniFi Security Gateway? If so, then this probably won’t work as-is, they don’t run EdgeOS (which is what the EdgeRouter and EdgeSwitch models run).

I am not familiar with USG, but I do know it integrates with the UniFi controller, so there might be a way to set up a notification or callback on the controller. Best of luck!

Yes its USG, and I believe its runs EdgeOS, becaz I remember once a customer support emailed me on a response for something else.

USG is also running edge OS as backend, so most of the things can be reused…
it’s interesting as I run a double wan failover on my USG…

Hi there!

I have 0 experience on SNMP and Home Assistant integration of the SNMP aspect.

I am running a Edgerouter X and looking for a way to pull data strait from my router to my Home Assistant display.

The screenshot of your meters is where i would like to strat (with the exception of a single line atm but there will be a failover in the future)

Would be someone willing to guide me step by step on the process of integrating this to my Home Assistant? I know spoon feeding a solution is not the optimal way in the long run but i honestly have 0 experience on the SNMP framework and how it operates and there is an ocean of information that is impossible to digest and produce a solid result.

Thank anyone willing to help for the time and effort in advance.

Snmp is a pretty big mess, it’s more of an art rather than a science.

First up, enable snmp on your router, in this case I set read-only access for the entire 192.168.0.0/24 range (you can adjust accordingly)

 service {
     snmp {
         community foobar {
             authorization ro
             client 192.168.0.0/24

Next install the snmpwalk and snmptranslate on your personal machine (if on mac, you can use brew). We’ll use that to query the router.

snmpwalk -v 2c -c foobar -Of IP_OF_ROUTER > snmpwalk.output

Now look at the snmpwalk.output and try to figure out the OID of the counters you’re interested in. You will need to compare the values to the output you get from your router. Assuming all edgeOs have similar names, look for something along the lines of

.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifInOctets.1 = Counter32: 12702145
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifInOctets.2 = Counter32: 297512845
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifInOctets.3 = Counter32: 0
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifInOctets.4 = Counter32: 821182776
...
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOutOctets.1 = Counter32: 12702145
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOutOctets.2 = Counter32: 1004930727
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOutOctets.3 = Counter32: 0
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOutOctets.4 = Counter32: 3935219899

Once you determine the specific OID, you can use snmptranslate to convert it to the numeric notation (which is what the homeassistant snmp accepts)

snmptranslate -On .iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifInOctets.4
.1.3.6.1.2.1.2.2.1.10.4

Since this is just a byte counter, if you want the bandwidth, you can use the homeassistant derivative to calculate that (see the bandwidth section of my initial post), where

  • wan_in is the byte counter directly from snmp
  • wan_in_der is the derivative of wan_in
  • wan_in_mbps is the template that converts wan_in_der from bytes/s to Mbps
1 Like