Monitoring your Unifi AP

Perfect. Thought that might be the issue.

1 Like

Many thanks for doing this and works great.

I have 5 APs so would have been a bit of effort to duplicate it 5 times so I made and APPDAEMON app from it, I am by no means an expert but it seems to work ok.

This will create all the sensors and update every 2 minutes as you had for all your APs specified in the target_macs field.

You will need to amend the cards to match each AP sensor names

No need for the command_line or template sensors

Don’t forget to add pyunifi to Appdaemon’s config

Not done the same for switches as not fussed about this level of detail for my switches but should be easily adaptable

EDIT: Have done it for my switches now to add POE ports power and voltage monitoring

from pyunifi.controller import Controller
import json
import re
import hassapi as hass
import datetime

class UnifiAPSW(hass.Hass):

    def initialize(self):
        self.log("Unifi AP and Switches Started")
        self.run_in(self.update_aps, 0)
        self.run_every(self.update_aps, datetime.datetime.now(), 600)
        self.run_in(self.update_switches, 0)
        self.run_every(self.update_switches, datetime.datetime.now(), 600)
        self.listen_event(self.unifi_update_event, "UNIFI_UPDATE")

    def unifi_update_event(self, UNIFI_UPDATE, data, kvargs):
        self.run_in(self.update_aps, 0)
        self.run_in(self.update_switches, 0)
 
    def update_aps(self, kwargs):
        self.log("Update APs Started")
        username = 'xxxxxxxxxxxxxxx'
        password = 'xxxxxxxxxxxx'
        target_macs = {'bedroom': 'xxxxx', 'bens_room': 'xxxxx', 'downstairs': 'xxxxx', 'garage': 'xxxxx', 'living_room': 'xxxxx'}
        for key in target_macs:
            entity = "sensor.unifi_" + key + "_ap"
            client = Controller('192.168.1.1', username, password, 443, 'UDMP-unifiOS', site_id='default', ssl_verify=False)
            stat = client.get_sysinfo()
            devs = client.get_device_stat(target_macs[key])
            #self.log(devs)
            clients = client.get_clients()
            numclients = int(devs['user-wlan-num_sta'])
            self.set_state(entity + "_clients", state = numclients, friendly_name = key.title() + " AP Clients", unit_of_measurement = "Clients")
            numguests = int(devs['guest-wlan-num_sta'])
            self.set_state(entity + "_guests", state = numguests, friendly_name = key.title() + " AP Guests", unit_of_measurement = "Guests")
            score = int(devs['satisfaction'])
            self.set_state(entity + "_score", state = score, friendly_name = key.title() + " AP Score", unit_of_measurement = "%" )
            update = devs['upgradable']
            self.set_state("binary_sensor.unifi_" + key + "_ap_update", state = update, friendly_name = key.title() + " AP Update", device_class="update" )
            cpu = float(devs['system-stats']['cpu'])
            self.set_state(entity + "_cpu", state = cpu, friendly_name = key.title() + " AP CPU", unit_of_measurement = "%")
            ram = float(devs['system-stats']['mem'])
            self.set_state(entity + "_ram", state = ram, friendly_name = key.title() + " AP RAM", unit_of_measurement = "%")
            activity = round(devs['uplink']['rx_bytes-r']/125000 + devs['uplink']['tx_bytes-r']/125000,1)
            self.set_state(entity + "_activity", state = activity, friendly_name = key.title() + " AP Activity")
            seconds = devs['uptime']
            days = seconds // 86400
            hours = (seconds - (days * 86400)) // 3600
            minutes = (seconds - (days * 86400) - (hours * 3600)) // 60
            uptime = str(days)+'d '+str(hours)+'h '+str(minutes)+'m'
            self.set_state(entity + "_uptime", state = uptime, friendly_name = key.title() + " AP Uptime")
            wifi0clients = int(devs['radio_table_stats'][0]['user-num_sta'])
            self.set_state(entity + "_2_4ghz_clients", state = wifi0clients, friendly_name = key.title() + " AP 2.4GHz Clients", unit_of_measurement = "Clients")
            wifi1clients = int(devs['radio_table_stats'][1]['user-num_sta'])
            self.set_state(entity + "_5ghz_clients", state = wifi1clients, friendly_name = key.title() + " AP 5GHz Clients", unit_of_measurement = "Clients")
            self.log(entity)
            model = devs['model']
            if model == 'UAL6':
                picture = "/local/images/unifiap62.png"
            elif model == 'U7IW':
                picture = "/local/images/unifiapiw2.png"   
            elif model == 'UHDIW':
                picture = "/local/images/unifiapiw2.png"   
            else:
                picture = "/local/images/unifiap62.png" 
            self.set_state(entity, state = numclients, attributes = {"entity_picture":picture, "Clients":numclients, "Guests":numguests, "Clients_wifi0":wifi0clients, "Clients_wifi1":wifi1clients, "Score":score, "CPU":str(cpu), "RAM":str(ram), "Uptime":uptime, "Activity":str(activity)+' Mbps', "Update":update})

    def update_switches(self, kwargs):
        self.log("Update Switches Started")
        username = 'xxxxxxxxxxx'
        password = 'xxxxxxx'
        target_macs = {'workshop_switch': xxxxxx', 'loft_switch': 'xxxxxx'}
        for key in target_macs:
            entity = "sensor.unifi_" + key
            client = Controller('192.168.1.1', username, password, 443, 'UDMP-unifiOS', site_id='default', ssl_verify=False)
            devs = client.get_device_stat(target_macs[key])
            model = devs['model']
            self.log('Switch Model: ' + model)
            for x in range(len(devs['port_table'])):
                port_poe = devs['port_table'][x]['port_poe']
                if port_poe == True:
                    port_name = devs['port_table'][x]['name']
                    poe_power = round(float(devs['port_table'][x]['poe_power']), 1)
                    poe_voltage = round(float(devs['port_table'][x]['poe_voltage']))
                    self.log(str(key) + ' Port ' + str(x+1) + ' ' + str(port_name) + ': ' + str(poe_power) + 'W' + ' ' + str(poe_voltage) + 'V')
                    self.set_state(entity + "_port" + str(x+1) + "_power", state = poe_power, attributes = {"friendly_name": port_name, "device_class": "power", "unit_of_measurement": "W", "model": model})
                    self.set_state(entity + "_port" + str(x+1) + "_voltage", state = poe_voltage, attributes = {"friendly_name": port_name, "device_class": "voltage", "unit_of_measurement": "V", "model": model})
                else:
                    self.log(str(key) + ' Port ' + str(x+1) + ": NOT POE")
2 Likes

Sorry if this has been asked before but I can’t see it in the thread. Is it possible to run this in my setup? I’m running Home Assistant OS on a Raspberry Pi4. I have no idea where to start with the Python interface installation - do I need something additional before this?

Definitely possible, I have AppDaemon running a repeating script to do exactly what you’re trying to do. Did you figure it out?

Nope - haven’t looked at it since though - got a few things going on at the moment. Can you share details of how that works?

I came up with this as an alternative if anyone is interested.

which one is the latest version?

or

GitHub - RubenDijk/homeassistant: Homeassistant stuff (this one is the linked on the top)

I’d love to get it working but I am stuck somewhere. Could you help me?
Currently I run 8 AP on a controller which is installed on a pi (Version 6.5.55), without a self-signed certificate (browser states that the certificate is not trustworthy) . My last try for the first AP was:

host = ‘Controller-IP
username = ‘Unifi-User
password = ‘Unifi-PW
version = ‘v6’
site_id = ‘default’
port = ‘8443’
verify_ssl = False
target_mac = ‘Unifi-Mac’ ## the mac address of your AP device

client = Controller(host, username, password, port, version,
site_id=site_id, ssl_verify=verify_ssl)

All I get is this error:

[homeassistant.components.command_line] Command failed: python3 /config/scripts/unifi_ap1.py

I also tried version v5; version unifiOS; and verify_ssl = True

Which device you running on ? Are you running a stand alone controller ? Think the port might be wrong.

I run the controller on a raspi 4, 8443 is the port I access the controller with my browser

Update: I tried Port 443 in combination with Version v5 and unifiOS as well as in combination with ssl = True and ssl= false.

no success so far.

Did you add the custom component: GitHub - custom-components/sensor.unifigateway: High level health status of UniFi Security Gateway devices via UniFi Controller ?

It needs some part of the component in order to work correctly.

Yes, this component is up and running. I’ll try more possibilities later on but for now I’ll let it be.

Thanks a lot @w1tw0lf for this project.
It’s exactly what I needed.
I’ve met some issues like some other people here.
Pay attention to setup the correct AP version !
Only 1 pending “issue” on my side.
I don’t have any icon shown. I keep eye icon in the card and on the entity as well.
Any hint on that ?
Thanks

Mind sharing a screenshot of the card ?

Here it is :
2022-02-08 08_40_07-Home – Home Assistant

For the icon, you need to customize the entity, sensor.****_ap with an entity picture. You can place the file as a *.png under /config/www

I uploaded the 5 that i have to the git page

I can’t because my sensor unifi_ap has no unique_ID
2022-02-08 09_26_14-Configuration – Home Assistant

Do you have any idea from where this comes from ?
Did I miss setup something ?

Don’t worry about, that is normal.

in your configuration.yaml add the following:

customize:
  sensor.unifi_ap:
    entity_picture: /local/u6.png

Just replace u6.png with the one you want to use. Make sure the png is located in /config/www. Restart home assistant and it will display correctly.

Thanks for your prompt replies.
Unfortunately, I don’t find where exactly I need to insert this in my configuration.yaml.
under line below ?

sensor:
  - platform: command_line

2022-02-08 10_12_40-Home Assistant

put it right at the end of the file.

customize should be at the beginning of a new line, in other words no spaces before.

sensor:
  - platform: command_line

customize:
  sensor.unifi_ap:
    entity_picture: /local/u6.png

PS: Sorry corrected my code snippet, had some spacing errors.