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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add devices filter page #332

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
254 changes: 214 additions & 40 deletions custom_components/xiaomi_home/config_flow.py

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion custom_components/xiaomi_home/miot/i18n/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
"config": {
"other": {
"devices": "Geräte",
"found_central_gateway": ", lokales zentrales Gateway gefunden"
"found_central_gateway": ", lokales zentrales Gateway gefunden",
"without_room": "Kein Raum zugewiesen"
},
"control_mode": {
"auto": "automatisch",
"cloud": "Cloud"
},
"filter_mode": {
"exclude": "ausschließen",
"include": "einschließen"
},
"room_name_rule": {
"none": "nicht synchronisieren",
"home_room": "Hausname und Raumname (Xiaomi Home Schlafzimmer)",
Expand Down
7 changes: 6 additions & 1 deletion custom_components/xiaomi_home/miot/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
"config": {
"other": {
"devices": "Devices",
"found_central_gateway": ", Found Local Central Hub Gateway"
"found_central_gateway": ", Found Local Central Hub Gateway",
"without_room": "No room assigned"
},
"control_mode": {
"auto": "Auto",
"cloud": "Cloud"
},
"filter_mode": {
"exclude": "Exclude",
"include": "Include"
},
"room_name_rule": {
"none": "Do not synchronize",
"home_room": "Home Name and Room Name (Xiaomi Home Bedroom)",
Expand Down
7 changes: 6 additions & 1 deletion custom_components/xiaomi_home/miot/i18n/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
"config": {
"other": {
"devices": "dispositivos",
"found_central_gateway": ", se encontró la puerta de enlace central local"
"found_central_gateway": ", se encontró la puerta de enlace central local",
"without_room": "Sin habitación asignada"
},
"control_mode": {
"auto": "automático",
"cloud": "nube"
},
"filter_mode": {
"exclude": "excluir",
"include": "incluir"
},
"room_name_rule": {
"none": "no sincronizar",
"home_room": "nombre de la casa y nombre de la habitación (Xiaomi Home Dormitorio)",
Expand Down
7 changes: 6 additions & 1 deletion custom_components/xiaomi_home/miot/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
"config": {
"other": {
"devices": "appareils",
"found_central_gateway": ", passerelle centrale locale trouvée"
"found_central_gateway": ", passerelle centrale locale trouvée",
"without_room": "Aucune pièce attribuée"
},
"control_mode": {
"auto": "automatique",
"cloud": "cloud"
},
"filter_mode": {
"exclude": "exclure",
"include": "inclure"
},
"room_name_rule": {
"none": "ne pas synchroniser",
"home_room": "nom de la maison et nom de la pièce (Xiaomi Home Chambre)",
Expand Down
7 changes: 6 additions & 1 deletion custom_components/xiaomi_home/miot/i18n/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
"config": {
"other": {
"devices": "デバイス",
"found_central_gateway": "、ローカル中央ゲートウェイが見つかりました"
"found_central_gateway": "、ローカル中央ゲートウェイが見つかりました",
"without_room": "部屋が割り当てられていません"
},
"control_mode": {
"auto": "自動",
"cloud": "クラウド"
},
"filter_mode": {
"exclude": "除外",
"include": "含む"
},
"room_name_rule": {
"none": "同期しない",
"home_room": "家の名前と部屋の名前 (Xiaomi Home 寝室)",
Expand Down
9 changes: 7 additions & 2 deletions custom_components/xiaomi_home/miot/i18n/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
"config": {
"other": {
"devices": "Apparaten",
"found_central_gateway": ", Lokale centrale hub-gateway gevonden"
"found_central_gateway": ", Lokale centrale hub-gateway gevonden",
"without_room": "Niet toegewezen kamer"
},
"control_mode": {
"auto": "Automatisch",
"cloud": "Cloud"
},
"filter_mode": {
"exclude": "Uitsluiten",
"include": "Inclusief"
},
"room_name_rule": {
"none": "Niet synchroniseren",
"home_room": "Huisnaam en Kamernaam (Xiaomi Home Slaapkamer)",
Expand Down Expand Up @@ -92,4 +97,4 @@
"-706014006": "Apparaatbeschrijving niet gevonden"
}
}
}
}
7 changes: 6 additions & 1 deletion custom_components/xiaomi_home/miot/i18n/pt-BR.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
"config": {
"other": {
"devices": "dispositivos",
"found_central_gateway": "encontrado o gateway central local"
"found_central_gateway": "encontrado o gateway central local",
"without_room": "sem quarto atribuído"
},
"control_mode": {
"auto": "automático",
"cloud": "nuvem"
},
"filter_mode": {
"exclude": "excluir",
"include": "incluir"
},
"room_name_rule": {
"none": "não sincronizado",
"home_room": "Nome da casa e nome do quarto (Xiaomi Home Quarto)",
Expand Down
7 changes: 6 additions & 1 deletion custom_components/xiaomi_home/miot/i18n/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
"config": {
"other": {
"devices": "dispositivos",
"found_central_gateway": ", encontrou a central de gateway local"
"found_central_gateway": ", encontrou a central de gateway local",
"without_room": "Sem quarto atribuído"
},
"control_mode": {
"auto": "Automático",
"cloud": "Nuvem"
},
"filter_mode": {
"exclude": "Excluir",
"include": "Incluir"
},
"room_name_rule": {
"none": "Não sincronizar",
"home_room": "Nome da casa e Nome do quarto (Xiaomi Home Quarto)",
Expand Down
7 changes: 6 additions & 1 deletion custom_components/xiaomi_home/miot/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
"config": {
"other": {
"devices": "устройства",
"found_central_gateway": ", найден локальный центральный шлюз"
"found_central_gateway": ", найден локальный центральный шлюз",
"without_room": "без комнаты"
},
"control_mode": {
"auto": "автоматический",
"cloud": "облако"
},
"filter_mode": {
"exclude": "исключить",
"include": "включить"
},
"room_name_rule": {
"none": "не синхронизировать",
"home_room": "название дома и название комнаты (Xiaomi Home Спальня)",
Expand Down
12 changes: 11 additions & 1 deletion custom_components/xiaomi_home/miot/i18n/zh-Hans.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"config": {
"other": {
"devices": "个设备",
"found_central_gateway": ",发现本地中枢网关"
"found_central_gateway": ",发现本地中枢网关",
"without_room": "未分配房间"
},
"control_mode": {
"auto": "自动",
Expand All @@ -14,6 +15,15 @@
"room": "房间名 (卧室)",
"home": "家庭名 (米家)"
},
"filter_mode": {
"exclude": "排除",
"include": "包含"
},
"connect_type": {
"0": "WiFi设备",
"1": "蓝牙设备",
"2": "其它类型"
},
"option_status": {
"enable": "启用",
"disable": "禁用"
Expand Down
7 changes: 6 additions & 1 deletion custom_components/xiaomi_home/miot/i18n/zh-Hant.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
"config": {
"other": {
"devices": "個設備",
"found_central_gateway": ",發現本地中樞網關"
"found_central_gateway": ",發現本地中樞網關",
"without_room": "未分配房間"
},
"control_mode": {
"auto": "自動",
"cloud": "雲端"
},
"filter_mode": {
"exclude": "排除",
"include": "包含"
},
"room_name_rule": {
"none": "不同步",
"home_room": "家庭名 和 房間名 (米家 臥室)",
Expand Down
4 changes: 2 additions & 2 deletions custom_components/xiaomi_home/miot/miot_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,14 +239,14 @@ async def init_async(self) -> None:
# Integration need to be add again
raise MIoTClientError('load_user_config_async error')
_LOGGER.debug('user config, %s', json.dumps(self._user_config))
# Load cache device list
await self.__load_cache_device_async()
# MIoT i18n client
self._i18n = MIoTI18n(
lang=self._entry_data.get(
'integration_language', DEFAULT_INTEGRATION_LANGUAGE),
loop=self._main_loop)
await self._i18n.init_async()
# Load cache device list
await self.__load_cache_device_async()
# MIoT oauth client instance
self._oauth = MIoTOauthClient(
client_id=OAUTH2_CLIENT_ID,
Expand Down
7 changes: 7 additions & 0 deletions custom_components/xiaomi_home/miot/miot_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,13 @@ def __init__(
self._session = aiohttp.ClientSession(loop=self._main_loop)

async def deinit_async(self) -> None:
if self._get_prop_timer:
self._get_prop_timer.cancel()
self._get_prop_timer = None
for item in self._get_prop_list.values():
fut: asyncio.Future = item.get('fut')
fut.cancel()
self._get_prop_list.clear()
if self._session and not self._session.closed:
await self._session.close()

Expand Down
4 changes: 2 additions & 2 deletions custom_components/xiaomi_home/miot/miot_i18n.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def __init__(
) -> None:
self._main_loop = loop or asyncio.get_event_loop()
self._lang = lang
self._data = None
self._data = {}

async def init_async(self) -> None:
if self._data:
Expand All @@ -94,7 +94,7 @@ async def init_async(self) -> None:
self._data = data

async def deinit_async(self) -> None:
self._data = None
self._data = {}

def translate(
self, key: str, replace: Optional[dict[str, str]] = None
Expand Down
23 changes: 12 additions & 11 deletions custom_components/xiaomi_home/miot/miot_mdns.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
import binascii
import copy
from enum import Enum
from typing import Callable, Optional
from typing import Callable, Coroutine, Optional
import logging

from zeroconf import (
Expand Down Expand Up @@ -98,8 +98,8 @@ class MipsServiceData:
def __init__(self, service_info: AsyncServiceInfo) -> None:
if service_info is None:
raise MipsServiceError('invalid params')
properties = service_info.decoded_properties
if properties is None:
properties: dict = service_info.decoded_properties
if not properties:
raise MipsServiceError('invalid service properties')
self.profile = properties.get('profile', None)
if self.profile is None:
Expand All @@ -111,9 +111,11 @@ def __init__(self, service_info: AsyncServiceInfo) -> None:
if not self.addresses:
raise MipsServiceError('invalid addresses')
self.addresses.sort()
if not service_info.port:
raise MipsServiceError('invalid port')
self.port = service_info.port
self.type = service_info.type
self.server = service_info.server
self.server = service_info.server or ''
# Parse profile
self.did = str(int.from_bytes(self.profile_bin[1:9]))
self.group_id = binascii.hexlify(
Expand Down Expand Up @@ -150,16 +152,15 @@ class MipsService:
_aio_browser: AsyncServiceBrowser
_services: dict[str, dict]
# key = (key, group_id)
_sub_list: dict[(str, str), Callable[[
str, MipsServiceState, dict], asyncio.Future]]
_sub_list: dict[tuple[str, str], Callable[[
str, MipsServiceState, dict], Coroutine]]

def __init__(
self, aiozc: AsyncZeroconf,
loop: Optional[asyncio.AbstractEventLoop] = None
) -> None:
self._aiozc = aiozc
self._main_loop = loop or asyncio.get_running_loop()
self._aio_browser = None

self._services = {}
self._sub_list = {}
Expand Down Expand Up @@ -207,7 +208,7 @@ def get_services(self, group_id: Optional[str] = None) -> dict[str, dict]:

def sub_service_change(
self, key: str, group_id: str,
handler: Callable[[str, MipsServiceState, dict], asyncio.Future]
handler: Callable[[str, MipsServiceState, dict], Coroutine]
) -> None:
if key is None or group_id is None or handler is None:
raise MipsServiceError('invalid params')
Expand All @@ -232,7 +233,7 @@ def __on_service_state_change(
for item in list(self._services.values()):
if item['name'] != name:
continue
service_data = self._services.pop(item['group_id'], None)
service_data = self._services.pop(item['group_id'], {})
self.__call_service_change(
state=MipsServiceState.REMOVED, data=service_data)
return
Expand Down Expand Up @@ -275,10 +276,10 @@ async def __request_service_info_async(
_LOGGER.error('invalid mips service, %s, %s', error, info)

def __call_service_change(
self, state: MipsServiceState, data: dict = None
self, state: MipsServiceState, data: dict
) -> None:
_LOGGER.info('call service change, %s, %s', state, data)
for keys in list(self._sub_list.keys()):
if keys[1] in [data['group_id'], '*']:
if keys[1] in [data.get('group_id', None), '*']:
self._main_loop.create_task(
self._sub_list[keys](data['group_id'], state, data))
28 changes: 25 additions & 3 deletions custom_components/xiaomi_home/translations/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,35 @@
},
"homes_select": {
"title": "Familie und Geräte auswählen",
"description": "## Gebrauchsanweisung\r\n### Steuerungsmodus\r\n- Automatisch: Wenn im lokalen Netzwerk ein verfügbarer Xiaomi-Zentralgateway vorhanden ist, wird Home Assistant bevorzugt Steuerbefehle über den Zentralgateway senden, um eine lokale Steuerung zu ermöglichen. Wenn im lokalen Netzwerk kein Zentralgateway vorhanden ist, wird versucht, Steuerbefehle über das Xiaomi-OT-Protokoll zu senden, um eine lokale Steuerung zu ermöglichen. Nur wenn die oben genannten Bedingungen für die lokale Steuerung nicht erfüllt sind, werden die Steuerbefehle über die Cloud gesendet.\r\n- Cloud: Steuerbefehle werden nur über die Cloud gesendet.\r\n### Familienimport für importierte Geräte\r\nDie Integration fügt Geräte aus den ausgewählten Familien hinzu.\r\n### Raumnamensynchronisationsmodus\r\nWenn Geräte von der Xiaomi Home App zu Home Assistant synchronisiert werden, wird die Bezeichnung des Bereichs, in dem sich die Geräte in Home Assistant befinden, nach folgenden Regeln benannt. Beachten Sie, dass das Synchronisieren von Geräten den von Xiaomi Home App festgelegten Familien- und Raum-Einstellungen nicht ändert.\r\n- Nicht synchronisieren: Das Gerät wird keinem Bereich hinzugefügt.\r\n- Andere Optionen: Der Bereich, in den das Gerät aufgenommen wird, wird nach dem Namen der Familie oder des Raums in der Xiaomi Home App benannt.\r\n### Action-Debug-Modus\r\nFür von MIoT-Spec-V2 definierte Gerätemethoden wird neben der Benachrichtigungs-Entität auch eine Texteingabe-Entität generiert. Damit können Sie bei der Fehlerbehebung Steuerbefehle an das Gerät senden.\r\n### Verstecke Nicht-Standard-Entitäten\r\nVerstecke Entitäten, die von nicht standardmäßigen MIoT-Spec-V2-Instanzen mit einem Namen beginnen, der mit einem \"*\" beginnt.\r\n\r\n \r\n### Hallo {nick_name}! Bitte wählen Sie den Steuerungsmodus der Integration sowie die Familie aus, in der sich die hinzuzufügenden Geräte befinden.",
"description": "## Gebrauchsanweisung\r\n### Familienimport für importierte Geräte\r\nDie Integration fügt Geräte aus den ausgewählten Familien hinzu.\r\n### Raumnamensynchronisationsmodus\r\nWenn Geräte von der Xiaomi Home App zu Home Assistant synchronisiert werden, wird die Bezeichnung des Bereichs, in dem sich die Geräte in Home Assistant befinden, nach folgenden Regeln benannt. Beachten Sie, dass das Synchronisieren von Geräten den von Xiaomi Home App festgelegten Familien- und Raum-Einstellungen nicht ändert.\r\n- Nicht synchronisieren: Das Gerät wird keinem Bereich hinzugefügt.\r\n- Andere Optionen: Der Bereich, in den das Gerät aufgenommen wird, wird nach dem Namen der Familie oder des Raums in der Xiaomi Home App benannt.\r\n### Erweiterte Einstellungen\r\nZeigen Sie erweiterte Einstellungen an, um die professionellen Konfigurationsoptionen der Integration zu ändern.\r\n\r\n \r\n### {nick_name} Hallo! Bitte wählen Sie die Familie aus, zu der Sie das Gerät hinzufügen möchten.",
"data": {
"ctrl_mode": "Steuerungsmodus",
"home_infos": "Familienimport für importierte Geräte",
"area_name_rule": "Raumnamensynchronisationsmodus",
"advanced_options": "Erweiterte Einstellungen"
}
},
"advanced_options": {
"title": "Erweiterte Einstellungen",
"description": "## Gebrauchsanweisung\r\n### Behalten Sie die Standardeinstellungen bei, es sei denn, Sie verstehen die folgenden Optionen vollständig.\r\n### Steuerungsmodus\r\n- Automatisch: Wenn ein verfügbarer Xiaomi-Hub im lokalen Netzwerk vorhanden ist, priorisiert Home Assistant das Senden von Steuerbefehlen über den Hub, um eine lokale Steuerung zu ermöglichen. Wenn kein Hub vorhanden ist, wird versucht, Steuerbefehle über das Xiaomi-OT-Protokoll zu senden. Nur wenn diese Bedingungen für die lokale Steuerung nicht erfüllt sind, werden die Befehle über die Cloud gesendet.\r\n- Cloud: Steuerbefehle werden ausschließlich über die Cloud gesendet.\r\n### Gerätefilterung\r\nFiltern Sie unerwünschte Geräte nach Familien.\r\n### Action-Debug-Modus\r\nFür Methoden, die von MIoT-Spec-V2-Geräten definiert werden, wird neben der Benachrichtigungsentität auch eine Texteingabe-Entität erstellt, mit der Sie während des Debuggens Steuerbefehle an das Gerät senden können.\r\n### Nicht standardmäßige Entitäten ausblenden\r\nBlendet Entitäten aus, die von nicht-standardmäßigen MIoT-Spec-V2-Instanzen generiert werden und deren Name mit „*“ beginnt.",
"data": {
"devices_filter": "Geräte filtern",
"ctrl_mode": "Steuerungsmodus",
"action_debug": "Action-Debug-Modus",
"hide_non_standard_entities": "Verstecke Nicht-Standard-Entitäten"
"hide_non_standard_entities": "Nicht standardmäßige Entitäten ausblenden"
}
},
"devices_filter": {
"title": "Geräte filtern",
"description": "## Gebrauchsanweisung\r\n- Unterstützt das Filtern von Geräten nach Raumnamen und Gerätetypen sowie das Filtern nach Gerätedimensionen.\r\n- Sie können auch die entsprechende Integrationsoption \"Konfiguration> Geräteliste aktualisieren\" aufrufen, um die Filterung erneut durchzuführen.",
"data": {
"room_filter_mode": "Familienraum filtern",
"room_list": "Familienraum",
"type_filter_mode": "Gerätetyp filtern",
"type_list": "Gerätetyp",
"model_filter_mode": "Gerätemodell filtern",
"model_list": "Gerätemodell",
"devices_filter_mode": "Geräte filtern",
"device_list": "Geräteliste"
}
}
},
Expand Down
Loading
Loading