From f10450c8a378e082331f3621af36c83370c7d9c4 Mon Sep 17 00:00:00 2001 From: AndreaTomatis Date: Thu, 21 Mar 2024 11:44:36 +0100 Subject: [PATCH 1/3] Fixed deprecation --- custom_components/vesync/__init__.py | 7 ++++--- custom_components/vesync/common.py | 7 ++++--- custom_components/vesync/config_flow.py | 5 +++-- custom_components/vesync/const.py | 23 ++++++++++++----------- custom_components/vesync/device_action.py | 9 +++++---- custom_components/vesync/humidifier.py | 10 ++++++---- custom_components/vesync/manifest.json | 2 +- custom_components/vesync/number.py | 3 +-- custom_components/vesync/sensor.py | 14 +++++++------- 9 files changed, 43 insertions(+), 37 deletions(-) diff --git a/custom_components/vesync/__init__.py b/custom_components/vesync/__init__.py index 16bec23..cdcfcd4 100644 --- a/custom_components/vesync/__init__.py +++ b/custom_components/vesync/__init__.py @@ -1,6 +1,8 @@ """VeSync integration.""" -import logging from datetime import timedelta +import logging + +from pyvesync.vesync import VeSync from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform @@ -8,7 +10,6 @@ from homeassistant.core import HomeAssistant, ServiceCall from homeassistant.helpers import config_validation as cv from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed -from pyvesync.vesync import VeSync from .common import async_process_devices from .const import ( @@ -111,7 +112,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b else: hass.async_create_task(forward_setup(config_entry, platform)) - for k, v in PLATFORMS.items(): + for k in PLATFORMS: _add_new_devices(k) hass.services.async_register( diff --git a/custom_components/vesync/common.py b/custom_components/vesync/common.py index e2c9dc5..02c4784 100644 --- a/custom_components/vesync/common.py +++ b/custom_components/vesync/common.py @@ -1,11 +1,12 @@ """Common utilities for VeSync Component.""" import logging +from pyvesync.vesyncfan import model_features as fan_model_features +from pyvesync.vesynckitchen import model_features as kitchen_model_features + from homeassistant.components.diagnostics import async_redact_data from homeassistant.helpers.entity import Entity, ToggleEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity -from pyvesync.vesyncfan import model_features as fan_model_features -from pyvesync.vesynckitchen import model_features as kitchen_model_features from .const import ( DOMAIN, @@ -104,7 +105,7 @@ async def async_process_devices(hass, manager): in VS_AIRFRYER_TYPES ): _LOGGER.warning( - "Found air fryer %s, support in progress.\n%s", airfryer.device_name + "Found air fryer %s, support in progress.\n", airfryer.device_name ) devices[VS_SENSORS].append(airfryer) devices[VS_BINARY_SENSORS].append(airfryer) diff --git a/custom_components/vesync/config_flow.py b/custom_components/vesync/config_flow.py index c1b34c7..7b2aa33 100644 --- a/custom_components/vesync/config_flow.py +++ b/custom_components/vesync/config_flow.py @@ -1,14 +1,15 @@ """Config flow utilities.""" -import logging from collections import OrderedDict +import logging +from pyvesync.vesync import VeSync import voluptuous as vol + from homeassistant import config_entries from homeassistant.components import dhcp from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.core import callback from homeassistant.data_entry_flow import FlowResult -from pyvesync.vesync import VeSync from .const import DOMAIN diff --git a/custom_components/vesync/const.py b/custom_components/vesync/const.py index 65f07e2..96fe288 100644 --- a/custom_components/vesync/const.py +++ b/custom_components/vesync/const.py @@ -1,6 +1,7 @@ """Constants for VeSync Component.""" -from homeassistant.const import DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, TIME_MINUTES +from homeassistant.components.sensor import SensorDeviceClass +from homeassistant.const import UnitOfTemperature, UnitOfTime DOMAIN = "vesync" VS_DISCOVERY = "vesync_discovery_{}" @@ -72,33 +73,33 @@ SENSOR_TYPES_AIRFRYER = { "current_temp": [ "current_temperature", "Current temperature", - TEMP_CELSIUS, + UnitOfTemperature.CELSIUS, None, - DEVICE_CLASS_TEMPERATURE, + SensorDeviceClass.TEMPERATURE, "current_temp", ], "cook_set_temp": [ "set_temperature", "Set temperature", - TEMP_CELSIUS, + UnitOfTemperature.CELSIUS, None, - DEVICE_CLASS_TEMPERATURE, + SensorDeviceClass.TEMPERATURE, "cook_set_temp", ], "cook_last_time": [ "cook_last_time", "Cook Remaining", - TIME_MINUTES, + UnitOfTime.MINUTES, "mdi:timer", - TIME_MINUTES, + UnitOfTime.MINUTES, "cook_last_time", ], "preheat_last_time": [ "preheat_last_time", "Preheat Remaining", - TIME_MINUTES, + UnitOfTime.MINUTES, "mdi:timer", - TIME_MINUTES, + UnitOfTime.MINUTES, "preheat_last_time", ], "cook_status": [ @@ -112,9 +113,9 @@ SENSOR_TYPES_AIRFRYER = { # "remaining_time": [ # "remaining_time", # "running:", - # TIME_MINUTES, + # UnitOfTime.MINUTES, # "mdi:timer", - # TIME_MINUTES, + # UnitOfTime.MINUTES, # "remaining_time", # ], } diff --git a/custom_components/vesync/device_action.py b/custom_components/vesync/device_action.py index b2c1c47..da951b0 100644 --- a/custom_components/vesync/device_action.py +++ b/custom_components/vesync/device_action.py @@ -3,8 +3,8 @@ from __future__ import annotations import logging -import homeassistant.helpers.config_validation as cv import voluptuous as vol + from homeassistant.components.device_automation import toggle_entity from homeassistant.const import ( ATTR_ENTITY_ID, @@ -16,7 +16,8 @@ from homeassistant.const import ( ) from homeassistant.core import Context, HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers import entity_registry +from homeassistant.helpers import entity_registry as er +import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import get_capability from homeassistant.helpers.typing import ConfigType, TemplateVarsType @@ -41,11 +42,11 @@ async def async_get_actions( hass: HomeAssistant, device_id: str ) -> list[dict[str, str]]: """List device actions for Humidifier devices.""" - registry = entity_registry.async_get(hass) + registry = er.async_get(hass) actions = await toggle_entity.async_get_actions(hass, device_id, DOMAIN) # Get all the integrations entities for this device - for entry in entity_registry.async_entries_for_device(registry, device_id): + for entry in er.async_entries_for_device(registry, device_id): if entry.domain != "fan": continue diff --git a/custom_components/vesync/humidifier.py b/custom_components/vesync/humidifier.py index e8a7703..05cdb7f 100644 --- a/custom_components/vesync/humidifier.py +++ b/custom_components/vesync/humidifier.py @@ -1,21 +1,23 @@ """Support for VeSync humidifiers.""" from __future__ import annotations +from collections.abc import Mapping import logging -from typing import Any, Mapping +from typing import Any + +from pyvesync.vesyncfan import VeSyncHumid200300S from homeassistant.components.humidifier import HumidifierEntity from homeassistant.components.humidifier.const import ( MODE_AUTO, MODE_NORMAL, MODE_SLEEP, - SUPPORT_MODES, + HumidifierEntityFeature, ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity_platform import AddEntitiesCallback -from pyvesync.vesyncfan import VeSyncHumid200300S from .common import VeSyncDevice from .const import ( @@ -122,7 +124,7 @@ class VeSyncHumidifierHA(VeSyncDevice, HumidifierEntity): @property def supported_features(self): """Flag supported features.""" - return SUPPORT_MODES + return HumidifierEntityFeature.MODES @property def target_humidity(self) -> int: diff --git a/custom_components/vesync/manifest.json b/custom_components/vesync/manifest.json index eb968b7..5957026 100644 --- a/custom_components/vesync/manifest.json +++ b/custom_components/vesync/manifest.json @@ -13,5 +13,5 @@ "iot_class": "cloud_polling", "issue_tracker": "https://github.com/vlebourl/custom_vesync", "requirements": ["pyvesync==2.1.10"], - "version": "1.3.0" + "version": "1.3.1" } diff --git a/custom_components/vesync/number.py b/custom_components/vesync/number.py index 1c9de09..7a4cd53 100644 --- a/custom_components/vesync/number.py +++ b/custom_components/vesync/number.py @@ -208,8 +208,7 @@ class VeSyncHumidifierTargetLevelHA(VeSyncNumberEntity): @property def device_class(self): - """ - Return the device class of the target humidity level. + """Return the device class of the target humidity level. Eventually this should become NumberDeviceClass but that was introduced in 2022.12. For maximum compatibility, using SensorDeviceClass as recommended by deprecation notice. diff --git a/custom_components/vesync/sensor.py b/custom_components/vesync/sensor.py index b98b43c..9a4cd09 100644 --- a/custom_components/vesync/sensor.py +++ b/custom_components/vesync/sensor.py @@ -7,7 +7,7 @@ from homeassistant.components.sensor import ( SensorStateClass, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ENERGY_KILO_WATT_HOUR, PERCENTAGE, POWER_WATT +from homeassistant.const import PERCENTAGE, UnitOfEnergy, UnitOfPower from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import EntityCategory @@ -170,7 +170,7 @@ class VeSyncPowerSensor(VeSyncOutletSensorEntity): @property def native_unit_of_measurement(self): """Return the Watt unit of measurement.""" - return POWER_WATT + return UnitOfPower.WATT @property def state_class(self): @@ -214,7 +214,7 @@ class VeSyncEnergySensor(VeSyncOutletSensorEntity): @property def native_unit_of_measurement(self): """Return the kWh unit of measurement.""" - return ENERGY_KILO_WATT_HOUR + return UnitOfEnergy.KILO_WATT_HOUR @property def state_class(self): @@ -276,12 +276,12 @@ class VeSyncAirQualitySensor(VeSyncHumidifierSensorEntity): quality = self.smarthumidifier.details["air_quality"] if isinstance(quality, (int, float)): return quality - _LOGGER.warn( + _LOGGER.warning( "Got non numeric value for AQI sensor from 'air_quality' for %s: %s", self.name, quality, ) - _LOGGER.warn("No air quality index found in '%s'", self.name) + _LOGGER.warning("No air quality index found in '%s'", self.name) return None @@ -313,12 +313,12 @@ class VeSyncAirQualityValueSensor(VeSyncHumidifierSensorEntity): quality_value = self.smarthumidifier.details["air_quality_value"] if isinstance(quality_value, (int, float)): return quality_value - _LOGGER.warn( + _LOGGER.warning( "Got non numeric value for AQI sensor from 'air_quality_value' for %s: %s", self.name, quality_value, ) - _LOGGER.warn("No air quality value found in '%s'", self.name) + _LOGGER.warning("No air quality value found in '%s'", self.name) return None From f123f0bb77f085dc95f1cdc161572c28484e64a4 Mon Sep 17 00:00:00 2001 From: AndreaTomatis Date: Sat, 20 Apr 2024 16:27:28 +0200 Subject: [PATCH 2/3] Improved code. --- custom_components/vesync/__init__.py | 3 ++- custom_components/vesync/binary_sensor.py | 6 +++--- custom_components/vesync/button.py | 3 ++- custom_components/vesync/fan.py | 7 ++++--- custom_components/vesync/sensor.py | 6 +++--- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/custom_components/vesync/__init__.py b/custom_components/vesync/__init__.py index cdcfcd4..41bb19f 100644 --- a/custom_components/vesync/__init__.py +++ b/custom_components/vesync/__init__.py @@ -1,4 +1,5 @@ """VeSync integration.""" + from datetime import timedelta import logging @@ -69,7 +70,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b try: await hass.async_add_executor_job(manager.update) except Exception as err: - raise UpdateFailed(f"Update failed: {err}") + raise UpdateFailed(f"Update failed: {err}") from err coordinator = DataUpdateCoordinator( hass, diff --git a/custom_components/vesync/binary_sensor.py b/custom_components/vesync/binary_sensor.py index a9dbd8f..38e3eb4 100644 --- a/custom_components/vesync/binary_sensor.py +++ b/custom_components/vesync/binary_sensor.py @@ -1,4 +1,5 @@ """Support for power & energy sensors for VeSync outlets.""" + import logging from homeassistant.components.binary_sensor import BinarySensorEntity @@ -46,7 +47,7 @@ def _setup_entities(devices, async_add_entities, coordinator): for dev in devices: if hasattr(dev, "fryer_status"): for stype in BINARY_SENSOR_TYPES_AIRFRYER.values(): - entities.append( + entities.append( # noqa: PERF401 VeSyncairfryerSensor( dev, coordinator, @@ -88,8 +89,7 @@ class VeSyncairfryerSensor(VeSyncBaseEntity, BinarySensorEntity): @property def is_on(self) -> bool: """Return a value indicating whether the Humidifier's water tank is lifted.""" - value = getattr(self.airfryer, self.stype[0], None) - return value + return getattr(self.airfryer, self.stype[0], None) # return self.smarthumidifier.details["water_tank_lifted"] @property diff --git a/custom_components/vesync/button.py b/custom_components/vesync/button.py index 8109629..c02cbfc 100644 --- a/custom_components/vesync/button.py +++ b/custom_components/vesync/button.py @@ -1,4 +1,5 @@ """Support for VeSync button.""" + import logging from homeassistant.components.button import ButtonEntity @@ -55,7 +56,7 @@ def _setup_entities(devices, async_add_entities, coordinator): for dev in devices: if hasattr(dev, "cook_set_temp"): for stype in SENSOR_TYPES_CS158.values(): - entities.append( + entities.append( # noqa: PERF401 VeSyncairfryerButton( dev, coordinator, diff --git a/custom_components/vesync/fan.py b/custom_components/vesync/fan.py index 6b3e736..25de507 100644 --- a/custom_components/vesync/fan.py +++ b/custom_components/vesync/fan.py @@ -1,4 +1,5 @@ """Support for VeSync fans.""" + import math from homeassistant.components.fan import FanEntity, FanEntityFeature @@ -165,9 +166,9 @@ class VeSyncFanHA(VeSyncDevice, FanEntity): def turn_on( self, - speed: str = None, - percentage: int = None, - preset_mode: str = None, + # speed: str | None = None, + percentage: int | None = None, + preset_mode: str | None = None, **kwargs, ) -> None: """Turn the device on.""" diff --git a/custom_components/vesync/sensor.py b/custom_components/vesync/sensor.py index 9a4cd09..4ce8198 100644 --- a/custom_components/vesync/sensor.py +++ b/custom_components/vesync/sensor.py @@ -1,4 +1,5 @@ """Support for power & energy sensors for VeSync outlets.""" + import logging from homeassistant.components.sensor import ( @@ -57,7 +58,7 @@ def _setup_entities(devices, async_add_entities, coordinator): for dev in devices: if hasattr(dev, "fryer_status"): for stype in SENSOR_TYPES_AIRFRYER.values(): - entities.append( + entities.append( # noqa: PERF401 VeSyncairfryerSensor( dev, coordinator, @@ -111,8 +112,7 @@ class VeSyncairfryerSensor(VeSyncBaseEntity, SensorEntity): @property def native_value(self): """Return the value.""" - value = getattr(self.airfryer, self.stype[5], None) - return value + return getattr(self.airfryer, self.stype[5], None) @property def native_unit_of_measurement(self): From 9cf5b5676b2630a600be833f0fc10c7694294ecb Mon Sep 17 00:00:00 2001 From: AndreaTomatis Date: Sat, 20 Apr 2024 16:33:26 +0200 Subject: [PATCH 3/3] Corrected manifest --- custom_components/vesync/manifest.json | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/custom_components/vesync/manifest.json b/custom_components/vesync/manifest.json index 5957026..3e63437 100644 --- a/custom_components/vesync/manifest.json +++ b/custom_components/vesync/manifest.json @@ -1,7 +1,13 @@ { "domain": "vesync", "name": "VeSync", - "codeowners": ["@markperdue", "@webdjoe", "@thegardenmonkey", "@vlebourl","@tv4you2016"], + "codeowners": [ + "@markperdue", + "@webdjoe", + "@thegardenmonkey", + "@vlebourl", + "@tv4you2016" + ], "config_flow": true, "dhcp": [ { @@ -9,9 +15,11 @@ "macaddress": "*" } ], - "documentation": "https://www.home-assistant.io/integrations/vesync", + "documentation": "https://github.com/AndreaTomatis/custom_vesync", "iot_class": "cloud_polling", - "issue_tracker": "https://github.com/vlebourl/custom_vesync", - "requirements": ["pyvesync==2.1.10"], + "issue_tracker": "https://github.com/AndreaTomatis/custom_vesync", + "requirements": [ + "pyvesync==2.1.10" + ], "version": "1.3.1" -} +} \ No newline at end of file