Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UniFi Uptime sensor #40058

Merged
merged 38 commits into from Sep 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ae63683
Added UniFi Uptime sensor
timkoers Sep 14, 2020
6d08aa2
Update sensor.py
timkoers Sep 14, 2020
b5c2f28
Changed timestamp format and device class
timkoers Sep 14, 2020
a3d55a3
Updated unit of measurement to None
timkoers Sep 14, 2020
a06cece
Added import
timkoers Sep 14, 2020
ee2bebe
Update homeassistant/components/unifi/sensor.py
timkoers Sep 14, 2020
b8613c5
Removed whitespace
timkoers Sep 14, 2020
c74fb3e
Added the uptime sensors option to the config flow
timkoers Sep 14, 2020
67c0818
All the unit tests should be there now
timkoers Sep 14, 2020
85c0fac
Whoops
timkoers Sep 14, 2020
2757268
Fixed translation
timkoers Sep 14, 2020
4fd76dd
Properly formatted the code
timkoers Sep 14, 2020
1dc42e5
Flake8 really has angel eyes
timkoers Sep 14, 2020
95ce1bb
Black should also be satisfied now
timkoers Sep 14, 2020
75f70c6
Should have satisfied all static code analysis tools
timkoers Sep 14, 2020
6b1c434
Fixed add uptime sensor function
timkoers Sep 14, 2020
08faf5c
Fixed overintendation
timkoers Sep 14, 2020
dfd796f
Fixed unit tests
timkoers Sep 14, 2020
0ea957b
Made a spelling mistake during editing of unit tests
timkoers Sep 14, 2020
47dd27d
Test verifies if utc time is correct
timkoers Sep 14, 2020
33c9874
Converted to iso format
timkoers Sep 14, 2020
d89ee56
Converted unit test to iso format
timkoers Sep 14, 2020
6fdce3a
Unit test sensor json had the wrong uptime name
timkoers Sep 14, 2020
14ccc96
Added options_updated handler
timkoers Sep 14, 2020
5acd113
Fixed remove sensors unit test
timkoers Sep 14, 2020
0436454
Update homeassistant/components/unifi/sensor.py
timkoers Sep 15, 2020
db06c80
Update homeassistant/components/unifi/sensor.py
timkoers Sep 15, 2020
45224d0
Update test_device_tracker.py
timkoers Sep 15, 2020
842c1d8
Fixed black formatting issue
timkoers Sep 15, 2020
6ebbf89
I think the code coverage should be good now
timkoers Sep 16, 2020
f22004b
Trying to add the sensors again
timkoers Sep 16, 2020
dc0ef50
Using signals to hopefully trigger the controller to add them again
timkoers Sep 16, 2020
1ad660b
Forgot import
timkoers Sep 16, 2020
94fdaa3
Sorted components
timkoers Sep 16, 2020
d169ffd
fixed isort comments
timkoers Sep 16, 2020
ec55200
Removed CLASS and DEVICE_CLASS
timkoers Sep 16, 2020
ba539a5
Added TYPE again
timkoers Sep 16, 2020
c095d08
Removed double underscores
timkoers Sep 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion homeassistant/components/unifi/config_flow.py
Expand Up @@ -16,6 +16,7 @@

from .const import (
CONF_ALLOW_BANDWIDTH_SENSORS,
CONF_ALLOW_UPTIME_SENSORS,
CONF_BLOCK_CLIENT,
CONF_CONTROLLER,
CONF_DETECTION_TIME,
Expand Down Expand Up @@ -312,7 +313,11 @@ async def async_step_statistics_sensors(self, user_input=None):
vol.Optional(
CONF_ALLOW_BANDWIDTH_SENSORS,
default=self.controller.option_allow_bandwidth_sensors,
): bool
): bool,
vol.Optional(
CONF_ALLOW_UPTIME_SENSORS,
default=self.controller.option_allow_uptime_sensors,
): bool,
}
),
)
Expand Down
2 changes: 2 additions & 0 deletions homeassistant/components/unifi/const.py
Expand Up @@ -12,6 +12,7 @@
UNIFI_WIRELESS_CLIENTS = "unifi_wireless_clients"

CONF_ALLOW_BANDWIDTH_SENSORS = "allow_bandwidth_sensors"
CONF_ALLOW_UPTIME_SENSORS = "allow_uptime_sensors"
CONF_BLOCK_CLIENT = "block_client"
CONF_DETECTION_TIME = "detection_time"
CONF_IGNORE_WIRED_BUG = "ignore_wired_bug"
Expand All @@ -22,6 +23,7 @@
CONF_SSID_FILTER = "ssid_filter"

DEFAULT_ALLOW_BANDWIDTH_SENSORS = False
DEFAULT_ALLOW_UPTIME_SENSORS = False
DEFAULT_IGNORE_WIRED_BUG = False
DEFAULT_POE_CLIENTS = True
DEFAULT_TRACK_CLIENTS = True
Expand Down
9 changes: 9 additions & 0 deletions homeassistant/components/unifi/controller.py
Expand Up @@ -33,6 +33,7 @@

from .const import (
CONF_ALLOW_BANDWIDTH_SENSORS,
CONF_ALLOW_UPTIME_SENSORS,
CONF_BLOCK_CLIENT,
CONF_CONTROLLER,
CONF_DETECTION_TIME,
Expand All @@ -45,6 +46,7 @@
CONF_TRACK_WIRED_CLIENTS,
CONTROLLER_ID,
DEFAULT_ALLOW_BANDWIDTH_SENSORS,
DEFAULT_ALLOW_UPTIME_SENSORS,
DEFAULT_DETECTION_TIME,
DEFAULT_IGNORE_WIRED_BUG,
DEFAULT_POE_CLIENTS,
Expand Down Expand Up @@ -184,6 +186,13 @@ def option_allow_bandwidth_sensors(self):
CONF_ALLOW_BANDWIDTH_SENSORS, DEFAULT_ALLOW_BANDWIDTH_SENSORS
)

@property
def option_allow_uptime_sensors(self):
"""Config entry option to allow uptime sensors."""
return self.config_entry.options.get(
CONF_ALLOW_UPTIME_SENSORS, DEFAULT_ALLOW_UPTIME_SENSORS
)

@callback
def async_unifi_signalling_callback(self, signal, data):
"""Handle messages back from UniFi library."""
Expand Down
60 changes: 56 additions & 4 deletions homeassistant/components/unifi/sensor.py
@@ -1,10 +1,11 @@
"""Support for bandwidth sensors with UniFi clients."""
import logging

from homeassistant.components.sensor import DOMAIN
from homeassistant.components.sensor import DEVICE_CLASS_TIMESTAMP, DOMAIN
from homeassistant.const import DATA_MEGABYTES
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
import homeassistant.util.dt as dt_util

from .const import DOMAIN as UNIFI_DOMAIN
from .unifi_client import UniFiClient
Expand All @@ -13,6 +14,7 @@

RX_SENSOR = "rx"
TX_SENSOR = "tx"
UPTIME_SENSOR = "uptime"


async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
Expand All @@ -22,15 +24,22 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up sensors for UniFi integration."""
controller = hass.data[UNIFI_DOMAIN][config_entry.entry_id]
controller.entities[DOMAIN] = {RX_SENSOR: set(), TX_SENSOR: set()}
controller.entities[DOMAIN] = {
RX_SENSOR: set(),
TX_SENSOR: set(),
UPTIME_SENSOR: set(),
}

@callback
def items_added(
clients: set = controller.api.clients, devices: set = controller.api.devices
) -> None:
"""Update the values of the controller."""
if controller.option_allow_bandwidth_sensors:
add_entities(controller, async_add_entities, clients)
add_bandwith_entities(controller, async_add_entities, clients)

if controller.option_allow_uptime_sensors:
add_uptime_entities(controller, async_add_entities, clients)

for signal in (controller.signal_update, controller.signal_options_update):
controller.listeners.append(async_dispatcher_connect(hass, signal, items_added))
Expand All @@ -39,7 +48,7 @@ def items_added(


@callback
def add_entities(controller, async_add_entities, clients):
def add_bandwith_entities(controller, async_add_entities, clients):
"""Add new sensor entities from the controller."""
sensors = []

Expand All @@ -55,6 +64,22 @@ def add_entities(controller, async_add_entities, clients):
async_add_entities(sensors)


@callback
def add_uptime_entities(controller, async_add_entities, clients):
MartinHjelmare marked this conversation as resolved.
Show resolved Hide resolved
"""Add new sensor entities from the controller."""
sensors = []

for mac in clients:
if mac in controller.entities[DOMAIN][UniFiUpTimeSensor.TYPE]:
continue

client = controller.api.clients[mac]
sensors.append(UniFiUpTimeSensor(client, controller))

if sensors:
async_add_entities(sensors)


class UniFiBandwidthSensor(UniFiClient):
"""UniFi bandwidth sensor base class."""

Expand Down Expand Up @@ -100,3 +125,30 @@ def state(self) -> int:
if self._is_wired:
return self.client.wired_tx_bytes / 1000000
return self.client.tx_bytes / 1000000


class UniFiUpTimeSensor(UniFiClient):
"""UniFi uptime sensor."""

DOMAIN = DOMAIN
TYPE = UPTIME_SENSOR

@property
def device_class(self) -> str:
"""Return device class."""
return DEVICE_CLASS_TIMESTAMP

@property
def name(self) -> str:
"""Return the name of the client."""
return f"{super().name} {self.TYPE.capitalize()}"

@property
def state(self) -> int:
"""Return the uptime of the client."""
return dt_util.utc_from_timestamp(float(self.client.uptime)).isoformat()

async def options_updated(self) -> None:
"""Config entry options are updated, remove entity if option is disabled."""
if not self.controller.option_allow_uptime_sensors:
await self.remove_item({self.client.mac})
3 changes: 2 additions & 1 deletion homeassistant/components/unifi/strings.json
Expand Up @@ -54,7 +54,8 @@
},
"statistics_sensors": {
"data": {
"allow_bandwidth_sensors": "Bandwidth usage sensors for network clients"
"allow_bandwidth_sensors": "Bandwidth usage sensors for network clients",
"allow_uptime_sensors": "Uptime sensors for network clients"
},
"description": "Configure statistics sensors",
"title": "UniFi options 3/3"
Expand Down
3 changes: 2 additions & 1 deletion homeassistant/components/unifi/translations/nl.json
Expand Up @@ -57,7 +57,8 @@
},
"statistics_sensors": {
"data": {
"allow_bandwidth_sensors": "Maak bandbreedtegebruiksensoren voor netwerkclients"
"allow_bandwidth_sensors": "Maak bandbreedtegebruiksensoren voor netwerkclients",
"allow_uptime_sensors": "Maak uptime-sensoren voor netwerkclients"
},
"title": "UniFi-opties 3/3"
}
Expand Down
8 changes: 7 additions & 1 deletion tests/components/unifi/test_config_flow.py
Expand Up @@ -4,6 +4,7 @@
from homeassistant import data_entry_flow
from homeassistant.components.unifi.const import (
CONF_ALLOW_BANDWIDTH_SENSORS,
CONF_ALLOW_UPTIME_SENSORS,
CONF_BLOCK_CLIENT,
CONF_CONTROLLER,
CONF_DETECTION_TIME,
Expand Down Expand Up @@ -341,7 +342,11 @@ async def test_advanced_option_flow(hass):
assert result["step_id"] == "statistics_sensors"

result = await hass.config_entries.options.async_configure(
result["flow_id"], user_input={CONF_ALLOW_BANDWIDTH_SENSORS: True}
result["flow_id"],
user_input={
CONF_ALLOW_BANDWIDTH_SENSORS: True,
CONF_ALLOW_UPTIME_SENSORS: True,
},
)

assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
Expand All @@ -355,6 +360,7 @@ async def test_advanced_option_flow(hass):
CONF_POE_CLIENTS: False,
CONF_BLOCK_CLIENT: [CLIENTS[0]["mac"]],
CONF_ALLOW_BANDWIDTH_SENSORS: True,
CONF_ALLOW_UPTIME_SENSORS: True,
}


Expand Down
3 changes: 3 additions & 0 deletions tests/components/unifi/test_controller.py
Expand Up @@ -13,6 +13,7 @@
CONF_CONTROLLER,
CONF_SITE_ID,
DEFAULT_ALLOW_BANDWIDTH_SENSORS,
DEFAULT_ALLOW_UPTIME_SENSORS,
DEFAULT_DETECTION_TIME,
DEFAULT_TRACK_CLIENTS,
DEFAULT_TRACK_DEVICES,
Expand Down Expand Up @@ -49,6 +50,7 @@
"sw_port": 1,
"wired-rx_bytes": 1234000000,
"wired-tx_bytes": 5678000000,
"uptime": 1562600160,
}

CONTROLLER_DATA = {
Expand Down Expand Up @@ -175,6 +177,7 @@ async def test_controller_setup(hass):
assert controller.site_role == SITES[controller.site_name]["role"]

assert controller.option_allow_bandwidth_sensors == DEFAULT_ALLOW_BANDWIDTH_SENSORS
assert controller.option_allow_uptime_sensors == DEFAULT_ALLOW_UPTIME_SENSORS
assert isinstance(controller.option_block_clients, list)
assert controller.option_track_clients == DEFAULT_TRACK_CLIENTS
assert controller.option_track_devices == DEFAULT_TRACK_DEVICES
Expand Down