From 3cc66450bd9566920822d636c635dc5344cac61c Mon Sep 17 00:00:00 2001 From: Li Shuzhen Date: Wed, 30 Jul 2025 15:13:04 +0800 Subject: [PATCH 1/6] feat: cover dead zone width (#1301) --- custom_components/xiaomi_home/config_flow.py | 40 +++++++++---------- custom_components/xiaomi_home/cover.py | 18 ++++++--- custom_components/xiaomi_home/miot/const.py | 6 +-- .../xiaomi_home/miot/miot_client.py | 8 ++-- .../xiaomi_home/translations/de.json | 4 +- .../xiaomi_home/translations/en.json | 4 +- .../xiaomi_home/translations/es.json | 4 +- .../xiaomi_home/translations/fr.json | 4 +- .../xiaomi_home/translations/it.json | 4 +- .../xiaomi_home/translations/ja.json | 4 +- .../xiaomi_home/translations/nl.json | 4 +- .../xiaomi_home/translations/pt-BR.json | 4 +- .../xiaomi_home/translations/pt.json | 4 +- .../xiaomi_home/translations/ru.json | 4 +- .../xiaomi_home/translations/zh-Hans.json | 4 +- .../xiaomi_home/translations/zh-Hant.json | 4 +- 16 files changed, 63 insertions(+), 57 deletions(-) diff --git a/custom_components/xiaomi_home/config_flow.py b/custom_components/xiaomi_home/config_flow.py index 8b72ac4..bcd6646 100644 --- a/custom_components/xiaomi_home/config_flow.py +++ b/custom_components/xiaomi_home/config_flow.py @@ -75,9 +75,9 @@ from .miot.const import ( DEFAULT_CLOUD_SERVER, DEFAULT_CTRL_MODE, DEFAULT_INTEGRATION_LANGUAGE, - DEFAULT_COVER_CLOSED_POSITION, - MIN_COVER_CLOSED_POSITION, - MAX_COVER_CLOSED_POSITION, + DEFAULT_COVER_DEAD_ZONE_WIDTH, + MIN_COVER_DEAD_ZONE_WIDTH, + MAX_COVER_DEAD_ZONE_WIDTH, DEFAULT_NICK_NAME, DEFAULT_OAUTH2_API_HOST, DOMAIN, @@ -132,7 +132,7 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): _cloud_server: str _integration_language: str - _cover_closed_position: int + _cover_dz_width: int _auth_info: dict _nick_name: str _home_selected: dict @@ -155,7 +155,7 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): self._main_loop = asyncio.get_running_loop() self._cloud_server = DEFAULT_CLOUD_SERVER self._integration_language = DEFAULT_INTEGRATION_LANGUAGE - self._cover_closed_position = DEFAULT_COVER_CLOSED_POSITION + self._cover_dz_width = DEFAULT_COVER_DEAD_ZONE_WIDTH self._storage_path = '' self._virtual_did = '' self._uid = '' @@ -956,7 +956,7 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): 'action_debug': self._action_debug, 'hide_non_standard_entities': self._hide_non_standard_entities, - 'cover_closed_position': self._cover_closed_position, + 'cover_dead_zone_width': self._cover_dz_width, 'display_binary_mode': self._display_binary_mode, 'display_devices_changed_notify': self._display_devices_changed_notify @@ -1001,7 +1001,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow): _hide_non_standard_entities: bool _display_binary_mode: list[str] _display_devs_notify: list[str] - _cover_closed_position: int + _cover_dz_width: int _oauth_redirect_url_full: str _auth_info: dict @@ -1022,7 +1022,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow): _opt_lan_ctrl_cfg: bool _opt_network_detect_cfg: bool _opt_check_network_deps: bool - _cover_pos_new: int + _cover_width_new: int _trans_rules_count: int _trans_rules_count_success: int @@ -1051,8 +1051,8 @@ class OptionsFlowHandler(config_entries.OptionsFlow): self._ctrl_mode = self._entry_data.get('ctrl_mode', DEFAULT_CTRL_MODE) self._integration_language = self._entry_data.get( 'integration_language', DEFAULT_INTEGRATION_LANGUAGE) - self._cover_closed_position = self._entry_data.get( - 'cover_closed_position', DEFAULT_COVER_CLOSED_POSITION) + self._cover_dz_width = self._entry_data.get( + 'cover_dead_zone_width', DEFAULT_COVER_DEAD_ZONE_WIDTH) self._nick_name = self._entry_data.get('nick_name', DEFAULT_NICK_NAME) self._action_debug = self._entry_data.get('action_debug', False) self._hide_non_standard_entities = self._entry_data.get( @@ -1078,7 +1078,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow): self._action_debug_new = False self._hide_non_standard_entities_new = False self._display_binary_mode_new = [] - self._cover_pos_new = self._cover_closed_position + self._cover_width_new = self._cover_dz_width self._update_user_info = False self._update_devices = False self._update_trans_rules = False @@ -1352,11 +1352,11 @@ class OptionsFlowHandler(config_entries.OptionsFlow): self._miot_i18n.translate( 'config.binary_mode')), # type: ignore vol.Optional( - 'cover_closed_position', - default=self._cover_closed_position # type: ignore + 'cover_dead_zone_width', + default=self._cover_dz_width # type: ignore ): vol.All(vol.Coerce(int), vol.Range( - min=MIN_COVER_CLOSED_POSITION, - max=MAX_COVER_CLOSED_POSITION)), + min=MIN_COVER_DEAD_ZONE_WIDTH, + max=MAX_COVER_DEAD_ZONE_WIDTH)), vol.Required( 'update_trans_rules', default=self._update_trans_rules # type: ignore @@ -1395,8 +1395,8 @@ class OptionsFlowHandler(config_entries.OptionsFlow): 'update_lan_ctrl_config', self._opt_lan_ctrl_cfg) self._opt_network_detect_cfg = user_input.get( 'network_detect_config', self._opt_network_detect_cfg) - self._cover_pos_new = user_input.get( - 'cover_closed_position', self._cover_closed_position) + self._cover_width_new = user_input.get( + 'cover_dead_zone_width', self._cover_dz_width) return await self.async_step_update_user_info() @@ -1945,7 +1945,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow): 'nick_name': self._nick_name, 'lang_new': INTEGRATION_LANGUAGES[self._lang_new], 'nick_name_new': self._nick_name_new, - 'cover_pos_new': self._cover_pos_new, + 'cover_width_new': self._cover_width_new, 'devices_add': len(self._devices_add), 'devices_remove': len(self._devices_remove), 'trans_rules_count': self._trans_rules_count, @@ -1972,8 +1972,8 @@ class OptionsFlowHandler(config_entries.OptionsFlow): if self._lang_new != self._integration_language: self._entry_data['integration_language'] = self._lang_new self._need_reload = True - if self._cover_pos_new != self._cover_closed_position: - self._entry_data['cover_closed_position'] = self._cover_pos_new + if self._cover_width_new != self._cover_dz_width: + self._entry_data['cover_dead_zone_width'] = self._cover_width_new self._need_reload = True if self._update_user_info: self._entry_data['nick_name'] = self._nick_name_new diff --git a/custom_components/xiaomi_home/cover.py b/custom_components/xiaomi_home/cover.py index e03be9a..deba601 100644 --- a/custom_components/xiaomi_home/cover.py +++ b/custom_components/xiaomi_home/cover.py @@ -91,7 +91,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry, class Cover(MIoTServiceEntity, CoverEntity): """Cover entities for Xiaomi Home.""" # pylint: disable=unused-argument - _cover_closed_position: int + _cover_dead_zone_width: int _prop_motor_control: Optional[MIoTSpecProperty] _prop_motor_value_open: Optional[int] _prop_motor_value_close: Optional[int] @@ -116,8 +116,8 @@ class Cover(MIoTServiceEntity, CoverEntity): self._attr_supported_color_modes = set() self._attr_supported_features = CoverEntityFeature(0) - self._cover_closed_position = ( - miot_device.miot_client.cover_closed_position) + self._cover_dead_zone_width = ( + miot_device.miot_client.cover_dead_zone_width) self._prop_motor_control = None self._prop_motor_value_open = None @@ -275,8 +275,14 @@ class Cover(MIoTServiceEntity, CoverEntity): self._prop_pos_closing = False return self.get_prop_value(prop=self._prop_target_position) pos = self.get_prop_value(prop=self._prop_current_position) - return None if pos is None else round(pos * 100 / - self._prop_position_value_range) + if pos is None: + return None + pos = round(pos*100/self._prop_position_value_range) + if pos <= self._cover_dead_zone_width: + pos = 0 + elif pos >= (100 - self._cover_dead_zone_width): + pos = 100 + return pos @property def is_opening(self) -> Optional[bool]: @@ -302,7 +308,7 @@ class Cover(MIoTServiceEntity, CoverEntity): def is_closed(self) -> Optional[bool]: """Return if the cover is closed.""" if self.current_cover_position is not None: - return self.current_cover_position <= self._cover_closed_position + return self.current_cover_position == 0 # The current position is prior to the status when determining # whether the cover is closed. if self._prop_status and self._prop_status_closed: diff --git a/custom_components/xiaomi_home/miot/const.py b/custom_components/xiaomi_home/miot/const.py index 37eecbc..8a0e44b 100644 --- a/custom_components/xiaomi_home/miot/const.py +++ b/custom_components/xiaomi_home/miot/const.py @@ -120,9 +120,9 @@ INTEGRATION_LANGUAGES = { 'zh-Hant': '繁體中文' } -DEFAULT_COVER_CLOSED_POSITION: int = 0 -MIN_COVER_CLOSED_POSITION: int = 0 -MAX_COVER_CLOSED_POSITION: int = 5 +DEFAULT_COVER_DEAD_ZONE_WIDTH: int = 0 +MIN_COVER_DEAD_ZONE_WIDTH: int = 0 +MAX_COVER_DEAD_ZONE_WIDTH: int = 5 DEFAULT_CTRL_MODE: str = 'auto' diff --git a/custom_components/xiaomi_home/miot/miot_client.py b/custom_components/xiaomi_home/miot/miot_client.py index d5c588b..c48d058 100644 --- a/custom_components/xiaomi_home/miot/miot_client.py +++ b/custom_components/xiaomi_home/miot/miot_client.py @@ -64,7 +64,7 @@ from .const import ( DEFAULT_CTRL_MODE, DEFAULT_INTEGRATION_LANGUAGE, DEFAULT_NICK_NAME, DOMAIN, MIHOME_CERT_EXPIRE_MARGIN, NETWORK_REFRESH_INTERVAL, OAUTH2_CLIENT_ID, SUPPORT_CENTRAL_GATEWAY_CTRL, - DEFAULT_COVER_CLOSED_POSITION) + DEFAULT_COVER_DEAD_ZONE_WIDTH) from .miot_cloud import MIoTHttpClient, MIoTOauthClient from .miot_error import MIoTClientError, MIoTErrorCode from .miot_mips import ( @@ -488,9 +488,9 @@ class MIoTClient: return self._display_binary_bool @property - def cover_closed_position(self) -> int: - return self._entry_data.get('cover_closed_position', - DEFAULT_COVER_CLOSED_POSITION) + def cover_dead_zone_width(self) -> int: + return self._entry_data.get('cover_dead_zone_width', + DEFAULT_COVER_DEAD_ZONE_WIDTH) @display_devices_changed_notify.setter def display_devices_changed_notify(self, value: list[str]) -> None: diff --git a/custom_components/xiaomi_home/translations/de.json b/custom_components/xiaomi_home/translations/de.json index 4bf7d72..697876a 100644 --- a/custom_components/xiaomi_home/translations/de.json +++ b/custom_components/xiaomi_home/translations/de.json @@ -125,7 +125,7 @@ "update_trans_rules": "Entitätskonvertierungsregeln aktualisieren", "update_lan_ctrl_config": "LAN-Steuerungskonfiguration aktualisieren", "network_detect_config": "Integrierte Netzwerkkonfiguration", - "cover_closed_position": "Die Position der geschlossenen Vorhänge" + "cover_dead_zone_width": "Die Breite des toten Winkels des Vorhangs" } }, "update_user_info": { @@ -184,7 +184,7 @@ }, "config_confirm": { "title": "Bestätigen Sie die Konfiguration", - "description": "**{nick_name}**, bitte bestätigen Sie die neuesten Konfigurationsinformationen und klicken Sie dann auf \"Senden\". Die Integration wird mit den aktualisierten Konfigurationen erneut geladen.\r\n\r\nIntegrationsprache:\t{lang_new}\r\nBenutzername:\t{nick_name_new}\r\nAction-Debug-Modus:\t{action_debug}\r\nVerstecke Nicht-Standard-Entitäten:\t{hide_non_standard_entities}\r\nDie Position der geschlossenen Vorhänge:\t{cover_pos_new}\r\nGerätestatusänderungen anzeigen:\t{display_devices_changed_notify}\r\nGeräteänderungen:\t{devices_add} neue Geräte hinzufügen, {devices_remove} Geräte entfernen\r\nKonvertierungsregeländerungen:\tInsgesamt {trans_rules_count} Regeln, aktualisiert {trans_rules_count_success} Regeln", + "description": "**{nick_name}**, bitte bestätigen Sie die neuesten Konfigurationsinformationen und klicken Sie dann auf \"Senden\". Die Integration wird mit den aktualisierten Konfigurationen erneut geladen.\r\n\r\nIntegrationsprache:\t{lang_new}\r\nBenutzername:\t{nick_name_new}\r\nAction-Debug-Modus:\t{action_debug}\r\nVerstecke Nicht-Standard-Entitäten:\t{hide_non_standard_entities}\r\nDie Breite des toten Winkels des Vorhangs:\t{cover_width_new}\r\nGerätestatusänderungen anzeigen:\t{display_devices_changed_notify}\r\nGeräteänderungen:\t{devices_add} neue Geräte hinzufügen, {devices_remove} Geräte entfernen\r\nKonvertierungsregeländerungen:\tInsgesamt {trans_rules_count} Regeln, aktualisiert {trans_rules_count_success} Regeln", "data": { "confirm": "Änderungen bestätigen" } diff --git a/custom_components/xiaomi_home/translations/en.json b/custom_components/xiaomi_home/translations/en.json index 82fc15b..55fa54b 100644 --- a/custom_components/xiaomi_home/translations/en.json +++ b/custom_components/xiaomi_home/translations/en.json @@ -125,7 +125,7 @@ "update_trans_rules": "Update entity conversion rules", "update_lan_ctrl_config": "Update LAN control configuration", "network_detect_config": "Integrated network configuration", - "cover_closed_position": "Cover closed position" + "cover_dead_zone_width": "Cover dead zone width" } }, "update_user_info": { @@ -184,7 +184,7 @@ }, "config_confirm": { "title": "Confirm Configuration", - "description": "Hello **{nick_name}**, please confirm the latest configuration information and then Click SUBMIT.\r\nThe integration will reload using the updated configuration.\r\n\r\nIntegration Language:\t{lang_new}\r\nNickname:\t{nick_name_new}\r\nDebug mode for action:\t{action_debug}\r\nHide non-standard created entities:\t{hide_non_standard_entities}\r\nCover closed position:\t{cover_pos_new}\r\nDisplay device status change notifications:\t{display_devices_changed_notify}\r\nDevice Changes:\tAdd **{devices_add}** devices, Remove **{devices_remove}** devices\r\nTransformation rules change:\tThere are a total of **{trans_rules_count}** rules, and updated **{trans_rules_count_success}** rules", + "description": "Hello **{nick_name}**, please confirm the latest configuration information and then Click SUBMIT.\r\nThe integration will reload using the updated configuration.\r\n\r\nIntegration Language:\t{lang_new}\r\nNickname:\t{nick_name_new}\r\nDebug mode for action:\t{action_debug}\r\nHide non-standard created entities:\t{hide_non_standard_entities}\r\nCover dead zone width:\t{cover_width_new}\r\nDisplay device status change notifications:\t{display_devices_changed_notify}\r\nDevice Changes:\tAdd **{devices_add}** devices, Remove **{devices_remove}** devices\r\nTransformation rules change:\tThere are a total of **{trans_rules_count}** rules, and updated **{trans_rules_count_success}** rules", "data": { "confirm": "Confirm the change" } diff --git a/custom_components/xiaomi_home/translations/es.json b/custom_components/xiaomi_home/translations/es.json index f03ac55..e3e64d0 100644 --- a/custom_components/xiaomi_home/translations/es.json +++ b/custom_components/xiaomi_home/translations/es.json @@ -125,7 +125,7 @@ "update_trans_rules": "Actualizar reglas de conversión de entidad", "update_lan_ctrl_config": "Actualizar configuración de control LAN", "network_detect_config": "Configuración de Red Integrada", - "cover_closed_position": "La posición de las cortinas cerradas" + "cover_dead_zone_width": "Anchura del punto ciego de la cortina" } }, "update_user_info": { @@ -184,7 +184,7 @@ }, "config_confirm": { "title": "Confirmar configuración", - "description": "¡Hola, **{nick_name}**! Por favor, confirme la última información de configuración y haga clic en \"Enviar\" para finalizar la configuración.\r\nLa integración se volverá a cargar con la nueva configuración.\r\n\r\nIdioma de la integración:\t{lang_new}\r\nApodo de usuario:\t{nick_name_new}\r\nModo de depuración de Action:\t{action_debug}\r\nOcultar entidades generadas no estándar:\t{hide_non_standard_entities}\r\nLa posición de las cortinas cerradas:\t{cover_pos_new}\r\nMostrar notificaciones de cambio de estado del dispositivo:\t{display_devices_changed_notify}\r\nCambios de dispositivos:\t{devices_add} dispositivos agregados, {devices_remove} dispositivos eliminados\r\nCambios en las reglas de conversión:\t{trans_rules_count} reglas en total, {trans_rules_count_success} reglas actualizadas", + "description": "¡Hola, **{nick_name}**! Por favor, confirme la última información de configuración y haga clic en \"Enviar\" para finalizar la configuración.\r\nLa integración se volverá a cargar con la nueva configuración.\r\n\r\nIdioma de la integración:\t{lang_new}\r\nApodo de usuario:\t{nick_name_new}\r\nModo de depuración de Action:\t{action_debug}\r\nOcultar entidades generadas no estándar:\t{hide_non_standard_entities}\r\nAnchura del punto ciego de la cortina:\t{cover_width_new}\r\nMostrar notificaciones de cambio de estado del dispositivo:\t{display_devices_changed_notify}\r\nCambios de dispositivos:\t{devices_add} dispositivos agregados, {devices_remove} dispositivos eliminados\r\nCambios en las reglas de conversión:\t{trans_rules_count} reglas en total, {trans_rules_count_success} reglas actualizadas", "data": { "confirm": "Confirmar modificación" } diff --git a/custom_components/xiaomi_home/translations/fr.json b/custom_components/xiaomi_home/translations/fr.json index 02675a2..270425c 100644 --- a/custom_components/xiaomi_home/translations/fr.json +++ b/custom_components/xiaomi_home/translations/fr.json @@ -125,7 +125,7 @@ "update_trans_rules": "Mettre à jour les règles de conversion d'entités", "update_lan_ctrl_config": "Mettre à jour la configuration de contrôle LAN", "network_detect_config": "Configuration Réseau Intégrée", - "cover_closed_position": "La position des rideaux fermés" + "cover_dead_zone_width": "Largeur de la zone aveugle du rideau" } }, "update_user_info": { @@ -184,7 +184,7 @@ }, "config_confirm": { "title": "Confirmer la configuration", - "description": "**{nick_name}** Bonjour ! Veuillez confirmer les dernières informations de configuration et cliquer sur \"Soumettre\".\r\nL'intégration rechargera avec la nouvelle configuration.\r\n\r\nLangue d'intégration : {lang_new}\r\nPseudo utilisateur : {nick_name_new}\r\nMode de débogage d'action : {action_debug}\r\nMasquer les entités générées non standard : {hide_non_standard_entities}\r\nLa position des rideaux fermés:\t{cover_pos_new}\r\nAfficher les notifications de changement d'état de l'appareil:\t{display_devices_changed_notify}\r\nModifications des appareils : Ajouter **{devices_add}** appareils, supprimer **{devices_remove}** appareils\r\nModifications des règles de conversion : **{trans_rules_count}** règles au total, mise à jour de **{trans_rules_count_success}** règles", + "description": "**{nick_name}** Bonjour ! Veuillez confirmer les dernières informations de configuration et cliquer sur \"Soumettre\".\r\nL'intégration rechargera avec la nouvelle configuration.\r\n\r\nLangue d'intégration : {lang_new}\r\nPseudo utilisateur : {nick_name_new}\r\nMode de débogage d'action : {action_debug}\r\nMasquer les entités générées non standard : {hide_non_standard_entities}\r\nLargeur de la zone aveugle du rideau:\t{cover_width_new}\r\nAfficher les notifications de changement d'état de l'appareil:\t{display_devices_changed_notify}\r\nModifications des appareils : Ajouter **{devices_add}** appareils, supprimer **{devices_remove}** appareils\r\nModifications des règles de conversion : **{trans_rules_count}** règles au total, mise à jour de **{trans_rules_count_success}** règles", "data": { "confirm": "Confirmer la modification" } diff --git a/custom_components/xiaomi_home/translations/it.json b/custom_components/xiaomi_home/translations/it.json index 4a06b58..e9308aa 100644 --- a/custom_components/xiaomi_home/translations/it.json +++ b/custom_components/xiaomi_home/translations/it.json @@ -125,7 +125,7 @@ "update_trans_rules": "Aggiorna le regole di conversione delle entità", "update_lan_ctrl_config": "Aggiorna configurazione del controllo LAN", "network_detect_config": "Configurazione di Rete Integrata", - "cover_closed_position": "La posizione delle tende chiuse" + "cover_dead_zone_width": "Larghezza dell’angolo cieco della tenda" } }, "update_user_info": { @@ -184,7 +184,7 @@ }, "config_confirm": { "title": "Conferma Configurazione", - "description": "Ciao **{nick_name}**, si prega di confermare le informazioni di configurazione più recenti e poi fare clic su INVIA.\r\nL'integrazione verrà ricaricata utilizzando la configurazione aggiornata.\r\n\r\nLingua dell'Integrazione:\t{lang_new}\r\nSoprannome:\t{nick_name_new}\r\nModalità di debug per azione:\t{action_debug}\r\nNascondi entità create non standard:\t{hide_non_standard_entities}\r\nLa posizione delle tende chiuse:\t{cover_pos_new}\r\nMostra notifiche di cambio stato del dispositivo:\t{display_devices_changed_notify}\r\nCambiamenti del Dispositivo:\tAggiungi **{devices_add}** dispositivi, Rimuovi **{devices_remove}** dispositivi\r\nCambiamenti delle regole di trasformazione:\tCi sono un totale di **{trans_rules_count}** regole, e aggiornate **{trans_rules_count_success}** regole", + "description": "Ciao **{nick_name}**, si prega di confermare le informazioni di configurazione più recenti e poi fare clic su INVIA.\r\nL'integrazione verrà ricaricata utilizzando la configurazione aggiornata.\r\n\r\nLingua dell'Integrazione:\t{lang_new}\r\nSoprannome:\t{nick_name_new}\r\nModalità di debug per azione:\t{action_debug}\r\nNascondi entità create non standard:\t{hide_non_standard_entities}\r\nLarghezza dell’angolo cieco della tenda:\t{cover_width_new}\r\nMostra notifiche di cambio stato del dispositivo:\t{display_devices_changed_notify}\r\nCambiamenti del Dispositivo:\tAggiungi **{devices_add}** dispositivi, Rimuovi **{devices_remove}** dispositivi\r\nCambiamenti delle regole di trasformazione:\tCi sono un totale di **{trans_rules_count}** regole, e aggiornate **{trans_rules_count_success}** regole", "data": { "confirm": "Conferma la modifica" } diff --git a/custom_components/xiaomi_home/translations/ja.json b/custom_components/xiaomi_home/translations/ja.json index ffa512e..bec2178 100644 --- a/custom_components/xiaomi_home/translations/ja.json +++ b/custom_components/xiaomi_home/translations/ja.json @@ -125,7 +125,7 @@ "update_trans_rules": "エンティティ変換ルールを更新する", "update_lan_ctrl_config": "LAN制御構成を更新する", "network_detect_config": "統合ネットワーク構成", - "cover_closed_position": "カーテンを閉じた位置" + "cover_dead_zone_width": "カーテンの死角幅" } }, "update_user_info": { @@ -184,7 +184,7 @@ }, "config_confirm": { "title": "構成を確認する", - "description": "**{nick_name}** さん、こんにちは! 最新の構成情報を確認してください。[送信] をクリックして、更新された構成を使用して再度読み込みます。\r\n\r\n統合言語:\t{lang_new}\r\nユーザー名:\t{nick_name_new}\r\nAction デバッグモード:\t{action_debug}\r\n非標準生成エンティティを非表示にする:\t{hide_non_standard_entities}\r\nカーテンを閉じた位置:\t{cover_pos_new}\r\nデバイスの状態変化通知を表示:\t{display_devices_changed_notify}\r\nデバイス変更:\t追加 **{devices_add}** 個のデバイス、削除 **{devices_remove}** 個のデバイス\r\n変換ルール変更:\t合計 **{trans_rules_count}** 個の規則、更新 **{trans_rules_count_success}** 個の規則", + "description": "**{nick_name}** さん、こんにちは! 最新の構成情報を確認してください。[送信] をクリックして、更新された構成を使用して再度読み込みます。\r\n\r\n統合言語:\t{lang_new}\r\nユーザー名:\t{nick_name_new}\r\nAction デバッグモード:\t{action_debug}\r\n非標準生成エンティティを非表示にする:\t{hide_non_standard_entities}\r\nカーテンの死角幅:\t{cover_width_new}\r\nデバイスの状態変化通知を表示:\t{display_devices_changed_notify}\r\nデバイス変更:\t追加 **{devices_add}** 個のデバイス、削除 **{devices_remove}** 個のデバイス\r\n変換ルール変更:\t合計 **{trans_rules_count}** 個の規則、更新 **{trans_rules_count_success}** 個の規則", "data": { "confirm": "変更を確認する" } diff --git a/custom_components/xiaomi_home/translations/nl.json b/custom_components/xiaomi_home/translations/nl.json index 125403f..966fd0a 100644 --- a/custom_components/xiaomi_home/translations/nl.json +++ b/custom_components/xiaomi_home/translations/nl.json @@ -125,7 +125,7 @@ "update_trans_rules": "Werk entiteitsconversieregels bij", "update_lan_ctrl_config": "Werk LAN controleconfiguratie bij", "network_detect_config": "Geïntegreerde Netwerkconfiguratie", - "cover_closed_position": "De positie van de gesloten gordijnen" + "cover_dead_zone_width": "Breedte van de dode hoek van het gordijn" } }, "update_user_info": { @@ -184,7 +184,7 @@ }, "config_confirm": { "title": "Bevestig Configuratie", - "description": "Hallo **{nick_name}**, bevestig alstublieft de nieuwste configuratie-informatie en klik vervolgens op INDENKEN.\r\nDe integratie zal opnieuw laden met de bijgewerkte configuratie.\r\n\r\nIntegratietaal:\t{lang_new}\r\nBijnaam:\t{nick_name_new}\r\nDebugmodus voor actie:\t{action_debug}\r\nVerberg niet-standaard gemaakte entiteiten:\t{hide_non_standard_entities}\r\nDe positie van de gesloten gordijnen:\t{cover_pos_new}\r\nApparaatstatuswijzigingen weergeven:\t{display_devices_changed_notify}\r\nWijzigingen in apparaten:\tVoeg **{devices_add}** apparaten toe, Verwijder **{devices_remove}** apparaten\r\nWijzigingen in transformateregels:\tEr zijn in totaal **{trans_rules_count}** regels, en **{trans_rules_count_success}** regels zijn bijgewerkt", + "description": "Hallo **{nick_name}**, bevestig alstublieft de nieuwste configuratie-informatie en klik vervolgens op INDENKEN.\r\nDe integratie zal opnieuw laden met de bijgewerkte configuratie.\r\n\r\nIntegratietaal:\t{lang_new}\r\nBijnaam:\t{nick_name_new}\r\nDebugmodus voor actie:\t{action_debug}\r\nVerberg niet-standaard gemaakte entiteiten:\t{hide_non_standard_entities}\r\nBreedte van de dode hoek van het gordijn:\t{cover_width_new}\r\nApparaatstatuswijzigingen weergeven:\t{display_devices_changed_notify}\r\nWijzigingen in apparaten:\tVoeg **{devices_add}** apparaten toe, Verwijder **{devices_remove}** apparaten\r\nWijzigingen in transformateregels:\tEr zijn in totaal **{trans_rules_count}** regels, en **{trans_rules_count_success}** regels zijn bijgewerkt", "data": { "confirm": "Bevestig de wijziging" } diff --git a/custom_components/xiaomi_home/translations/pt-BR.json b/custom_components/xiaomi_home/translations/pt-BR.json index a383b8b..542e464 100644 --- a/custom_components/xiaomi_home/translations/pt-BR.json +++ b/custom_components/xiaomi_home/translations/pt-BR.json @@ -125,7 +125,7 @@ "update_trans_rules": "Atualizar regras de conversão de entidades", "update_lan_ctrl_config": "Atualizar configuração de controle LAN", "network_detect_config": "Configuração de Rede Integrada", - "cover_closed_position": "A posição das cortinas fechadas" + "cover_dead_zone_width": "Largura da área cega da cortina" } }, "update_user_info": { @@ -184,7 +184,7 @@ }, "config_confirm": { "title": "Confirmar Configuração", - "description": "Olá **{nick_name}**, confirme as informações da configuração mais recente e depois clique em ENVIAR.\r\nA integração será recarregada com a configuração atualizada.\r\n\r\nIdioma da Integração:\t{lang_new}\r\nApelido:\t{nick_name_new}\r\nModo de depuração para ação:\t{action_debug}\r\nOcultar entidades não padrão criadas:\t{hide_non_standard_entities}\r\nA posição das cortinas fechadas:\t{cover_pos_new}\r\nExibir notificações de mudança de status do dispositivo:\t{display_devices_changed_notify}\r\nAlterações de Dispositivos:\tAdicionar **{devices_add}** dispositivos, Remover **{devices_remove}** dispositivos\r\nAlteração nas Regras de Transformação:\tUm total de **{trans_rules_count}** regras, e **{trans_rules_count_success}** regras atualizadas", + "description": "Olá **{nick_name}**, confirme as informações da configuração mais recente e depois clique em ENVIAR.\r\nA integração será recarregada com a configuração atualizada.\r\n\r\nIdioma da Integração:\t{lang_new}\r\nApelido:\t{nick_name_new}\r\nModo de depuração para ação:\t{action_debug}\r\nOcultar entidades não padrão criadas:\t{hide_non_standard_entities}\r\nLargura da área cega da cortina:\t{cover_width_new}\r\nExibir notificações de mudança de status do dispositivo:\t{display_devices_changed_notify}\r\nAlterações de Dispositivos:\tAdicionar **{devices_add}** dispositivos, Remover **{devices_remove}** dispositivos\r\nAlteração nas Regras de Transformação:\tUm total de **{trans_rules_count}** regras, e **{trans_rules_count_success}** regras atualizadas", "data": { "confirm": "Confirmar a mudança" } diff --git a/custom_components/xiaomi_home/translations/pt.json b/custom_components/xiaomi_home/translations/pt.json index d747658..2e6fe14 100644 --- a/custom_components/xiaomi_home/translations/pt.json +++ b/custom_components/xiaomi_home/translations/pt.json @@ -125,7 +125,7 @@ "update_trans_rules": "Atualizar regras de conversão de entidades", "update_lan_ctrl_config": "Atualizar configuração de controlo LAN", "network_detect_config": "Configuração de Rede Integrada", - "cover_closed_position": "A posição das cortinas fechadas" + "cover_dead_zone_width": "Largura da zona cega da cortina" } }, "update_user_info": { @@ -184,7 +184,7 @@ }, "config_confirm": { "title": "Confirmar Configuração", - "description": "Olá **{nick_name}**, confirme a informação da configuração mais recente e depois clique em SUBMETER.\r\nA integração será recarregada com a configuração atualizada.\r\n\r\nIdioma da Integração:\t{lang_new}\r\nAlcunha:\t{nick_name_new}\r\nModo de depuração de ação:\t{action_debug}\r\nOcultar entidades não padrão:\t{hide_non_standard_entities}\r\nA posição das cortinas fechadas:\t{cover_pos_new}\r\nExibir notificações de mudança de status do dispositivo:\t{display_devices_changed_notify}\r\nAlterações aos Dispositivos:\tAdicionar **{devices_add}** dispositivos, Remover **{devices_remove}** dispositivos\r\nAlteração das Regras de Transformação:\tExistem **{trans_rules_count}** regras no total, com **{trans_rules_count_success}** regras atualizadas", + "description": "Olá **{nick_name}**, confirme a informação da configuração mais recente e depois clique em SUBMETER.\r\nA integração será recarregada com a configuração atualizada.\r\n\r\nIdioma da Integração:\t{lang_new}\r\nAlcunha:\t{nick_name_new}\r\nModo de depuração de ação:\t{action_debug}\r\nOcultar entidades não padrão:\t{hide_non_standard_entities}\r\nLargura da zona cega da cortina:\t{cover_width_new}\r\nExibir notificações de mudança de status do dispositivo:\t{display_devices_changed_notify}\r\nAlterações aos Dispositivos:\tAdicionar **{devices_add}** dispositivos, Remover **{devices_remove}** dispositivos\r\nAlteração das Regras de Transformação:\tExistem **{trans_rules_count}** regras no total, com **{trans_rules_count_success}** regras atualizadas", "data": { "confirm": "Confirmar a alteração" } diff --git a/custom_components/xiaomi_home/translations/ru.json b/custom_components/xiaomi_home/translations/ru.json index 09bbcd5..1fa5df7 100644 --- a/custom_components/xiaomi_home/translations/ru.json +++ b/custom_components/xiaomi_home/translations/ru.json @@ -125,7 +125,7 @@ "update_trans_rules": "Обновить правила преобразования сущностей", "update_lan_ctrl_config": "Обновить конфигурацию управления LAN", "network_detect_config": "Интегрированная Сетевая Конфигурация", - "cover_closed_position": "Положение закрытых штор" + "cover_dead_zone_width": "Ширина «мертвой зоны» шторы" } }, "update_user_info": { @@ -184,7 +184,7 @@ }, "config_confirm": { "title": "Подтверждение настройки", - "description": "**{nick_name}** Здравствуйте! Подтвердите последнюю информацию о настройке и нажмите «Отправить». Интеграция будет перезагружена с использованием обновленных настроек.\r\n\r\nЯзык интеграции:\t{lang_new}\r\nИмя пользователя:\t{nick_name_new}\r\nРежим отладки Action:\t{action_debug}\r\nСкрыть непроизводственные сущности:\t{hide_non_standard_entities}\r\nПоложение закрытых штор:\t{cover_pos_new}\r\nОтображать уведомления о изменении состояния устройства:\t{display_devices_changed_notify}\r\nИзменение устройства:\tДобавлено **{devices_add}** устройство, удалено **{devices_remove}** устройства\r\nИзменение правил преобразования:\tВсего **{trans_rules_count}** правил, обновлено **{trans_rules_count_success}** правил", + "description": "**{nick_name}** Здравствуйте! Подтвердите последнюю информацию о настройке и нажмите «Отправить». Интеграция будет перезагружена с использованием обновленных настроек.\r\n\r\nЯзык интеграции:\t{lang_new}\r\nИмя пользователя:\t{nick_name_new}\r\nРежим отладки Action:\t{action_debug}\r\nСкрыть непроизводственные сущности:\t{hide_non_standard_entities}\r\nШирина «мертвой зоны» шторы:\t{cover_width_new}\r\nОтображать уведомления о изменении состояния устройства:\t{display_devices_changed_notify}\r\nИзменение устройства:\tДобавлено **{devices_add}** устройство, удалено **{devices_remove}** устройства\r\nИзменение правил преобразования:\tВсего **{trans_rules_count}** правил, обновлено **{trans_rules_count_success}** правил", "data": { "confirm": "Подтвердить изменения" } diff --git a/custom_components/xiaomi_home/translations/zh-Hans.json b/custom_components/xiaomi_home/translations/zh-Hans.json index 328f62c..fd65e69 100644 --- a/custom_components/xiaomi_home/translations/zh-Hans.json +++ b/custom_components/xiaomi_home/translations/zh-Hans.json @@ -125,7 +125,7 @@ "update_trans_rules": "更新实体转换规则", "update_lan_ctrl_config": "更新局域网控制配置", "network_detect_config": "集成网络配置", - "cover_closed_position": "窗帘关闭位置" + "cover_dead_zone_width": "窗帘盲区宽度" } }, "update_user_info": { @@ -184,7 +184,7 @@ }, "config_confirm": { "title": "确认配置", - "description": "**{nick_name}** 您好!请确认最新的配置信息,然后点击“提交”。\r\n集成将会使用更新后的配置重新载入。\r\n\r\n集成语言:\t{lang_new}\r\n用户昵称:\t{nick_name_new}\r\nAction 调试模式:\t{action_debug}\r\n隐藏非标准生成实体:\t{hide_non_standard_entities}\r\n窗帘关闭位置:\t{cover_pos_new}\r\n显示设备状态变化通知:\t{display_devices_changed_notify}\r\n设备变化:\t新增 **{devices_add}** 个设备,移除 **{devices_remove}** 个设备\r\n转换规则变化:\t共条 **{trans_rules_count}** 规则,更新 **{trans_rules_count_success}** 条规则", + "description": "**{nick_name}** 您好!请确认最新的配置信息,然后点击“提交”。\r\n集成将会使用更新后的配置重新载入。\r\n\r\n集成语言:\t{lang_new}\r\n用户昵称:\t{nick_name_new}\r\nAction 调试模式:\t{action_debug}\r\n隐藏非标准生成实体:\t{hide_non_standard_entities}\r\n窗帘盲区宽度:\t{cover_width_new}\r\n显示设备状态变化通知:\t{display_devices_changed_notify}\r\n设备变化:\t新增 **{devices_add}** 个设备,移除 **{devices_remove}** 个设备\r\n转换规则变化:\t共条 **{trans_rules_count}** 规则,更新 **{trans_rules_count_success}** 条规则", "data": { "confirm": "确认修改" } diff --git a/custom_components/xiaomi_home/translations/zh-Hant.json b/custom_components/xiaomi_home/translations/zh-Hant.json index e2997a7..5f0cc07 100644 --- a/custom_components/xiaomi_home/translations/zh-Hant.json +++ b/custom_components/xiaomi_home/translations/zh-Hant.json @@ -125,7 +125,7 @@ "update_trans_rules": "更新實體轉換規則", "update_lan_ctrl_config": "更新局域網控制配置", "network_detect_config": "集成網絡配置", - "cover_closed_position": "窗簾關閉位置" + "cover_dead_zone_width": "窗簾盲區寬度" } }, "update_user_info": { @@ -184,7 +184,7 @@ }, "config_confirm": { "title": "確認配置", - "description": "**{nick_name}** 您好!請確認最新的配置信息,然後點擊“提交”。\r\n集成將會使用更新後的配置重新載入。\r\n\r\n集成語言:\t{lang_new}\r\n用戶暱稱:\t{nick_name_new}\r\nAction 調試模式:\t{action_debug}\r\n隱藏非標準生成實體:\t{hide_non_standard_entities}\r\n窗簾關閉位置:\t{cover_pos_new}\r\n顯示設備狀態變化通知:\t{display_devices_changed_notify}\r\n設備變化:\t新增 **{devices_add}** 個設備,移除 **{devices_remove}** 個設備\r\n轉換規則變化:\t共條 **{trans_rules_count}** 規則,更新 **{trans_rules_count_success}** 條規則", + "description": "**{nick_name}** 您好!請確認最新的配置信息,然後點擊“提交”。\r\n集成將會使用更新後的配置重新載入。\r\n\r\n集成語言:\t{lang_new}\r\n用戶暱稱:\t{nick_name_new}\r\nAction 調試模式:\t{action_debug}\r\n隱藏非標準生成實體:\t{hide_non_standard_entities}\r\n窗簾盲區寬度:\t{cover_width_new}\r\n顯示設備狀態變化通知:\t{display_devices_changed_notify}\r\n設備變化:\t新增 **{devices_add}** 個設備,移除 **{devices_remove}** 個設備\r\n轉換規則變化:\t共條 **{trans_rules_count}** 規則,更新 **{trans_rules_count_success}** 條規則", "data": { "confirm": "確認修改" } From dae63657d7ea64d2879272d3ba64e6acb746d952 Mon Sep 17 00:00:00 2001 From: Li Shuzhen Date: Wed, 30 Jul 2025 15:14:20 +0800 Subject: [PATCH 2/6] fix: vacuum status (#1299) * fix: vacuum status (#1283) * fix: vacuum continue to sweep * refactor: core warnings about vacuum activity (#1288) --- custom_components/xiaomi_home/vacuum.py | 145 ++++++++++++++---------- 1 file changed, 83 insertions(+), 62 deletions(-) diff --git a/custom_components/xiaomi_home/vacuum.py b/custom_components/xiaomi_home/vacuum.py index 9582b6a..3957f86 100644 --- a/custom_components/xiaomi_home/vacuum.py +++ b/custom_components/xiaomi_home/vacuum.py @@ -60,6 +60,12 @@ from .miot.const import DOMAIN from .miot.miot_device import MIoTDevice, MIoTServiceEntity, MIoTEntityData from .miot.miot_spec import (MIoTSpecAction, MIoTSpecProperty) +try: # VacuumActivity is introduced in HA core 2025.1.0 + from homeassistant.components.vacuum import VacuumActivity + HA_CORE_HAS_ACTIVITY = True +except ImportError: + HA_CORE_HAS_ACTIVITY = False + _LOGGER = logging.getLogger(__name__) @@ -85,6 +91,11 @@ class Vacuum(MIoTServiceEntity, StateVacuumEntity): _prop_status: Optional[MIoTSpecProperty] _prop_fan_level: Optional[MIoTSpecProperty] _prop_battery_level: Optional[MIoTSpecProperty] + _prop_status_cleaning: Optional[list[int]] + _prop_status_docked: Optional[list[int]] + _prop_status_paused: Optional[list[int]] + _prop_status_returning: Optional[list[int]] + _prop_status_error: Optional[list[int]] _action_start_sweep: Optional[MIoTSpecAction] _action_stop_sweeping: Optional[MIoTSpecAction] @@ -107,6 +118,11 @@ class Vacuum(MIoTServiceEntity, StateVacuumEntity): self._prop_status = None self._prop_fan_level = None self._prop_battery_level = None + self._prop_status_cleaning = [] + self._prop_status_docked = [] + self._prop_status_paused = [] + self._prop_status_returning = [] + self._prop_status_error = [] self._action_start_sweep = None self._action_stop_sweeping = None self._action_pause_sweeping = None @@ -126,6 +142,35 @@ class Vacuum(MIoTServiceEntity, StateVacuumEntity): self._status_map = prop.value_list.to_map() self._attr_supported_features |= VacuumEntityFeature.STATE self._prop_status = prop + for item in prop.value_list.items: + item_str: str = item.name + item_name: str = re.sub(r'[^a-z]', '', item_str) + if item_name in { + 'charging', 'charged', 'chargingcompleted', + 'fullcharge', 'fullpower', 'findchargerpause', + 'drying', 'washing', 'wash', 'inthewash', + 'inthedry', 'stationworking', 'dustcollecting', + 'upgrade', 'upgrading', 'updating' + }: + self._prop_status_docked.append(item.value) + elif item_name in {'paused', 'pause'}: + self._prop_status_paused.append(item.value) + elif item_name in { + 'gocharging', 'cleancompletegocharging', + 'findchargewash', 'backtowashmop', 'gowash', + 'gowashing', 'summon' + }: + self._prop_status_returning.append(item.value) + elif item_name in { + 'error', 'breakcharging', 'gochargebreak' + }: + self._prop_status_error.append(item.value) + elif (item_name.find('sweeping') != -1) or ( + item_name.find('mopping') != -1) or (item_name in { + 'cleaning', 'remoteclean', 'continuesweep', + 'busy', 'building', 'buildingmap', 'mapping' + }): + self._prop_status_cleaning.append(item.value) elif prop.name == 'fan-level': if not prop.value_list: _LOGGER.error('invalid fan-level value_list, %s', @@ -160,16 +205,10 @@ class Vacuum(MIoTServiceEntity, StateVacuumEntity): async def async_start(self) -> None: """Start or resume the cleaning task.""" - try: # VacuumActivity is introduced in HA core 2025.1.0 - # pylint: disable=import-outside-toplevel - from homeassistant.components.vacuum import VacuumActivity - if (self.activity - == VacuumActivity.PAUSED) and self._action_continue_sweep: - await self.action_async(action=self._action_continue_sweep) - return - except ImportError: - if self.state and (self.state in {'paused', 'pause' - }) and self._action_continue_sweep: + if self._prop_status is not None: + status = self.get_prop_value(prop=self._prop_status) + if (status in self._prop_status_paused + ) and self._action_continue_sweep: await self.action_async(action=self._action_continue_sweep) return await self.action_async(action=self._action_start_sweep) @@ -203,9 +242,22 @@ class Vacuum(MIoTServiceEntity, StateVacuumEntity): return self._device_name @property - def state(self) -> Optional[str]: - """Return the current state of the vacuum cleaner. + def battery_level(self) -> Optional[int]: + """The current battery level of the vacuum cleaner.""" + return self.get_prop_value(prop=self._prop_battery_level) + @property + def fan_speed(self) -> Optional[str]: + """The current fan speed of the vacuum cleaner.""" + return self.get_map_value( + map_=self._fan_level_map, + key=self.get_prop_value(prop=self._prop_fan_level)) + + if HA_CORE_HAS_ACTIVITY: + + @property + def activity(self) -> Optional[str]: + """The current vacuum activity. To fix the HA warning below: Detected that custom integration 'xiaomi_home' is setting state directly.Entity XXX( Optional[str]: - """The current vacuum activity.""" - status = self.get_prop_value(prop=self._prop_status) - if status is None: - return None - status_value = self.get_map_value(map_=self._status_map, key=status) - if status_value is None: - return None - try: - # pylint: disable=import-outside-toplevel - from homeassistant.components.vacuum import VacuumActivity - status_value = status_value.lower() - status_str = re.sub(r'[^a-z]', '', status_value) - if status_str in { - 'charging', 'charged', 'chargingcompleted', 'fullcharge', - 'fullpower', 'findchargerpause', 'drying', 'washing', - 'wash', 'inthewash', 'inthedry', 'stationworking', - 'dustcollecting', 'upgrade', 'upgrading', 'updating' - }: - return VacuumActivity.DOCKED - if status_str in {'paused', 'pause'}: - return VacuumActivity.PAUSED - if status_str in { - 'gocharging', 'cleancompletegocharging', 'findchargewash', - 'backtowashmop', 'gowash', 'gowashing', 'summon' - }: - return VacuumActivity.RETURNING - if (status_str.find('sweeping') - != -1) or (status_str.find('mopping') - != -1) or (status_str in { - 'cleaning', 'remoteclean', 'continuesweep', - 'busy', 'building', 'buildingmap', 'mapping' - }): + """ + status = self.get_prop_value(prop=self._prop_status) + if status is None: + return None + if status in self._prop_status_cleaning: return VacuumActivity.CLEANING - if status_str in {'error', 'breakcharging', 'gochargebreak'}: + if status in self._prop_status_docked: + return VacuumActivity.DOCKED + if status in self._prop_status_paused: + return VacuumActivity.PAUSED + if status in self._prop_status_returning: + return VacuumActivity.RETURNING + if status in self._prop_status_error: return VacuumActivity.ERROR return VacuumActivity.IDLE - except ImportError: - return status_value - @property - def battery_level(self) -> Optional[int]: - """The current battery level of the vacuum cleaner.""" - return self.get_prop_value(prop=self._prop_battery_level) + else: - @property - def fan_speed(self) -> Optional[str]: - """The current fan speed of the vacuum cleaner.""" - return self.get_map_value( - map_=self._fan_level_map, - key=self.get_prop_value(prop=self._prop_fan_level)) + @property + def state(self) -> Optional[str]: + """The current state of the vacuum.""" + status = self.get_prop_value(prop=self._prop_status) + return None if (status is None) else self.get_map_value( + map_=self._status_map, key=status) From f3abbef94cfdf9cb4af66cb47114e8de96357384 Mon Sep 17 00:00:00 2001 From: Li Shuzhen Date: Wed, 30 Jul 2025 15:15:28 +0800 Subject: [PATCH 3/6] fix: set the device on when the switch status is False or None (#1303) * fix: set the air conditioner on if its switch status property is False or None (#1277) * feat: add a standalone switch for 090615.aircondition.ktf * fix: add an alongside switch for juhl.aircondition.hvac (#1287) --- custom_components/xiaomi_home/climate.py | 2 +- .../xiaomi_home/miot/specs/spec_add.json | 38 +++++++++++++++++++ custom_components/xiaomi_home/water_heater.py | 2 +- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/custom_components/xiaomi_home/climate.py b/custom_components/xiaomi_home/climate.py index 5259de5..9d872e3 100644 --- a/custom_components/xiaomi_home/climate.py +++ b/custom_components/xiaomi_home/climate.py @@ -546,7 +546,7 @@ class AirConditioner(FeatureOnOff, FeatureTargetTemperature, f'{self.entity_id}') return # set the device on - if self.get_prop_value(prop=self._prop_on) is False: + if self.get_prop_value(prop=self._prop_on) is not True: await self.set_property_async(prop=self._prop_on, value=True, write_ha_state=False) diff --git a/custom_components/xiaomi_home/miot/specs/spec_add.json b/custom_components/xiaomi_home/miot/specs/spec_add.json index 8d14aec..2a5bba3 100644 --- a/custom_components/xiaomi_home/miot/specs/spec_add.json +++ b/custom_components/xiaomi_home/miot/specs/spec_add.json @@ -1,5 +1,23 @@ { "urn:miot-spec-v2:device:air-conditioner:0000A004:090615-ktf:1": [ + { + "iid": 2, + "type": "urn:miot-spec-v2:service:switch:0000780C:090615-ktf:1", + "description": "AC Switch", + "properties": [ + { + "iid": 1, + "type": "urn:miot-spec-v2:property:on:00000006:090615-ktf:1", + "description": "Switch Status", + "format": "bool", + "access": [ + "read", + "write", + "notify" + ] + } + ] + }, { "iid": 4, "type": "urn:miot-spec-v2:service:environment:0000780A:090615-ktf:1", @@ -24,6 +42,26 @@ ] } ], + "urn:miot-spec-v2:device:air-conditioner:0000A004:juhl-hvac:1": [ + { + "iid": 2, + "type": "urn:miot-spec-v2:service:switch:0000780C:juhl-hvac:1", + "description": "AC Switch", + "properties": [ + { + "iid": 1, + "type": "urn:miot-spec-v2:property:on:00000006:juhl-hvac:1", + "description": "Switch Status", + "format": "bool", + "access": [ + "read", + "write", + "notify" + ] + } + ] + } + ], "urn:miot-spec-v2:device:airer:0000A00D:hyd-lyjpro:1": [ { "iid": 3, diff --git a/custom_components/xiaomi_home/water_heater.py b/custom_components/xiaomi_home/water_heater.py index e28e8ff..7f8f402 100644 --- a/custom_components/xiaomi_home/water_heater.py +++ b/custom_components/xiaomi_home/water_heater.py @@ -168,7 +168,7 @@ class WaterHeater(MIoTServiceEntity, WaterHeaterEntity): if operation_mode == STATE_ON: await self.set_property_async(prop=self._prop_on, value=True) return - if self.get_prop_value(prop=self._prop_on) is False: + if self.get_prop_value(prop=self._prop_on) is not True: await self.set_property_async(prop=self._prop_on, value=True, write_ha_state=False) From f11b2f2f6828a4aa44f3487b68612cfc8c38491a Mon Sep 17 00:00:00 2001 From: Li Shuzhen Date: Fri, 1 Aug 2025 14:54:33 +0800 Subject: [PATCH 4/6] fix: hide sensitive info in printing logs (#1328) --- custom_components/xiaomi_home/miot/miot_client.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/custom_components/xiaomi_home/miot/miot_client.py b/custom_components/xiaomi_home/miot/miot_client.py index c48d058..f8f3141 100644 --- a/custom_components/xiaomi_home/miot/miot_client.py +++ b/custom_components/xiaomi_home/miot/miot_client.py @@ -253,7 +253,18 @@ class MIoTClient: if not self._user_config: # Integration need to be add again raise MIoTClientError('load_user_config_async error') - _LOGGER.debug('user config, %s', json.dumps(self._user_config)) + # Hide sensitive info in printing + p_user_config: dict = deepcopy(self._user_config) + p_access_token: str = p_user_config['auth_info']['access_token'] + p_refresh_token: str = p_user_config['auth_info']['refresh_token'] + p_mac_key: str = p_user_config['auth_info']['mac_key'] + p_user_config['auth_info'][ + 'access_token'] = f"{p_access_token[:5]}***{p_access_token[-5:]}" + p_user_config['auth_info'][ + 'refresh_token'] = f"{p_refresh_token[:5]}***{p_refresh_token[-5:]}" + p_user_config['auth_info'][ + 'mac_key'] = f"{p_mac_key[:5]}***{p_mac_key[-5:]}" + _LOGGER.debug('user config, %s', json.dumps(p_user_config)) # MIoT i18n client self._i18n = MIoTI18n( lang=self._entry_data.get( From 3f2c2a648bb58593e2e363e7a25a729ba3a0a743 Mon Sep 17 00:00:00 2001 From: Li Shuzhen Date: Fri, 1 Aug 2025 14:56:42 +0800 Subject: [PATCH 5/6] Fix specs (#1329) * fix: cuco.plug.cp2d electric current (#1279) * fix: xiaomi.fan.p45 fan level (#1291) * docs: add necessary notices * fix: xiaomi.aircondition.c17 humidity-range unit (#1308) * fix: xiaomi.airc.h40h00 humidity-range unit * fix: sanmei.valve.s1 power consumption, current and voltage (#1327) * fix: xiaomi.aircondition.m16 humidity-range unit --- .github/ISSUE_TEMPLATE/bug_report.yaml | 4 +-- .../xiaomi_home/miot/specs/spec_modify.yaml | 30 +++++++++++++++++-- doc/README_zh.md | 2 +- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml index 1fca160..4be50f8 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yaml +++ b/.github/ISSUE_TEMPLATE/bug_report.yaml @@ -5,8 +5,8 @@ body: attributes: label: Describe the Bug / 描述问题 description: | - > A clear and concise description of what the bug is. - > 清晰且简明地描述问题。 + > A clear and concise description of what the bug is. Please include the device model information (Like xiaomi.gateway.hub1 which can be found in Device info page). + > 清晰且简明地描述问题。请注明设备 model 信息(例如 xiaomi.gateway.hub1,可在设备详情页查询)。 validations: required: true diff --git a/custom_components/xiaomi_home/miot/specs/spec_modify.yaml b/custom_components/xiaomi_home/miot/specs/spec_modify.yaml index 16fbb56..183879a 100644 --- a/custom_components/xiaomi_home/miot/specs/spec_modify.yaml +++ b/custom_components/xiaomi_home/miot/specs/spec_modify.yaml @@ -1,6 +1,10 @@ urn:miot-spec-v2:device:air-condition-outlet:0000A045:lumi-mcn04:1: prop.3.4: format: uint8 +urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c17:1: + prop.10.6: + unit: none +urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c17:2: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c17:1 urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c20:1: prop.10.6: unit: none @@ -15,6 +19,15 @@ urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c35:1: prop.10.6: unit: none urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c35:2: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-c35:1 +urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-h40h00:1: + prop.10.6: + unit: none +urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m16:1: + prop.10.6: + unit: none +urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m16:2: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m16:1 +urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m16:3: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m16:1 +urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m16:4: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m16:1 urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:1: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:6 urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:2: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:6 urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:3: urn:miot-spec-v2:device:air-conditioner:0000A004:xiaomi-m9:6 @@ -86,6 +99,13 @@ urn:miot-spec-v2:device:bath-heater:0000A028:xiaomi-s1:1: urn:miot-spec-v2:device:curtain:0000A00C:bjkcz-kczble:1:0000D031: prop.2.2: name: status-a +urn:miot-spec-v2:device:electronic-valve:0000A0A7:sanmei-s1:1: + prop.3.1: + expr: round(src_value/100, 2) + prop.3.2: + expr: round(src_value/100, 2) + prop.3.3: + expr: round(src_value/10, 1) urn:miot-spec-v2:device:fan:0000A005:dmaker-p33:1: prop.2.2: name: fan-level-a @@ -101,6 +121,9 @@ urn:miot-spec-v2:device:fan:0000A005:dmaker-p5:1: urn:miot-spec-v2:device:fan:0000A005:xiaomi-p43:1: prop.2.2: name: fan-level-a +urn:miot-spec-v2:device:fan:0000A005:xiaomi-p45:1:0000D062: + prop.2.4: + name: fan-level-a urn:miot-spec-v2:device:fan:0000A005:xiaomi-p51:1: prop.2.2: name: fan-level-a @@ -172,7 +195,7 @@ urn:miot-spec-v2:device:magnet-sensor:0000A016:linp-m1:1: description: open - value: 1 description: closed - expr: src_value!=1 + expr: (src_value!=1) urn:miot-spec-v2:device:motion-sensor:0000A014:lumi-acn001:1: prop.3.2: access: @@ -213,6 +236,9 @@ urn:miot-spec-v2:device:outlet:0000A002:cuco-cp2:2: unit: mA prop.3.2: expr: round(src_value/10, 1) +urn:miot-spec-v2:device:outlet:0000A002:cuco-cp2d:1: + prop.3.2: + expr: round(src_value/1000, 2) urn:miot-spec-v2:device:outlet:0000A002:cuco-v3:1: prop.11.1: name: power-consumption @@ -257,7 +283,7 @@ urn:miot-spec-v2:device:router:0000A036:xiaomi-rd08:1: urn:miot-spec-v2:device:safe-box:0000A042:loock-v1:1: prop.5.1: name: contact-state - expr: src_value!=1 + expr: (src_value!=1) urn:miot-spec-v2:device:switch:0000A003:090615-x1tpm:1:0000D042: prop.27.3: name: light-on diff --git a/doc/README_zh.md b/doc/README_zh.md index 2895984..cb76272 100644 --- a/doc/README_zh.md +++ b/doc/README_zh.md @@ -93,7 +93,7 @@ git checkout v1.0.0 - 米家集成是否支持本地化控制? - 米家集成支持通过[小米中枢网关](https://www.mi.com/shop/buy/detail?product_id=15755&cfrom=search)(固件版本 3.4.0_000 以上)或内置中枢网关(软件版本 0.8.0 以上)的米家设备实现本地化控制。如果没有小米中枢网关或其他带中枢网关功能的设备,那么所有控制指令都会通过小米云发送。支持 Home Assistant 本地化控制的小米中枢网关(含内置中枢网关)的固件尚未发布,固件升级计划请参阅 MIoT 团队的通知。 + 米家集成支持通过[小米中枢网关](https://www.mi.com/shop/buy/detail?product_id=15755&cfrom=search)(固件版本 3.3.0_0023 及以上)或内置中枢网关(软件版本 0.8.9 及以上)的米家设备实现本地化控制。如果没有小米中枢网关或其他带中枢网关功能的设备,那么所有控制指令都会通过小米云发送。支持 Home Assistant 本地化控制的小米中枢网关(含内置中枢网关)的固件尚未发布,固件升级计划请参阅 MIoT 团队的通知。 小米中枢网关仅在中国大陆可用,在其他地区不可用。 From 7c97b85f02c96ca72ac763538c3d6f7f3a3615ca Mon Sep 17 00:00:00 2001 From: Li Shuzhen Date: Mon, 4 Aug 2025 09:44:12 +0800 Subject: [PATCH 6/6] docs: update changelog and version to v0.4.1 (#1336) --- CHANGELOG.md | 10 ++++++++++ custom_components/xiaomi_home/manifest.json | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9af7631..75c7caf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,14 @@ # CHANGELOG +## v0.4.1 +### Changed +- The setting option "Cover closed position" in CONFIGURE is changed to "Cover dead zone width". [#1301](https://github.com/XiaoMi/ha_xiaomi_home/pull/1301) +- Add an alongside switch entity for 090615.aircondition.ktf and juhl.aircondition.hvac. [#1303](https://github.com/XiaoMi/ha_xiaomi_home/pull/1303) +### Fixed +- Fix the vacuum status so that the vacuum activity will not always be idle. [#1299](https://github.com/XiaoMi/ha_xiaomi_home/pull/1299) +- Set the device on when the switch status is False or None. [#1303](https://github.com/XiaoMi/ha_xiaomi_home/pull/1303) +- Hide sensitive info in printing logs. [#1328](https://github.com/XiaoMi/ha_xiaomi_home/pull/1328) +- Fix the MIoT-Spec-V2 of cuco.plug.cp2d electric current, xiaomi.fan.p45 fan level, sanmei.valve.s1 power consumption, current and voltage, xiaomi.aircondition.c17, xiaomi.aircondition.m16 and xiaomi.airc.h40h00 humidity-range unit. [#1329](https://github.com/XiaoMi/ha_xiaomi_home/pull/1329) + ## v0.4.0 ### Added - Add the watch as the device tracker entity. [#1189](https://github.com/XiaoMi/ha_xiaomi_home/pull/1189) diff --git a/custom_components/xiaomi_home/manifest.json b/custom_components/xiaomi_home/manifest.json index a313a36..e444e30 100644 --- a/custom_components/xiaomi_home/manifest.json +++ b/custom_components/xiaomi_home/manifest.json @@ -25,7 +25,7 @@ "cryptography", "psutil" ], - "version": "v0.4.0", + "version": "v0.4.1", "zeroconf": [ "_miot-central._tcp.local." ]