2021-11-26 21:44:49 +00:00
|
|
|
"""The tests for the UniFi Network device tracker platform."""
|
2021-03-07 12:20:04 +00:00
|
|
|
|
2019-07-14 19:57:09 +00:00
|
|
|
from datetime import timedelta
|
2021-01-10 19:12:21 +00:00
|
|
|
from unittest.mock import patch
|
2016-02-19 23:19:03 +00:00
|
|
|
|
2022-01-24 14:11:33 +00:00
|
|
|
from aiounifi.controller import MESSAGE_CLIENT, MESSAGE_CLIENT_REMOVED, MESSAGE_DEVICE
|
2021-03-05 20:28:41 +00:00
|
|
|
from aiounifi.websocket import STATE_DISCONNECTED, STATE_RUNNING
|
2019-12-10 19:05:18 +00:00
|
|
|
|
2019-07-14 19:57:09 +00:00
|
|
|
from homeassistant import config_entries
|
2020-04-23 14:48:24 +00:00
|
|
|
from homeassistant.components.device_tracker import DOMAIN as TRACKER_DOMAIN
|
2019-07-14 19:57:09 +00:00
|
|
|
from homeassistant.components.unifi.const import (
|
2020-03-12 10:56:50 +00:00
|
|
|
CONF_BLOCK_CLIENT,
|
2020-04-17 06:39:01 +00:00
|
|
|
CONF_IGNORE_WIRED_BUG,
|
2019-08-21 20:22:42 +00:00
|
|
|
CONF_SSID_FILTER,
|
2020-02-13 00:15:08 +00:00
|
|
|
CONF_TRACK_CLIENTS,
|
2019-08-31 20:04:04 +00:00
|
|
|
CONF_TRACK_DEVICES,
|
|
|
|
CONF_TRACK_WIRED_CLIENTS,
|
2020-04-23 14:48:24 +00:00
|
|
|
DOMAIN as UNIFI_DOMAIN,
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2021-03-07 12:20:04 +00:00
|
|
|
from homeassistant.const import STATE_HOME, STATE_NOT_HOME, STATE_UNAVAILABLE
|
2021-03-09 13:25:03 +00:00
|
|
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
2019-07-14 19:57:09 +00:00
|
|
|
import homeassistant.util.dt as dt_util
|
2019-06-02 16:24:13 +00:00
|
|
|
|
2020-01-03 18:23:17 +00:00
|
|
|
from .test_controller import ENTRY_CONFIG, setup_unifi_integration
|
2019-10-07 19:55:35 +00:00
|
|
|
|
2020-05-04 17:29:49 +00:00
|
|
|
from tests.common import async_fire_time_changed
|
2020-04-30 20:29:50 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
|
|
|
|
async def test_no_entities(hass, aioclient_mock):
|
2019-07-14 19:57:09 +00:00
|
|
|
"""Test the update_clients function when no clients are found."""
|
2021-02-05 15:31:47 +00:00
|
|
|
await setup_unifi_integration(hass, aioclient_mock)
|
2019-07-25 14:56:56 +00:00
|
|
|
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 0
|
2019-07-14 19:57:09 +00:00
|
|
|
|
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_tracked_wireless_clients(
|
|
|
|
hass, aioclient_mock, mock_unifi_websocket, mock_device_registry
|
|
|
|
):
|
2021-03-07 12:20:04 +00:00
|
|
|
"""Verify tracking of wireless clients."""
|
|
|
|
client = {
|
|
|
|
"ap_mac": "00:00:00:00:02:01",
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "client",
|
|
|
|
"ip": "10.0.0.1",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2021-03-07 12:20:04 +00:00
|
|
|
hass, aioclient_mock, clients_response=[client]
|
2021-02-05 15:31:47 +00:00
|
|
|
)
|
|
|
|
controller = hass.data[UNIFI_DOMAIN][config_entry.entry_id]
|
2020-05-04 17:29:49 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 1
|
|
|
|
assert hass.states.get("device_tracker.client").state == STATE_NOT_HOME
|
2020-05-04 17:29:49 +00:00
|
|
|
|
|
|
|
# State change signalling works without events
|
2021-03-07 12:20:04 +00:00
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2020-05-04 17:29:49 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
client_state = hass.states.get("device_tracker.client")
|
2022-01-24 14:11:33 +00:00
|
|
|
assert client_state.state == STATE_NOT_HOME
|
2021-03-07 12:20:04 +00:00
|
|
|
assert client_state.attributes["ip"] == "10.0.0.1"
|
|
|
|
assert client_state.attributes["mac"] == "00:00:00:00:00:01"
|
|
|
|
assert client_state.attributes["hostname"] == "client"
|
|
|
|
assert client_state.attributes["host_name"] == "client"
|
2020-05-04 17:29:49 +00:00
|
|
|
|
2022-01-24 14:11:33 +00:00
|
|
|
# Updated timestamp marks client as home
|
|
|
|
|
|
|
|
client["last_seen"] = dt_util.as_timestamp(dt_util.utcnow())
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
2022-01-24 14:11:33 +00:00
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
|
|
|
"data": [client],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2020-05-04 17:29:49 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client").state == STATE_HOME
|
|
|
|
|
|
|
|
# Change time to mark client as away
|
2020-05-04 17:29:49 +00:00
|
|
|
|
2021-01-10 19:12:21 +00:00
|
|
|
new_time = dt_util.utcnow() + controller.option_detection_time
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=new_time):
|
|
|
|
async_fire_time_changed(hass, new_time)
|
|
|
|
await hass.async_block_till_done()
|
2020-05-04 17:29:49 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client").state == STATE_NOT_HOME
|
|
|
|
|
2022-01-24 14:11:33 +00:00
|
|
|
# Same timestamp again means client is away
|
2021-10-26 20:04:16 +00:00
|
|
|
|
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
|
|
|
"data": [client],
|
|
|
|
}
|
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert hass.states.get("device_tracker.client").state == STATE_NOT_HOME
|
|
|
|
|
2020-05-04 17:29:49 +00:00
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_tracked_clients(
|
|
|
|
hass, aioclient_mock, mock_unifi_websocket, mock_device_registry
|
|
|
|
):
|
2019-07-14 19:57:09 +00:00
|
|
|
"""Test the update_items function with some clients."""
|
2021-03-07 12:20:04 +00:00
|
|
|
client_1 = {
|
|
|
|
"ap_mac": "00:00:00:00:02:01",
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "client_1",
|
|
|
|
"ip": "10.0.0.1",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
|
|
|
client_2 = {
|
|
|
|
"ip": "10.0.0.2",
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:02",
|
|
|
|
"name": "Client 2",
|
|
|
|
}
|
|
|
|
client_3 = {
|
|
|
|
"essid": "ssid2",
|
|
|
|
"hostname": "client_3",
|
|
|
|
"ip": "10.0.0.3",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:03",
|
|
|
|
}
|
|
|
|
client_4 = {
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "client_4",
|
|
|
|
"ip": "10.0.0.4",
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": dt_util.as_timestamp(dt_util.utcnow()),
|
|
|
|
"mac": "00:00:00:00:00:04",
|
|
|
|
}
|
|
|
|
client_5 = {
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "client_5",
|
|
|
|
"ip": "10.0.0.5",
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": None,
|
|
|
|
"mac": "00:00:00:00:00:05",
|
|
|
|
}
|
2019-12-30 18:40:52 +00:00
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
await setup_unifi_integration(
|
2019-10-03 20:23:25 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2019-10-03 20:23:25 +00:00
|
|
|
options={CONF_SSID_FILTER: ["ssid"]},
|
2021-03-07 12:20:04 +00:00
|
|
|
clients_response=[client_1, client_2, client_3, client_4, client_5],
|
|
|
|
known_wireless_clients=(client_4["mac"],),
|
2019-10-03 20:23:25 +00:00
|
|
|
)
|
2019-07-14 19:57:09 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 4
|
|
|
|
assert hass.states.get("device_tracker.client_1").state == STATE_NOT_HOME
|
|
|
|
assert hass.states.get("device_tracker.client_2").state == STATE_NOT_HOME
|
2019-07-14 19:57:09 +00:00
|
|
|
|
2020-03-16 11:10:45 +00:00
|
|
|
# Client on SSID not in SSID filter
|
2021-03-07 12:20:04 +00:00
|
|
|
assert not hass.states.get("device_tracker.client_3")
|
2019-07-14 19:57:09 +00:00
|
|
|
|
2019-12-30 18:40:52 +00:00
|
|
|
# Wireless client with wired bug, if bug active on restart mark device away
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client_4").state == STATE_NOT_HOME
|
2019-12-30 18:40:52 +00:00
|
|
|
|
2020-02-27 19:50:34 +00:00
|
|
|
# A client that has never been seen should be marked away.
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client_5").state == STATE_NOT_HOME
|
2020-02-27 19:50:34 +00:00
|
|
|
|
2020-02-13 00:15:08 +00:00
|
|
|
# State change signalling works
|
2021-03-07 12:20:04 +00:00
|
|
|
|
2022-01-24 14:11:33 +00:00
|
|
|
client_1["last_seen"] += 1
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client_1],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2020-05-08 20:19:27 +00:00
|
|
|
await hass.async_block_till_done()
|
2020-05-07 07:58:04 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client_1").state == STATE_HOME
|
2020-05-07 07:58:04 +00:00
|
|
|
|
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_tracked_devices(
|
|
|
|
hass, aioclient_mock, mock_unifi_websocket, mock_device_registry
|
|
|
|
):
|
2020-05-07 07:58:04 +00:00
|
|
|
"""Test the update_items function with some devices."""
|
2021-03-07 12:20:04 +00:00
|
|
|
device_1 = {
|
|
|
|
"board_rev": 3,
|
|
|
|
"device_id": "mock-id",
|
|
|
|
"has_fan": True,
|
|
|
|
"fan_level": 0,
|
|
|
|
"ip": "10.0.1.1",
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"model": "US16P150",
|
|
|
|
"name": "Device 1",
|
|
|
|
"next_interval": 20,
|
|
|
|
"overheating": True,
|
|
|
|
"state": 1,
|
|
|
|
"type": "usw",
|
|
|
|
"upgradable": True,
|
|
|
|
"version": "4.0.42.10433",
|
|
|
|
}
|
|
|
|
device_2 = {
|
|
|
|
"board_rev": 3,
|
|
|
|
"device_id": "mock-id",
|
|
|
|
"has_fan": True,
|
|
|
|
"ip": "10.0.1.2",
|
|
|
|
"mac": "00:00:00:00:01:02",
|
|
|
|
"model": "US16P150",
|
|
|
|
"name": "Device 2",
|
|
|
|
"next_interval": 20,
|
|
|
|
"state": 0,
|
|
|
|
"type": "usw",
|
|
|
|
"version": "4.0.42.10433",
|
|
|
|
}
|
2021-03-05 20:28:41 +00:00
|
|
|
await setup_unifi_integration(
|
2020-08-27 11:56:20 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2021-03-07 12:20:04 +00:00
|
|
|
devices_response=[device_1, device_2],
|
2020-05-07 07:58:04 +00:00
|
|
|
)
|
2021-03-05 20:28:41 +00:00
|
|
|
|
2020-05-07 07:58:04 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 2
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.device_1").state == STATE_HOME
|
|
|
|
assert hass.states.get("device_tracker.device_2").state == STATE_NOT_HOME
|
2020-05-07 07:58:04 +00:00
|
|
|
|
|
|
|
# State change signalling work
|
2021-03-07 12:20:04 +00:00
|
|
|
|
|
|
|
device_1["next_interval"] = 20
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_DEVICE},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [device_1],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2021-03-07 12:20:04 +00:00
|
|
|
device_2["next_interval"] = 50
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_DEVICE},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [device_2],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2019-07-14 19:57:09 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.device_1").state == STATE_HOME
|
|
|
|
assert hass.states.get("device_tracker.device_2").state == STATE_HOME
|
|
|
|
|
|
|
|
# Change of time can mark device not_home outside of expected reporting interval
|
2020-05-07 07:58:04 +00:00
|
|
|
|
2021-01-10 19:12:21 +00:00
|
|
|
new_time = dt_util.utcnow() + timedelta(seconds=90)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=new_time):
|
|
|
|
async_fire_time_changed(hass, new_time)
|
|
|
|
await hass.async_block_till_done()
|
2020-05-07 07:58:04 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.device_1").state == STATE_NOT_HOME
|
|
|
|
assert hass.states.get("device_tracker.device_2").state == STATE_HOME
|
2019-07-29 21:13:04 +00:00
|
|
|
|
2020-02-13 00:15:08 +00:00
|
|
|
# Disabled device is unavailable
|
2021-03-07 12:20:04 +00:00
|
|
|
|
|
|
|
device_1["disabled"] = True
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_DEVICE},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [device_1],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2020-02-13 00:15:08 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.device_1").state == STATE_UNAVAILABLE
|
|
|
|
assert hass.states.get("device_tracker.device_2").state == STATE_HOME
|
2020-02-13 00:15:08 +00:00
|
|
|
|
2020-05-10 15:14:45 +00:00
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_remove_clients(
|
|
|
|
hass, aioclient_mock, mock_unifi_websocket, mock_device_registry
|
|
|
|
):
|
2020-04-16 22:08:53 +00:00
|
|
|
"""Test the remove_items function with some clients."""
|
2021-03-07 12:20:04 +00:00
|
|
|
client_1 = {
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "client_1",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
|
|
|
client_2 = {
|
|
|
|
"hostname": "client_2",
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:02",
|
|
|
|
}
|
2021-03-05 20:28:41 +00:00
|
|
|
await setup_unifi_integration(
|
2021-03-07 12:20:04 +00:00
|
|
|
hass, aioclient_mock, clients_response=[client_1, client_2]
|
2020-04-16 22:08:53 +00:00
|
|
|
)
|
2021-03-05 20:28:41 +00:00
|
|
|
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 2
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client_1")
|
|
|
|
assert hass.states.get("device_tracker.client_2")
|
2020-04-16 22:08:53 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
# Remove client
|
2020-04-16 22:08:53 +00:00
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT_REMOVED},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client_1],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2020-04-16 22:08:53 +00:00
|
|
|
await hass.async_block_till_done()
|
2021-02-14 19:42:55 +00:00
|
|
|
await hass.async_block_till_done()
|
2020-04-16 22:08:53 +00:00
|
|
|
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 1
|
2021-03-07 12:20:04 +00:00
|
|
|
assert not hass.states.get("device_tracker.client_1")
|
|
|
|
assert hass.states.get("device_tracker.client_2")
|
2020-04-16 22:08:53 +00:00
|
|
|
|
|
|
|
|
2021-09-27 10:04:29 +00:00
|
|
|
async def test_remove_client_but_keep_device_entry(
|
2022-01-05 07:16:43 +00:00
|
|
|
hass, aioclient_mock, mock_unifi_websocket, mock_device_registry
|
2021-09-27 10:04:29 +00:00
|
|
|
):
|
|
|
|
"""Test that unifi entity base remove config entry id from a multi integration device registry entry."""
|
|
|
|
client_1 = {
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "client_1",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
|
|
|
await setup_unifi_integration(hass, aioclient_mock, clients_response=[client_1])
|
|
|
|
|
|
|
|
device_registry = dr.async_get(hass)
|
|
|
|
device_entry = device_registry.async_get_or_create(
|
|
|
|
config_entry_id="other",
|
|
|
|
connections={("mac", "00:00:00:00:00:01")},
|
|
|
|
)
|
|
|
|
|
|
|
|
entity_registry = er.async_get(hass)
|
|
|
|
other_entity = entity_registry.async_get_or_create(
|
|
|
|
TRACKER_DOMAIN,
|
|
|
|
"other",
|
|
|
|
"unique_id",
|
|
|
|
device_id=device_entry.id,
|
|
|
|
)
|
2022-01-05 07:16:43 +00:00
|
|
|
assert len(device_entry.config_entries) == 3
|
2021-09-27 10:04:29 +00:00
|
|
|
|
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT_REMOVED},
|
|
|
|
"data": [client_1],
|
|
|
|
}
|
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 0
|
|
|
|
|
|
|
|
device_entry = device_registry.async_get(other_entity.device_id)
|
2022-01-05 07:16:43 +00:00
|
|
|
assert len(device_entry.config_entries) == 2
|
2021-09-27 10:04:29 +00:00
|
|
|
|
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_controller_state_change(
|
|
|
|
hass, aioclient_mock, mock_unifi_websocket, mock_device_registry
|
|
|
|
):
|
2020-02-13 00:15:08 +00:00
|
|
|
"""Verify entities state reflect on controller becoming unavailable."""
|
2021-03-07 12:20:04 +00:00
|
|
|
client = {
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "client",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
|
|
|
device = {
|
|
|
|
"board_rev": 3,
|
|
|
|
"device_id": "mock-id",
|
|
|
|
"has_fan": True,
|
|
|
|
"fan_level": 0,
|
|
|
|
"ip": "10.0.1.1",
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"model": "US16P150",
|
|
|
|
"name": "Device",
|
|
|
|
"next_interval": 20,
|
|
|
|
"overheating": True,
|
|
|
|
"state": 1,
|
|
|
|
"type": "usw",
|
|
|
|
"upgradable": True,
|
|
|
|
"version": "4.0.42.10433",
|
|
|
|
}
|
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
await setup_unifi_integration(
|
2020-08-27 11:56:20 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2021-03-07 12:20:04 +00:00
|
|
|
clients_response=[client],
|
|
|
|
devices_response=[device],
|
2020-02-13 00:15:08 +00:00
|
|
|
)
|
2021-03-05 20:28:41 +00:00
|
|
|
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 2
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client").state == STATE_NOT_HOME
|
|
|
|
assert hass.states.get("device_tracker.device").state == STATE_HOME
|
2021-01-26 15:41:28 +00:00
|
|
|
|
2020-01-31 19:23:25 +00:00
|
|
|
# Controller unavailable
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(state=STATE_DISCONNECTED)
|
2020-01-31 19:23:25 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client").state == STATE_UNAVAILABLE
|
|
|
|
assert hass.states.get("device_tracker.device").state == STATE_UNAVAILABLE
|
2020-01-31 19:23:25 +00:00
|
|
|
|
|
|
|
# Controller available
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(state=STATE_RUNNING)
|
2020-01-31 19:23:25 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client").state == STATE_NOT_HOME
|
|
|
|
assert hass.states.get("device_tracker.device").state == STATE_HOME
|
2020-01-31 19:23:25 +00:00
|
|
|
|
2020-02-13 00:15:08 +00:00
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_option_track_clients(hass, aioclient_mock, mock_device_registry):
|
2020-02-13 00:15:08 +00:00
|
|
|
"""Test the tracking of clients can be turned off."""
|
2021-03-07 12:20:04 +00:00
|
|
|
wireless_client = {
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "wireless_client",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
|
|
|
wired_client = {
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:02",
|
|
|
|
"name": "Wired Client",
|
|
|
|
}
|
|
|
|
device = {
|
|
|
|
"board_rev": 3,
|
|
|
|
"device_id": "mock-id",
|
|
|
|
"has_fan": True,
|
|
|
|
"fan_level": 0,
|
|
|
|
"ip": "10.0.1.1",
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"model": "US16P150",
|
|
|
|
"name": "Device",
|
|
|
|
"next_interval": 20,
|
|
|
|
"overheating": True,
|
|
|
|
"state": 1,
|
|
|
|
"type": "usw",
|
|
|
|
"upgradable": True,
|
|
|
|
"version": "4.0.42.10433",
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2020-08-27 11:56:20 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2021-03-07 12:20:04 +00:00
|
|
|
clients_response=[wireless_client, wired_client],
|
|
|
|
devices_response=[device],
|
2020-02-13 00:15:08 +00:00
|
|
|
)
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 3
|
|
|
|
assert hass.states.get("device_tracker.wireless_client")
|
|
|
|
assert hass.states.get("device_tracker.wired_client")
|
|
|
|
assert hass.states.get("device_tracker.device")
|
2020-02-13 00:15:08 +00:00
|
|
|
|
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_TRACK_CLIENTS: False},
|
2020-02-13 00:15:08 +00:00
|
|
|
)
|
2019-08-01 15:22:08 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert not hass.states.get("device_tracker.wireless_client")
|
|
|
|
assert not hass.states.get("device_tracker.wired_client")
|
|
|
|
assert hass.states.get("device_tracker.device")
|
2020-02-13 00:15:08 +00:00
|
|
|
|
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_TRACK_CLIENTS: True},
|
2020-02-13 00:15:08 +00:00
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.wireless_client")
|
|
|
|
assert hass.states.get("device_tracker.wired_client")
|
|
|
|
assert hass.states.get("device_tracker.device")
|
2020-02-13 00:15:08 +00:00
|
|
|
|
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_option_track_wired_clients(hass, aioclient_mock, mock_device_registry):
|
2020-02-13 00:15:08 +00:00
|
|
|
"""Test the tracking of wired clients can be turned off."""
|
2021-03-07 12:20:04 +00:00
|
|
|
wireless_client = {
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "wireless_client",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
|
|
|
wired_client = {
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:02",
|
|
|
|
"name": "Wired Client",
|
|
|
|
}
|
|
|
|
device = {
|
|
|
|
"board_rev": 3,
|
|
|
|
"device_id": "mock-id",
|
|
|
|
"has_fan": True,
|
|
|
|
"fan_level": 0,
|
|
|
|
"ip": "10.0.1.1",
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"model": "US16P150",
|
|
|
|
"name": "Device",
|
|
|
|
"next_interval": 20,
|
|
|
|
"overheating": True,
|
|
|
|
"state": 1,
|
|
|
|
"type": "usw",
|
|
|
|
"upgradable": True,
|
|
|
|
"version": "4.0.42.10433",
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2020-08-27 11:56:20 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2021-03-07 12:20:04 +00:00
|
|
|
clients_response=[wireless_client, wired_client],
|
|
|
|
devices_response=[device],
|
2020-02-13 00:15:08 +00:00
|
|
|
)
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 3
|
|
|
|
assert hass.states.get("device_tracker.wireless_client")
|
|
|
|
assert hass.states.get("device_tracker.wired_client")
|
|
|
|
assert hass.states.get("device_tracker.device")
|
2019-08-01 15:22:08 +00:00
|
|
|
|
2019-08-31 20:04:04 +00:00
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_TRACK_WIRED_CLIENTS: False},
|
2019-08-31 20:04:04 +00:00
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
2020-02-13 00:15:08 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.wireless_client")
|
|
|
|
assert not hass.states.get("device_tracker.wired_client")
|
|
|
|
assert hass.states.get("device_tracker.device")
|
2020-02-13 00:15:08 +00:00
|
|
|
|
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_TRACK_WIRED_CLIENTS: True},
|
2020-02-13 00:15:08 +00:00
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.wireless_client")
|
|
|
|
assert hass.states.get("device_tracker.wired_client")
|
|
|
|
assert hass.states.get("device_tracker.device")
|
2020-02-13 00:15:08 +00:00
|
|
|
|
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_option_track_devices(hass, aioclient_mock, mock_device_registry):
|
2020-02-13 00:15:08 +00:00
|
|
|
"""Test the tracking of devices can be turned off."""
|
2021-03-07 12:20:04 +00:00
|
|
|
client = {
|
|
|
|
"hostname": "client",
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
|
|
|
device = {
|
|
|
|
"board_rev": 3,
|
|
|
|
"device_id": "mock-id",
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"model": "US16P150",
|
|
|
|
"name": "Device",
|
|
|
|
"next_interval": 20,
|
|
|
|
"overheating": True,
|
|
|
|
"state": 1,
|
|
|
|
"type": "usw",
|
|
|
|
"upgradable": True,
|
|
|
|
"version": "4.0.42.10433",
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2020-08-27 11:56:20 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2021-03-07 12:20:04 +00:00
|
|
|
clients_response=[client],
|
|
|
|
devices_response=[device],
|
2020-02-13 00:15:08 +00:00
|
|
|
)
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 2
|
|
|
|
assert hass.states.get("device_tracker.client")
|
|
|
|
assert hass.states.get("device_tracker.device")
|
2020-02-13 00:15:08 +00:00
|
|
|
|
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_TRACK_DEVICES: False},
|
2020-02-13 00:15:08 +00:00
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client")
|
|
|
|
assert not hass.states.get("device_tracker.device")
|
2019-08-31 20:04:04 +00:00
|
|
|
|
2020-02-13 00:15:08 +00:00
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_TRACK_DEVICES: True},
|
2020-02-13 00:15:08 +00:00
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client")
|
|
|
|
assert hass.states.get("device_tracker.device")
|
2020-02-13 00:15:08 +00:00
|
|
|
|
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_option_ssid_filter(
|
|
|
|
hass, aioclient_mock, mock_unifi_websocket, mock_device_registry
|
|
|
|
):
|
2020-05-08 20:19:27 +00:00
|
|
|
"""Test the SSID filter works.
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
Client will travel from a supported SSID to an unsupported ssid.
|
|
|
|
Client on SSID2 will be removed on change of options.
|
2020-05-08 20:19:27 +00:00
|
|
|
"""
|
2021-03-07 12:20:04 +00:00
|
|
|
client = {
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "client",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": dt_util.as_timestamp(dt_util.utcnow()),
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
|
|
|
client_on_ssid2 = {
|
|
|
|
"essid": "ssid2",
|
|
|
|
"hostname": "client_on_ssid2",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:02",
|
|
|
|
}
|
2020-05-08 20:19:27 +00:00
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2021-03-07 12:20:04 +00:00
|
|
|
hass, aioclient_mock, clients_response=[client, client_on_ssid2]
|
2020-05-08 20:19:27 +00:00
|
|
|
)
|
2021-02-05 15:31:47 +00:00
|
|
|
controller = hass.data[UNIFI_DOMAIN][config_entry.entry_id]
|
2020-05-08 20:19:27 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 2
|
2020-04-17 06:39:01 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client").state == STATE_HOME
|
|
|
|
assert hass.states.get("device_tracker.client_on_ssid2").state == STATE_NOT_HOME
|
2020-04-17 06:39:01 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Setting SSID filter will remove clients outside of filter
|
2020-04-17 06:39:01 +00:00
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_SSID_FILTER: ["ssid"]},
|
2020-02-13 00:15:08 +00:00
|
|
|
)
|
2020-04-17 06:39:01 +00:00
|
|
|
await hass.async_block_till_done()
|
2020-02-13 00:15:08 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Not affected by SSID filter
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client").state == STATE_HOME
|
2020-05-08 20:19:27 +00:00
|
|
|
|
|
|
|
# Removed due to SSID filter
|
2021-03-07 12:20:04 +00:00
|
|
|
assert not hass.states.get("device_tracker.client_on_ssid2")
|
2020-02-13 00:15:08 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Roams to SSID outside of filter
|
2021-03-07 12:20:04 +00:00
|
|
|
client["essid"] = "other_ssid"
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2020-05-08 20:19:27 +00:00
|
|
|
# Data update while SSID filter is in effect shouldn't create the client
|
2021-03-07 12:20:04 +00:00
|
|
|
client_on_ssid2["last_seen"] = dt_util.as_timestamp(dt_util.utcnow())
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client_on_ssid2],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2020-02-13 00:15:08 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# SSID filter marks client as away
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client").state == STATE_NOT_HOME
|
2020-05-08 20:19:27 +00:00
|
|
|
|
|
|
|
# SSID still outside of filter
|
2021-03-07 12:20:04 +00:00
|
|
|
assert not hass.states.get("device_tracker.client_on_ssid2")
|
2020-02-13 00:15:08 +00:00
|
|
|
|
|
|
|
# Remove SSID filter
|
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_SSID_FILTER: []},
|
2020-02-13 00:15:08 +00:00
|
|
|
)
|
2021-01-20 22:58:02 +00:00
|
|
|
await hass.async_block_till_done()
|
2021-03-05 20:28:41 +00:00
|
|
|
|
2022-01-24 14:11:33 +00:00
|
|
|
client["last_seen"] += 1
|
|
|
|
client_on_ssid2["last_seen"] += 1
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client_on_ssid2],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2020-02-13 00:15:08 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client").state == STATE_HOME
|
|
|
|
assert hass.states.get("device_tracker.client_on_ssid2").state == STATE_HOME
|
2020-05-08 20:19:27 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
# Time pass to mark client as away
|
2020-05-08 20:19:27 +00:00
|
|
|
|
2021-01-10 19:12:21 +00:00
|
|
|
new_time = dt_util.utcnow() + controller.option_detection_time
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=new_time):
|
|
|
|
async_fire_time_changed(hass, new_time)
|
|
|
|
await hass.async_block_till_done()
|
2020-05-08 20:19:27 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client").state == STATE_NOT_HOME
|
2020-05-08 20:19:27 +00:00
|
|
|
|
2022-01-24 14:11:33 +00:00
|
|
|
client_on_ssid2["last_seen"] += 1
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client_on_ssid2],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2021-01-20 22:58:02 +00:00
|
|
|
await hass.async_block_till_done()
|
2021-03-07 12:20:04 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Client won't go away until after next update
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client_on_ssid2").state == STATE_HOME
|
2020-02-13 00:15:08 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Trigger update to get client marked as away
|
2022-01-24 14:11:33 +00:00
|
|
|
client_on_ssid2["last_seen"] += 1
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client_on_ssid2],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2021-01-17 02:10:52 +00:00
|
|
|
await hass.async_block_till_done()
|
2021-01-10 19:12:21 +00:00
|
|
|
|
|
|
|
new_time = (
|
|
|
|
dt_util.utcnow() + controller.option_detection_time + timedelta(seconds=1)
|
|
|
|
)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=new_time):
|
|
|
|
async_fire_time_changed(hass, new_time)
|
|
|
|
await hass.async_block_till_done()
|
2020-05-08 20:19:27 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client_on_ssid2").state == STATE_NOT_HOME
|
2020-05-08 20:19:27 +00:00
|
|
|
|
2019-07-29 21:13:04 +00:00
|
|
|
|
2021-03-05 20:28:41 +00:00
|
|
|
async def test_wireless_client_go_wired_issue(
|
2022-01-05 07:16:43 +00:00
|
|
|
hass, aioclient_mock, mock_unifi_websocket, mock_device_registry
|
2021-03-05 20:28:41 +00:00
|
|
|
):
|
2019-10-02 19:43:14 +00:00
|
|
|
"""Test the solution to catch wireless device go wired UniFi issue.
|
|
|
|
|
2021-11-26 21:44:49 +00:00
|
|
|
UniFi Network has a known issue that when a wireless device goes away it sometimes gets marked as wired.
|
2019-10-02 19:43:14 +00:00
|
|
|
"""
|
2021-03-07 12:20:04 +00:00
|
|
|
client = {
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "client",
|
|
|
|
"ip": "10.0.0.1",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": dt_util.as_timestamp(dt_util.utcnow()),
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
2019-10-02 19:43:14 +00:00
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2021-03-07 12:20:04 +00:00
|
|
|
hass, aioclient_mock, clients_response=[client]
|
2021-02-05 15:31:47 +00:00
|
|
|
)
|
|
|
|
controller = hass.data[UNIFI_DOMAIN][config_entry.entry_id]
|
2021-03-07 12:20:04 +00:00
|
|
|
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 1
|
2019-10-02 19:43:14 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Client is wireless
|
2021-03-07 12:20:04 +00:00
|
|
|
client_state = hass.states.get("device_tracker.client")
|
|
|
|
assert client_state.state == STATE_HOME
|
|
|
|
assert client_state.attributes["is_wired"] is False
|
2019-10-02 19:43:14 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Trigger wired bug
|
2022-01-24 14:11:33 +00:00
|
|
|
client["last_seen"] += 1
|
2021-03-07 12:20:04 +00:00
|
|
|
client["is_wired"] = True
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2019-10-02 19:43:14 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Wired bug fix keeps client marked as wireless
|
2021-03-07 12:20:04 +00:00
|
|
|
client_state = hass.states.get("device_tracker.client")
|
|
|
|
assert client_state.state == STATE_HOME
|
|
|
|
assert client_state.attributes["is_wired"] is False
|
2019-12-10 19:05:18 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Pass time
|
2021-01-10 19:12:21 +00:00
|
|
|
new_time = dt_util.utcnow() + controller.option_detection_time
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=new_time):
|
|
|
|
async_fire_time_changed(hass, new_time)
|
|
|
|
await hass.async_block_till_done()
|
2019-12-10 19:05:18 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Marked as home according to the timer
|
2021-03-07 12:20:04 +00:00
|
|
|
client_state = hass.states.get("device_tracker.client")
|
|
|
|
assert client_state.state == STATE_NOT_HOME
|
|
|
|
assert client_state.attributes["is_wired"] is False
|
2020-05-08 20:19:27 +00:00
|
|
|
|
|
|
|
# Try to mark client as connected
|
2022-01-24 14:11:33 +00:00
|
|
|
client["last_seen"] += 1
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2020-05-08 20:19:27 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
# Make sure it don't go online again until wired bug disappears
|
2021-03-07 12:20:04 +00:00
|
|
|
client_state = hass.states.get("device_tracker.client")
|
|
|
|
assert client_state.state == STATE_NOT_HOME
|
|
|
|
assert client_state.attributes["is_wired"] is False
|
2020-04-17 06:39:01 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Make client wireless
|
2022-01-24 14:11:33 +00:00
|
|
|
client["last_seen"] += 1
|
2021-03-07 12:20:04 +00:00
|
|
|
client["is_wired"] = False
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2020-04-17 06:39:01 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Client is no longer affected by wired bug and can be marked online
|
2021-03-07 12:20:04 +00:00
|
|
|
client_state = hass.states.get("device_tracker.client")
|
|
|
|
assert client_state.state == STATE_HOME
|
|
|
|
assert client_state.attributes["is_wired"] is False
|
2020-04-17 06:39:01 +00:00
|
|
|
|
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_option_ignore_wired_bug(
|
|
|
|
hass, aioclient_mock, mock_unifi_websocket, mock_device_registry
|
|
|
|
):
|
2020-04-17 06:39:01 +00:00
|
|
|
"""Test option to ignore wired bug."""
|
2021-03-07 12:20:04 +00:00
|
|
|
client = {
|
|
|
|
"ap_mac": "00:00:00:00:02:01",
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "client",
|
|
|
|
"ip": "10.0.0.1",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": dt_util.as_timestamp(dt_util.utcnow()),
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
2020-04-17 06:39:01 +00:00
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
|
|
|
hass,
|
|
|
|
aioclient_mock,
|
|
|
|
options={CONF_IGNORE_WIRED_BUG: True},
|
2021-03-07 12:20:04 +00:00
|
|
|
clients_response=[client],
|
2020-04-17 06:39:01 +00:00
|
|
|
)
|
2021-02-05 15:31:47 +00:00
|
|
|
controller = hass.data[UNIFI_DOMAIN][config_entry.entry_id]
|
2020-04-23 14:48:24 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 1
|
2020-04-17 06:39:01 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Client is wireless
|
2021-03-07 12:20:04 +00:00
|
|
|
client_state = hass.states.get("device_tracker.client")
|
|
|
|
assert client_state.state == STATE_HOME
|
|
|
|
assert client_state.attributes["is_wired"] is False
|
2020-04-17 06:39:01 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Trigger wired bug
|
2021-03-07 12:20:04 +00:00
|
|
|
client["is_wired"] = True
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2020-04-17 06:39:01 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Wired bug in effect
|
2021-03-07 12:20:04 +00:00
|
|
|
client_state = hass.states.get("device_tracker.client")
|
|
|
|
assert client_state.state == STATE_HOME
|
|
|
|
assert client_state.attributes["is_wired"] is True
|
2019-10-02 19:43:14 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# pass time
|
2021-01-10 19:12:21 +00:00
|
|
|
new_time = dt_util.utcnow() + controller.option_detection_time
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=new_time):
|
|
|
|
async_fire_time_changed(hass, new_time)
|
|
|
|
await hass.async_block_till_done()
|
2020-05-08 20:19:27 +00:00
|
|
|
|
|
|
|
# Timer marks client as away
|
2021-03-07 12:20:04 +00:00
|
|
|
client_state = hass.states.get("device_tracker.client")
|
|
|
|
assert client_state.state == STATE_NOT_HOME
|
|
|
|
assert client_state.attributes["is_wired"] is True
|
2020-05-08 20:19:27 +00:00
|
|
|
|
|
|
|
# Mark client as connected again
|
2022-01-24 14:11:33 +00:00
|
|
|
client["last_seen"] += 1
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2020-05-08 20:19:27 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
# Ignoring wired bug allows client to go home again even while affected
|
2021-03-07 12:20:04 +00:00
|
|
|
client_state = hass.states.get("device_tracker.client")
|
|
|
|
assert client_state.state == STATE_HOME
|
|
|
|
assert client_state.attributes["is_wired"] is True
|
2020-05-08 20:19:27 +00:00
|
|
|
|
|
|
|
# Make client wireless
|
2022-01-24 14:11:33 +00:00
|
|
|
client["last_seen"] += 1
|
2021-03-07 12:20:04 +00:00
|
|
|
client["is_wired"] = False
|
2021-03-05 20:28:41 +00:00
|
|
|
mock_unifi_websocket(
|
|
|
|
data={
|
|
|
|
"meta": {"message": MESSAGE_CLIENT},
|
2021-03-07 12:20:04 +00:00
|
|
|
"data": [client],
|
2021-03-05 20:28:41 +00:00
|
|
|
}
|
|
|
|
)
|
2019-10-02 19:43:14 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
# Client is wireless and still connected
|
2021-03-07 12:20:04 +00:00
|
|
|
client_state = hass.states.get("device_tracker.client")
|
|
|
|
assert client_state.state == STATE_HOME
|
|
|
|
assert client_state.attributes["is_wired"] is False
|
2019-10-02 19:43:14 +00:00
|
|
|
|
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_restoring_client(hass, aioclient_mock, mock_device_registry):
|
2021-03-07 12:20:04 +00:00
|
|
|
"""Verify clients are restored from clients_all if they ever was registered to entity registry."""
|
|
|
|
client = {
|
|
|
|
"hostname": "client",
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
|
|
|
restored = {
|
|
|
|
"hostname": "restored",
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:02",
|
|
|
|
}
|
|
|
|
not_restored = {
|
|
|
|
"hostname": "not_restored",
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:03",
|
|
|
|
}
|
|
|
|
|
2019-08-18 04:34:11 +00:00
|
|
|
config_entry = config_entries.ConfigEntry(
|
2019-10-03 20:23:25 +00:00
|
|
|
version=1,
|
2020-04-23 14:48:24 +00:00
|
|
|
domain=UNIFI_DOMAIN,
|
2019-10-03 20:23:25 +00:00
|
|
|
title="Mock Title",
|
|
|
|
data=ENTRY_CONFIG,
|
|
|
|
source="test",
|
|
|
|
options={},
|
2021-11-18 23:56:22 +00:00
|
|
|
entry_id="1",
|
2019-08-18 04:34:11 +00:00
|
|
|
)
|
|
|
|
|
2021-03-09 13:25:03 +00:00
|
|
|
registry = er.async_get(hass)
|
2019-07-29 21:13:04 +00:00
|
|
|
registry.async_get_or_create(
|
2020-04-23 14:48:24 +00:00
|
|
|
TRACKER_DOMAIN,
|
|
|
|
UNIFI_DOMAIN,
|
2021-03-07 12:20:04 +00:00
|
|
|
f'{restored["mac"]}-site_id',
|
|
|
|
suggested_object_id=restored["hostname"],
|
2019-08-18 04:34:11 +00:00
|
|
|
config_entry=config_entry,
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2019-07-29 21:13:04 +00:00
|
|
|
|
2019-10-03 20:23:25 +00:00
|
|
|
await setup_unifi_integration(
|
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-03-12 10:56:50 +00:00
|
|
|
options={CONF_BLOCK_CLIENT: True},
|
2021-03-07 12:20:04 +00:00
|
|
|
clients_response=[client],
|
|
|
|
clients_all_response=[restored, not_restored],
|
2019-10-03 20:23:25 +00:00
|
|
|
)
|
2019-07-29 21:13:04 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 2
|
|
|
|
assert hass.states.get("device_tracker.client")
|
|
|
|
assert hass.states.get("device_tracker.restored")
|
|
|
|
assert not hass.states.get("device_tracker.not_restored")
|
2019-08-02 08:13:00 +00:00
|
|
|
|
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_dont_track_clients(hass, aioclient_mock, mock_device_registry):
|
2020-01-31 16:33:00 +00:00
|
|
|
"""Test don't track clients config works."""
|
2021-03-07 12:20:04 +00:00
|
|
|
wireless_client = {
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "Wireless client",
|
|
|
|
"ip": "10.0.0.1",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
|
|
|
wired_client = {
|
|
|
|
"hostname": "Wired client",
|
|
|
|
"ip": "10.0.0.2",
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:02",
|
|
|
|
}
|
|
|
|
device = {
|
|
|
|
"board_rev": 3,
|
|
|
|
"device_id": "mock-id",
|
|
|
|
"has_fan": True,
|
|
|
|
"fan_level": 0,
|
|
|
|
"ip": "10.0.1.1",
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"model": "US16P150",
|
|
|
|
"name": "Device",
|
|
|
|
"next_interval": 20,
|
|
|
|
"overheating": True,
|
|
|
|
"state": 1,
|
|
|
|
"type": "usw",
|
|
|
|
"upgradable": True,
|
|
|
|
"version": "4.0.42.10433",
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2019-10-03 20:23:25 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-04-23 14:48:24 +00:00
|
|
|
options={CONF_TRACK_CLIENTS: False},
|
2021-03-07 12:20:04 +00:00
|
|
|
clients_response=[wireless_client, wired_client],
|
|
|
|
devices_response=[device],
|
2019-10-03 20:23:25 +00:00
|
|
|
)
|
2019-08-02 08:13:00 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 1
|
|
|
|
assert not hass.states.get("device_tracker.wireless_client")
|
|
|
|
assert not hass.states.get("device_tracker.wired_client")
|
|
|
|
assert hass.states.get("device_tracker.device")
|
2020-05-08 20:19:27 +00:00
|
|
|
|
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_TRACK_CLIENTS: True},
|
2020-05-08 20:19:27 +00:00
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 3
|
|
|
|
assert hass.states.get("device_tracker.wireless_client")
|
|
|
|
assert hass.states.get("device_tracker.wired_client")
|
|
|
|
assert hass.states.get("device_tracker.device")
|
2019-08-02 08:13:00 +00:00
|
|
|
|
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_dont_track_devices(hass, aioclient_mock, mock_device_registry):
|
2020-01-31 16:33:00 +00:00
|
|
|
"""Test don't track devices config works."""
|
2021-03-07 12:20:04 +00:00
|
|
|
client = {
|
|
|
|
"hostname": "client",
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
|
|
|
device = {
|
|
|
|
"board_rev": 3,
|
|
|
|
"device_id": "mock-id",
|
|
|
|
"has_fan": True,
|
|
|
|
"fan_level": 0,
|
|
|
|
"ip": "10.0.1.1",
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:01:01",
|
|
|
|
"model": "US16P150",
|
|
|
|
"name": "Device",
|
|
|
|
"next_interval": 20,
|
|
|
|
"overheating": True,
|
|
|
|
"state": 1,
|
|
|
|
"type": "usw",
|
|
|
|
"upgradable": True,
|
|
|
|
"version": "4.0.42.10433",
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2019-10-03 20:23:25 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-04-23 14:48:24 +00:00
|
|
|
options={CONF_TRACK_DEVICES: False},
|
2021-03-07 12:20:04 +00:00
|
|
|
clients_response=[client],
|
|
|
|
devices_response=[device],
|
2019-10-03 20:23:25 +00:00
|
|
|
)
|
2019-08-02 08:13:00 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 1
|
|
|
|
assert hass.states.get("device_tracker.client")
|
|
|
|
assert not hass.states.get("device_tracker.device")
|
2019-08-02 21:51:06 +00:00
|
|
|
|
2020-05-08 20:19:27 +00:00
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_TRACK_DEVICES: True},
|
2020-05-08 20:19:27 +00:00
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 2
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.client")
|
|
|
|
assert hass.states.get("device_tracker.device")
|
2020-05-08 20:19:27 +00:00
|
|
|
|
2019-08-02 21:51:06 +00:00
|
|
|
|
2022-01-05 07:16:43 +00:00
|
|
|
async def test_dont_track_wired_clients(hass, aioclient_mock, mock_device_registry):
|
2020-01-31 16:33:00 +00:00
|
|
|
"""Test don't track wired clients config works."""
|
2021-03-07 12:20:04 +00:00
|
|
|
wireless_client = {
|
|
|
|
"essid": "ssid",
|
|
|
|
"hostname": "Wireless Client",
|
|
|
|
"is_wired": False,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:01",
|
|
|
|
}
|
|
|
|
wired_client = {
|
|
|
|
"is_wired": True,
|
|
|
|
"last_seen": 1562600145,
|
|
|
|
"mac": "00:00:00:00:00:02",
|
|
|
|
"name": "Wired Client",
|
|
|
|
}
|
|
|
|
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry = await setup_unifi_integration(
|
2019-10-03 20:23:25 +00:00
|
|
|
hass,
|
2021-02-05 15:31:47 +00:00
|
|
|
aioclient_mock,
|
2020-04-23 14:48:24 +00:00
|
|
|
options={CONF_TRACK_WIRED_CLIENTS: False},
|
2021-03-07 12:20:04 +00:00
|
|
|
clients_response=[wireless_client, wired_client],
|
2019-10-03 20:23:25 +00:00
|
|
|
)
|
2019-08-02 21:51:06 +00:00
|
|
|
|
2021-03-07 12:20:04 +00:00
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 1
|
|
|
|
assert hass.states.get("device_tracker.wireless_client")
|
|
|
|
assert not hass.states.get("device_tracker.wired_client")
|
2020-05-08 20:19:27 +00:00
|
|
|
|
|
|
|
hass.config_entries.async_update_entry(
|
2021-02-05 15:31:47 +00:00
|
|
|
config_entry,
|
2020-08-27 11:56:20 +00:00
|
|
|
options={CONF_TRACK_WIRED_CLIENTS: True},
|
2020-05-08 20:19:27 +00:00
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert len(hass.states.async_entity_ids(TRACKER_DOMAIN)) == 2
|
2021-03-07 12:20:04 +00:00
|
|
|
assert hass.states.get("device_tracker.wireless_client")
|
|
|
|
assert hass.states.get("device_tracker.wired_client")
|