Skip to content

Commit 0beec7b

Browse files
authored
Connected devices stats added (#4)
* Connected devices stats added * Recursive search for connected devices
1 parent 20e5e0b commit 0beec7b

12 files changed

+437
-138
lines changed

README.md

+43-76
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,17 @@
1-
# Управление роутерами Huawei WiFi Mesh 3 из Home Assistant
2-
3-
Компонент для Home Assistant, позволяющий управлять роутерами [Huawei WiFi Mesh 3](https://consumer.huawei.com/ru/routers/wifi-mesh3/) через локальную сеть.
4-
5-
**0.7.1**
6-
7-
- включение/отключение NFC
8-
- включение/отключение TWT (снижение энергопотребления устройств Wi-Fi 6 в спящем режиме)
9-
- управление функцией быстрого роуминга (802.11r)
10-
- отслеживание подключенных устройств
11-
- определение конкретного роутера, к которому подключено устройство
12-
- определение параметров подключения устройств (частота, сила сигнала, гостевые и mesh устройства)
13-
- информация об аппаратной версии роутера
14-
- информация о версии прошивки роутера
15-
16-
## Установка
17-
18-
Необходимо скопировать папку `huawei_mesh_router` из [последнего релиза](https://github.com/vmakeev/huawei_mesh_router/releases/latest) в папку `custom_components`, расположенную в папке с конфигурацией Home Assistant, после чего перезапустить Home Assistant.
19-
20-
## Настройка
21-
22-
Конфигурация > [Устройства и службы](https://my.home-assistant.io/redirect/integrations/) > Добавить интеграцию > [Huawei Mesh Router](https://my.home-assistant.io/redirect/config_flow_start/?domain=huawei_mesh_router)
23-
24-
По умолчанию роутеры Huawei WiFi Mesh 3 используют имя пользователя `admin`, хотя оно и не отображается в web-интерфейсе и в мобильном приложении
25-
26-
## Отслеживание устройств
27-
28-
Каждое отслеживаемое устройство предоставляет следующие атрибуты:
29-
30-
| Атрибут | Описание | Только когда подключено |
31-
|---------|----------|-------------------------|
32-
|source_type| всегда `router`| Нет |
33-
|ip| IP-адрес устройства | Да |
34-
|mac|MAC-адрес устройства| Нет |
35-
|host_name| Имя устройства по данным самого устройства| Нет |
36-
|connected_via| Имя роутера, через который выполнено подключение. Для основного роутера - `Huawei Mesh 3` | Да |
37-
|interface_type| Тип интерфейса подключения (например `5GHz`, `LAN` и т.д.)| Да |
38-
|rssi| Сила сигнала для беспроводных подключений| Да |
39-
|is_guest| Является ли устройство подключенным к гостевой сети | Да |
40-
|is_hilink| Подключено ли устройство через HiLink (обычно это другие роутеры)| Да |
41-
|friendly_name| Имя устройства, предоставленное роутером | Нет |
42-
43-
Имена устройств для отслеживания, включая роутеры, могут быть изменены в [интерфейсе управления вашей mesh-системой](http://192.168.3.1/html/index.html#/devicecontrol), после чего компонент обновит их и в Home Assistant
44-
45-
46-
Пример markdown карточки, отображающей часть информации об отслеживаемом устройстве:
47-
48-
```
49-
Мой телефон: Rssi
50-
{{- " **" + state_attr('device_tracker.my_phone', 'rssi') | string }}** *via*
51-
{{- " **" + state_attr('device_tracker.my_phone', 'connected_via') | string }}**
52-
{{- " **(" + state_attr('device_tracker.my_phone', 'interface_type') | string }})**
53-
```
54-
55-
Результат:
56-
Мой телефон: Rssi **30** *via* **Kitchen router** (**5GHz**)
57-
58-
-----
59-
601
# Control Huawei WiFi Mesh 3 routers from Home Assistant
612

62-
Home Assistant custom component for control [Huawei WiFi Mesh 3](https://consumer.huawei.com/ru/routers/wifi-mesh3/) routers over LAN.
3+
Home Assistant custom component for control [Huawei WiFi Mesh 3](https://consumer.huawei.com/en/routers/wifi-mesh3/) routers over LAN.
634

64-
**0.7.1**
5+
**0.7.2**
656

7+
- sensors for the number of connected devices (total and for each individual router)
668
- enable/disable NFC
679
- enable/disable TWT (reduce power consumption of Wi-Fi 6 devices in sleep mode)
6810
- control of the fast roaming function (802.11r)
6911
- connected devices tracking
7012
- obtaining of the specific router to which the device is connected
71-
- obtaining of device connection parameters (frequency, signal strength, guest and mesh devices)
72-
- hardware version of the router
73-
- firmware version of the router
13+
- obtaining of device connection parameters (frequency, signal strength, guest and hilink devices)
14+
- hardware and firmware version of the router
7415

7516
## Installation
7617

@@ -86,18 +27,18 @@ By default, Huawei WiFi Mesh 3 routers use the username `admin`, although it is
8627

8728
Each tracked device exposes the following attributes:
8829

89-
| Attribute | Description | Only when connected |
90-
|----------------|-------------------|---------------------|
91-
| source_type | always `router` | No |
92-
| ip | Device IP address | Yes |
93-
| mac | MAC address of the device | No |
94-
| hostname | Device name according to the device itself | No |
95-
| connected_via | The name of the router through which the connection was made. For the primary router - `Huawei Mesh 3` | Yes |
96-
| interface_type | Connection interface type (eg `5GHz`, `LAN`, etc.) | Yes |
97-
| rssi | Signal strength for wireless connections | Yes |
98-
| is_guest | Is the device connected to the guest network | Yes |
99-
| is_hilink | Is the device connected via HiLink (usually other routers) | Yes |
100-
| friendly_name | Device name provided by the router | No |
30+
| Attribute | Description | Only when connected |
31+
|------------------|----------------------------------------------|---------------------|
32+
| `source_type` | Always `router` | No |
33+
| `ip` | Device IP address | Yes |
34+
| `mac` | MAC address of the device | No |
35+
| `hostname` | Device name according to the device itself | No |
36+
| `connected_via` | The name of the router through which the connection was made. For the primary router - `Huawei Mesh 3` (or your configuration name) | Yes |
37+
| `interface_type` | Connection interface type (`5GHz`, `2.4GHz`, `LAN`) | Yes |
38+
| `rssi` | Signal strength for wireless connections | Yes |
39+
| `is_guest` | Is the device connected to the guest network | Yes |
40+
| `is_hilink` | Is the device connected via HiLink (usually other routers) | Yes |
41+
| `friendly_name` | Device name provided by the router | No |
10142

10243
Tracked device names, including routers, can be changed in [your mesh control interface](http://192.168.3.1/html/index.html#/devicecontrol), after which the component will update them in Home Assistant
10344

@@ -112,3 +53,29 @@ My phone: Rssi
11253

11354
Result:
11455
My phone: Rssi **30** *via* **Kitchen router** (**5GHz**)
56+
57+
## Sensors
58+
59+
### Number of connected devices
60+
61+
The component provides the ability to obtain the number of connected devices both to the entire mesh network and to specific routers using sensors.
62+
63+
There are two sensors that are always present:
64+
* `sensor.<integration_name>_clients_total` - total number of devices connected to the mesh network
65+
* `sensor.<integration_name>_clients_primary_router` - number of devices connected to the primary router
66+
67+
Also, one sensor is created for each additional router in the mesh network:
68+
* `sensor.<integration_name>_clients_<router_name>`
69+
70+
_Note: when additional routers are disconnected from the network, their personal sensors are automatically deleted._
71+
72+
Each sensor exposes the following attributes:
73+
74+
| Attribute | Description |
75+
|--------------------|--------------------------------------------------|
76+
| `guest_clients` | Number of devices connected to the guest network |
77+
| `hilink_clients` | Number of devices connected via HiLink |
78+
| `wireless_clients` | Number of devices connected wirelessly |
79+
| `lan_clients` | Number of devices connected by cable |
80+
| `wifi_2_4_clients` | Number of devices connected to Wi-Fi 2.4 GHz |
81+
| `wifi_5_clients` | Number of devices connected to Wi-Fi 5 GHz |

custom_components/huawei_mesh_router/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ async def async_setup(hass, _config):
2929
# ---------------------------
3030
# async_setup_entry
3131
# ---------------------------
32-
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
32+
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
3333
"""Set up Huawei Router as config entry."""
3434
coordinator = HuaweiControllerDataUpdateCoordinator(hass, config_entry)
3535
await coordinator.async_config_entry_first_refresh()

custom_components/huawei_mesh_router/config_flow.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
"""Config flow to configure Mikrotik Router."""
1+
"""Config flow to configure Huawei Mesh Router."""
22

33
import logging
44

custom_components/huawei_mesh_router/connected_device.py

+42-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
11
from typing import Dict
2+
from homeassistant.backports.enum import StrEnum
3+
4+
from .const import VENDOR_CLASS_ID_ROUTER
5+
6+
7+
# ---------------------------
8+
# HuaweiInterfaceType
9+
# ---------------------------
10+
class HuaweiInterfaceType(StrEnum):
11+
INTERFACE_5GHZ = "5GHz"
12+
INTERFACE_2_4GHZ = "2.4GHz"
13+
INTERFACE_LAN = "LAN"
214

315

416
# ---------------------------
@@ -11,7 +23,7 @@ def __init__(self,
1123
host_name: str,
1224
mac: str,
1325
is_active: bool,
14-
**kwargs: Dict):
26+
**kwargs: Dict) -> None:
1527
self._name: str = name
1628
self._host_name: str = host_name
1729
self._mac: str = mac
@@ -28,6 +40,12 @@ def update_device_data(self,
2840
self._is_active: bool = is_active
2941
self._data: Dict = kwargs or {}
3042

43+
def __str__(self) -> str:
44+
return f"Device {self._name} ({self._host_name}), {'' if self._is_active else 'not '}active, data: {self._data}"
45+
46+
def __repr__(self) -> str:
47+
return self.__str__()
48+
3149
@property
3250
def name(self) -> str:
3351
"""Return the name of the device."""
@@ -48,15 +66,35 @@ def mac(self) -> str:
4866
"""Return the mac address of the device."""
4967
return self._mac
5068

69+
@property
70+
def connected_via_id(self) -> str | None:
71+
"""Return the id of parent device."""
72+
return self._data.get("connected_via_id")
73+
74+
@property
75+
def interface_type(self) -> HuaweiInterfaceType | None:
76+
"""Return the connection interface type."""
77+
return self._data.get("interface_type")
78+
5179
@property
5280
def is_active(self) -> bool:
5381
"""Return true when device is connected to mesh."""
5482
return self._is_active
5583

5684
@property
57-
def is_hilink(self) -> bool | None:
58-
"""Return true when device is hilink mesh router."""
59-
return self._data.get("is_hilink")
85+
def is_guest(self) -> bool:
86+
"""Return true when device is guest."""
87+
return self._data.get("is_guest", False)
88+
89+
@property
90+
def is_hilink(self) -> bool:
91+
"""Return true when device is hilink."""
92+
return self._data.get("is_hilink", False)
93+
94+
@property
95+
def is_router(self) -> bool:
96+
"""Return true when device is hilink router."""
97+
return self.is_hilink and self._data.get("vendor_class_id") == VENDOR_CLASS_ID_ROUTER
6098

6199
@property
62100
def all_attrs(self) -> Dict:

custom_components/huawei_mesh_router/const.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@
1212
DEFAULT_SCAN_INTERVAL = 30
1313

1414
ATTR_MANUFACTURER = "Huawei"
15-
PLATFORMS = [Platform.SWITCH, Platform.DEVICE_TRACKER]
15+
PLATFORMS = [Platform.SWITCH, Platform.DEVICE_TRACKER, Platform.SENSOR]
1616

1717
SWITCHES_NFC = "nfc_switch"
1818
SWITCHES_WIFI_80211R = "wifi_80211r_switch"
1919
SWITCHES_WIFI_TWT = "wifi_twt_switch"
20+
21+
VENDOR_CLASS_ID_ROUTER = "router"
22+
23+
CONNECTED_VIA_ID_PRIMARY = "primary"

custom_components/huawei_mesh_router/device_tracker.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Support for Huawei routers as device tracker."""
22
import logging
33

4+
from typing import Any
45
from homeassistant.components.device_tracker.config_entry import ScannerEntity
56
from homeassistant.components.device_tracker.const import (
67
SOURCE_TYPE_ROUTER,
@@ -14,7 +15,7 @@
1415
from .const import DOMAIN
1516
from .update_coordinator import HuaweiControllerDataUpdateCoordinator
1617

17-
FILTER_ATTRS = ("ip_address",)
18+
FILTER_ATTRS = ("ip_address", "connected_via_id", "vendor_class_id")
1819
_LOGGER = logging.getLogger(__name__)
1920

2021

@@ -45,7 +46,7 @@ def coordinator_updated():
4546
# ---------------------------
4647
@callback
4748
def update_items(coordinator: HuaweiControllerDataUpdateCoordinator,
48-
async_add_entities, tracked):
49+
async_add_entities, tracked) -> None:
4950
"""Update tracked device state from the hub."""
5051
new_tracked = []
5152
for mac, device in coordinator.connected_devices.items():
@@ -63,18 +64,18 @@ def update_items(coordinator: HuaweiControllerDataUpdateCoordinator,
6364
class HuaweiTracker(CoordinatorEntity, ScannerEntity):
6465
"""Representation of network device."""
6566

66-
def __init__(self, device: ConnectedDevice, coordinator: HuaweiControllerDataUpdateCoordinator):
67+
def __init__(self, device: ConnectedDevice, coordinator: HuaweiControllerDataUpdateCoordinator) -> None:
6768
"""Initialize the tracked device."""
6869
self.device: ConnectedDevice = device
6970
super().__init__(coordinator)
7071

7172
@property
72-
def is_connected(self):
73+
def is_connected(self) -> bool:
7374
"""Return true if the client is connected to the network."""
7475
return self.device.is_active
7576

7677
@property
77-
def source_type(self):
78+
def source_type(self) -> str:
7879
"""Return the source type of the client."""
7980
return SOURCE_TYPE_ROUTER
8081

@@ -104,7 +105,7 @@ def unique_id(self) -> str:
104105
return f'{self.coordinator.unique_id}_{self.device.mac}'
105106

106107
@property
107-
def extra_state_attributes(self):
108+
def extra_state_attributes(self) -> dict[str, Any]:
108109
"""Return the device state attributes."""
109110
return {k: v for k, v in self.device.all_attrs.items() if k not in FILTER_ATTRS}
110111

0 commit comments

Comments
 (0)