diff --git a/custom_components/hilo/__init__.py b/custom_components/hilo/__init__.py index a93e68db..99c3d229 100644 --- a/custom_components/hilo/__init__.py +++ b/custom_components/hilo/__init__.py @@ -326,6 +326,14 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except asyncio.CancelledError: pass + for task in list(hilo.subscriptions): + if task and not task.done(): + task.cancel() + try: + await task + except asyncio.CancelledError: + pass + try: await hilo._api.signalr_devices.disconnect() except Exception as err: @@ -337,14 +345,6 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) if unload_ok: - try: - if hasattr(hilo, "_api") and hilo._api and hasattr(hilo._api, "session"): - if hilo._api.session and not hilo._api.session.closed: - await hilo._api.session.close() - LOG.debug("Session closed") - except Exception as err: - LOG.error("Error closing session: %s", err) - LOG.debug("Hilo Integration unloaded") hass.data[DOMAIN].pop(entry.entry_id) @@ -951,7 +951,7 @@ class Hilo: async def async_update(self) -> None: """Update tarif periodically.""" - if self.generate_energy_meters or self.track_unknown_sources: + if self.generate_energy_meters: self.check_tarif() if self.track_unknown_sources: diff --git a/custom_components/hilo/manifest.json b/custom_components/hilo/manifest.json index b9d2c7f8..2d73487b 100644 --- a/custom_components/hilo/manifest.json +++ b/custom_components/hilo/manifest.json @@ -11,6 +11,6 @@ "documentation": "https://github.com/dvd-dev/hilo", "iot_class": "cloud_push", "issue_tracker": "https://github.com/dvd-dev/hilo/issues", - "requirements": ["python-hilo>=2026.3.5"], - "version": "2026.8.3" + "requirements": ["python-hilo>=2026.9.1"], + "version": "2026.9.1" } diff --git a/custom_components/midea_ac_lan/climate.py b/custom_components/midea_ac_lan/climate.py index d275bda9..49538b27 100644 --- a/custom_components/midea_ac_lan/climate.py +++ b/custom_components/midea_ac_lan/climate.py @@ -505,8 +505,11 @@ class MideaACClimate(MideaClimate): if self._customize_swing is not None: return self._customize_swing caps = getattr(self._device, "capabilities", {}) - if "swing_vertical" in caps or "swing_horizontal" in caps: - return bool(caps.get("swing_vertical") or caps.get("swing_horizontal")) + if not isinstance(caps, dict): + return True + swing_modes = caps.get("swing_modes") + if isinstance(swing_modes, list): + return bool("vertical" in swing_modes or "horizontal" in swing_modes) return True @property @@ -519,20 +522,23 @@ class MideaACClimate(MideaClimate): if self._customize_hvac_modes is not None: return self._customize_hvac_modes caps = getattr(self._device, "capabilities", {}) - if not caps: + if not isinstance(caps, dict) or not caps: return list(self._mode_index) - modes = [HVACMode.OFF] - if caps.get("auto_mode"): - modes.append(HVACMode.AUTO) - if caps.get("cool_mode"): - modes.append(HVACMode.COOL) - if caps.get("dry_mode"): - modes.append(HVACMode.DRY) - if caps.get("heat_mode"): - modes.append(HVACMode.HEAT) + modes_list = caps.get("modes") + if not isinstance(modes_list, list): + return list(self._mode_index) + hvac_modes = [HVACMode.OFF] + if "auto" in modes_list: + hvac_modes.append(HVACMode.AUTO) + if "cool" in modes_list: + hvac_modes.append(HVACMode.COOL) + if "dry" in modes_list: + hvac_modes.append(HVACMode.DRY) + if "heat" in modes_list: + hvac_modes.append(HVACMode.HEAT) # fan-only is always available on AC devices - modes.append(HVACMode.FAN_ONLY) - return modes + hvac_modes.append(HVACMode.FAN_ONLY) + return hvac_modes @property def preset_modes(self) -> list[str]: @@ -553,15 +559,17 @@ class MideaACClimate(MideaClimate): if self._customize_preset_modes is not None: return self._customize_preset_modes caps = getattr(self._device, "capabilities", {}) - if not caps: + if not isinstance(caps, dict) or not caps: return all_presets + modes_list = caps.get("modes") + has_heat = isinstance(modes_list, list) and "heat" in modes_list keep = { PRESET_NONE: True, PRESET_COMFORT: True, PRESET_ECO: bool(caps.get("eco")), PRESET_BOOST: bool(caps.get("turbo_cool") or caps.get("turbo_heat")), PRESET_SLEEP: True, - PRESET_AWAY: bool(caps.get("heat_mode")), + PRESET_AWAY: has_heat, } return [preset for preset in all_presets if keep[preset]] @@ -658,21 +666,24 @@ class MideaACClimate(MideaClimate): if self._customize_fan_modes is not None: return self._customize_fan_modes caps = getattr(self._device, "capabilities", {}) - if not caps: + if not isinstance(caps, dict) or not caps: + return list(self._fan_speeds.keys()) + fan_speeds_list = caps.get("fan_speeds") + if not isinstance(fan_speeds_list, list): return list(self._fan_speeds.keys()) # stepless/inverter fan: expose every discrete speed, not just "full" - if caps.get("fan_custom"): + if "custom" in fan_speeds_list: return list(self._fan_speeds.keys()) cap_by_fan = { - FAN_SILENT: "fan_silent", - FAN_LOW: "fan_low", - FAN_MEDIUM: "fan_medium", - FAN_HIGH: "fan_high", - FAN_FULL_SPEED: "fan_custom", - FAN_AUTO: "fan_auto", + FAN_SILENT: "silent", + FAN_LOW: "low", + FAN_MEDIUM: "medium", + FAN_HIGH: "high", + FAN_FULL_SPEED: "custom", + FAN_AUTO: "auto", } modes = [ - name for name in self._fan_speeds if caps.get(cap_by_fan.get(name, "")) + name for name in self._fan_speeds if cap_by_fan.get(name) in fan_speeds_list ] return modes or list(self._fan_speeds.keys()) diff --git a/custom_components/midea_ac_lan/manifest.json b/custom_components/midea_ac_lan/manifest.json index 1e11eba9..cc73b01e 100644 --- a/custom_components/midea_ac_lan/manifest.json +++ b/custom_components/midea_ac_lan/manifest.json @@ -15,7 +15,7 @@ "midealan" ], "requirements": [ - "midea-lan==2026.9.0" + "midea-lan==2026.9.1" ], - "version": "2026.9.0" + "version": "2026.9.1" } diff --git a/custom_components/midea_ac_lan/translations/de.json b/custom_components/midea_ac_lan/translations/de.json index 65bb5214..9bbcc754 100644 --- a/custom_components/midea_ac_lan/translations/de.json +++ b/custom_components/midea_ac_lan/translations/de.json @@ -22,7 +22,7 @@ "account": "Konto", "password": "Passwort" }, - "description": "Mit dem Midea-Konto anmelden. Das Konto wird nur verwendet, um die Geräteinformationen zu erhalten.\nDie Konfiguration kann wieder entfernt werden, nachdem alle Geräte konfiguriert wurden.", + "description": "Melden Sie sich an und rufen Sie das Geräte-Token ab.\n\n\nDerzeit können nur persönliche SmartHome- und Meiju-Konten Geräte-Tokens abrufen. Details finden Sie in der README-Dokumentation.", "title": "Login" }, "discovery": { diff --git a/custom_components/midea_ac_lan/translations/en.json b/custom_components/midea_ac_lan/translations/en.json index 84faa50c..70334259 100644 --- a/custom_components/midea_ac_lan/translations/en.json +++ b/custom_components/midea_ac_lan/translations/en.json @@ -22,7 +22,7 @@ "account": "Account", "password": "Password" }, - "description": "Login and storage your Midea account only for getting the appliance info.\nYou can remove this configuration after all appliance configured.", + "description": "Login and get the appliance token.\n\n\nCurrently, only personal SmartHome and Meiju accounts can retrieve appliance Tokens. See README doc for details.", "title": "Login" }, "discovery": { diff --git a/custom_components/midea_ac_lan/translations/es.json b/custom_components/midea_ac_lan/translations/es.json index 5230237f..c3ee94ab 100644 --- a/custom_components/midea_ac_lan/translations/es.json +++ b/custom_components/midea_ac_lan/translations/es.json @@ -22,7 +22,7 @@ "account": "Cuenta", "password": "Contraseña" }, - "description": "Inicie sesión y guarde su cuenta Midea solo para obtener la información del electrodoméstico.\nPuede eliminar esta configuración después de haber configurado todos los dispositivos.", + "description": "Inicie sesión y obtenga el token del electrodoméstico.\n\n\nActualmente, solo las cuentas personales de SmartHome y Meiju pueden recuperar los Tokens de electrodomésticos. Consulte la documentación README para obtener más detalles.", "title": "Iniciar sesión" }, "discovery": { diff --git a/custom_components/midea_ac_lan/translations/fr.json b/custom_components/midea_ac_lan/translations/fr.json index d0eed5f0..2cdc1983 100644 --- a/custom_components/midea_ac_lan/translations/fr.json +++ b/custom_components/midea_ac_lan/translations/fr.json @@ -22,7 +22,7 @@ "account": "Account", "password": "Password" }, - "description": "Login and storage your Midea account only for getting the appliance info.\nYou can remove this configuration after all appliance configured.", + "description": "Connectez-vous et récupérez le token de l'appareil.\n\n\nActuellement, seuls les comptes personnels SmartHome et Meiju peuvent récupérer les Tokens des appareils. Consultez la documentation README pour plus de détails.", "title": "Login" }, "discovery": { diff --git a/custom_components/midea_ac_lan/translations/hu.json b/custom_components/midea_ac_lan/translations/hu.json index 32f83a5c..f2016a33 100644 --- a/custom_components/midea_ac_lan/translations/hu.json +++ b/custom_components/midea_ac_lan/translations/hu.json @@ -22,7 +22,7 @@ "account": "Fiók", "password": "Jelszó" }, - "description": "Jelentkezzen be és tárolja el Midea-fiókját, kizárólag a készülékei információinak a megszerzéséhez.\nAz összes készülékének beállítása után eltávolíthatja ezt a konfigurációt.", + "description": "Jelentkezzen be, és kérje le a készülék tokenjét.\n\n\nJelenleg csak személyes SmartHome- és Meiju-fiókokkal lehet lekérni a készülékek Tokenjeit. Részletekért lásd a README dokumentációt.", "title": "Bejelentkezés" }, "discovery": { diff --git a/custom_components/midea_ac_lan/translations/it.json b/custom_components/midea_ac_lan/translations/it.json index 88bd50f7..700c8ef8 100644 --- a/custom_components/midea_ac_lan/translations/it.json +++ b/custom_components/midea_ac_lan/translations/it.json @@ -22,7 +22,7 @@ "account": "Account", "password": "Password" }, - "description": "Accedi e salva il tuo account Midea solo per ottenere le informazioni sugli elettrodomestici.\nPuoi rimuovere questa configurazione dopo aver completato la configurazione di tutti gli elettrodomestici.", + "description": "Accedi e ottieni il token dell'elettrodomestico.\n\n\nAttualmente, solo gli account personali SmartHome e Meiju possono recuperare i Token degli elettrodomestici. Per i dettagli, consulta la documentazione README.", "title": "Accesso" }, "discovery": { diff --git a/custom_components/midea_ac_lan/translations/ru.json b/custom_components/midea_ac_lan/translations/ru.json index f2e95585..d7f23b4d 100644 --- a/custom_components/midea_ac_lan/translations/ru.json +++ b/custom_components/midea_ac_lan/translations/ru.json @@ -22,7 +22,7 @@ "account": "Аккаунт", "password": "Пароль" }, - "description": "Login and storage your Midea account only for getting the appliance info.\nYou can remove this configuration after all appliance configured.", + "description": "Войдите в аккаунт и получите токен устройства.\n\n\nВ настоящее время токены устройств могут получать только личные аккаунты SmartHome и Meiju. Подробности см. в документации README.", "title": "Login" }, "discovery": { diff --git a/custom_components/midea_ac_lan/translations/sk.json b/custom_components/midea_ac_lan/translations/sk.json index 1764eaef..6476d292 100644 --- a/custom_components/midea_ac_lan/translations/sk.json +++ b/custom_components/midea_ac_lan/translations/sk.json @@ -22,7 +22,7 @@ "account": "Account", "password": "Password" }, - "description": "Login and storage your Midea account only for getting the appliance info.\nYou can remove this configuration after all appliance configured.", + "description": "Prihláste sa a získajte token zariadenia.\n\n\nAktuálne môžu Tokeny zariadení získať iba osobné účty SmartHome a Meiju. Podrobnosti nájdete v dokumentácii README.", "title": "Login" }, "discovery": { diff --git a/custom_components/midea_ac_lan/translations/zh-Hans.json b/custom_components/midea_ac_lan/translations/zh-Hans.json index a2463495..b26d9248 100644 --- a/custom_components/midea_ac_lan/translations/zh-Hans.json +++ b/custom_components/midea_ac_lan/translations/zh-Hans.json @@ -22,7 +22,7 @@ "account": "账号", "password": "密码" }, - "description": "登录并保存你的美的账户,仅用于获取添加设备时设备信息\n添加设备完成后,你可以删除该配置", + "description": "登录并获取设备 Token。\n\n\n目前仅个人 SmartHome 和 Meiju 账号可获取设备 Token。详情请参考 README 文档。", "title": "登录" }, "discovery": { diff --git a/zigbee2mqtt/state.json b/zigbee2mqtt/state.json index 41809156..b2e82ee4 100644 --- a/zigbee2mqtt/state.json +++ b/zigbee2mqtt/state.json @@ -4,7 +4,7 @@ "state": "ON", "led_brightness": 100, "countdown_to_turn_off": 0, - "voltage": 119.8, + "voltage": 120.3, "countdown_to_turn_on": 0, "ac_frequency": 60, "power_factor": 0.14, @@ -22,12 +22,12 @@ }, "0xffffb40e0607af27": { "state": "ON", - "voltage": 120.5, + "voltage": 119.4, "ac_frequency": 60, "led_brightness": 100, "countdown_to_turn_off": 0, "countdown_to_turn_on": 0, - "power": 1.9, + "power": 2, "current": 0.09, "energy": 39.8, "power_factor": 0.17, @@ -45,10 +45,10 @@ "state": "ON", "led_brightness": 100, "countdown_to_turn_off": 0, - "voltage": 119.5, + "voltage": 119.8, "countdown_to_turn_on": 0, - "energy": 78.08, - "power_factor": 0.31, + "energy": 78.11, + "power_factor": 0.9, "ac_frequency": 60, "update": { "state": "idle", @@ -58,8 +58,8 @@ "latest_release_notes": null }, "linkquality": 80, - "power": 0.2, - "current": 0.01, + "power": 83.2, + "current": 0.78, "power_on_behavior": "on" }, "0xb40e060fffe031e3": { @@ -74,13 +74,13 @@ "led_brightness": 100, "countdown_to_turn_off": 0, "countdown_to_turn_on": 0, - "voltage": 118.7, + "voltage": 119, "state": "ON", "ac_frequency": 60, - "energy": 158.61, - "power": 101.7, - "current": 0.9, - "power_factor": 0.94, + "energy": 158.66, + "power": 93.9, + "current": 0.84, + "power_factor": 0.93, "update": { "state": "idle", "installed_version": 268513381, @@ -96,9 +96,9 @@ "countdown_to_turn_off": 0, "countdown_to_turn_on": 0, "voltage": 119.8, - "energy": 77.43, + "energy": 77.44, "state": "ON", - "power": 18.3, + "power": 17.2, "current": 0.26, "ac_frequency": 60, "power_factor": 0.55, @@ -114,7 +114,7 @@ }, "0xffffb40e060895b3": { "state": "ON", - "voltage": 116.7, + "voltage": 120.2, "ac_frequency": 60, "energy": 10.85, "current": 0.02, @@ -136,14 +136,14 @@ "0xffffb40e0608864e": { "led_brightness": 100, "countdown_to_turn_off": 0, - "voltage": 122, + "voltage": 120.7, "energy": 24.07, "countdown_to_turn_on": 0, "state": "ON", "current": 0.02, "ac_frequency": 60, "power": 0.3, - "power_factor": 0.14, + "power_factor": 0.19, "update": { "state": "idle", "installed_version": 268513381,