From d088bbdb23b57071cf4dbad16f9014c506c32eb3 Mon Sep 17 00:00:00 2001 From: Dmitry Mamontov Date: Sun, 14 Mar 2021 15:17:21 +0300 Subject: [PATCH] add Mesh detector and Redmi AX5 --- README.md | 31 +++++++----- custom_components/miwifi/core/const.py | 3 +- custom_components/miwifi/core/luci.py | 68 ++++++++++++++++---------- custom_components/miwifi/manifest.json | 2 +- 4 files changed, 62 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index ab5f490..8cc82ac 100644 --- a/README.md +++ b/README.md @@ -17,31 +17,35 @@ Component for tracking devices and managing routers based on [MiWiFi](http://miw ## FAQ **Q. Do I need to get telnet or ssh?** -A. Not. integration works through Luci-API +**A.** Not. integration works through Luci-API **Q. How often are states updated?** -A. Once every 10 seconds. This is the most optimal time for correct work. +**A.** Once every 10 seconds. This is the most optimal time for correct work. **Q. In addition to tracking devices, what else does the integration allow you to do?** -A. The integration creates sensors to track the number of connected devices through different types of connections (`5 Ghz`, `2.4 Ghz`, `lan`, `guest`). Creates binary sensors that track (`mode`, `wifi state`, `wan state`). Creates switches to control `LEDs` and `reboot` the router. It also collects statistics on connected devices (Signal, Uptime, etc.) +**A.** The integration creates sensors to track the number of connected devices through different types of connections (`5 Ghz`, `2.4 Ghz`, `lan`, `guest`). Creates binary sensors that track (`mode`, `wifi state`, `wan state`). Creates switches to control `LEDs` and `reboot` the router. It also collects statistics on connected devices (Signal, Uptime, etc.) **Q. Does the integration support legacy device tracking via `known_devices.yaml`?** -A. This is a legacy device tracking option. But the integration allows importing names, dev_id, icon from the file `known_devices.yaml` and associating with new devices by mac-address. To do this, simply create or rename the file to `legacy_known_devices.yaml` +**A.** This is a legacy device tracking option. But the integration allows importing names, dev_id, icon from the file `known_devices.yaml` and associating with new devices by mac-address. To do this, simply create or rename the file to `legacy_known_devices.yaml` **Q. Does the integration support routers connected in `repeater mode` or `access point mode`?** -A. Yes, the integration supports devices connected in `repeater mode` or `access point mode`. But to get the number of devices and their tracking, you will also need to connect and configure the parent router. +**A.** Yes, the integration supports devices connected in `repeater mode` or `access point mode`. But to get the number of devices and their tracking, you will also need to connect and configure the parent router. **Q. Can I use the router in `repeater mode` or `access point mode` without a parent MiWiFi device?** -A. It is possible with the `force_load_repeater_devices` option enabled. But there is a limitation. You will not see IP, uptime, and connection type, but the name will be the mac-address. +**A.** It is possible with the `force_load_repeater_devices` option enabled. But there is a limitation. You will not see IP, uptime, and connection type, but the name will be the mac-address. + +**Q. Does Mesh support routers?** + +**A.** Yes, they are supported. **Q. Is a reboot required after changing the [PRO] settings?** -A. Reboot is required +**A.** Reboot is required ## Install Installed through the custom repository [HACS](https://hacs.xyz/) - `dmamontov/hass-miwifi` @@ -109,11 +113,12 @@ target: ## Routers tested Many more Xiaomi and Redmi routers supported by MiWiFi (OpenWRT - Luci API) -| Image | Router | Firmware version | Status | -| --------------------------------------------------- | ---------------------------------------------------------------- | -------------------------- | ----------------------------- | -| ![](http://www1.miwifi.com/statics/img/2100@1x.png) | [Xiaomi AC2100](https://www.mi.com/miwifiac) | 2.0.743(CN) | Supported | -| ![](http://www1.miwifi.com/statics/img/RA72.png) | [Xiaomi AX3600](https://www.mi.com/r3600) | 1.0.79(CN), 3.0.22(Global) | Supported | -| ![](http://www1.miwifi.com/statics/img/AX1800.png) | [Xiaomi AX1800](https://www.mi.com/buy/detail?product_id=12027) | 3.0.34(Global) | Supported | -| ![](http://www1.miwifi.com/statics/img/r3p.png) | [Xiaomi PRO R3P](http://item.mi.com/1172800043.html) | 2.16.29(CN) | With restrictions* | +| Image | Router | Firmware version | Status | +| --------------------------------------------------- | ---------------------------------------------------------------- | --------------------------- | ----------------------------- | +| ![](http://www1.miwifi.com/statics/img/RA72.png) | [Xiaomi AX3600](https://www.mi.com/r3600) | 1.0.79(CN), 3.0.22(Global) | Supported | +| ![](http://www1.miwifi.com/statics/img/AX1800.png) | [Xiaomi AX1800](https://www.mi.com/buy/detail?product_id=12027) | 1.0.378(CN) | Supported | +| ![](http://miwifi.com/statics/img/RA67.png) | [Redmi AX5](https://www.mi.com/buy/detail?product_id=12258) | 1.0.33(CN), 3.0.34(Global) | Supported | +| ![](http://www1.miwifi.com/statics/img/2100@1x.png) | [Xiaomi AC2100](https://www.mi.com/miwifiac) | 2.0.743(CN) | Supported | +| ![](http://www1.miwifi.com/statics/img/r3p.png) | [Xiaomi PRO R3P](http://item.mi.com/1172800043.html) | 2.16.29(CN) | With restrictions* | * Not all integration options may be supported. diff --git a/custom_components/miwifi/core/const.py b/custom_components/miwifi/core/const.py index 2795515..348e958 100644 --- a/custom_components/miwifi/core/const.py +++ b/custom_components/miwifi/core/const.py @@ -37,7 +37,8 @@ "devices_2_4ghz": {"name": "Devices (2.4 Ghz)", "icon": "mdi:counter", "unit": "pcs"}, "devices_guest": {"name": "Devices (guest)", "icon": "mdi:counter", "unit": "pcs"}, "uptime": {"name": "Uptime", "icon": "mdi:timer-sand", "unit": None}, - "mode": {"name": "Mode", "icon": "mdi:transit-connection-variant", "unit": None} + "mode": {"name": "Mode", "icon": "mdi:transit-connection-variant", "unit": None}, + "memory_usage": {"name": "Memory usage", "icon": "mdi:memory", "unit": "%"} } LIGHTS = { diff --git a/custom_components/miwifi/core/luci.py b/custom_components/miwifi/core/luci.py index 7d1a74c..1b939c0 100644 --- a/custom_components/miwifi/core/luci.py +++ b/custom_components/miwifi/core/luci.py @@ -64,7 +64,7 @@ def __init__( "binary_sensor": {"state": False, "wifi_state": False, "wan_state": False}, "sensor": { "devices": 0, "devices_lan": 0, "devices_5ghz": 0, "devices_2_4ghz": 0, "devices_guest": 0, - "mode": "default", "uptime": "0:00:00" + "memory_usage": 0, "mode": "default", "uptime": "0:00:00" }, } @@ -149,13 +149,20 @@ async def set_device_data(self) -> None: self._data["sensor"]["uptime"] = str(timedelta(seconds = int(float(status["upTime"])))) + if "mem" in status and isinstance(status["mem"], dict) and "usage" in status["mem"]: + self._data["sensor"]["memory_usage"] = int(float(status["mem"]["usage"]) * 100) + else: + del self._data["sensor"]["memory_usage"] + async def set_entity_data(self) -> None: mode = await self.mode() wifi_status = await self.wifi_status() wan_info = await self.wan_info() led = await self.led() - self.is_repeater_mode = mode["mode"] > 0 + if self._data["sensor"]["mode"] != "mesh": + self.is_repeater_mode = mode["mode"] > 0 + self._data["sensor"]["mode"] = MODE_MAP[mode["mode"]] if mode["mode"] in MODE_MAP else "undefined" wifi_state = True for state in wifi_status["status"]: @@ -173,8 +180,6 @@ async def set_entity_data(self) -> None: else: self._data["binary_sensor"]["wan_state"] = uptime > 0 - self._data["sensor"]["mode"] = MODE_MAP[mode["mode"]] if mode["mode"] in MODE_MAP else "undefined" - async def set_devices_list(self) -> None: wifi_connect_devices = await self.wifi_connect_devices() self._signals = {} @@ -194,37 +199,43 @@ async def set_devices_list(self) -> None: device_list = await self.device_list() - if "list" in device_list: - device_list = {item['mac']:item for item in device_list["list"]} + if "list" not in device_list or len(device_list["list"]) <= 0: + if len(self._signals) > 0 and not self.is_repeater_mode: + self.is_repeater_mode = True + self._data["sensor"]["mode"] = "mesh" + + return - devices_to_ip = {} - entities_map = await self.get_entities_map() + device_list = {item['mac']:item for item in device_list["list"]} - for mac in device_list: - device = device_list[mac] + devices_to_ip = {} + entities_map = await self.get_entities_map() - if device["parent"] and device["parent"] in device_list and device_list[device["parent"]]["ip"][0]["ip"] in entities_map: - ip = device_list[device["parent"]]["ip"][0]["ip"] - else: - ip = self._ip + for mac in device_list: + device = device_list[mac] - device["connection"] = CONNECTION_RANGES[device["type"]] + if device["parent"] and device["parent"] in device_list and device_list[device["parent"]]["ip"][0]["ip"] in entities_map: + ip = device_list[device["parent"]]["ip"][0]["ip"] + else: + ip = self._ip - if ip not in devices_to_ip: - devices_to_ip[ip] = {} + device["connection"] = CONNECTION_RANGES[device["type"]] - devices_to_ip[ip][mac] = device + if ip not in devices_to_ip: + devices_to_ip[ip] = {} - for ip in devices_to_ip: - if len(devices_to_ip[ip]) == 0: - continue + devices_to_ip[ip][mac] = device - if ip == self._ip: - await self.add_devices(devices_to_ip[ip]) - elif not self.hass.data[DOMAIN][entities_map[ip]].api.is_force_load: - await self.hass.data[DOMAIN][entities_map[ip]].api.add_devices(devices_to_ip[ip]) - await asyncio.sleep(1) - self.hass.data[DOMAIN][entities_map[ip]].update_devices() + for ip in devices_to_ip: + if len(devices_to_ip[ip]) == 0: + continue + + if ip == self._ip: + await self.add_devices(devices_to_ip[ip]) + elif not self.hass.data[DOMAIN][entities_map[ip]].api.is_force_load: + await self.hass.data[DOMAIN][entities_map[ip]].api.add_devices(devices_to_ip[ip]) + await asyncio.sleep(1) + self.hass.data[DOMAIN][entities_map[ip]].update_devices() async def add_devices(self, devices: dict, is_force: bool = False) -> None: if not self._device_data: @@ -240,6 +251,9 @@ async def add_devices(self, devices: dict, is_force: bool = False) -> None: "uptime": self._data["sensor"]["uptime"] } + if "memory_usage" in self._data["sensor"]: + sensor_default["memory_usage"] = self._data["sensor"]["memory_usage"] + if is_force: try: new_status = await self.new_status() diff --git a/custom_components/miwifi/manifest.json b/custom_components/miwifi/manifest.json index 464c0b6..b244bc7 100644 --- a/custom_components/miwifi/manifest.json +++ b/custom_components/miwifi/manifest.json @@ -1,7 +1,7 @@ { "domain": "miwifi", "name": "MiWiFi", - "version": "1.0.5", + "version": "1.0.6", "documentation": "https://github.com/dmamontov/hass-miwifi", "config_flow": true, "requirements": [],