Open myopenflixr opened 7 months ago
I'm having exactly the same issue as well.
Same here! Works fine for a few hours and then starts failing until the next reboot.
Experiencing the same issue. Seems to be connected to the latest UniFi OS 3.2. Started here after having upgraded the UniFi Cloud Key.
Logger: homeassistant.helpers.entity
Source: helpers/entity.py:698
First occurred: 20:06:37 (32 occurrences)
Last logged: 20:22:07
Update for sensor.unifi_gateway_firmware_upgradable fails
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 698, in async_update_ha_state
await self.async_device_update()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 961, in async_device_update
await hass.async_add_executor_job(self.update)
File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/util/__init__.py", line 190, in wrapper
result = method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/unifigateway/sensor.py", line 162, in update
if devices.get('upgradable'):
^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'get'
Logger: homeassistant.helpers.entity
Source: helpers/entity.py:698
First occurred: 20:06:37 (32 occurrences)
Last logged: 20:22:07
Update for sensor.unifi_gateway_alerts fails
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 698, in async_update_ha_state
await self.async_device_update()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 961, in async_device_update
await hass.async_add_executor_job(self.update)
File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/util/__init__.py", line 190, in wrapper
result = method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/unifigateway/sensor.py", line 145, in update
if not alert['archived']:
~~~~~^^^^^^^^^^^^
TypeError: string indices must be integers, not 'str'
Logger: homeassistant.helpers.entity
Source: helpers/entity.py:698
First occurred: 20:06:37 (128 occurrences)
Last logged: 20:22:07
Update for sensor.unifi_gateway_www fails
Update for sensor.unifi_gateway_wan fails
Update for sensor.unifi_gateway_wlan fails
Update for sensor.unifi_gateway_lan fails
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 698, in async_update_ha_state
await self.async_device_update()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 961, in async_device_update
await hass.async_add_executor_job(self.update)
File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/util/__init__.py", line 190, in wrapper
result = method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/unifigateway/sensor.py", line 174, in update
if sub['subsystem'] == self._sensor:
~~~^^^^^^^^^^^^^
TypeError: string indices must be integers, not 'str'
I have the same issue, if anyone finds a fix please let me know
Same here. Only option is to reload. Frustrating, given I have automation hung off this.
Seem to work again as it should with HA 2024.1.1. In case it stops again I will report here.
Addendum: I wrote too soon. The issue started again :(
Same here. After a reload it works for a couple of hours and then fails again.
same here.
Logger: homeassistant.helpers.entity
Source: helpers/entity.py:894
First occurred: 08:51:25 (1 occurrences)
Last logged: 08:51:25
Update for sensor.unifi_gateway_firmware_upgradable fails
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 894, in async_update_ha_state
await self.async_device_update()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1214, in async_device_update
await hass.async_add_executor_job(self.update)
File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/util/__init__.py", line 190, in wrapper
result = method(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/unifigateway/sensor.py", line 162, in update
if devices.get('upgradable'):
^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'get'
I also have this issue
last update was about 3 years. So I do not expect anything. A pitty
I guess it’s time to remove it?
I guess it’s time to remove it?
Sadly it pretty much looks like this useful tool has turned into abandonedware.
Why is not anyone else taking over? Can't imagine some devs are not into this as ubiquiti is very popular! Same issue here. Only thing that helps is to reset the Template sensors or reboot HA
I guess it’s time to remove it?
Sadly it pretty much looks like this useful tool has turned into abandonedware.
What about this one? https://github.com/zvldz/unifi_status/tree/master/custom_components/unifi_status
Looks like someone took over but its also not updated for 2 years
Why is not anyone else taking over? Can't imagine some devs are not into this as ubiquiti is very popular! Same issue here. Only thing that helps is to reset the Template sensors or reboot HA
I tried resetting the template sensors but it instantly fails for me. Yeah I wish I had the skills to take it over, it works so well
I guess it’s time to remove it?
Sadly it pretty much looks like this useful tool has turned into abandonedware.
What about this one? https://github.com/zvldz/unifi_status/tree/master/custom_components/unifi_status
Looks like someone took over but its also not updated for 2 years
Tried it and no good. I even tried removing code that I didn’t use like firmware and vpn but it still crashes.
Maybe @zvldz could fix it if anyone can get hold of them?
I guess it’s time to remove it?
Sadly it pretty much looks like this useful tool has turned into abandonedware.
What about this one? https://github.com/zvldz/unifi_status/tree/master/custom_components/unifi_status Looks like someone took over but its also not updated for 2 years
Tried it and no good. I even tried removing code that I didn’t use like firmware and vpn but it still crashes.
Maybe @zvldz could fix it if anyone can get hold of them?
Since the new update today it's completely broken and the sensors doesn't work anymore. 😢
I managed to replace all the functionality I was using this for via other means quite easily. I get bits of information now for my dream machine SE instead using the official integration (status, uptime, external IP, and a few others) and a graph for bandwidth usage via SNMP.
Depending on what people used this for, you may be able to do the same without too much difficulty.
I tried SNMP but I couldn’t get CPU usage and also when it updated it wiped off my SNMP install. This is on the UDM-Pro
On Sat, 10 Feb 2024 at 11:51, SeeThisIsMe @.***> wrote:
I managed to replace all the functionality I was using this for via other means quite easily. I get bits of information now for my dream machine SE instead using the official integration (status, uptime, external IP, and a few others) and a graph for bandwidth usage via SNMP.
Depending on what people used this for, you may be able to do the same without too much difficulty.
— Reply to this email directly, view it on GitHub https://github.com/custom-components/sensor.unifigateway/issues/59#issuecomment-1936779870, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKH2FP66NCR2FFMEBTAS4PDYS2777AVCNFSM6AAAAABAE6EHR6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMZWG43TSOBXGA . You are receiving this because you are subscribed to this thread.Message ID: @.*** com>
I managed to replace all the functionality I was using this for via other means quite easily. I get bits of information now for my dream machine SE instead using the official integration (status, uptime, external IP, and a few others) and a graph for bandwidth usage via SNMP.
Depending on what people used this for, you may be able to do the same without too much difficulty.
Do you mind sharing? I think alot of people will find that useful.
@SeeThisIsMe It would be really great if you could share the steps you took to get it to work. That will benefit many more of us.
Here is my "fix"... please note that this script grew organically over time as I moved features from the other plugins to my unified script ( pun intended ) ...
#!/usr/local/bin/python
from datetime import timedelta
import json, yaml, requests
from datetime import datetime
import requests,time
from re import sub
import sys
resp={}
resp['data']={}
def parse_uptime(uptime):
seconds = 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'
return uptime
controller_url = 'https://xxxxx.xxxxx.xxxxx'
username = 'xxxx'
password = 'xxxx'
site = 'default' # The site ID, 'default' for most installations
login_url = f'{controller_url}/api/auth/login'
login_data = {
'username': username,
'password': password
}
session = requests.Session()
response = session.post(login_url, json=login_data, verify=True)
response.raise_for_status()
def snake_case(s):
return '_'.join(
sub('([A-Z][a-z]+)', r' \1',
sub('([A-Z]+)', r' \1',
s.replace('-', ' '))).split()).lower()
rules_url = 'https://xxxx.xxxx.xxxx/proxy/network/api/s/default/stat/device'
response = session.get(rules_url, verify=False)
response.raise_for_status()
rules = response.json()
sysinfo_url = 'https://xxxx.xxxx.xxxx/proxy/network/api/s/default/stat/sysinfo'
response = session.get(sysinfo_url, verify=False)
response.raise_for_status()
version = response.json()
health_url = 'https://xxxx.xxxx.xxx/proxy/network/api/s/default/stat/health'
response = session.get(health_url, verify=False)
response.raise_for_status()
health_data = response.json()
# keys = health_data['data'][0].keys()
# a = {k: set(d[k] for d in health_data['data']) for k in keys}
# print(json.dumps(health_data, indent = 1))
#
for h in health_data['data']:
match h['subsystem']:
case 'www':
# print(json.dumps(h, indent = 1))
resp['data'].update({
"health_" + h['subsystem'] + ".status": h['status'],
"health_" + h['subsystem'] + ".tx_bytes-r": h['tx_bytes-r'],
"health_" + h['subsystem'] + ".rx_bytes-r": h['rx_bytes-r'],
"health_" + h['subsystem'] + ".latency": h['latency'],
"health_" + h['subsystem'] + ".uptime": h['uptime'],
"health_" + h['subsystem'] + ".drops": h['drops'],
"health_" + h['subsystem'] + ".xput_up": h['xput_up'],
"health_" + h['subsystem'] + ".xput_down": h['xput_down'],
"health_" + h['subsystem'] + ".speedtest_status": h['speedtest_status'],
"health_" + h['subsystem'] + ".speedtest_lastrun": h['speedtest_lastrun'],
"health_" + h['subsystem'] + ".speedtest_ping": h['speedtest_ping'],
"health_" + h['subsystem'] + ".uptime": h['uptime']
})
case 'vpn':
resp['data'].update({
"health_" + h['subsystem'] + ".status": h['status'],
})
# test
case 'wlan':
resp['data'].update({
"health_" + h['subsystem'] + ".num_user": h['num_user'],
"health_" + h['subsystem'] + ".num_guest": h['num_guest'],
"health_" + h['subsystem'] + ".num_iot": h['num_iot'],
"health_" + h['subsystem'] + ".tx_bytes": h['tx_bytes-r'],
"health_" + h['subsystem'] + ".rx_bytes": h['rx_bytes-r'],
"health_" + h['subsystem'] + ".status": h['status'],
"health_" + h['subsystem'] + ".num_ap": h['num_ap']
})
case 'lan':
resp['data'].update({
"health_" + h['subsystem'] + ".status": h['status'],
"health_" + h['subsystem'] + ".num_user": h['num_user'],
"health_" + h['subsystem'] + ".num_iot": h['num_iot'],
"health_" + h['subsystem'] + ".num_sw": h['num_sw'],
"health_" + h['subsystem'] + ".num_adopted": h['num_adopted']
})
# test
case 'wan':
# print(h['subsystem'])
# print(json.dumps(h, indent = 1))
resp['data'].update({
"health_" + h['subsystem'] + ".status": h['status'],
"health_" + h['subsystem'] + ".isp_organization": h['isp_organization'],
"health_" + h['subsystem'] + ".isp_name": h['isp_name'],
"health_" + h['subsystem'] + ".gw_version": h['gw_version'],
"health_" + h['subsystem'] + ".num_sta": h['num_sta'],
"health_" + h['subsystem'] + ".cpu": h['gw_system-stats']['cpu'],
"health_" + h['subsystem'] + ".mem": h['gw_system-stats']['mem'],
"health_" + h['subsystem'] + ".uptime": h['gw_system-stats']['uptime'],
"health_" + h['subsystem'] + ".tx_bytes": h['tx_bytes-r'],
"health_" + h['subsystem'] + ".rx_bytes": h['rx_bytes-r']
})
case _:
print("else")
# uptime_stats = "https://xxxxx.xxx.xxxx/proxy/network/api/s/default/stat/stats"
#
# response_stats = session.get(uptime_stats, verify=False)
# response_stats.raise_for_status()
# data = response_stats.json()["data"][0]
# # # print(version)
# json.dumps(print(resp['data']))
# print(json.dumps(resp['data'], indent = 1))
# print(json.dumps({
# "cpu": data["system-stats"]["cpu"],
# "cpu_temp": round(data["temperatures"][1]["value"], 1),
# "system_temp": round(data["temperatures"][0]["value"], 1),
# "memory": data["system-stats"]["mem"],
# "disk": round(data["storage"][1]["used"] / data["storage"][1]["size"] * 100, 1),
# "internet": data["wan1"]["up"],
# "uptime": datetime.fromtimestamp(data["startup_timestamp"]).isoformat(),
# "availability": data["uptime_stats"]["WAN"]["availability"],
# "average_latency": data["uptime_stats"]["WAN"]["latency_average"],
# "down": data["uplink"]["rx_rate"] / 1000000,
# "up": data["uplink"]["tx_rate"] / 1000000,
# "version": data["displayable_version"],
# "last_wan_ip": data["last_wan_ip"]
# }))
# sys.exit(2)
resp["version"]=version['data'][0]['version']
# # Find the rule to update
for client_data in rules['data']:
## If switch is offline ignore
if client_data['state'] == 0:
continue
name=snake_case(client_data['name'])
# print(client_data)
# resp[name]={}
# # print(version)
# json.dumps(print(client_data))
internet = None
speedtest_status = None
# print("client_data['model'] %s",client_data['model'] )
if client_data['model'] == "UDMPRO":
speedtest_status = client_data['uplink']['speedtest_status'] == "Success"
internet = client_data['uplink']['up']
# if 'uplink' in client_data.keys():
# if client_data['uplink']['uplink_source'] == 'legacy':
# internet = client_data['uplink']['up']
# else:
# internet = client_data['internet']
# print("client_data['model'] %s",client_data['model'] )
# elif 'internet' in client_data.keys():
# internet = client_data['internet']
# print("client_data['model'] %s",client_data['model'] )
cpu=0
ram=0
try:
if client_data['system-stats'] and client_data['system-stats'] != {} and len(client_data['system-stats'].keys()) != 0:
try:
cpu = float(client_data['system-stats']['cpu'])
except:
cpu = 0.0
try:
ram = float(client_data['system-stats']['mem'])
except:
ram = 0
except:
print("An exception occurred")
print(json.dumps(client_data, indent = 1))
print("------")
activity = round(client_data['uplink']['rx_bytes-r']/125000 + client_data['uplink']['tx_bytes-r']/125000,1)
uptime = parse_uptime(client_data['uptime'])
update = int(client_data['upgradable'])
model_type = client_data['model']
# print(type)
if client_data['is_access_point']:
wifi0clients = client_data['radio_table_stats'][0]['user-num_sta']
wifi1clients = client_data['radio_table_stats'][1]['user-num_sta']
wifi0score = client_data['radio_table_stats'][0]['satisfaction']
wifi1score = client_data['radio_table_stats'][1]['satisfaction']
numclients = client_data['user-wlan-num_sta']
numguests = client_data['guest-wlan-num_sta']
score = client_data['satisfaction']
# raise ValueError('Some error')
resp['data'].update ({
name+".Clients":numclients,
name+".Guests":numguests,
name+".Clients_wifi0":wifi0clients ,
name+".Clients_wifi1":wifi1clients ,
name+".Score":score,
name+".CPU": cpu,
name+".RAM":ram,
name+".Uptime":uptime,
name+".Score_wifi0":wifi0score ,
name+".Score_wifi1":wifi1score ,
name+".Activity":str(activity)+' Mbps',
name+".Update":update,
})
else:
cpu_temp = None
board_temp = None
wan_drops = None
wan_latency = None
if 'temperatures' in client_data.keys() and client_data['temperatures']!={}:
for t in client_data['temperatures']:
if t['type'] == "cpu" : cpu_temp = t['value']
if t['type'] == "board" : board_temp = t['value']
# json.dumps(print(client_data))
# print(json.dumps(client_data, indent = 1))
storage_used = None
storage_size = None
if 'storage' in client_data.keys() and client_data['storage']!=[]:
for t in client_data['storage']:
if t['mount_point'] == "/persistent":
storage_size = t['size']
storage_used = t['used']
availability=None
latency_average=None
uplink_ip=None
if 'uptime_stats' in client_data.keys() and client_data['uptime_stats']!={}:
for t in client_data['uptime_stats']['WAN']['alerting_monitors']:
if t['target'] == "1.1.1.1":
latency_average = t['latency_average']
availability = t['availability']
if 'uplink' in client_data.keys() and client_data['uplink']!={} and 'comment' in client_data['uplink'].keys():
# json.dumps(print(client_data['uplink']))
# print(json.dumps(client_data['uplink'], indent = 1))
if client_data['uplink']['comment'] == "WAN":
wan_latency = client_data['uplink']['latency']
wan_drops = client_data['uplink']['drops']
uplink_ip = client_data['uplink']['ip']
# uplink
# print(t)
# print(json.dumps(client_data, indent = 1))
# if 'speedtest-status' in client_data.keys() and client_data['speedtest-status'] is not None:
# print("---")
# # print(client_data['speedtest-status'])
# # json.dumps(print(client_data))
# print(json.dumps(client_data['uplink'], indent = 1))
# print("---")
# internet = client_data['internet']
usedports = client_data['num_sta']
userports = client_data['user-num_sta']
guestports = client_data['guest-num_sta']
resp['data'].update({
name+".Activity":str(activity)+' Mbps',
name+".CPU":cpu,
name+".RAM":ram,
name+".Uptime":uptime,
name+".Ports_used":usedports,
name+".Ports_user":userports,
name+".Ports_guest":guestports,
name+".Update":update,
name+".Model": model_type
})
if 'speedtest_ping' in client_data['uplink'].keys() and client_data['uplink']['speedtest_ping'] is not None:
resp['data'].update({
name+".Speedtest_ping": client_data['uplink']['speedtest_ping'],
name+".Speedtest_up": client_data['uplink']['xput_up'],
name+".Speedtest_down": client_data['uplink']['xput_down']
})
if storage_used is not None:
resp['data'].update({
name+".StorageUsed": storage_used,
name+".StorageSize": storage_size
})
if internet is not None:
resp['data'].update({
name+".Internet": internet
})
if speedtest_status is not None:
resp['data'].update({
name+".SpeedTestPass": speedtest_status
})
if cpu_temp is not None:
resp['data'].update({
name+".CPUTemp":cpu_temp,
name+".BoardTemp":board_temp
})
if wan_drops is not None:
resp['data'].update({
name+".WanDrops":wan_drops,
name+".WanLatency":wan_latency
})
if latency_average is not None:
resp['data'].update({
name+".LatencyAvg":latency_average,
name+".WanAvailability":availability
})
if uplink_ip is not None:
resp['data'].update({
name+".UplinkIP":uplink_ip
})
# print(resp)
# formatted_json = json.dumps(resp, sort_keys=True, indent=4)
# colorful_json = highlight(formatted_json, lexers.JsonLexer(), formatters.TerminalFormatter())
# print(colorful_json)
json_formatted_str = json.dumps(resp, indent=2)
print(json_formatted_str)
# Log out of the UniFi Controller
logout_url = f'{controller_url}/api/auth/logout'
session.post(logout_url, verify=False)
sys.exit(0)
Here is my ha config
command_line:
- sensor:
name: udmpro_disk_usage
command: !secret udmpro_disk_usage
scan_interval: 3600
- sensor:
command: '/config/scripts/unifi_combined2.py'
command_timeout: 180
name: unifi_stats
value_template: '{{value_json.version}}'
scan_interval: 300
json_attributes:
- data
template:
binary_sensor:
- name: Unifi UDM Pro Internet Up
unique_id: unifi_udmpro_internet_up
state: >
{{ state_attr('sensor.unifi_stats','data')['udmpro.Internet'] }}
sensor:
## Unifi AP Basement
- name: Unifi AP Basement Guests
unique_id: unifi_ap_basement_guests
state: >
{{ state_attr('sensor.unifi_stats','data')['basement_ap.Guests'] }}
- name: Unifi AP Basement Activity
unique_id: unifi_ap_basement_activity
unit_of_measurement: 'Mbps'
state: >
{{ state_attr('sensor.unifi_stats','data')['basement_ap.Activity'].split(' ')[0] | float(0) }}
- name: Unifi AP Basement RAM
unique_id: unifi_ap_basement_ram
unit_of_measurement: '%'
state: >
{{ state_attr('sensor.unifi_stats','data')['basement_ap.RAM'] | float(0) }}
- name: Unifi AP Basement CPU
unique_id: unifi_ap_basement_cpu
unit_of_measurement: '%'
state: >
{{ state_attr('sensor.unifi_stats','data')['basement_ap.CPU'] | float(0) }}
- name: Unifi AP Basement Score
unique_id: unifi_ap_basement_score
state: >
{{ state_attr('sensor.unifi_stats','data')['basement_ap.Score'] }}
- name: Unifi AP Basement 2.4gHz Score
unique_id: unifi_ap_basement_2ghz_score
state: >
{{ state_attr('sensor.unifi_stats','data')['basement_ap.Score_wifi0'] | default(0) }}
- name: Unifi AP Basement 5gHz Score
unique_id: unifi_ap_basement_5ghz_score
state: >
{{ state_attr('sensor.unifi_stats','data')['basement_ap.Score_wifi1'] | default(0) }}
- name: Unifi AP Basement 2.4gHz Clients
unique_id: unifi_ap_basement_2ghz_wifi_devices
state: >
{{ state_attr('sensor.unifi_stats','data')['basement_ap.Clients_wifi0'] | default(0) }}
- name: Unifi AP Basement 5gHz Clients
unique_id: unifi_ap_basement_5ghz_wifi_devices
state: >
{{ state_attr('sensor.unifi_stats','data')['basement_ap.Clients_wifi1'] | default(0) }}
- name: Unifi AP Basement Total Clients
unique_id: unifi_ap_basement_total_clients
state: >
{{ state_attr('sensor.unifi_stats','data')['basement_ap.Clients_wifi0'] + state_attr('sensor.unifi_stats','data')['basement_ap.Clients_wifi1'] | default(0) }}
- name: Unifi AP Basement Updates
unique_id: unifi_ap_basement_update
state: >
{% if state_attr('sensor.unifi_stats', 'data')['basement_ap.Update'] == 0 %}
No
{% else %}
Available
{% endif %}
### Unifi AP Outside
- name: Unifi AP Outside Guests
unique_id: unifi_ap_outside_guests
state: >
{{ state_attr('sensor.unifi_stats','data')['outside_ap.Guests'] }}
- name: Unifi AP Outside Activity
unique_id: unifi_ap_outside_activity
unit_of_measurement: 'Mbps'
state: >
{{ state_attr('sensor.unifi_stats','data')['outside_ap.Activity'].split(' ')[0] | float(0) }}
- name: Unifi AP Outside RAM
unique_id: unifi_ap_outside_ram
unit_of_measurement: '%'
state: >
{{ state_attr('sensor.unifi_stats','data')['outside_ap.RAM'] | float(0) }}
- name: Unifi AP Outside CPU
unique_id: unifi_ap_outside_cpu
unit_of_measurement: '%'
state: >
{{ state_attr('sensor.unifi_stats','data')['outside_ap.CPU'] | float(0) }}
- name: Unifi AP Outside Score
unique_id: unifi_ap_outside_score
state: >
{{ state_attr('sensor.unifi_stats','data')['outside_ap.Score'] }}
- name: Unifi AP Outside 2.4gHz Score
unique_id: unifi_ap_outside_2ghz_score
state: >
{{ state_attr('sensor.unifi_stats','data')['outside_ap.Score_wifi0'] | default(0) }}
- name: Unifi AP Outside 5gHz Score
unique_id: unifi_ap_outside_5ghz_score
state: >
{{ state_attr('sensor.unifi_stats','data')['outside_ap.Score_wifi1'] | default(0) }}
- name: Unifi AP Outside 2.4gHz Clients
unique_id: unifi_ap_outside_2ghz_wifi_devices
state: >
{{ state_attr('sensor.unifi_stats','data')['outside_ap.Clients_wifi0'] | default(0) }}
- name: Unifi AP Outside 5gHz Clients
unique_id: unifi_ap_outside_5ghz_wifi_devices
state: >
{{ state_attr('sensor.unifi_stats','data')['outside_ap.Clients_wifi1'] | default(0) }}
- name: Unifi AP Outside total Clients
unique_id: unifi_ap_outside_total_clients
state: >
{{ state_attr('sensor.unifi_stats','data')['outside_ap.Clients_wifi0'] + state_attr('sensor.unifi_stats','data')['outside_ap.Clients_wifi1'] | default(0) }}
- name: Unifi AP Outside Updates
unique_id: unifi_ap_outside_update
state: >
{% if state_attr('sensor.unifi_stats', 'data')['outside_ap.Update'] == 0 %}
No
{% else %}
Available
{% endif %}
# Unifi AP Upstairs
- name: Unifi AP Upstairs Guests
unique_id: unifi_ap_upstairs_guests
state: >
{{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Guests'] }}
- name: Unifi AP Upstairs Activity
unique_id: unifi_ap_upstairs_activity
unit_of_measurement: 'Mbps'
state: >
{{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Activity'].split(' ')[0] | float(0) }}
- name: Unifi AP Upstairs RAM
unique_id: unifi_ap_upstairs_ram
unit_of_measurement: '%'
state: >
{{ state_attr('sensor.unifi_stats','data')['upstairs_ap.RAM'] | float(0) }}
- name: Unifi AP Upstairs CPU
unique_id: unifi_ap_upstairs_cpu
unit_of_measurement: '%'
state: >
{{ state_attr('sensor.unifi_stats','data')['upstairs_ap.CPU'] | float(0) }}
- name: Unifi AP Upstairs Score
unique_id: unifi_ap_upstairs_score
state: >
{{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Score'] }}
- name: Unifi AP Upstairs 2.4gHz Score
unique_id: unifi_ap_upstairs_2ghz_score
state: >
{{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Score_wifi0'] | default(0) }}
- name: Unifi AP Upstairs 5gHz Score
unique_id: unifi_ap_upstairs_5ghz_score
state: >
{{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Score_wifi1'] | default(0) }}
- name: Unifi AP Upstairs 2.4gHz Clients
unique_id: unifi_ap_upstairs_2ghz_wifi_devices
state: >
{{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Clients_wifi0'] | default(0) }}
- name: Unifi AP Upstairs 5gHz Clients
unique_id: unifi_ap_upstairs_5ghz_wifi_devices
state: >
{{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Clients_wifi1'] | default(0) }}
- name: Unifi AP Upstairs total Clients
unique_id: unifi_ap_upstairs_total_clients
state: >
{{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Clients_wifi0'] + state_attr('sensor.unifi_stats','data')['upstairs_ap.Clients_wifi1'] | default(0) }}
- name: Unifi AP Upstairs Updates
unique_id: unifi_ap_upstairs_update
state: >
{% if state_attr('sensor.unifi_stats', 'data')['upstairs_ap.Update'] == 0 %}
No
{% else %}
Available
{% endif %}
### Unifi UDM Pro
- name: Unifi UDM Pro Ports Used
unique_id: unifi_udmpro_ports_used
state: >
{{ state_attr('sensor.unifi_stats','data')['udmpro.Ports_used'] }}
- name: Unifi UDM Pro Ports User
unique_id: unifi_udmpro_guests
state: >
{{ state_attr('sensor.unifi_stats','data')['udmpro.Ports_user'] }}
- name: Unifi UDM Pro Ports Guest
unique_id: unifi_udmpro_ports_guests
state: >
{{ state_attr('sensor.unifi_stats','data')['udmpro.Ports_guest'] | default(0)}}
- name: Unifi UDM Pro Activity
unique_id: unifi_udmpro_activity
unit_of_measurement: 'Mbps'
state: >
{{ state_attr('sensor.unifi_stats','data')['udmpro.Activity'].split(' ')[0] | float(0) }}
- name: Unifi UDM Pro RAM
unique_id: unifi_udmpro_ram
unit_of_measurement: '%'
state: >
{{ state_attr('sensor.unifi_stats','data')['udmpro.RAM'] | float(0) }}
- name: Unifi UDM Pro CPU
unique_id: unifi_udmpro_cpu
unit_of_measurement: '%'
state: >
{{ state_attr('sensor.unifi_stats','data')['udmpro.CPU'] | float(0) }}
- name: Unifi UDM Pro CPU Temp
unique_id: unifi_udmpro_cpu_temp
unit_of_measurement: 'c'
state: >
{{ state_attr('sensor.unifi_stats','data')['udmpro.CPUTemp'] | default(0) }}
- name: Unifi UDM Pro Board Temp
unique_id: unifi_udmpro_board_temp
unit_of_measurement: 'c'
state: >
{{ state_attr('sensor.unifi_stats','data')['udmpro.BoardTemp'] | default(0) }}
- name: Unifi UDM Pro Updates
unique_id: unifi_udmpro_update
state: >
{% if state_attr('sensor.unifi_stats', 'data')['udmpro.Update'] == 0 %}
No
{% else %}
Available
{% endif %}
- name: Unifi UDM Pro Speedtest Ping
unique_id: unifi_udmpro_speed_test_ping
state: >
{{state_attr('sensor.unifi_stats','data')['udmpro.Speedtest_ping']}}
- name: Unifi UDM Pro Speedtest up
unique_id: unifi_udmpro_speed_test_up
state: >
{{state_attr('sensor.unifi_stats','data')['udmpro.Speedtest_up']}}
- name: Unifi UDM Pro Speedtest Down
unique_id: unifi_udmpro_speed_test_down
state: >
{{state_attr('sensor.unifi_stats','data')['udmpro.Speedtest_down']}}
# Unifi AP Garage
- name: Unifi AP Garage Guests
unique_id: unifi_ap_garage_guests
state: >
{{ state_attr('sensor.unifi_stats','data')['garage_ap.Guests'] }}
- name: Unifi AP Garage Activity
unique_id: unifi_ap_garage_activity
unit_of_measurement: 'Mbps'
state: >
{{ state_attr('sensor.unifi_stats','data')['garage_ap.Activity'].split(' ')[0] | float(0) }}
- name: Unifi AP Garage RAM
unique_id: unifi_ap_garage_ram
unit_of_measurement: '%'
state: >
{{ state_attr('sensor.unifi_stats','data')['garage_ap.RAM'] | float(0) }}
- name: Unifi AP Garage CPU
unique_id: unifi_ap_garage_cpu
unit_of_measurement: '%'
state: >
{{ state_attr('sensor.unifi_stats','data')['garage_ap.CPU'] | float(0) }}
- name: Unifi AP Garage Score
unique_id: unifi_ap_garage_score
state: >
{{ state_attr('sensor.unifi_stats','data')['garage_ap.Score'] }}
- name: Unifi AP Garage 2.4gHz Score
unique_id: unifi_ap_garage_2ghz_score
state: >
{{ state_attr('sensor.unifi_stats','data')['garage_ap.Score_wifi0'] | default(0) }}
- name: Unifi AP Garage 5gHz Score
unique_id: unifi_ap_garage_5ghz_score
state: >
{{ state_attr('sensor.unifi_stats','data')['garage_ap.Score_wifi1'] | default(0) }}
- name: Unifi AP Garage 2.4gHz Clients
unique_id: unifi_ap_garage_2ghz_wifi_devices
state: >
{{ state_attr('sensor.unifi_stats','data')['garage_ap.Clients_wifi0'] | default(0) }}
- name: Unifi AP Garage 5gHz Clients
unique_id: unifi_ap_garage_5ghz_wifi_devices
state: >
{{ state_attr('sensor.unifi_stats','data')['garage_ap.Clients_wifi1'] | default(0) }}
- name: Unifi AP Garage total Clients
unique_id: unifi_ap_garage_total_clients
state: >
{{ state_attr('sensor.unifi_stats','data')['garage_ap.Clients_wifi0'] + state_attr('sensor.unifi_stats','data')['garage_ap.Clients_wifi1'] | default(0) }}
- name: Unifi AP Garage Updates
unique_id: unifi_ap_garage_update
state: >
{% if state_attr('sensor.unifi_stats', 'data')['garage_ap.Update'] == 0 %}
No
{% else %}
Available
{% endif %}
- name: "UDM CPU"
unique_id: unifi_gateway_wan_cpu
unit_of_measurement: "%"
state: >
{{ state_attr('sensor.unifi_stats','data')['health_wan.cpu'] }}
- name: "UDM Memory"
unique_id: unifi_gateway_wan_mem
unit_of_measurement: "%"
state: >
{{ state_attr('sensor.unifi_stats','data')['health_wan.mem'] }}
- name: "WAN IP"
unique_id: unifi_gateway_wan_ip
state: >
{{ state_attr('sensor.unifi_stats','data')['udmpro.UplinkIP'] }}
- name: "WAN Download"
unique_id: unifi_gateway_wan_download
unit_of_measurement: Kbps
icon: "mdi:progress-download"
state: >
{{ (state_attr('sensor.unifi_stats','data')['health_wan.rx_bytes'] / 1024 )| int }}
- name: "USG Uptime"
unique_id: unifi_gateway_wan_uptime
state: >-
{%- set time = state_attr('sensor.unifi_stats','data')['health_wan.uptime'] | int %}
{%- set minutes = ((time % 3600) // 60) %}
{%- set minutes = '{}min'.format(minutes) if minutes > 0 else '' %}
{%- set hours = ((time % 86400) // 3600) %}
{%- set hours = '{}hr '.format(hours) if hours > 0 else '' %}
{%- set days = (time // 86400) %}
{%- set days = '{}d '.format(days) if days > 0 else '' %}
{{ 'Less than 1 min' if time < 60 else days + hours + minutes }}
- name: "USG Firmware Version"
unique_id: unifi_gateway_firmware_version
icon: "mdi:database-plus"
state: >-
{{ state_attr('sensor.unifi_stats','data')['health_wan.gw_version'] }}
- name: "USG Speedtest Download"
unique_id: unifi_gateway_www_xput_down
unit_of_measurement: Mbps
icon: "mdi:progress-download"
state: >-
{{ state_attr('sensor.unifi_stats','data')['health_www.xput_down'] }}
- name: "USG Speedtest Upload"
unique_id: unifi_gateway_www_xput_up
unit_of_measurement: Mbps
icon: "mdi:progress-upload"
state: >-
{{ state_attr('sensor.unifi_stats','data')['health_www.xput_up'] }}
- name: "USG Speedtest Ping"
unique_id: unifi_gateway_www_speedtest_ping
unit_of_measurement: ms
icon: "mdi:progress-clock"
state: >-
{{ state_attr('sensor.unifi_stats','data')['health_www.speedtest_ping'] }}
- name: "Internet Uptime"
unique_id: unifi_gateway_www_uptime
state: >
{%- set time = state_attr('sensor.unifi_stats','data')['health_www.uptime'] | int %}
{%- set minutes = ((time % 3600) // 60) %}
{%- set minutes = '{}min'.format(minutes) if minutes > 0 else '' %}
{%- set hours = ((time % 86400) // 3600) %}
{%- set hours = '{}hr '.format(hours) if hours > 0 else '' %}
{%- set days = (time // 86400) %}
{%- set days = '{}d '.format(days) if days > 0 else '' %}
{{ 'Less than 1 min' if time < 60 else days + hours + minutes }}
- name: "Unifi Wlan Users"
unique_id: unifi_gateway_wlan_num_user
icon: "mdi:account-multiple"
state: >
{{ state_attr('sensor.unifi_stats','data')['health_lan.num_user'] }}
- name: "Unifi Users Lan"
unique_id: unifi_gateway_lan_num_user
icon: "mdi:account-multiple"
state: >
{{ state_attr('sensor.unifi_stats','data')['health_lan.num_user'] }}
- name: "UDM-Firmware Version"
unique_id: unifi_gateway_firmware
state: >
{{ state_attr('sensor.unifi_stats','version') }}
icon: mdi:counter
hope its helpful to someone
Thank you very much!! How did you implement this? The configuration.yaml part is clear, but the python script is not listed like:
On Mon, 12 Feb 2024 at 14:10, John Dyer @.***> wrote:
Here is my "fix"... please note that this script grew organically over time as I moved features from the other plugins to mine... not once have I gone back over the code to refactor, clean up, or optimize!!
!/usr/local/bin/python
from datetime import timedeltaimport json, yaml, requestsfrom datetime import datetimeimport requests,timefrom re import subimport sys resp={}resp['data']={}
def parse_uptime(uptime): seconds = 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' return uptime controller_url = 'https://xxxxx.xxxxx.xxxxx'username = 'xxxx'password = 'xxxx'site = 'default' # The site ID, 'default' for most installations
login_url = f'{controller_url}/api/auth/login'login_data = { 'username': username, 'password': password } session = requests.Session()response = session.post(login_url, json=login_data, verify=True)response.raise_for_status() def snakecase(s): return ''.join( sub('([A-Z][a-z]+)', r' \1', sub('([A-Z]+)', r' \1', s.replace('-', ' '))).split()).lower()
rules_url = 'https://xxxx.xxxx.xxxx/proxy/network/api/s/default/stat/device' response = session.get(rules_url, verify=False)response.raise_for_status()rules = response.json()sysinfo_url = 'https://xxxx.xxxx.xxxx/proxy/network/api/s/default/stat/sysinfo' response = session.get(sysinfo_url, verify=False)response.raise_for_status()version = response.json()
health_url = 'https://xxxx.xxxx.xxx/proxy/network/api/s/default/stat/health' response = session.get(health_url, verify=False)response.raise_for_status()health_data = response.json()
keys = health_data['data'][0].keys()# a = {k: set(d[k] for d in health_data['data']) for k in keys}# print(json.dumps(health_data, indent = 1))#for h in health_data['data']:
match h['subsystem']: case 'www':
print(json.dumps(h, indent = 1))
resp['data'].update({ "health_" + h['subsystem'] + ".status": h['status'], "health_" + h['subsystem'] + ".tx_bytes-r": h['tx_bytes-r'], "health_" + h['subsystem'] + ".rx_bytes-r": h['rx_bytes-r'], "health_" + h['subsystem'] + ".latency": h['latency'], "health_" + h['subsystem'] + ".uptime": h['uptime'], "health_" + h['subsystem'] + ".drops": h['drops'], "health_" + h['subsystem'] + ".xput_up": h['xput_up'], "health_" + h['subsystem'] + ".xput_down": h['xput_down'], "health_" + h['subsystem'] + ".speedtest_status": h['speedtest_status'], "health_" + h['subsystem'] + ".speedtest_lastrun": h['speedtest_lastrun'], "health_" + h['subsystem'] + ".speedtest_ping": h['speedtest_ping'], "health_" + h['subsystem'] + ".uptime": h['uptime'] }) case 'vpn': resp['data'].update({ "health_" + h['subsystem'] + ".status": h['status'], }) # test case 'wlan': resp['data'].update({ "health_" + h['subsystem'] + ".num_user": h['num_user'], "health_" + h['subsystem'] + ".num_guest": h['num_guest'], "health_" + h['subsystem'] + ".num_iot": h['num_iot'], "health_" + h['subsystem'] + ".tx_bytes": h['tx_bytes-r'], "health_" + h['subsystem'] + ".rx_bytes": h['rx_bytes-r'], "health_" + h['subsystem'] + ".status": h['status'], "health_" + h['subsystem'] + ".num_ap": h['num_ap'] }) case 'lan': resp['data'].update({ "health_" + h['subsystem'] + ".status": h['status'], "health_" + h['subsystem'] + ".num_user": h['num_user'], "health_" + h['subsystem'] + ".num_iot": h['num_iot'], "health_" + h['subsystem'] + ".num_sw": h['num_sw'], "health_" + h['subsystem'] + ".num_adopted": h['num_adopted'] }) # test case 'wan': # print(h['subsystem']) # print(json.dumps(h, indent = 1)) resp['data'].update({ "health_" + h['subsystem'] + ".status": h['status'], "health_" + h['subsystem'] + ".isp_organization": h['isp_organization'], "health_" + h['subsystem'] + ".isp_name": h['isp_name'], "health_" + h['subsystem'] + ".gw_version": h['gw_version'], "health_" + h['subsystem'] + ".num_sta": h['num_sta'], "health_" + h['subsystem'] + ".cpu": h['gw_system-stats']['cpu'], "health_" + h['subsystem'] + ".mem": h['gw_system-stats']['mem'], "health_" + h['subsystem'] + ".uptime": h['gw_system-stats']['uptime'], "health_" + h['subsystem'] + ".tx_bytes": h['tx_bytes-r'], "health_" + h['subsystem'] + ".rx_bytes": h['rx_bytes-r'] }) case _: print("else")
uptime_stats = "https://xxxxx.xxx.xxxx/proxy/network/api/s/default/stat/stats"
response_stats = session.get(uptime_stats, verify=False)# response_stats.raise_for_status()# data = response_stats.json()["data"][0]# # # print(version)# json.dumps(print(resp['data']))# print(json.dumps(resp['data'], indent = 1))# print(json.dumps({# "cpu": data["system-stats"]["cpu"],# "cpu_temp": round(data["temperatures"][1]["value"], 1),# "system_temp": round(data["temperatures"][0]["value"], 1),# "memory": data["system-stats"]["mem"],# "disk": round(data["storage"][1]["used"] / data["storage"][1]["size"] * 100, 1),# "internet": data["wan1"]["up"],# "uptime": datetime.fromtimestamp(data["startup_timestamp"]).isoformat(),# "availability": data["uptime_stats"]["WAN"]["availability"],# "average_latency": data["uptime_stats"]["WAN"]["latency_average"],# "down": data["uplink"]["rx_rate"] / 1000000,# "up": data["uplink"]["tx_rate"] / 1000000,# "version": data["displayable_version"],# "last_wan_ip": data["last_wan_ip"]# }))# sys.exit(2)
resp["version"]=version['data'][0]['version']# # Find the rule to updatefor client_data in rules['data']:
If switch is offline ignore
if client_data['state'] == 0: continue
name=snake_case(client_data['name'])
print(client_data)
resp[name]={}
print(version)
json.dumps(print(client_data))
internet = None speedtest_status = None
print("client_data['model'] %s",client_data['model'] )
if client_data['model'] == "UDMPRO": speedtest_status = client_data['uplink']['speedtest_status'] == "Success" internet = client_data['uplink']['up']
if 'uplink' in client_data.keys():
# if client_data['uplink']['uplink_source'] == 'legacy': # internet = client_data['uplink']['up'] # else: # internet = client_data['internet'] # print("client_data['model'] %s",client_data['model'] ) # elif 'internet' in client_data.keys(): # internet = client_data['internet'] # print("client_data['model'] %s",client_data['model'] )
cpu=0 ram=0 try: if client_data['system-stats'] and client_data['system-stats'] != {} and len(client_data['system-stats'].keys()) != 0: try: cpu = float(client_data['system-stats']['cpu']) except: cpu = 0.0 try: ram = float(client_data['system-stats']['mem']) except: ram = 0 except: print("An exception occurred") print(json.dumps(client_data, indent = 1)) print("------")
activity = round(client_data['uplink']['rx_bytes-r']/125000 + client_data['uplink']['tx_bytes-r']/125000,1) uptime = parse_uptime(client_data['uptime']) update = int(client_data['upgradable']) model_type = client_data['model']
print(type)
if client_data['is_access_point']: wifi0clients = client_data['radio_table_stats'][0]['user-num_sta'] wifi1clients = client_data['radio_table_stats'][1]['user-num_sta'] wifi0score = client_data['radio_table_stats'][0]['satisfaction'] wifi1score = client_data['radio_table_stats'][1]['satisfaction'] numclients = client_data['user-wlan-num_sta'] numguests = client_data['guest-wlan-num_sta'] score = client_data['satisfaction']
# raise ValueError('Some error') resp['data'].update ({ name+".Clients":numclients, name+".Guests":numguests, name+".Clients_wifi0":wifi0clients , name+".Clients_wifi1":wifi1clients , name+".Score":score, name+".CPU": cpu, name+".RAM":ram, name+".Uptime":uptime, name+".Score_wifi0":wifi0score , name+".Score_wifi1":wifi1score , name+".Activity":str(activity)+' Mbps', name+".Update":update, })
else: cpu_temp = None board_temp = None wan_drops = None wan_latency = None if 'temperatures' in client_data.keys() and client_data['temperatures']!={}: for t in client_data['temperatures']: if t['type'] == "cpu" : cpu_temp = t['value'] if t['type'] == "board" : board_temp = t['value']
# json.dumps(print(client_data)) # print(json.dumps(client_data, indent = 1)) storage_used = None storage_size = None if 'storage' in client_data.keys() and client_data['storage']!=[]: for t in client_data['storage']: if t['mount_point'] == "/persistent": storage_size = t['size'] storage_used = t['used'] availability=None latency_average=None uplink_ip=None if 'uptime_stats' in client_data.keys() and client_data['uptime_stats']!={}: for t in client_data['uptime_stats']['WAN']['alerting_monitors']: if t['target'] == "1.1.1.1": latency_average = t['latency_average'] availability = t['availability'] if 'uplink' in client_data.keys() and client_data['uplink']!={} and 'comment' in client_data['uplink'].keys(): # json.dumps(print(client_data['uplink'])) # print(json.dumps(client_data['uplink'], indent = 1)) if client_data['uplink']['comment'] == "WAN": wan_latency = client_data['uplink']['latency'] wan_drops = client_data['uplink']['drops'] uplink_ip = client_data['uplink']['ip']
uplink
# print(t) # print(json.dumps(client_data, indent = 1)) # if 'speedtest-status' in client_data.keys() and client_data['speedtest-status'] is not None: # print("---") # # print(client_data['speedtest-status']) # # json.dumps(print(client_data)) # print(json.dumps(client_data['uplink'], indent = 1)) # print("---") # internet = client_data['internet'] usedports = client_data['num_sta'] userports = client_data['user-num_sta'] guestports = client_data['guest-num_sta'] resp['data'].update({ name+".Activity":str(activity)+' Mbps', name+".CPU":cpu, name+".RAM":ram, name+".Uptime":uptime, name+".Ports_used":usedports, name+".Ports_user":userports, name+".Ports_guest":guestports, name+".Update":update, name+".Model": model_type }) if 'speedtest_ping' in client_data['uplink'].keys() and client_data['uplink']['speedtest_ping'] is not None: resp['data'].update({ name+".Speedtest_ping": client_data['uplink']['speedtest_ping'], name+".Speedtest_up": client_data['uplink']['xput_up'], name+".Speedtest_down": client_data['uplink']['xput_down'] }) if storage_used is not None: resp['data'].update({ name+".StorageUsed": storage_used, name+".StorageSize": storage_size }) if internet is not None: resp['data'].update({ name+".Internet": internet }) if speedtest_status is not None: resp['data'].update({ name+".SpeedTestPass": speedtest_status }) if cpu_temp is not None: resp['data'].update({ name+".CPUTemp":cpu_temp, name+".BoardTemp":board_temp }) if wan_drops is not None: resp['data'].update({ name+".WanDrops":wan_drops, name+".WanLatency":wan_latency }) if latency_average is not None: resp['data'].update({ name+".LatencyAvg":latency_average, name+".WanAvailability":availability }) if uplink_ip is not None: resp['data'].update({ name+".UplinkIP":uplink_ip })
print(resp)# formatted_json = json.dumps(resp, sort_keys=True, indent=4)# colorful_json = highlight(formatted_json, lexers.JsonLexer(), formatters.TerminalFormatter())# print(colorful_json)json_formatted_str = json.dumps(resp, indent=2)print(json_formatted_str)# Log out of the UniFi Controllerlogout_url = f'{controller_url}/api/auth/logout'session.post(logout_url, verify=False)
sys.exit(0)
Here is my ha config
- sensor: command: '/config/scripts/unifi_combined2.py' command_timeout: 180 name: unifi_stats value_template: '{{value_json.version}}' scan_interval: 300 json_attributes:
- data
template: binary_sensor:
name: Unifi UDM Pro Internet Up unique_id: unifi_udmpro_internet_up state: > {{ state_attr('sensor.unifi_stats','data')['udmpro.Internet'] }}
sensor:
Unifi AP Basement
name: Unifi AP Basement Guests unique_id: unifi_ap_basement_guests state: > {{ state_attr('sensor.unifi_stats','data')['basement_ap.Guests'] }}
name: Unifi AP Basement Activity unique_id: unifi_ap_basement_activity unit_of_measurement: 'Mbps' state: > {{ state_attr('sensor.unifi_stats','data')['basement_ap.Activity'].split(' ')[0] | float(0) }}
name: Unifi AP Basement RAM unique_id: unifi_ap_basement_ram unit_of_measurement: '%' state: > {{ state_attr('sensor.unifi_stats','data')['basement_ap.RAM'] | float(0) }}
name: Unifi AP Basement CPU unique_id: unifi_ap_basement_cpu unit_of_measurement: '%' state: > {{ state_attr('sensor.unifi_stats','data')['basement_ap.CPU'] | float(0) }}
name: Unifi AP Basement Score unique_id: unifi_ap_basement_score state: > {{ state_attr('sensor.unifi_stats','data')['basement_ap.Score'] }}
name: Unifi AP Basement 2.4gHz Score unique_id: unifi_ap_basement_2ghz_score state: > {{ state_attr('sensor.unifi_stats','data')['basement_ap.Score_wifi0'] | default(0) }}
name: Unifi AP Basement 5gHz Score unique_id: unifi_ap_basement_5ghz_score state: > {{ state_attr('sensor.unifi_stats','data')['basement_ap.Score_wifi1'] | default(0) }}
name: Unifi AP Basement 2.4gHz Clients unique_id: unifi_ap_basement_2ghz_wifi_devices state: > {{ state_attr('sensor.unifi_stats','data')['basement_ap.Clients_wifi0'] | default(0) }}
name: Unifi AP Basement 5gHz Clients unique_id: unifi_ap_basement_5ghz_wifi_devices state: > {{ state_attr('sensor.unifi_stats','data')['basement_ap.Clients_wifi1'] | default(0) }}
name: Unifi AP Basement Total Clients unique_id: unifi_ap_basement_total_clients state: > {{ state_attr('sensor.unifi_stats','data')['basement_ap.Clients_wifi0'] + state_attr('sensor.unifi_stats','data')['basement_ap.Clients_wifi1'] | default(0) }}
name: Unifi AP Basement Updates unique_id: unifi_ap_basement_update state: > {% if state_attr('sensor.unifi_stats', 'data')['basement_ap.Update'] == 0 %} No {% else %} Available {% endif %}
Unifi AP Outside
name: Unifi AP Outside Guests unique_id: unifi_ap_outside_guests state: > {{ state_attr('sensor.unifi_stats','data')['outside_ap.Guests'] }}
name: Unifi AP Outside Activity unique_id: unifi_ap_outside_activity unit_of_measurement: 'Mbps' state: > {{ state_attr('sensor.unifi_stats','data')['outside_ap.Activity'].split(' ')[0] | float(0) }}
name: Unifi AP Outside RAM unique_id: unifi_ap_outside_ram unit_of_measurement: '%' state: > {{ state_attr('sensor.unifi_stats','data')['outside_ap.RAM'] | float(0) }}
name: Unifi AP Outside CPU unique_id: unifi_ap_outside_cpu unit_of_measurement: '%' state: > {{ state_attr('sensor.unifi_stats','data')['outside_ap.CPU'] | float(0) }}
name: Unifi AP Outside Score unique_id: unifi_ap_outside_score state: > {{ state_attr('sensor.unifi_stats','data')['outside_ap.Score'] }}
name: Unifi AP Outside 2.4gHz Score unique_id: unifi_ap_outside_2ghz_score state: > {{ state_attr('sensor.unifi_stats','data')['outside_ap.Score_wifi0'] | default(0) }}
name: Unifi AP Outside 5gHz Score unique_id: unifi_ap_outside_5ghz_score state: > {{ state_attr('sensor.unifi_stats','data')['outside_ap.Score_wifi1'] | default(0) }}
name: Unifi AP Outside 2.4gHz Clients unique_id: unifi_ap_outside_2ghz_wifi_devices state: > {{ state_attr('sensor.unifi_stats','data')['outside_ap.Clients_wifi0'] | default(0) }}
name: Unifi AP Outside 5gHz Clients unique_id: unifi_ap_outside_5ghz_wifi_devices state: > {{ state_attr('sensor.unifi_stats','data')['outside_ap.Clients_wifi1'] | default(0) }}
name: Unifi AP Outside total Clients unique_id: unifi_ap_outside_total_clients state: > {{ state_attr('sensor.unifi_stats','data')['outside_ap.Clients_wifi0'] + state_attr('sensor.unifi_stats','data')['outside_ap.Clients_wifi1'] | default(0) }}
name: Unifi AP Outside Updates unique_id: unifi_ap_outside_update state: > {% if state_attr('sensor.unifi_stats', 'data')['outside_ap.Update'] == 0 %} No {% else %} Available {% endif %}
Unifi AP Upstairs
name: Unifi AP Upstairs Guests unique_id: unifi_ap_upstairs_guests state: > {{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Guests'] }}
name: Unifi AP Upstairs Activity unique_id: unifi_ap_upstairs_activity unit_of_measurement: 'Mbps' state: > {{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Activity'].split(' ')[0] | float(0) }}
name: Unifi AP Upstairs RAM unique_id: unifi_ap_upstairs_ram unit_of_measurement: '%' state: > {{ state_attr('sensor.unifi_stats','data')['upstairs_ap.RAM'] | float(0) }}
name: Unifi AP Upstairs CPU unique_id: unifi_ap_upstairs_cpu unit_of_measurement: '%' state: > {{ state_attr('sensor.unifi_stats','data')['upstairs_ap.CPU'] | float(0) }}
name: Unifi AP Upstairs Score unique_id: unifi_ap_upstairs_score state: > {{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Score'] }}
name: Unifi AP Upstairs 2.4gHz Score unique_id: unifi_ap_upstairs_2ghz_score state: > {{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Score_wifi0'] | default(0) }}
name: Unifi AP Upstairs 5gHz Score unique_id: unifi_ap_upstairs_5ghz_score state: > {{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Score_wifi1'] | default(0) }}
name: Unifi AP Upstairs 2.4gHz Clients unique_id: unifi_ap_upstairs_2ghz_wifi_devices state: > {{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Clients_wifi0'] | default(0) }}
name: Unifi AP Upstairs 5gHz Clients unique_id: unifi_ap_upstairs_5ghz_wifi_devices state: > {{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Clients_wifi1'] | default(0) }}
name: Unifi AP Upstairs total Clients unique_id: unifi_ap_upstairs_total_clients state: > {{ state_attr('sensor.unifi_stats','data')['upstairs_ap.Clients_wifi0'] + state_attr('sensor.unifi_stats','data')['upstairs_ap.Clients_wifi1'] | default(0) }}
name: Unifi AP Upstairs Updates unique_id: unifi_ap_upstairs_update state: > {% if state_attr('sensor.unifi_stats', 'data')['upstairs_ap.Update'] == 0 %} No {% else %} Available {% endif %}
Unifi UDM Pro
name: Unifi UDM Pro Ports Used unique_id: unifi_udmpro_ports_used state: > {{ state_attr('sensor.unifi_stats','data')['udmpro.Ports_used'] }}
name: Unifi UDM Pro Ports User unique_id: unifi_udmpro_guests state: > {{ state_attr('sensor.unifi_stats','data')['udmpro.Ports_user'] }}
name: Unifi UDM Pro Ports Guest unique_id: unifi_udmpro_ports_guests state: > {{ state_attr('sensor.unifi_stats','data')['udmpro.Ports_guest'] | default(0)}}
name: Unifi UDM Pro Activity unique_id: unifi_udmpro_activity unit_of_measurement: 'Mbps' state: > {{ state_attr('sensor.unifi_stats','data')['udmpro.Activity'].split(' ')[0] | float(0) }}
name: Unifi UDM Pro RAM unique_id: unifi_udmpro_ram unit_of_measurement: '%' state: > {{ state_attr('sensor.unifi_stats','data')['udmpro.RAM'] | float(0) }}
name: Unifi UDM Pro CPU unique_id: unifi_udmpro_cpu unit_of_measurement: '%' state: > {{ state_attr('sensor.unifi_stats','data')['udmpro.CPU'] | float(0) }}
name: Unifi UDM Pro CPU Temp unique_id: unifi_udmpro_cpu_temp unit_of_measurement: 'c' state: > {{ state_attr('sensor.unifi_stats','data')['udmpro.CPUTemp'] | default(0) }}
name: Unifi UDM Pro Board Temp unique_id: unifi_udmpro_board_temp unit_of_measurement: 'c' state: > {{ state_attr('sensor.unifi_stats','data')['udmpro.BoardTemp'] | default(0) }}
name: Unifi UDM Pro Updates unique_id: unifi_udmpro_update state: > {% if state_attr('sensor.unifi_stats', 'data')['udmpro.Update'] == 0 %} No {% else %} Available {% endif %}
name: Unifi UDM Pro Speedtest Ping unique_id: unifi_udmpro_speed_test_ping state: > {{state_attr('sensor.unifi_stats','data')['udmpro.Speedtest_ping']}}
name: Unifi UDM Pro Speedtest up unique_id: unifi_udmpro_speed_test_up state: > {{state_attr('sensor.unifi_stats','data')['udmpro.Speedtest_up']}}
name: Unifi UDM Pro Speedtest Down unique_id: unifi_udmpro_speed_test_down state: > {{state_attr('sensor.unifi_stats','data')['udmpro.Speedtest_down']}}
Unifi AP Garage
name: Unifi AP Garage Guests unique_id: unifi_ap_garage_guests state: > {{ state_attr('sensor.unifi_stats','data')['garage_ap.Guests'] }}
name: Unifi AP Garage Activity unique_id: unifi_ap_garage_activity unit_of_measurement: 'Mbps' state: > {{ state_attr('sensor.unifi_stats','data')['garage_ap.Activity'].split(' ')[0] | float(0) }}
name: Unifi AP Garage RAM unique_id: unifi_ap_garage_ram unit_of_measurement: '%' state: > {{ state_attr('sensor.unifi_stats','data')['garage_ap.RAM'] | float(0) }}
name: Unifi AP Garage CPU unique_id: unifi_ap_garage_cpu unit_of_measurement: '%' state: > {{ state_attr('sensor.unifi_stats','data')['garage_ap.CPU'] | float(0) }}
name: Unifi AP Garage Score unique_id: unifi_ap_garage_score state: > {{ state_attr('sensor.unifi_stats','data')['garage_ap.Score'] }}
name: Unifi AP Garage 2.4gHz Score unique_id: unifi_ap_garage_2ghz_score state: > {{ state_attr('sensor.unifi_stats','data')['garage_ap.Score_wifi0'] | default(0) }}
name: Unifi AP Garage 5gHz Score unique_id: unifi_ap_garage_5ghz_score state: > {{ state_attr('sensor.unifi_stats','data')['garage_ap.Score_wifi1'] | default(0) }}
name: Unifi AP Garage 2.4gHz Clients unique_id: unifi_ap_garage_2ghz_wifi_devices state: > {{ state_attr('sensor.unifi_stats','data')['garage_ap.Clients_wifi0'] | default(0) }}
name: Unifi AP Garage 5gHz Clients unique_id: unifi_ap_garage_5ghz_wifi_devices state: > {{ state_attr('sensor.unifi_stats','data')['garage_ap.Clients_wifi1'] | default(0) }}
name: Unifi AP Garage total Clients unique_id: unifi_ap_garage_total_clients state: > {{ state_attr('sensor.unifi_stats','data')['garage_ap.Clients_wifi0'] + state_attr('sensor.unifi_stats','data')['garage_ap.Clients_wifi1'] | default(0) }}
name: Unifi AP Garage Updates unique_id: unifi_ap_garage_update state: > {% if state_attr('sensor.unifi_stats', 'data')['garage_ap.Update'] == 0 %} No {% else %} Available {% endif %}
name: "UDM CPU" unique_id: unifi_gateway_wan_cpu unit_of_measurement: "%" state: > {{ state_attr('sensor.unifi_stats','data')['health_wan.cpu'] }}
name: "UDM Memory" unique_id: unifi_gateway_wan_mem unit_of_measurement: "%" state: > {{ state_attr('sensor.unifi_stats','data')['health_wan.mem'] }}
name: "WAN IP" unique_id: unifi_gateway_wan_ip state: > {{ state_attr('sensor.unifi_stats','data')['udmpro.UplinkIP'] }}
name: "WAN Download" unique_id: unifi_gateway_wan_download unit_of_measurement: Kbps icon: "mdi:progress-download" state: > {{ (state_attr('sensor.unifi_stats','data')['health_wan.rx_bytes'] / 1024 )| int }}
name: "USG Uptime" unique_id: unifi_gateway_wan_uptime state: >- {%- set time = state_attr('sensor.unifi_stats','data')['health_wan.uptime'] | int %} {%- set minutes = ((time % 3600) // 60) %} {%- set minutes = '{}min'.format(minutes) if minutes > 0 else '' %} {%- set hours = ((time % 86400) // 3600) %} {%- set hours = '{}hr '.format(hours) if hours > 0 else '' %} {%- set days = (time // 86400) %} {%- set days = '{}d '.format(days) if days > 0 else '' %} {{ 'Less than 1 min' if time < 60 else days + hours + minutes }}
name: "USG Firmware Version" unique_id: unifi_gateway_firmware_version icon: "mdi:database-plus" state: >- {{ state_attr('sensor.unifi_stats','data')['health_wan.gw_version'] }}
name: "USG Speedtest Download" unique_id: unifi_gateway_www_xput_down unit_of_measurement: Mbps icon: "mdi:progress-download" state: >- {{ state_attr('sensor.unifi_stats','data')['health_www.xput_down'] }}
name: "USG Speedtest Upload" unique_id: unifi_gateway_www_xput_up unit_of_measurement: Mbps icon: "mdi:progress-upload" state: >- {{ state_attr('sensor.unifi_stats','data')['health_www.xput_up'] }}
name: "USG Speedtest Ping" unique_id: unifi_gateway_www_speedtest_ping unit_of_measurement: ms icon: "mdi:progress-clock" state: >- {{ state_attr('sensor.unifi_stats','data')['health_www.speedtest_ping'] }}
name: "Internet Uptime" unique_id: unifi_gateway_www_uptime state: > {%- set time = state_attr('sensor.unifi_stats','data')['health_www.uptime'] | int %} {%- set minutes = ((time % 3600) // 60) %} {%- set minutes = '{}min'.format(minutes) if minutes > 0 else '' %} {%- set hours = ((time % 86400) // 3600) %} {%- set hours = '{}hr '.format(hours) if hours > 0 else '' %} {%- set days = (time // 86400) %} {%- set days = '{}d '.format(days) if days > 0 else '' %} {{ 'Less than 1 min' if time < 60 else days + hours + minutes }}
name: "Unifi Wlan Users" unique_id: unifi_gateway_wlan_num_user icon: "mdi:account-multiple" state: > {{ state_attr('sensor.unifi_stats','data')['health_lan.num_user'] }}
name: "Unifi Users Lan" unique_id: unifi_gateway_lan_num_user icon: "mdi:account-multiple" state: > {{ state_attr('sensor.unifi_stats','data')['health_lan.num_user'] }}
name: "UDM-Firmware Version" unique_id: unifi_gateway_firmware state: > {{ state_attr('sensor.unifi_stats','version') }} icon: mdi:counter
hope its helpful to someone
— Reply to this email directly, view it on GitHub https://github.com/custom-components/sensor.unifigateway/issues/59#issuecomment-1938652085, or unsubscribe https://github.com/notifications/unsubscribe-auth/AYS5HXJRTOXGLDJYPXDIOQLYTIIDHAVCNFSM6AAAAABAE6EHR6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMZYGY2TEMBYGU . You are receiving this because you commented.Message ID: @.***>
I dont really like inline python so I put my scripts into a script folder and execute them from the command_line sensor w/ the full path
I dont really like inline python so I put my scripts into a script folder and execute them from the command_line sensor w/ the full path
Do you mind sharing that part of the command_line?
I did.... So try these steps
command_line:
- sensor:
command: '/config/scripts/unifi_combined.py'
command_timeout: 180
name: unifi_stats
value_template: '{{value_json.version}}'
scan_interval: 300
json_attributes:
- data
Hope that helps
is the "chmod +x /config/scripts/unifi_combined.py" really needed? And also how do I do this? via SSH?
On Mon, 12 Feb 2024 at 18:28, John Dyer @.***> wrote:
I did.... So try these steps
- Take the python code and paste that into /config/scripts/unifi_combined.py
- chmod +x /config/scripts/unifi_combined.py
- Add the following to your configuration.yaml
command_line:
- sensor: command: '/config/scripts/unifi_combined.py' command_timeout: 180 name: unifi_stats value_template: '{{value_json.version}}' scan_interval: 300 json_attributes:
- data
— Reply to this email directly, view it on GitHub https://github.com/custom-components/sensor.unifigateway/issues/59#issuecomment-1939200163, or unsubscribe https://github.com/notifications/unsubscribe-auth/AYS5HXIDJM3D34CEW6PDFYTYTJGLPAVCNFSM6AAAAABAE6EHR6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMZZGIYDAMJWGM . You are receiving this because you commented.Message ID: @.***>
oh yea, its all via SSH... sorry, guess I assumed you were using ssh
when loading the command_line (i copied your script) i get the following error. Do you know what happend? Do i need to install python or something?
Logger: homeassistant.components.command_line.utils Source: components/command_line/utils.py:54 Integration: Command Line (documentation, issues) First occurred: 19:19:58 (3 occurrences) Last logged: 19:21:58
Command failed (with return code 1): /config/scripts/unifi_combined.py Command failed (with return code 1): python3 /config/scripts/unifi_ap.py
On Mon, 12 Feb 2024 at 18:43, John Dyer @.***> wrote:
oh yea, its all via SSH... sorry, guess I assumed you were using ssh
— Reply to this email directly, view it on GitHub https://github.com/custom-components/sensor.unifigateway/issues/59#issuecomment-1939224956, or unsubscribe https://github.com/notifications/unsubscribe-auth/AYS5HXPQ4BI6PTQA6HEIYLTYTJIEXAVCNFSM6AAAAABAE6EHR6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMZZGIZDIOJVGY . You are receiving this because you commented.Message ID: @.***>
Can you drop to ssh shell and run
python3 /config/scripts/unifi_ap.py
python3 /config/scripts/unifi_combined.py
I would like to see the error
Also tried with pyscript (custom component)
oh FFS.... seems like you dont have some packages installed via your custom components that I do have... ok we can work around this..... We're going to make a stub component that just installs that package and nothing else.... Total hack but should work
mkdir /config/custom_components/hello_world
cd /config/custom_components/hello_world
wget https://gist.githubusercontent.com/johntdyer/4d1cf4692241e6a7ac299e64f2657efe/raw/21e870f2ff190ce44598a1f8b65bcdfbfd704ca9/__init__.py
wget https://gist.githubusercontent.com/johntdyer/4d1cf4692241e6a7ac299e64f2657efe/raw/21e870f2ff190ce44598a1f8b65bcdfbfd704ca9/manifest.json
Then restart and try again, if it doesnt work please attach the startup logs to your response
Hi
@johntdyer - big big thanks for sharing your solution and helping to make it work for others. The additional info this has, beyond the official Unifi integration is very useful!
I've been follwoing along today and am seeing similiar errors. I have added the py script, and the command line sensor. The good news is that this IS logging into my Unifi (UDM-Pro) system, I can see the login in the Unifi logs. The sensor remains "Unknown" however, and the only issue in the logs is ...
2024-02-12 21:15:02.767 ERROR (SyncWorker_5) [homeassistant.components.command_line.utils] Command failed (with return code 1): /config/scripts/unifi_combined.py 2024-02-12 21:15:02.767 WARNING (MainThread) [homeassistant.components.command_line] Empty reply found when expecting JSON data
Let me know if I can provide any additional info and thanks again!
@PlayFaster yea, this is what all that jsondump() commented out code is about.... need to run the script yourself in terminal and get the exact line its failing then see if you can dump that value and see whats missing that it expects.... the are seemingly an inasane amount of nuances between versions and models as to what is returned, even basic stuff like uptime is different amongst versions .... honestly this is probably why the author of this said to hell with it.... Unifi kinda sucks in that they dont even publish an api , its all reverse engineered
Hi @johntdyer . Understood and thanks. I'll start going thru the script and see what works for me and doesn't..
trying to follow along and have made progress. Thanks so much for trying to help us out @johntdyer .
Feeling like I have everything in place but I am getting an error of ModuleNotFoundError: No module named 'request' when trying to run the script.
Ran your wget's as well so not sure whats up with the request module.
can you try pip3 install request
?
ERROR: Could not find a version that satisfies the requirement request (from versions: none) ERROR: No matching distribution found for request
Just kidding... was missing an (s) in requests.
pip3 install requests
A step forward, but now SSL errors attempting to connect.
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate
Hi Folks. This now works for me. Again, a BIG thanks to @johntdyer for this.
For reference, in case its of use to anyone, here's what I needed to change (including fixing some of my own misinterpretations!) ...
(1) If you're not using an SSL cert, change verify=True to verify=False in Line 35
I made two changes because I thought I should. I should NOT have, these were ...
(2) Script Line 22: controller_url = 'https://xxxxx.xxxxx.xxxxx'
Even if you're not using a certificate, don't change the https to http!
(3) Put your username and password into Lines 23 and 24. Do NOT put them into lines 30 and 31 again!
Note: Once I used @johntdyer WGET commands, I did not need to load any further modules, such as "requests" etc. All worked, once I made the above mods.
Happy network monitoring to all. Remember, "it's a hobby, not an obsession" (?)
thanks so much @johntdyer and @PlayFaster. Up and running.
Hi Folks. This now works for me. Again, a BIG thanks to @johntdyer for this.
For reference, in case its of use to anyone, here's what I needed to change (including fixing some of my own misinterpretations!) ...
(1) If you're not using an SSL cert, change verify=True to verify=False in Line 35
I made two changes because I thought I should. I should NOT have, these were ...
(2) Script Line 22: controller_url = 'https://xxxxx.xxxxx.xxxxx' Even if you're not using a certificate, don't change the https to http! (3) Put your username and password into Lines 23 and 24. Do NOT put them into lines 30 and 31 again!
Note: Once I used @johntdyer WGET commands, I did not need to load any further modules, such as "requests" etc. All worked, once I made the above mods.
Happy network monitoring to all. Remember, "it's a hobby, not an obsession" (?)
Nice its working for me also! The SSL check to false did the trick. Now i can make the templates and put all the information in the sensors. Thank you everyone!! @johntdyer you are so good, you should make your own integration for Unifi 👍
(1) If you're not using an SSL cert, change verify=True to verify=False in Line 35
@johntdyer Do you know by any chance to get more WAN info out of it? Currently i dont get the WAN IP for example. I see you commented out some parts of the script, but not sure if intended. By the looks of your template sensors you are getting the IP's, right?
Again, thank you so much :)
The WAN ip is there
➜ ~
➜ ~ python3 /config/scripts/unifi_combined2.py
{
"data": {
"health_wlan.num_user": 96,
"health_wlan.num_guest": 0,
"health_wlan.num_iot": 0,
"health_wlan.tx_bytes": 0,
"health_wlan.rx_bytes": 0,
"health_wlan.status": "ok",
"health_wlan.num_ap": 4,
"health_wan.status": "ok",
"health_wan.isp_organization": "ATT-INTERNET4",
"health_wan.isp_name": "AT&T Internet",
"health_wan.gw_version": "3.2.9.14421",
"health_wan.num_sta": 167,
"health_wan.cpu": "28.9",
"health_wan.mem": "87.4",
"health_wan.uptime": "2073560",
"health_wan.tx_bytes": 27286,
"health_wan.rx_bytes": 77557,
"health_www.status": "ok",
"health_www.tx_bytes-r": 27286,
"health_www.rx_bytes-r": 77557,
"health_www.latency": 2,
"health_www.uptime": 301294,
"health_www.drops": 5,
"health_www.xput_up": 885.83,
"health_www.xput_down": 798.636,
"health_www.speedtest_status": "Success",
"health_www.speedtest_lastrun": 1707562348,
"health_www.speedtest_ping": 7,
"health_lan.status": "ok",
"health_lan.num_user": 71,
"health_lan.num_iot": 12,
"health_lan.num_sw": 7,
"health_lan.num_adopted": 7,
"health_vpn.status": "error",
"upstairs_great_room.Activity": "0.0 Mbps",
"upstairs_great_room.CPU": 0,
"upstairs_great_room.RAM": 0,
"upstairs_great_room.Uptime": "23d 1h 13m",
"upstairs_great_room.Ports_used": 1,
"upstairs_great_room.Ports_user": 1,
"upstairs_great_room.Ports_guest": 0,
"upstairs_great_room.Update": 0,
"upstairs_great_room.Model": "USMINI",
"attic_switch.Activity": "0.0 Mbps",
"attic_switch.CPU": 56.6,
"attic_switch.RAM": 38.6,
"attic_switch.Uptime": "14d 19h 28m",
"attic_switch.Ports_used": 1,
"attic_switch.Ports_user": 1,
"attic_switch.Ports_guest": 0,
"attic_switch.Update": 0,
"attic_switch.Model": "US8P60",
"udmpro.Activity": "0.8 Mbps",
"udmpro.CPU": 28.9,
"udmpro.RAM": 87.4,
"udmpro.Uptime": "23d 23h 59m",
"udmpro.Ports_used": 160,
"udmpro.Ports_user": 160,
"udmpro.Ports_guest": 0,
"udmpro.Update": 0,
"udmpro.Model": "UDMPRO",
"udmpro.Speedtest_ping": 7,
"udmpro.Speedtest_up": 885.83,
"udmpro.Speedtest_down": 798.636,
"udmpro.StorageUsed": 300494848,
"udmpro.StorageSize": 2046640128,
"udmpro.Internet": true,
"udmpro.SpeedTestPass": true,
"udmpro.CPUTemp": 64.0,
"udmpro.BoardTemp": 44.0,
"udmpro.WanDrops": 5,
"udmpro.WanLatency": 2,
"udmpro.LatencyAvg": 100,
"udmpro.WanAvailability": 100.0,
"udmpro.UplinkIP": "xxxxx.xxxx.xxxx.xxxx",
"garage_ap.Clients": 21,
"garage_ap.Guests": 0,
"garage_ap.Clients_wifi0": 20,
"garage_ap.Clients_wifi1": 1,
"garage_ap.Score": 96,
"garage_ap.CPU": 15.4,
"garage_ap.RAM": 50.1,
"garage_ap.Uptime": "61d 23h 32m",
"garage_ap.Score_wifi0": 96,
"garage_ap.Score_wifi1": 100,
"garage_ap.Activity": "0.0 Mbps",
"garage_ap.Update": 0,
"outside_switch.Activity": "0.0 Mbps",
"outside_switch.CPU": 6.4,
"outside_switch.RAM": 17.2,
"outside_switch.Uptime": "14d 19h 29m",
"outside_switch.Ports_used": 9,
"outside_switch.Ports_user": 9,
"outside_switch.Ports_guest": 0,
"outside_switch.Update": 0,
"outside_switch.Model": "USF5P",
"outside_ap.Clients": 7,
"outside_ap.Guests": 0,
"outside_ap.Clients_wifi0": 7,
"outside_ap.Clients_wifi1": 0,
"outside_ap.Score": 98,
"outside_ap.CPU": 7.4,
"outside_ap.RAM": 48.1,
"outside_ap.Uptime": "5d 5h 15m",
"outside_ap.Score_wifi0": 98,
"outside_ap.Score_wifi1": -1,
"outside_ap.Activity": "0.0 Mbps",
"outside_ap.Update": 0,
"core_switch.Activity": "0.0 Mbps",
"core_switch.CPU": 59.1,
"core_switch.RAM": 32.2,
"core_switch.Uptime": "9d 4h 57m",
"core_switch.Ports_used": 42,
"core_switch.Ports_user": 42,
"core_switch.Ports_guest": 0,
"core_switch.Update": 0,
"core_switch.Model": "US48PRO",
"upstairs_switch.Activity": "0.0 Mbps",
"upstairs_switch.CPU": 56.5,
"upstairs_switch.RAM": 38.6,
"upstairs_switch.Uptime": "14d 19h 27m",
"upstairs_switch.Ports_used": 3,
"upstairs_switch.Ports_user": 3,
"upstairs_switch.Ports_guest": 0,
"upstairs_switch.Update": 0,
"upstairs_switch.Model": "US8",
"upstairs_ap.Clients": 25,
"upstairs_ap.Guests": 0,
"upstairs_ap.Clients_wifi0": 24,
"upstairs_ap.Clients_wifi1": 1,
"upstairs_ap.Score": 98,
"upstairs_ap.CPU": 9.6,
"upstairs_ap.RAM": 66.9,
"upstairs_ap.Uptime": "4d 7h 25m",
"upstairs_ap.Score_wifi0": 99,
"upstairs_ap.Score_wifi1": 98,
"upstairs_ap.Activity": "0.0 Mbps",
"upstairs_ap.Update": 0,
"garage_switch.Activity": "0.0 Mbps",
"garage_switch.CPU": 0,
"garage_switch.RAM": 0,
"garage_switch.Uptime": "113d 20h 13m",
"garage_switch.Ports_used": 2,
"garage_switch.Ports_user": 2,
"garage_switch.Ports_guest": 0,
"garage_switch.Update": 0,
"garage_switch.Model": "USMINI",
"basement_ap.Clients": 41,
"basement_ap.Guests": 0,
"basement_ap.Clients_wifi0": 34,
"basement_ap.Clients_wifi1": 7,
"basement_ap.Score": 97,
"basement_ap.CPU": 29.2,
"basement_ap.RAM": 50.6,
"basement_ap.Uptime": "7d 14h 53m",
"basement_ap.Score_wifi0": 97,
"basement_ap.Score_wifi1": 98,
"basement_ap.Activity": "0.0 Mbps",
"basement_ap.Update": 0
},
"version": "8.0.28"
}
➜ ~
or am I misunderstanding ?
for you its there but not for me :( Not sure about other UDM users. The whole uplink info is not there.
Data health_wlan.num_user: 28 health_wlan.num_guest: 0 health_wlan.num_iot: 0 health_wlan.tx_bytes: 55502 health_wlan.rx_bytes: 8433 health_wlan.status: ok health_wlan.num_ap: 3 health_wan.status: ok health_wan.isp_organization: KPN B.V. health_wan.isp_name: KPN health_wan.gw_version: 3.2.12.14768 health_wan.num_sta: 32 health_wan.cpu: '3.2' health_wan.mem: '87.7' health_wan.uptime: '1006518' health_wan.tx_bytes: 10397 health_wan.rx_bytes: 17620 health_www.status: ok health_www.tx_bytes-r: 10397 health_www.rx_bytes-r: 17620 health_www.latency: 10 health_www.uptime: 1006480 health_www.drops: 1 health_www.xput_up: 58.794 health_www.xput_down: 162.908 health_www.speedtest_status: Success health_www.speedtest_lastrun: 1707793245 health_www.speedtest_ping: 13 health_lan.status: ok health_lan.num_user: 4 health_lan.num_iot: 0 health_lan.num_sw: 4 health_lan.num_adopted: 4 health_vpn.status: ok ap_03_zolder.Clients: 11 ap_03_zolder.Guests: 0 ap_03_zolder.Clients_wifi0: 9 ap_03_zolder.Clients_wifi1: 2 ap_03_zolder.Score: 97 ap_03_zolder.CPU: 1.3 ap_03_zolder.RAM: 40 ap_03_zolder.Uptime: 12d 1h 28m ap_03_zolder.Score_wifi0: 97 ap_03_zolder.Score_wifi1: 99 ap_03_zolder.Activity: 0.0 Mbps ap_03_zolder.Update: 0 usw_flex_mini_woonkamer.Activity: 0.0 Mbps usw_flex_mini_woonkamer.CPU: 0 usw_flex_mini_woonkamer.RAM: 0 usw_flex_mini_woonkamer.Uptime: 22d 9h 30m usw_flex_mini_woonkamer.Ports_used: 1 usw_flex_mini_woonkamer.Ports_user: 1 usw_flex_mini_woonkamer.Ports_guest: 0 usw_flex_mini_woonkamer.Update: 0 usw_flex_mini_woonkamer.Model: USMINI dream_machine.Clients: 11 dream_machine.Guests: 0 dream_machine.Clients_wifi0: 7 dream_machine.Clients_wifi1: 4 dream_machine.Score: 99 dream_machine.CPU: 3.2 dream_machine.RAM: 87.7 dream_machine.Uptime: 11d 15h 35m dream_machine.Score_wifi0: 99 dream_machine.Score_wifi1: 99 dream_machine.Activity: 0.2 Mbps dream_machine.Update: 0 usw_flex_mini_zolder.Activity: 0.0 Mbps usw_flex_mini_zolder.CPU: 0 usw_flex_mini_zolder.RAM: 0 usw_flex_mini_zolder.Uptime: 30d 5h 31m usw_flex_mini_zolder.Ports_used: 3 usw_flex_mini_zolder.Ports_user: 3 usw_flex_mini_zolder.Ports_guest: 0 usw_flex_mini_zolder.Update: 0 usw_flex_mini_zolder.Model: USMINI usw_flex_mini_slaapkamer.Activity: 0.0 Mbps usw_flex_mini_slaapkamer.CPU: 0 usw_flex_mini_slaapkamer.RAM: 0 usw_flex_mini_slaapkamer.Uptime: 30d 5h 1m usw_flex_mini_slaapkamer.Ports_used: 0 usw_flex_mini_slaapkamer.Ports_user: 0 usw_flex_mini_slaapkamer.Ports_guest: 0 usw_flex_mini_slaapkamer.Update: 0 usw_flex_mini_slaapkamer.Model: USMINI ap_02_slaapkamer.Clients: 6 ap_02_slaapkamer.Guests: 0 ap_02_slaapkamer.Clients_wifi0: 4 ap_02_slaapkamer.Clients_wifi1: 2 ap_02_slaapkamer.Score: 98 ap_02_slaapkamer.CPU: 0.5 ap_02_slaapkamer.RAM: 41.2 ap_02_slaapkamer.Uptime: 30d 4h 32m ap_02_slaapkamer.Score_wifi0: 98 ap_02_slaapkamer.Score_wifi1: 99 ap_02_slaapkamer.Activity: 0.0 Mbps ap_02_slaapkamer.Update: 0
The WAN IP does show for me, just to confirm. Running on a UDM Pro.
I would suggest going to the URL for the Health info directly on your UDM and see what appears there.
Go to https://xxxx.xxxx.xxx/proxy/network/api/s/default/stat/health (login to your UDM console first) and see what's produced. Search for wan_ip, or your actual IP address.
Yes when i run this i see more stats including wan IP and for example targets of ping tests.. How can i integrate this into my Home Assistant? Change the python part?
I also see alot of data in https://xxx.xxx.xxx/proxy/network/api/s/default/stat/sysinfo but how do i extract it?
Below is my python script (listed by john)
`
from datetime import timedelta import json, yaml, requests from datetime import datetime import requests,time from re import sub import sys
resp={} resp['data']={}
def parse_uptime(uptime): seconds = 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' return uptime
controller_url = 'https://192.168.1.1' username = 'username' password = 'password' site = 'default' # The site ID, 'default' for most installations
login_url = f'{controller_url}/api/auth/login' login_data = { 'username': username, 'password': password }
session = requests.Session() response = session.post(login_url, json=login_data, verify=False) response.raise_for_status()
def snakecase(s): return ''.join( sub('([A-Z][a-z]+)', r' \1', sub('([A-Z]+)', r' \1', s.replace('-', ' '))).split()).lower()
rules_url = 'https://192.168.1.1/proxy/network/api/s/default/stat/device'
response = session.get(rules_url, verify=False) response.raise_for_status() rules = response.json() sysinfo_url = 'https://192.168.1.1/proxy/network/api/s/default/stat/sysinfo'
response = session.get(sysinfo_url, verify=False) response.raise_for_status() version = response.json()
health_url = 'https://192.168.1.1/proxy/network/api/s/default/stat/health'
response = session.get(health_url, verify=False) response.raise_for_status() health_data = response.json()
# for h in health_data['data']:
match h['subsystem']: case 'www':
resp['data'].update({
"health_" + h['subsystem'] + ".status": h['status'],
"health_" + h['subsystem'] + ".tx_bytes-r": h['tx_bytes-r'],
"health_" + h['subsystem'] + ".rx_bytes-r": h['rx_bytes-r'],
"health_" + h['subsystem'] + ".latency": h['latency'],
"health_" + h['subsystem'] + ".uptime": h['uptime'],
"health_" + h['subsystem'] + ".drops": h['drops'],
"health_" + h['subsystem'] + ".xput_up": h['xput_up'],
"health_" + h['subsystem'] + ".xput_down": h['xput_down'],
"health_" + h['subsystem'] + ".speedtest_status": h['speedtest_status'],
"health_" + h['subsystem'] + ".speedtest_lastrun": h['speedtest_lastrun'],
"health_" + h['subsystem'] + ".speedtest_ping": h['speedtest_ping'],
"health_" + h['subsystem'] + ".uptime": h['uptime']
})
case 'vpn':
resp['data'].update({
"health_" + h['subsystem'] + ".status": h['status'],
})
# test
case 'wlan':
resp['data'].update({
"health_" + h['subsystem'] + ".num_user": h['num_user'],
"health_" + h['subsystem'] + ".num_guest": h['num_guest'],
"health_" + h['subsystem'] + ".num_iot": h['num_iot'],
"health_" + h['subsystem'] + ".tx_bytes": h['tx_bytes-r'],
"health_" + h['subsystem'] + ".rx_bytes": h['rx_bytes-r'],
"health_" + h['subsystem'] + ".status": h['status'],
"health_" + h['subsystem'] + ".num_ap": h['num_ap']
})
case 'lan':
resp['data'].update({
"health_" + h['subsystem'] + ".status": h['status'],
"health_" + h['subsystem'] + ".num_user": h['num_user'],
"health_" + h['subsystem'] + ".num_iot": h['num_iot'],
"health_" + h['subsystem'] + ".num_sw": h['num_sw'],
"health_" + h['subsystem'] + ".num_adopted": h['num_adopted']
})
# test
case 'wan':
# print(h['subsystem'])
# print(json.dumps(h, indent = 1))
resp['data'].update({
"health_" + h['subsystem'] + ".status": h['status'],
"health_" + h['subsystem'] + ".isp_organization": h['isp_organization'],
"health_" + h['subsystem'] + ".isp_name": h['isp_name'],
"health_" + h['subsystem'] + ".gw_version": h['gw_version'],
"health_" + h['subsystem'] + ".num_sta": h['num_sta'],
"health_" + h['subsystem'] + ".cpu": h['gw_system-stats']['cpu'],
"health_" + h['subsystem'] + ".mem": h['gw_system-stats']['mem'],
"health_" + h['subsystem'] + ".uptime": h['gw_system-stats']['uptime'],
"health_" + h['subsystem'] + ".tx_bytes": h['tx_bytes-r'],
"health_" + h['subsystem'] + ".rx_bytes": h['rx_bytes-r']
})
case _:
print("else")
#
resp["version"]=version['data'][0]['version']
for client_data in rules['data']:
if client_data['state'] == 0: continue
name=snake_case(client_data['name'])
internet = None speedtest_status = None
if client_data['model'] == "UDMPRO": speedtest_status = client_data['uplink']['speedtest_status'] == "Success" internet = client_data['uplink']['up']
# if client_data['uplink']['uplink_source'] == 'legacy':
# internet = client_data['uplink']['up']
# else:
# internet = client_data['internet']
# print("client_data['model'] %s",client_data['model'] )
# elif 'internet' in client_data.keys():
# internet = client_data['internet']
# print("client_data['model'] %s",client_data['model'] )
cpu=0 ram=0 try: if client_data['system-stats'] and client_data['system-stats'] != {} and len(client_data['system-stats'].keys()) != 0: try: cpu = float(client_data['system-stats']['cpu']) except: cpu = 0.0 try: ram = float(client_data['system-stats']['mem']) except: ram = 0 except: print("An exception occurred") print(json.dumps(client_data, indent = 1)) print("------")
activity = round(client_data['uplink']['rx_bytes-r']/125000 + client_data['uplink']['tx_bytes-r']/125000,1) uptime = parse_uptime(client_data['uptime']) update = int(client_data['upgradable']) model_type = client_data['model']
if client_data['is_access_point']: wifi0clients = client_data['radio_table_stats'][0]['user-num_sta'] wifi1clients = client_data['radio_table_stats'][1]['user-num_sta'] wifi0score = client_data['radio_table_stats'][0]['satisfaction'] wifi1score = client_data['radio_table_stats'][1]['satisfaction'] numclients = client_data['user-wlan-num_sta'] numguests = client_data['guest-wlan-num_sta'] score = client_data['satisfaction']
# raise ValueError('Some error')
resp['data'].update ({
name+".Clients":numclients,
name+".Guests":numguests,
name+".Clients_wifi0":wifi0clients ,
name+".Clients_wifi1":wifi1clients ,
name+".Score":score,
name+".CPU": cpu,
name+".RAM":ram,
name+".Uptime":uptime,
name+".Score_wifi0":wifi0score ,
name+".Score_wifi1":wifi1score ,
name+".Activity":str(activity)+' Mbps',
name+".Update":update,
})
else: cpu_temp = None board_temp = None wan_drops = None wan_latency = None if 'temperatures' in client_data.keys() and client_data['temperatures']!={}: for t in client_data['temperatures']: if t['type'] == "cpu" : cpu_temp = t['value'] if t['type'] == "board" : board_temp = t['value']
# json.dumps(print(client_data))
# print(json.dumps(client_data, indent = 1))
storage_used = None
storage_size = None
if 'storage' in client_data.keys() and client_data['storage']!=[]:
for t in client_data['storage']:
if t['mount_point'] == "/persistent":
storage_size = t['size']
storage_used = t['used']
availability=None
latency_average=None
uplink_ip=None
if 'uptime_stats' in client_data.keys() and client_data['uptime_stats']!={}:
for t in client_data['uptime_stats']['WAN']['alerting_monitors']:
if t['target'] == "1.1.1.1":
latency_average = t['latency_average']
availability = t['availability']
if 'uplink' in client_data.keys() and client_data['uplink']!={} and 'comment' in client_data['uplink'].keys():
# json.dumps(print(client_data['uplink']))
# print(json.dumps(client_data['uplink'], indent = 1))
if client_data['uplink']['comment'] == "WAN":
wan_latency = client_data['uplink']['latency']
wan_drops = client_data['uplink']['drops']
uplink_ip = client_data['uplink']['ip']
# print(t)
# print(json.dumps(client_data, indent = 1))
# if 'speedtest-status' in client_data.keys() and client_data['speedtest-status'] is not None:
# print("---")
# # print(client_data['speedtest-status'])
# # json.dumps(print(client_data))
# print(json.dumps(client_data['uplink'], indent = 1))
# print("---")
# internet = client_data['internet']
usedports = client_data['num_sta']
userports = client_data['user-num_sta']
guestports = client_data['guest-num_sta']
resp['data'].update({
name+".Activity":str(activity)+' Mbps',
name+".CPU":cpu,
name+".RAM":ram,
name+".Uptime":uptime,
name+".Ports_used":usedports,
name+".Ports_user":userports,
name+".Ports_guest":guestports,
name+".Update":update,
name+".Model": model_type
})
if 'speedtest_ping' in client_data['uplink'].keys() and client_data['uplink']['speedtest_ping'] is not None:
resp['data'].update({
name+".Speedtest_ping": client_data['uplink']['speedtest_ping'],
name+".Speedtest_up": client_data['uplink']['xput_up'],
name+".Speedtest_down": client_data['uplink']['xput_down']
})
if storage_used is not None:
resp['data'].update({
name+".StorageUsed": storage_used,
name+".StorageSize": storage_size
})
if internet is not None:
resp['data'].update({
name+".Internet": internet
})
if speedtest_status is not None:
resp['data'].update({
name+".SpeedTestPass": speedtest_status
})
if cpu_temp is not None:
resp['data'].update({
name+".CPUTemp":cpu_temp,
name+".BoardTemp":board_temp
})
if wan_drops is not None:
resp['data'].update({
name+".WanDrops":wan_drops,
name+".WanLatency":wan_latency
})
if latency_average is not None:
resp['data'].update({
name+".LatencyAvg":latency_average,
name+".WanAvailability":availability
})
if uplink_ip is not None:
resp['data'].update({
name+".UplinkIP":uplink_ip
})
json_formatted_str = json.dumps(resp, indent=2) print(json_formatted_str)
logout_url = f'{controller_url}/api/auth/logout' session.post(logout_url, verify=False)
sys.exit(0) `
Hi There. Try adding the wan_ip line into the WAN section, see below, added as 2nd line, under status ... see if this works for you ...
case 'wan':
# print(h['subsystem'])
# print(json.dumps(h, indent = 1))
resp['data'].update({
"health_" + h['subsystem'] + ".status": h['status'],
"health_" + h['subsystem'] + ".wan_ip": h['wan_ip'],
"health_" + h['subsystem'] + ".isp_organization": h['isp_organization'],
"health_" + h['subsystem'] + ".isp_name": h['isp_name'],
"health_" + h['subsystem'] + ".gw_version": h['gw_version'],
"health_" + h['subsystem'] + ".num_sta": h['num_sta'],
"health_" + h['subsystem'] + ".cpu": h['gw_system-stats']['cpu'],
"health_" + h['subsystem'] + ".mem": h['gw_system-stats']['mem'],
"health_" + h['subsystem'] + ".uptime": h['gw_system-stats']['uptime'],
"health_" + h['subsystem'] + ".tx_bytes": h['tx_bytes-r'],
"health_" + h['subsystem'] + ".rx_bytes": h['rx_bytes-r']
})
Hi There. Try adding the wan_ip line into the WAN section, see below, added as 2nd line, under status ... see if this works for you ...
case 'wan': # print(h['subsystem']) # print(json.dumps(h, indent = 1)) resp['data'].update({ "health_" + h['subsystem'] + ".status": h['status'], "health_" + h['subsystem'] + ".wan_ip": h['wan_ip'], "health_" + h['subsystem'] + ".isp_organization": h['isp_organization'], "health_" + h['subsystem'] + ".isp_name": h['isp_name'], "health_" + h['subsystem'] + ".gw_version": h['gw_version'], "health_" + h['subsystem'] + ".num_sta": h['num_sta'], "health_" + h['subsystem'] + ".cpu": h['gw_system-stats']['cpu'], "health_" + h['subsystem'] + ".mem": h['gw_system-stats']['mem'], "health_" + h['subsystem'] + ".uptime": h['gw_system-stats']['uptime'], "health_" + h['subsystem'] + ".tx_bytes": h['tx_bytes-r'], "health_" + h['subsystem'] + ".rx_bytes": h['rx_bytes-r'] })
Works like a charm! Thank you. Do you also know how to export the values of latency?
{"WAN":{"alerting_monitors":[{"availability":100.0,"latency_average":10,"target":"ping.ui.com","type":"icmp"},{"availability":100.0,"latency_average":100,"target":"1.1.1.1","type":"dns"},{"availability":100.0,"latency_average":100,"target":"8.8.8.8","type":"dns"}],"availability":100.0,"latency_average":10,"monitors":[{"availability":100.0,"latency_average":10,"target":"www.microsoft.com","type":"icmp"},{"availability":100.0,"latency_average":10,"target":"google.com","type":"icmp"},{"availability":100.0,"latency_average":10,"target":"1.1.1.1","type":"icmp"}],"time_period":86400,"uptime":199463}}},{"subsystem":"www","status":"ok","tx_bytes-r":8125,"rx_bytes-
Hi. Not sure, on mobile now, will take a look later to see.
I am having an error that seemed to start on Home Assistant 2023.11. After a couple hours of restarting Home Assistant, the sensors fail and stop updating. The only FIX is to restart Home Assistant to get the sensor data back. But, it stops working and throws errors again after a couple hours.
Here's two entries in the Logs showing the errors.
Any help would be greatly appreciated!