diff --git a/README.md b/README.md
index b9d83c6..d354258 100644
--- a/README.md
+++ b/README.md
@@ -84,6 +84,7 @@ Many more Xiaomi and Redmi routers supported by MiWiFi
| ![](images/RB03.png) | **Redmi Router AX6S** | RB03 | 🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢 |
| ![](images/RB01.png) | **Xiaomi Router AX3200** | RB01 | 🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢 |
| ![](images/RA81.png) | **Redmi Router AX3000** | RA81 | 🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢 |
+| ![](images/CR6606.png) | **Xiaomi China Unicom WiFi 6 Router** | CR6606 | 🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢 |
| ![](images/RA71.png) | **Redmi Router AX1800** | RA71 | 🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢 |
| ![](images/RA69.png) | **Redmi Router AX6** | RA69 | 🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢 |
| ![](images/RA67.png) | **Redmi Router AX5** | RA67 | 🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢🟢 | 🟢🟢🟢🟢🟢 |
diff --git a/custom_components/miwifi/config_flow.py b/custom_components/miwifi/config_flow.py
index 3f9b91d..3ad5cf7 100644
--- a/custom_components/miwifi/config_flow.py
+++ b/custom_components/miwifi/config_flow.py
@@ -21,6 +21,7 @@
from .const import (
CONF_ACTIVITY_DAYS,
+ CONF_IS_TRACK_DEVICES,
CONF_IS_FORCE_LOAD,
CONF_STAY_ONLINE,
CONF_ENCRYPTION_ALGORITHM,
@@ -136,6 +137,7 @@ async def async_step_user(
EncryptionAlgorithm.SHA256,
]
),
+ vol.Required(CONF_IS_TRACK_DEVICES, default=True): cv.boolean,
vol.Required(
CONF_STAY_ONLINE, default=DEFAULT_STAY_ONLINE
): cv.positive_int,
@@ -223,6 +225,7 @@ async def async_step_discovery_confirm(
EncryptionAlgorithm.SHA256,
]
),
+ vol.Required(CONF_IS_TRACK_DEVICES, default=True): cv.boolean,
vol.Required(
CONF_STAY_ONLINE, default=DEFAULT_STAY_ONLINE
): cv.positive_int,
@@ -337,6 +340,12 @@ def _get_options_schema(self) -> vol.Schema:
EncryptionAlgorithm.SHA256,
]
),
+ vol.Required(
+ CONF_IS_TRACK_DEVICES,
+ default=get_config_value(
+ self._config_entry, CONF_IS_TRACK_DEVICES, True
+ ),
+ ): cv.boolean,
vol.Required(
CONF_STAY_ONLINE,
default=get_config_value(
diff --git a/custom_components/miwifi/const.py b/custom_components/miwifi/const.py
index 599fc78..5c9bcb1 100644
--- a/custom_components/miwifi/const.py
+++ b/custom_components/miwifi/const.py
@@ -41,6 +41,7 @@
"""Custom conf"""
CONF_STAY_ONLINE: Final = "stay_online"
+CONF_IS_TRACK_DEVICES: Final = "is_track_devices"
CONF_IS_FORCE_LOAD: Final = "is_force_load"
CONF_ACTIVITY_DAYS: Final = "activity_days"
CONF_ENCRYPTION_ALGORITHM: Final = "encryption_algorithm"
diff --git a/custom_components/miwifi/device_tracker.py b/custom_components/miwifi/device_tracker.py
index 78856d4..47906ce 100644
--- a/custom_components/miwifi/device_tracker.py
+++ b/custom_components/miwifi/device_tracker.py
@@ -41,6 +41,7 @@
ATTR_TRACKER_UP_SPEED,
ATTR_TRACKER_UPDATER_ENTRY_ID,
ATTRIBUTION,
+ CONF_IS_TRACK_DEVICES,
CONF_STAY_ONLINE,
DEFAULT_CALL_DELAY,
DEFAULT_STAY_ONLINE,
@@ -98,7 +99,10 @@ def add_device(new_device: dict) -> None:
:param new_device: dict: Device object
"""
- if new_device[ATTR_TRACKER_UPDATER_ENTRY_ID] != config_entry.entry_id:
+ if (
+ not get_config_value(config_entry, CONF_IS_TRACK_DEVICES, True)
+ or new_device[ATTR_TRACKER_UPDATER_ENTRY_ID] != config_entry.entry_id
+ ):
return # pragma: no cover
entity_id: str = generate_entity_id(
diff --git a/custom_components/miwifi/enum.py b/custom_components/miwifi/enum.py
index c3da5d9..5e07e14 100644
--- a/custom_components/miwifi/enum.py
+++ b/custom_components/miwifi/enum.py
@@ -238,3 +238,4 @@ def __str__(self) -> str:
RA72 = "ra72"
RA70 = "ra70"
RB04 = "rb04"
+ CR6606 = "cr6606"
diff --git a/custom_components/miwifi/manifest.json b/custom_components/miwifi/manifest.json
index 225ce59..89bcdfb 100644
--- a/custom_components/miwifi/manifest.json
+++ b/custom_components/miwifi/manifest.json
@@ -1,7 +1,7 @@
{
"domain": "miwifi",
"name": "MiWiFi",
- "version": "2.7.5",
+ "version": "2.8.0",
"documentation": "https://github.com/dmamontov/hass-miwifi/wiki",
"issue_tracker": "https://github.com/dmamontov/hass-miwifi/issues",
"config_flow": true,
diff --git a/custom_components/miwifi/strings.json b/custom_components/miwifi/strings.json
index 998e51a..a773230 100644
--- a/custom_components/miwifi/strings.json
+++ b/custom_components/miwifi/strings.json
@@ -13,6 +13,8 @@
"data": {
"ip_address": "[%key:common::config_flow::data::ip_address%]",
"password": "[%key:common::config_flow::data::password%]",
+ "encryption_algorithm": "Password encryption algorithm",
+ "is_track_devices": "Track devices",
"stay_online": "Minimum stay online in seconds",
"scan_interval": "Scan interval in seconds [PRO]",
"timeout": "Timeout of requests in seconds [PRO]"
@@ -34,6 +36,8 @@
"data": {
"ip_address": "[%key:common::config_flow::data::ip_address%]",
"password": "[%key:common::config_flow::data::password%]",
+ "encryption_algorithm": "Password encryption algorithm",
+ "is_track_devices": "Track devices",
"stay_online": "Minimum stay online in seconds",
"scan_interval": "Scan interval in seconds [PRO]",
"activity_days": "Allowed number of days to wait after the last activity [PRO]",
diff --git a/custom_components/miwifi/switch.py b/custom_components/miwifi/switch.py
index d36ed93..c79cd98 100644
--- a/custom_components/miwifi/switch.py
+++ b/custom_components/miwifi/switch.py
@@ -326,7 +326,7 @@ def _additional_prepare(self) -> bool:
self._attr_entity_registry_enabled_default = False
is_available = False
- return is_available
+ return is_available and self.entity_description.key in self._updater.data
def _change_icon(self, is_on: bool) -> None:
"""Change icon
diff --git a/custom_components/miwifi/translations/de.json b/custom_components/miwifi/translations/de.json
index da8d40f..2e4db7b 100644
--- a/custom_components/miwifi/translations/de.json
+++ b/custom_components/miwifi/translations/de.json
@@ -15,6 +15,7 @@
"ip_address": "IP Adresse",
"password": "Passwort",
"encryption_algorithm": "Passwort Verschlüsselungsalgorithmus",
+ "is_track_devices": "Geräte verfolgen",
"stay_online": "Mindestaufenthalt in Sekunden online",
"scan_interval": "Scanintervall in Sekunden [PRO]",
"timeout": "Timeout von Anfragen in Sekunden [PRO]"
@@ -37,6 +38,7 @@
"ip_address": "IP Adresse",
"password": "Passwort",
"encryption_algorithm": "Passwort Verschlüsselungsalgorithmus",
+ "is_track_devices": "Geräte verfolgen",
"stay_online": "Mindestaufenthalt in Sekunden online",
"scan_interval": "Scanintervall in Sekunden [PRO]",
"activity_days": "Anzahl an Tagen, die nach der letzten Aktivität gewartet werden soll [PRO]",
diff --git a/custom_components/miwifi/translations/en.json b/custom_components/miwifi/translations/en.json
index 1c66667..1712fb9 100644
--- a/custom_components/miwifi/translations/en.json
+++ b/custom_components/miwifi/translations/en.json
@@ -15,6 +15,7 @@
"ip_address": "IP address",
"password": "Password",
"encryption_algorithm": "Password encryption algorithm",
+ "is_track_devices": "Track devices",
"stay_online": "Minimum stay online in seconds",
"scan_interval": "Scan interval in seconds [PRO]",
"timeout": "Timeout of requests in seconds [PRO]"
@@ -37,6 +38,7 @@
"ip_address": "IP address",
"password": "Password",
"encryption_algorithm": "Password encryption algorithm",
+ "is_track_devices": "Track devices",
"stay_online": "Minimum stay online in seconds",
"scan_interval": "Scan interval in seconds [PRO]",
"activity_days": "Allowed number of days to wait after the last activity [PRO]",
diff --git a/custom_components/miwifi/translations/fr.json b/custom_components/miwifi/translations/fr.json
index 3a8f96d..9ae41c6 100644
--- a/custom_components/miwifi/translations/fr.json
+++ b/custom_components/miwifi/translations/fr.json
@@ -15,6 +15,7 @@
"ip_address": "Adresse IP",
"password": "Mot de passe",
"encryption_algorithm": "Algorithme de cryptage du mot de passe",
+ "is_track_devices": "Suivre les appareils",
"stay_online": "Reste en ligne minimum en secondes",
"scan_interval": "Intervalle d'analyse en secondes [PRO]",
"timeout": "Délai d'expiration des requêtes en secondes [PRO]"
@@ -37,6 +38,7 @@
"ip_address": "Adresse IP",
"password": "Mot de passe",
"encryption_algorithm": "Algorithme de cryptage du mot de passe",
+ "is_track_devices": "Suivre les appareils",
"stay_online": "Reste en ligne minimum en secondes",
"scan_interval": "Intervalle d'analyse en secondes [PRO]",
"activity_days": "Nombre de jours d'attente autorisés après la dernière activité [PRO]",
diff --git a/custom_components/miwifi/translations/pt-BR.json b/custom_components/miwifi/translations/pt-BR.json
index ea87db2..f768286 100644
--- a/custom_components/miwifi/translations/pt-BR.json
+++ b/custom_components/miwifi/translations/pt-BR.json
@@ -15,6 +15,7 @@
"ip_address": "Endereço IP",
"password": "Senha",
"encryption_algorithm": "Algoritmo de criptografia de senha",
+ "is_track_devices": "Dispositivos de rastreamento",
"stay_online": "Estadia mínima online em segundos",
"scan_interval": "Intervalo de varredura em segundos [PRO]",
"timeout": "Tempo limite de solicitações em segundos [PRO]"
@@ -40,6 +41,7 @@
"ip_address": "Endereço IP",
"password": "Senha",
"encryption_algorithm": "Algoritmo de criptografia de senha",
+ "is_track_devices": "Dispositivos de rastreamento",
"stay_online": "Estadia mínima online em segundos",
"scan_interval": "Intervalo de varredura em segundos [PRO]",
"activity_days": "Número permitido de dias de espera após a última atividade [PRO]",
diff --git a/custom_components/miwifi/translations/ru.json b/custom_components/miwifi/translations/ru.json
index d3d5d76..870f046 100644
--- a/custom_components/miwifi/translations/ru.json
+++ b/custom_components/miwifi/translations/ru.json
@@ -15,6 +15,7 @@
"ip_address": "IP адрес",
"password": "Пароль",
"encryption_algorithm": "Алгоритм шифрования пароля",
+ "is_track_devices": "Отслеживать устройства",
"stay_online": "Минимальное пребывание онлайн в секундах",
"scan_interval": "Интервал сканирования в секундах [PRO]",
"timeout": "Тайм-аут запросов в секундах [PRO]"
@@ -38,6 +39,7 @@
"password": "Пароль",
"encryption_algorithm": "Алгоритм шифрования пароля",
"stay_online": "Минимальное пребывание онлайн в секундах",
+ "is_track_devices": "Отслеживать устройства",
"scan_interval": "Интервал сканирования в секундах [PRO]",
"activity_days": "Допустимое количество дней ожидания после последней активности [PRO]",
"timeout": "Тайм-аут запросов в секундах [PRO]",
diff --git a/custom_components/miwifi/translations/tr.json b/custom_components/miwifi/translations/tr.json
index df7d45d..6fc1917 100644
--- a/custom_components/miwifi/translations/tr.json
+++ b/custom_components/miwifi/translations/tr.json
@@ -15,6 +15,7 @@
"ip_address": "IP adresi",
"password": "Parola",
"encryption_algorithm": "Şifreleme algoritması",
+ "is_track_devices": "Cihazları takip edin",
"stay_online": "En az çevrimiçi kalma süresi (saniye)",
"scan_interval": "Tarama aralığı (saniye) [PRO]",
"timeout": "İstek zaman aşımı (saniye) [PRO]"
@@ -37,6 +38,7 @@
"ip_address": "IP adresi",
"password": "Parola",
"encryption_algorithm": "Şifreleme algoritması",
+ "is_track_devices": "Cihazları takip edin",
"stay_online": "En az çevrimiçi kalma süresi (saniye)",
"scan_interval": "Tarama aralığı (saniye) [PRO]",
"activity_days": "Son aktiviteden sonra beklenmesi gereken süre (gün) [PRO]",
diff --git a/custom_components/miwifi/updater.py b/custom_components/miwifi/updater.py
index a7abb07..8c33006 100644
--- a/custom_components/miwifi/updater.py
+++ b/custom_components/miwifi/updater.py
@@ -623,7 +623,10 @@ async def _async_prepare_wifi(self, data: dict) -> None:
:param data: dict
"""
- response: dict = await self.luci.wifi_detail_all()
+ try:
+ response: dict = await self.luci.wifi_detail_all()
+ except LuciError:
+ return
if "bsd" in response:
data[ATTR_BINARY_SENSOR_DUAL_BAND] = int(response["bsd"]) == 1
diff --git a/images/CR6606.png b/images/CR6606.png
new file mode 100644
index 0000000..d6ecf11
Binary files /dev/null and b/images/CR6606.png differ
diff --git a/tests/test_switch.py b/tests/test_switch.py
index 6769b25..a5c98c7 100644
--- a/tests/test_switch.py
+++ b/tests/test_switch.py
@@ -39,7 +39,7 @@
DOMAIN,
UPDATER,
)
-from custom_components.miwifi.exceptions import LuciRequestError
+from custom_components.miwifi.exceptions import LuciConnectionError, LuciRequestError
from custom_components.miwifi.helper import generate_entity_id
from custom_components.miwifi.updater import LuciUpdater
from tests.setup import MultipleSideEffect, async_mock_luci_client, async_setup
@@ -218,6 +218,56 @@ async def test_init_without_guest(hass: HomeAssistant) -> None:
assert registry.async_get(unique_id) is None
+async def test_init_with_error(hass: HomeAssistant) -> None:
+ """Test init.
+
+ :param hass: HomeAssistant
+ """
+
+ with patch(
+ "custom_components.miwifi.updater.LuciClient"
+ ) as mock_luci_client, patch(
+ "custom_components.miwifi.updater.async_dispatcher_send"
+ ), patch(
+ "custom_components.miwifi.async_start_discovery", return_value=None
+ ), patch(
+ "custom_components.miwifi.device_tracker.socket.socket"
+ ) as mock_socket, patch(
+ "custom_components.miwifi.updater.asyncio.sleep", return_value=None
+ ):
+ mock_socket.return_value.recv.return_value = AsyncMock(return_value=None)
+
+ await async_mock_luci_client(mock_luci_client)
+
+ mock_luci_client.return_value.wifi_detail_all = AsyncMock(
+ side_effect=LuciConnectionError
+ )
+
+ setup_data: list = await async_setup(hass)
+
+ config_entry: MockConfigEntry = setup_data[1]
+
+ assert await hass.config_entries.async_setup(config_entry.entry_id)
+ await hass.async_block_till_done()
+
+ updater: LuciUpdater = hass.data[DOMAIN][config_entry.entry_id][UPDATER]
+ registry = er.async_get(hass)
+
+ assert updater.last_update_success
+
+ unique_id: str = _generate_id(ATTR_SWITCH_WIFI_2_4_NAME, updater)
+ states: State | None = hass.states.get(unique_id)
+ assert states is not None
+ assert states.state == STATE_UNAVAILABLE
+ assert registry.async_get(unique_id) is not None
+
+ unique_id = _generate_id(ATTR_SWITCH_WIFI_5_0_NAME, updater)
+ states = hass.states.get(unique_id)
+ assert states is not None
+ assert states.state == STATE_UNAVAILABLE
+ assert registry.async_get(unique_id) is not None
+
+
async def test_init_bsd(
hass: HomeAssistant,
) -> None: