From d4776184f686316d9f536b56168634af9f0edfdd Mon Sep 17 00:00:00 2001 From: "[PT]GOODVIBE[PT]" Date: Tue, 24 Oct 2023 00:24:25 +0100 Subject: [PATCH 1/7] Air Fryer Properties (AirFryer158) --- README.md | 9 ++ custom_components/vesync/binary_sensor.py | 63 +++++++++++++ custom_components/vesync/common.py | 53 +++++++---- custom_components/vesync/const.py | 1 + custom_components/vesync/manifest.json | 2 +- custom_components/vesync/sensor.py | 109 +++++++++++++++++++++- 6 files changed, 217 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index b9f31d6..29555b7 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + # **Important message** > > Unfortunately, I no longer have time to maintain this repo. I am therefore looking for someone to take it over before archiving it. If interested please contact me. @@ -44,6 +45,13 @@ logger: pyvesync: debug ``` +## TODO LIST +``` +- [x] Air Fryer Properties (AirFryer158) +- [ ] Air Fryer Methods +- [ ] Create the Card +``` + ### Contributing All contributions are very welcomed! @@ -54,3 +62,4 @@ pip install pre-commit pre-commit install pre-commit run --all-files ``` + diff --git a/custom_components/vesync/binary_sensor.py b/custom_components/vesync/binary_sensor.py index f587dac..d430641 100644 --- a/custom_components/vesync/binary_sensor.py +++ b/custom_components/vesync/binary_sensor.py @@ -13,6 +13,25 @@ _LOGGER = logging.getLogger(__name__) +SENSOR_TYPES_CS158 = { + # unique_id,name # icon, #atribut read, + "is_heating": [ + "is_heating", + "preheating", + "mdi:pot-steam-outline", + ], + "is_cooking": [ + "is_cooking", + "cooking", + "mdi:rice", + ], + "is_running": [ + "is_running", + "running", + "mdi:pause", + ], +} + async def async_setup_entry( hass: HomeAssistant, @@ -44,6 +63,15 @@ def _setup_entities(devices, async_add_entities, coordinator): """Check if device is online and add entity.""" entities = [] for dev in devices: + if (dev.device_type) == "CS158-AF": + for stype in SENSOR_TYPES_CS158.values(): + entities.append( + VeSyncairfryerSensor( + dev, + coordinator, + stype, + ) + ) if has_feature(dev, "details", "water_lacks"): entities.append(VeSyncOutOfWaterSensor(dev, coordinator)) if has_feature(dev, "details", "water_tank_lifted"): @@ -52,6 +80,41 @@ def _setup_entities(devices, async_add_entities, coordinator): async_add_entities(entities, update_before_add=True) +class VeSyncairfryerSensor(VeSyncBaseEntity, BinarySensorEntity): + def __init__(self, airfryer, coordinator, stype): + """Initialize the VeSync humidifier device.""" + super().__init__(airfryer, coordinator) + self.airfryer = airfryer + self.stype = stype + + @property + def entity_category(self): + """Return the diagnostic entity category.""" + return EntityCategory.DIAGNOSTIC + + @property + def unique_id(self): + """Return unique ID for water tank lifted sensor on device.""" + return f"{super().unique_id}-" + self.stype[0] + + @property + def name(self): + """Return sensor name.""" + return f"{super().name}_" + self.stype[1] + + @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 self.smarthumidifier.details["water_tank_lifted"] + + @property + def icon(self): + """Return the icon to use in the frontend, if any.""" + return self.stype[2] + + class VeSyncBinarySensorEntity(VeSyncBaseEntity, BinarySensorEntity): """Representation of a binary sensor describing diagnostics of a VeSync humidifier.""" diff --git a/custom_components/vesync/common.py b/custom_components/vesync/common.py index 1732c62..0b0b6ea 100644 --- a/custom_components/vesync/common.py +++ b/custom_components/vesync/common.py @@ -1,13 +1,16 @@ """Common utilities for VeSync Component.""" import logging +from typing import Optional 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 +from pyvesync.vesyncfan import model_features as fan_model_features +from pyvesync.vesynckitchen import model_features as kitchen_model_features from .const import ( DOMAIN, + VS_AIRFRYER_TYPES, VS_BINARY_SENSORS, VS_FAN_TYPES, VS_FANS, @@ -27,16 +30,6 @@ def has_feature(device, dictionary, attribute): return getattr(device, dictionary, {}).get(attribute, None) is not None -def is_humidifier(device_type: str) -> bool: - """Return true if the device type is a humidifier.""" - return model_features(device_type)["module"] in VS_HUMIDIFIERS_TYPES - - -def is_air_purifier(device_type: str) -> bool: - """Return true if the device type is a an air purifier.""" - return model_features(device_type)["module"] in VS_FAN_TYPES - - async def async_process_devices(hass, manager): """Assign devices to proper component.""" devices = { @@ -54,14 +47,15 @@ async def async_process_devices(hass, manager): ["cid", "uuid", "mac_id"], ) - _LOGGER.debug( + _LOGGER.warning( "Found the following devices: %s", redacted, ) if ( - manager.fans is None - and manager.bulbs is None + manager.bulbs is None + and manager.fans is None + and manager.kitchen is None and manager.outlets is None and manager.switches is None ): @@ -70,13 +64,13 @@ async def async_process_devices(hass, manager): if manager.fans: for fan in manager.fans: # VeSync classifies humidifiers as fans - if is_humidifier(fan.device_type): + if fan_model_features(fan.device_type)["module"] in VS_HUMIDIFIERS_TYPES: devices[VS_HUMIDIFIERS].append(fan) - elif is_air_purifier(fan.device_type): + elif fan_model_features(fan.device_type)["module"] in VS_FAN_TYPES: devices[VS_FANS].append(fan) else: _LOGGER.warning( - "Unknown device type %s %s (enable debug for more info)", + "Unknown fan type %s %s (enable debug for more info)", fan.device_name, fan.device_type, ) @@ -102,6 +96,24 @@ async def async_process_devices(hass, manager): else: devices[VS_LIGHTS].append(switch) + if manager.kitchen: + for airfryer in manager.kitchen: + if ( + kitchen_model_features(airfryer.device_type)["module"] + in VS_AIRFRYER_TYPES + ): + _LOGGER.warning( + "Found air fryer %s, support in progress.\n%s", airfryer.device_name + ) + devices[VS_SENSORS].append(airfryer) + devices[VS_BINARY_SENSORS].append(airfryer) + else: + _LOGGER.warning( + "Unknown device type %s %s (enable debug for more info)", + airfryer.device_name, + airfryer.device_type, + ) + return devices @@ -130,7 +142,7 @@ def unique_id(self): @property def base_name(self): """Return the name of the device.""" - return self.device.device_name + return self.device.device_type @property def name(self): @@ -153,6 +165,11 @@ def device_info(self): "sw_version": self.device.current_firm_version, } + @property + def icon(self) -> Optional[str]: + """Return the icon to use in the frontend, if any.""" + return self._icon + async def async_added_to_hass(self): """When entity is added to hass.""" self.async_on_remove( diff --git a/custom_components/vesync/const.py b/custom_components/vesync/const.py index 7ea7957..ea74289 100644 --- a/custom_components/vesync/const.py +++ b/custom_components/vesync/const.py @@ -26,6 +26,7 @@ VS_FAN_TYPES = ["VeSyncAirBypass", "VeSyncAir131", "VeSyncVital"] VS_HUMIDIFIERS_TYPES = ["VeSyncHumid200300S", "VeSyncHumid200S", "VeSyncHumid1000S"] +VS_AIRFRYER_TYPES = ["VeSyncAirFryer158"] DEV_TYPE_TO_HA = { "ESL100": "bulb-dimmable", diff --git a/custom_components/vesync/manifest.json b/custom_components/vesync/manifest.json index ea55c1e..5c37b8d 100644 --- a/custom_components/vesync/manifest.json +++ b/custom_components/vesync/manifest.json @@ -1,7 +1,7 @@ { "domain": "vesync", "name": "VeSync", - "codeowners": ["@markperdue", "@webdjoe", "@thegardenmonkey", "@vlebourl"], + "codeowners": ["@markperdue", "@webdjoe", "@thegardenmonkey", "@vlebourl","@tv4you2016"], "config_flow": true, "dhcp": [ { diff --git a/custom_components/vesync/sensor.py b/custom_components/vesync/sensor.py index e69a785..c925ba4 100644 --- a/custom_components/vesync/sensor.py +++ b/custom_components/vesync/sensor.py @@ -7,7 +7,14 @@ SensorStateClass, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ENERGY_KILO_WATT_HOUR, PERCENTAGE, POWER_WATT +from homeassistant.const import ( + ENERGY_KILO_WATT_HOUR, + PERCENTAGE, + POWER_WATT, + TEMP_CELSIUS, + TIME_MINUTES, + DEVICE_CLASS_TEMPERATURE, +) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import EntityCategory @@ -18,6 +25,58 @@ _LOGGER = logging.getLogger(__name__) +SENSOR_TYPES_CS158 = { + # unique_id ,#name ,# unit of measurement,# icon, # device class, #atribut read, + "current_temp": [ + "current_temperature", + "Current temperature", + TEMP_CELSIUS, + None, + DEVICE_CLASS_TEMPERATURE, + "current_temp", + ], + "cook_set_temp": [ + "set_temperature", + "Set temperature", + TEMP_CELSIUS, + None, + DEVICE_CLASS_TEMPERATURE, + "cook_set_temp", + ], + "cook_last_time": [ + "cook_last_time", + "Cook Remaining", + TIME_MINUTES, + "mdi:timer", + TIME_MINUTES, + "cook_last_time", + ], + "preheat_last_time": [ + "preheat_last_time", + "Preheat Remaining", + TIME_MINUTES, + "mdi:timer", + TIME_MINUTES, + "preheat_last_time", + ], + "cook_status": [ + "cook_status", + "Cook Status", + None, + "mdi:rotate-3d-variant", + None, + "cook_status", + ], + "remaining_time": [ + "remaining_time", + "running:", + TIME_MINUTES, + "mdi:timer", + TIME_MINUTES, + "remaining_time", + ], +} + async def async_setup_entry( hass: HomeAssistant, @@ -49,6 +108,16 @@ def _setup_entities(devices, async_add_entities, coordinator): """Check if device is online and add entity.""" entities = [] for dev in devices: + if (dev.device_type) == "CS158-AF": + for stype in SENSOR_TYPES_CS158.values(): + entities.append( + VeSyncairfryerSensor( + dev, + coordinator, + stype, + ) + ) + if DEV_TYPE_TO_HA.get(dev.device_type) == "outlet": entities.extend( ( @@ -68,6 +137,44 @@ def _setup_entities(devices, async_add_entities, coordinator): async_add_entities(entities, update_before_add=True) +class VeSyncairfryerSensor(VeSyncBaseEntity, SensorEntity): + def __init__(self, airfryer, coordinator, stype): + """Initialize the VeSync outlet device.""" + + super().__init__(airfryer, coordinator) + self.airfryer = airfryer + self.stype = stype + + @property + def unique_id(self): + """Return unique ID for power sensor on device.""" + return f"{super().unique_id}-" + self.stype[0] + + @property + def name(self): + """Return sensor name.""" + return f"{super().name}_" + self.stype[1] + + @property + def device_class(self): + return self.stype[4] + + @property + def native_value(self): + value = getattr(self.airfryer, self.stype[5], None) + return value + + @property + def native_unit_of_measurement(self): + # return self.airfryer.temp_unit + return self.stype[2] + + @property + def icon(self): + """Return the icon to use in the frontend, if any.""" + return self.stype[3] + + class VeSyncOutletSensorEntity(VeSyncBaseEntity, SensorEntity): """Representation of a sensor describing diagnostics of a VeSync outlet.""" From 957e6a232491ca4a1b579b60016af72289f4efa4 Mon Sep 17 00:00:00 2001 From: "[PT]GOODVIBE[PT]" Date: Tue, 24 Oct 2023 19:29:56 +0100 Subject: [PATCH 2/7] Fix icon error [*] Fix icon error [*] Frist BETA Air Fryer Methods --- custom_components/vesync/__init__.py | 2 + custom_components/vesync/binary_sensor.py | 2 +- custom_components/vesync/button.py | 97 +++++++++++++++++++++++ custom_components/vesync/common.py | 9 +-- custom_components/vesync/const.py | 1 + custom_components/vesync/diagnostics.py | 17 ++-- custom_components/vesync/sensor.py | 2 +- custom_components/vesync/switch.py | 12 +++ 8 files changed, 127 insertions(+), 15 deletions(-) create mode 100644 custom_components/vesync/button.py diff --git a/custom_components/vesync/__init__.py b/custom_components/vesync/__init__.py index 29e3ddc..6c293cf 100644 --- a/custom_components/vesync/__init__.py +++ b/custom_components/vesync/__init__.py @@ -23,6 +23,7 @@ VS_NUMBERS, VS_SENSORS, VS_SWITCHES, + VS_BUTTON, ) PLATFORMS = { @@ -33,6 +34,7 @@ Platform.HUMIDIFIER: VS_HUMIDIFIERS, Platform.NUMBER: VS_NUMBERS, Platform.BINARY_SENSOR: VS_BINARY_SENSORS, + Platform.BUTTON: VS_BUTTON, } _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/vesync/binary_sensor.py b/custom_components/vesync/binary_sensor.py index d430641..92f7af0 100644 --- a/custom_components/vesync/binary_sensor.py +++ b/custom_components/vesync/binary_sensor.py @@ -100,7 +100,7 @@ def unique_id(self): @property def name(self): """Return sensor name.""" - return f"{super().name}_" + self.stype[1] + return self.stype[1] @property def is_on(self) -> bool: diff --git a/custom_components/vesync/button.py b/custom_components/vesync/button.py new file mode 100644 index 0000000..7c5163b --- /dev/null +++ b/custom_components/vesync/button.py @@ -0,0 +1,97 @@ +"""Support for VeSync button.""" +import logging + + +from homeassistant.components.button import ButtonEntity +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers.dispatcher import async_dispatcher_connect +from homeassistant.helpers.entity import EntityCategory +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .common import VeSyncBaseEntity +from .const import DOMAIN, VS_DISCOVERY, VS_BUTTON + +_LOGGER = logging.getLogger(__name__) + + +SENSOR_TYPES_CS158 = { + # unique_id,name # icon, + "end": [ + "end", + "End cooking or preheating ", + "mdi:stop", + ], +} + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up switches.""" + + coordinator = hass.data[DOMAIN][config_entry.entry_id]["coordinator"] + + @callback + def discover(devices): + """Add new devices to platform.""" + _setup_entities(devices, async_add_entities, coordinator) + + config_entry.async_on_unload( + async_dispatcher_connect(hass, VS_DISCOVERY.format(VS_BUTTON), discover) + ) + + _setup_entities( + hass.data[DOMAIN][config_entry.entry_id][VS_BUTTON], + async_add_entities, + coordinator, + ) + + +@callback +def _setup_entities(devices, async_add_entities, coordinator): + """Check if device is online and add entity.""" + entities = [] + for dev in devices: + if hasattr(dev, "cook_set_temp"): + for stype in SENSOR_TYPES_CS158.values(): + entities.append( + VeSyncairfryerButton( + dev, + coordinator, + stype, + ) + ) + + async_add_entities(entities, update_before_add=True) + + +class VeSyncairfryerButton(VeSyncBaseEntity, ButtonEntity): + """Base class for VeSync switch Device Representations.""" + + def __init__(self, airfryer, coordinator, stype): + """Initialize the VeSync humidifier device.""" + super().__init__(airfryer, coordinator) + self.airfryer = airfryer + self.stype = stype + + @property + def unique_id(self): + """Return unique ID for water tank lifted sensor on device.""" + return f"{super().unique_id}-" + self.stype[0] + + @property + def name(self): + """Return sensor name.""" + return self.stype[1] + + @property + def icon(self): + """Return the icon to use in the frontend, if any.""" + return self.stype[2] + + def press(self) -> None: + """Return True if device is on.""" + self.airfryer.end() diff --git a/custom_components/vesync/common.py b/custom_components/vesync/common.py index 0b0b6ea..0caf42b 100644 --- a/custom_components/vesync/common.py +++ b/custom_components/vesync/common.py @@ -20,6 +20,7 @@ VS_NUMBERS, VS_SENSORS, VS_SWITCHES, + VS_BUTTON, ) _LOGGER = logging.getLogger(__name__) @@ -40,6 +41,7 @@ async def async_process_devices(hass, manager): VS_HUMIDIFIERS: [], VS_NUMBERS: [], VS_BINARY_SENSORS: [], + VS_BUTTON: [], } redacted = async_redact_data( @@ -107,6 +109,8 @@ async def async_process_devices(hass, manager): ) devices[VS_SENSORS].append(airfryer) devices[VS_BINARY_SENSORS].append(airfryer) + devices[VS_SWITCHES].append(airfryer) + devices[VS_BUTTON].append(airfryer) else: _LOGGER.warning( "Unknown device type %s %s (enable debug for more info)", @@ -165,11 +169,6 @@ def device_info(self): "sw_version": self.device.current_firm_version, } - @property - def icon(self) -> Optional[str]: - """Return the icon to use in the frontend, if any.""" - return self._icon - async def async_added_to_hass(self): """When entity is added to hass.""" self.async_on_remove( diff --git a/custom_components/vesync/const.py b/custom_components/vesync/const.py index ea74289..93e8bf1 100644 --- a/custom_components/vesync/const.py +++ b/custom_components/vesync/const.py @@ -4,6 +4,7 @@ VS_DISCOVERY = "vesync_discovery_{}" SERVICE_UPDATE_DEVS = "update_devices" +VS_BUTTON = "button" VS_SWITCHES = "switches" VS_FAN = "fan" VS_FANS = "fans" diff --git a/custom_components/vesync/diagnostics.py b/custom_components/vesync/diagnostics.py index ccaad25..2899227 100644 --- a/custom_components/vesync/diagnostics.py +++ b/custom_components/vesync/diagnostics.py @@ -7,7 +7,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from .common import is_humidifier +# from .common import is_humidifier from .const import DOMAIN TO_REDACT = {"cid", "uuid", "mac_id"} @@ -19,11 +19,12 @@ async def async_get_config_entry_diagnostics( """Return diagnostics for a config entry.""" data = hass.data[DOMAIN][entry.entry_id] devices = {} - for type in ["fans", "outlets", "switches", "bulbs"]: - for d in data["manager"]._dev_list[type]: - t = "humidifier" if is_humidifier(d.device_type) else type - devices = { - **devices, - **{t: [{k: v for k, v in d.__dict__.items() if k != "manager"}]}, - } + + # for type in ["fans", "outlets", "switches", "bulbs"]: + # for d in data["manager"]._dev_list[type]: + # t = "humidifier" if is_humidifier(d.device_type) else type + # devices = { + # **devices, + # **{t: [{k: v for k, v in d.__dict__.items() if k != "manager"}]}, + # } return async_redact_data(devices, TO_REDACT) diff --git a/custom_components/vesync/sensor.py b/custom_components/vesync/sensor.py index c925ba4..5030371 100644 --- a/custom_components/vesync/sensor.py +++ b/custom_components/vesync/sensor.py @@ -153,7 +153,7 @@ def unique_id(self): @property def name(self): """Return sensor name.""" - return f"{super().name}_" + self.stype[1] + return self.stype[1] @property def device_class(self): diff --git a/custom_components/vesync/switch.py b/custom_components/vesync/switch.py index 65887b1..753f956 100644 --- a/custom_components/vesync/switch.py +++ b/custom_components/vesync/switch.py @@ -2,6 +2,7 @@ import logging from homeassistant.components.switch import SwitchEntity +from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -14,6 +15,17 @@ _LOGGER = logging.getLogger(__name__) +SENSOR_TYPES_CS158 = { + # unique_id,name # icon, #atribut read, + "end": [ + "end", + "End cooking or preheating ", + "mdi:pot-steam-outline", + "is_running", + ], +} + + async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, From 3da22d2e234ba17b45cb2c88dd678cd4935c873b Mon Sep 17 00:00:00 2001 From: "[PT]GOODVIBE[PT]" Date: Thu, 26 Oct 2023 09:42:41 +0100 Subject: [PATCH 3/7] Add olther model AIRFRYER --- custom_components/vesync/binary_sensor.py | 25 +------ custom_components/vesync/const.py | 80 +++++++++++++++++++++++ custom_components/vesync/sensor.py | 67 +++---------------- custom_components/vesync/switch.py | 10 --- 4 files changed, 92 insertions(+), 90 deletions(-) diff --git a/custom_components/vesync/binary_sensor.py b/custom_components/vesync/binary_sensor.py index 92f7af0..1131146 100644 --- a/custom_components/vesync/binary_sensor.py +++ b/custom_components/vesync/binary_sensor.py @@ -9,29 +9,10 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .common import VeSyncBaseEntity, has_feature -from .const import DOMAIN, VS_BINARY_SENSORS, VS_DISCOVERY +from .const import DOMAIN, VS_BINARY_SENSORS, VS_DISCOVERY, BINARY_SENSOR_TYPES_AIRFRYER _LOGGER = logging.getLogger(__name__) -SENSOR_TYPES_CS158 = { - # unique_id,name # icon, #atribut read, - "is_heating": [ - "is_heating", - "preheating", - "mdi:pot-steam-outline", - ], - "is_cooking": [ - "is_cooking", - "cooking", - "mdi:rice", - ], - "is_running": [ - "is_running", - "running", - "mdi:pause", - ], -} - async def async_setup_entry( hass: HomeAssistant, @@ -63,8 +44,8 @@ def _setup_entities(devices, async_add_entities, coordinator): """Check if device is online and add entity.""" entities = [] for dev in devices: - if (dev.device_type) == "CS158-AF": - for stype in SENSOR_TYPES_CS158.values(): + if hasattr(dev, "fryer_status"): + for stype in BINARY_SENSOR_TYPES_AIRFRYER.values(): entities.append( VeSyncairfryerSensor( dev, diff --git a/custom_components/vesync/const.py b/custom_components/vesync/const.py index 93e8bf1..46bdb7d 100644 --- a/custom_components/vesync/const.py +++ b/custom_components/vesync/const.py @@ -1,5 +1,11 @@ """Constants for VeSync Component.""" +from homeassistant.const import ( + TEMP_CELSIUS, + TIME_MINUTES, + DEVICE_CLASS_TEMPERATURE, +) + DOMAIN = "vesync" VS_DISCOVERY = "vesync_discovery_{}" SERVICE_UPDATE_DEVS = "update_devices" @@ -29,6 +35,7 @@ VS_HUMIDIFIERS_TYPES = ["VeSyncHumid200300S", "VeSyncHumid200S", "VeSyncHumid1000S"] VS_AIRFRYER_TYPES = ["VeSyncAirFryer158"] + DEV_TYPE_TO_HA = { "ESL100": "bulb-dimmable", "ESL100CW": "bulb-tunable-white", @@ -42,3 +49,76 @@ "ESD16": "walldimmer", "ESWD16": "walldimmer", } + + +BINARY_SENSOR_TYPES_AIRFRYER = { + # unique_id,name # icon, #atribut read, + "is_heating": [ + "is_heating", + "preheating", + "mdi:pot-steam-outline", + ], + "is_cooking": [ + "is_cooking", + "cooking", + "mdi:rice", + ], + "is_running": [ + "is_running", + "running", + "mdi:pause", + ], +} + + +SENSOR_TYPES_AIRFRYER = { + # unique_id ,#name ,# unit of measurement,# icon, # device class, #atribut read, + "current_temp": [ + "current_temperature", + "Current temperature", + TEMP_CELSIUS, + None, + DEVICE_CLASS_TEMPERATURE, + "current_temp", + ], + "cook_set_temp": [ + "set_temperature", + "Set temperature", + TEMP_CELSIUS, + None, + DEVICE_CLASS_TEMPERATURE, + "cook_set_temp", + ], + "cook_last_time": [ + "cook_last_time", + "Cook Remaining", + TIME_MINUTES, + "mdi:timer", + TIME_MINUTES, + "cook_last_time", + ], + "preheat_last_time": [ + "preheat_last_time", + "Preheat Remaining", + TIME_MINUTES, + "mdi:timer", + TIME_MINUTES, + "preheat_last_time", + ], + "cook_status": [ + "cook_status", + "Cook Status", + None, + "mdi:rotate-3d-variant", + None, + "cook_status", + ], + # "remaining_time": [ + # "remaining_time", + # "running:", + # TIME_MINUTES, + # "mdi:timer", + # TIME_MINUTES, + # "remaining_time", + # ], +} diff --git a/custom_components/vesync/sensor.py b/custom_components/vesync/sensor.py index 5030371..ff9a393 100644 --- a/custom_components/vesync/sensor.py +++ b/custom_components/vesync/sensor.py @@ -11,9 +11,6 @@ ENERGY_KILO_WATT_HOUR, PERCENTAGE, POWER_WATT, - TEMP_CELSIUS, - TIME_MINUTES, - DEVICE_CLASS_TEMPERATURE, ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -21,62 +18,16 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .common import VeSyncBaseEntity, has_feature -from .const import DEV_TYPE_TO_HA, DOMAIN, VS_DISCOVERY, VS_SENSORS +from .const import ( + DEV_TYPE_TO_HA, + DOMAIN, + VS_DISCOVERY, + VS_SENSORS, + SENSOR_TYPES_AIRFRYER, +) _LOGGER = logging.getLogger(__name__) -SENSOR_TYPES_CS158 = { - # unique_id ,#name ,# unit of measurement,# icon, # device class, #atribut read, - "current_temp": [ - "current_temperature", - "Current temperature", - TEMP_CELSIUS, - None, - DEVICE_CLASS_TEMPERATURE, - "current_temp", - ], - "cook_set_temp": [ - "set_temperature", - "Set temperature", - TEMP_CELSIUS, - None, - DEVICE_CLASS_TEMPERATURE, - "cook_set_temp", - ], - "cook_last_time": [ - "cook_last_time", - "Cook Remaining", - TIME_MINUTES, - "mdi:timer", - TIME_MINUTES, - "cook_last_time", - ], - "preheat_last_time": [ - "preheat_last_time", - "Preheat Remaining", - TIME_MINUTES, - "mdi:timer", - TIME_MINUTES, - "preheat_last_time", - ], - "cook_status": [ - "cook_status", - "Cook Status", - None, - "mdi:rotate-3d-variant", - None, - "cook_status", - ], - "remaining_time": [ - "remaining_time", - "running:", - TIME_MINUTES, - "mdi:timer", - TIME_MINUTES, - "remaining_time", - ], -} - async def async_setup_entry( hass: HomeAssistant, @@ -108,8 +59,8 @@ def _setup_entities(devices, async_add_entities, coordinator): """Check if device is online and add entity.""" entities = [] for dev in devices: - if (dev.device_type) == "CS158-AF": - for stype in SENSOR_TYPES_CS158.values(): + if hasattr(dev, "fryer_status"): + for stype in SENSOR_TYPES_AIRFRYER.values(): entities.append( VeSyncairfryerSensor( dev, diff --git a/custom_components/vesync/switch.py b/custom_components/vesync/switch.py index 753f956..b3553e5 100644 --- a/custom_components/vesync/switch.py +++ b/custom_components/vesync/switch.py @@ -15,16 +15,6 @@ _LOGGER = logging.getLogger(__name__) -SENSOR_TYPES_CS158 = { - # unique_id,name # icon, #atribut read, - "end": [ - "end", - "End cooking or preheating ", - "mdi:pot-steam-outline", - "is_running", - ], -} - async def async_setup_entry( hass: HomeAssistant, From 6ee1166fb62a1ee5d15e4f7a97b8ccad8204a418 Mon Sep 17 00:00:00 2001 From: "[PT]GOODVIBE[PT]" Date: Thu, 26 Oct 2023 10:51:23 +0100 Subject: [PATCH 4/7] Fix Linters error --- custom_components/vesync/binary_sensor.py | 4 ++-- custom_components/vesync/button.py | 4 ++-- custom_components/vesync/common.py | 5 ++--- custom_components/vesync/config_flow.py | 2 +- custom_components/vesync/const.py | 4 ++-- custom_components/vesync/diagnostics.py | 4 ++-- custom_components/vesync/fan.py | 2 +- custom_components/vesync/humidifier.py | 2 +- custom_components/vesync/light.py | 6 +++--- custom_components/vesync/number.py | 10 +++++----- custom_components/vesync/sensor.py | 18 +++++++++--------- custom_components/vesync/switch.py | 19 +++++++++---------- 12 files changed, 39 insertions(+), 41 deletions(-) diff --git a/custom_components/vesync/binary_sensor.py b/custom_components/vesync/binary_sensor.py index 1131146..9e2128a 100644 --- a/custom_components/vesync/binary_sensor.py +++ b/custom_components/vesync/binary_sensor.py @@ -62,7 +62,7 @@ def _setup_entities(devices, async_add_entities, coordinator): class VeSyncairfryerSensor(VeSyncBaseEntity, BinarySensorEntity): - def __init__(self, airfryer, coordinator, stype): + def __init__(self, airfryer, coordinator, stype) -> None: """Initialize the VeSync humidifier device.""" super().__init__(airfryer, coordinator) self.airfryer = airfryer @@ -99,7 +99,7 @@ def icon(self): class VeSyncBinarySensorEntity(VeSyncBaseEntity, BinarySensorEntity): """Representation of a binary sensor describing diagnostics of a VeSync humidifier.""" - def __init__(self, humidifier, coordinator): + def __init__(self, humidifier, coordinator) -> None: """Initialize the VeSync humidifier device.""" super().__init__(humidifier, coordinator) self.smarthumidifier = humidifier diff --git a/custom_components/vesync/button.py b/custom_components/vesync/button.py index 7c5163b..74fc509 100644 --- a/custom_components/vesync/button.py +++ b/custom_components/vesync/button.py @@ -6,7 +6,7 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.entity import EntityCategory + from homeassistant.helpers.entity_platform import AddEntitiesCallback from .common import VeSyncBaseEntity @@ -71,7 +71,7 @@ def _setup_entities(devices, async_add_entities, coordinator): class VeSyncairfryerButton(VeSyncBaseEntity, ButtonEntity): """Base class for VeSync switch Device Representations.""" - def __init__(self, airfryer, coordinator, stype): + def __init__(self, airfryer, coordinator, stype) -> None: """Initialize the VeSync humidifier device.""" super().__init__(airfryer, coordinator) self.airfryer = airfryer diff --git a/custom_components/vesync/common.py b/custom_components/vesync/common.py index 0caf42b..e0a8154 100644 --- a/custom_components/vesync/common.py +++ b/custom_components/vesync/common.py @@ -1,6 +1,5 @@ """Common utilities for VeSync Component.""" import logging -from typing import Optional from homeassistant.components.diagnostics import async_redact_data from homeassistant.helpers.entity import Entity, ToggleEntity @@ -124,7 +123,7 @@ async def async_process_devices(hass, manager): class VeSyncBaseEntity(CoordinatorEntity, Entity): """Base class for VeSync Entity Representations.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync device.""" self.device = device super().__init__(coordinator, context=device) @@ -179,7 +178,7 @@ async def async_added_to_hass(self): class VeSyncDevice(VeSyncBaseEntity, ToggleEntity): """Base class for VeSync Device Representations.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync device.""" super().__init__(device, coordinator) diff --git a/custom_components/vesync/config_flow.py b/custom_components/vesync/config_flow.py index edba11c..c1b34c7 100644 --- a/custom_components/vesync/config_flow.py +++ b/custom_components/vesync/config_flow.py @@ -20,7 +20,7 @@ class VeSyncFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 - def __init__(self): + def __init__(self) -> None: """Instantiate config flow.""" self._username = None self._password = None diff --git a/custom_components/vesync/const.py b/custom_components/vesync/const.py index 46bdb7d..4faa8ae 100644 --- a/custom_components/vesync/const.py +++ b/custom_components/vesync/const.py @@ -52,7 +52,7 @@ BINARY_SENSOR_TYPES_AIRFRYER = { - # unique_id,name # icon, #atribut read, + # unique_id,name # icon, #attribute read, "is_heating": [ "is_heating", "preheating", @@ -72,7 +72,7 @@ SENSOR_TYPES_AIRFRYER = { - # unique_id ,#name ,# unit of measurement,# icon, # device class, #atribut read, + # unique_id ,#name ,# unit of measurement,# icon, # device class, #attribute read, "current_temp": [ "current_temperature", "Current temperature", diff --git a/custom_components/vesync/diagnostics.py b/custom_components/vesync/diagnostics.py index 2899227..ee418ac 100644 --- a/custom_components/vesync/diagnostics.py +++ b/custom_components/vesync/diagnostics.py @@ -8,7 +8,7 @@ from homeassistant.core import HomeAssistant # from .common import is_humidifier -from .const import DOMAIN +# from .const import DOMAIN TO_REDACT = {"cid", "uuid", "mac_id"} @@ -17,7 +17,7 @@ async def async_get_config_entry_diagnostics( hass: HomeAssistant, entry: ConfigEntry ) -> dict[str, Any]: """Return diagnostics for a config entry.""" - data = hass.data[DOMAIN][entry.entry_id] + # data = hass.data[DOMAIN][entry.entry_id] devices = {} # for type in ["fans", "outlets", "switches", "bulbs"]: diff --git a/custom_components/vesync/fan.py b/custom_components/vesync/fan.py index ea64b84..6b3e736 100644 --- a/custom_components/vesync/fan.py +++ b/custom_components/vesync/fan.py @@ -62,7 +62,7 @@ def _setup_entities(devices, async_add_entities, coordinator): class VeSyncFanHA(VeSyncDevice, FanEntity): """Representation of a VeSync fan.""" - def __init__(self, fan, coordinator): + def __init__(self, fan, coordinator) -> None: """Initialize the VeSync fan device.""" super().__init__(fan, coordinator) self.smartfan = fan diff --git a/custom_components/vesync/humidifier.py b/custom_components/vesync/humidifier.py index 431e295..e8a7703 100644 --- a/custom_components/vesync/humidifier.py +++ b/custom_components/vesync/humidifier.py @@ -100,7 +100,7 @@ class VeSyncHumidifierHA(VeSyncDevice, HumidifierEntity): _attr_max_humidity = MAX_HUMIDITY _attr_min_humidity = MIN_HUMIDITY - def __init__(self, humidifier: VeSyncHumid200300S, coordinator): + def __init__(self, humidifier: VeSyncHumid200300S, coordinator) -> None: """Initialize the VeSync humidifier device.""" super().__init__(humidifier, coordinator) self.smarthumidifier = humidifier diff --git a/custom_components/vesync/light.py b/custom_components/vesync/light.py index fd45cd7..59ab5e5 100644 --- a/custom_components/vesync/light.py +++ b/custom_components/vesync/light.py @@ -140,7 +140,7 @@ def turn_on(self, **kwargs): class VeSyncDimmableLightHA(VeSyncBaseLight, LightEntity): """Representation of a VeSync dimmable light device.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync dimmable light device.""" super().__init__(device, coordinator) @@ -158,7 +158,7 @@ def supported_color_modes(self): class VeSyncTunableWhiteLightHA(VeSyncBaseLight, LightEntity): """Representation of a VeSync Tunable White Light device.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync Tunable White Light device.""" super().__init__(device, coordinator) @@ -213,7 +213,7 @@ def supported_color_modes(self): class VeSyncNightLightHA(VeSyncDimmableLightHA): """Representation of the night light on a VeSync device.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync device.""" super().__init__(device, coordinator) self.device = device diff --git a/custom_components/vesync/number.py b/custom_components/vesync/number.py index 306044a..1c9de09 100644 --- a/custom_components/vesync/number.py +++ b/custom_components/vesync/number.py @@ -61,7 +61,7 @@ def _setup_entities(devices, async_add_entities, coordinator): class VeSyncNumberEntity(VeSyncBaseEntity, NumberEntity): """Representation of a number for configuring a VeSync fan.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync fan device.""" super().__init__(device, coordinator) @@ -74,7 +74,7 @@ def entity_category(self): class VeSyncFanSpeedLevelHA(VeSyncNumberEntity): """Representation of the fan speed level of a VeSync fan.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the number entity.""" super().__init__(device, coordinator) self._attr_native_min_value = device.config_dict["levels"][0] @@ -109,7 +109,7 @@ def set_native_value(self, value): class VeSyncHumidifierMistLevelHA(VeSyncNumberEntity): """Representation of the mist level of a VeSync humidifier.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the number entity.""" super().__init__(device, coordinator) self._attr_native_min_value = device.config_dict["mist_levels"][0] @@ -144,7 +144,7 @@ def set_native_value(self, value): class VeSyncHumidifierWarmthLevelHA(VeSyncNumberEntity): """Representation of the warmth level of a VeSync humidifier.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the number entity.""" super().__init__(device, coordinator) self._attr_native_min_value = device.config_dict["warm_mist_levels"][0] @@ -179,7 +179,7 @@ def set_native_value(self, value): class VeSyncHumidifierTargetLevelHA(VeSyncNumberEntity): """Representation of the target humidity level of a VeSync humidifier.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the number entity.""" super().__init__(device, coordinator) self._attr_native_min_value = MIN_HUMIDITY diff --git a/custom_components/vesync/sensor.py b/custom_components/vesync/sensor.py index ff9a393..d56642e 100644 --- a/custom_components/vesync/sensor.py +++ b/custom_components/vesync/sensor.py @@ -89,7 +89,7 @@ def _setup_entities(devices, async_add_entities, coordinator): class VeSyncairfryerSensor(VeSyncBaseEntity, SensorEntity): - def __init__(self, airfryer, coordinator, stype): + def __init__(self, airfryer, coordinator, stype) -> None: """Initialize the VeSync outlet device.""" super().__init__(airfryer, coordinator) @@ -129,7 +129,7 @@ def icon(self): class VeSyncOutletSensorEntity(VeSyncBaseEntity, SensorEntity): """Representation of a sensor describing diagnostics of a VeSync outlet.""" - def __init__(self, plug, coordinator): + def __init__(self, plug, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) self.smartplug = plug @@ -143,7 +143,7 @@ def entity_category(self): class VeSyncPowerSensor(VeSyncOutletSensorEntity): """Representation of current power use for a VeSync outlet.""" - def __init__(self, plug, coordinator): + def __init__(self, plug, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) @@ -186,7 +186,7 @@ def update(self): class VeSyncEnergySensor(VeSyncOutletSensorEntity): """Representation of current day's energy use for a VeSync outlet.""" - def __init__(self, plug, coordinator): + def __init__(self, plug, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) self.smartplug = plug @@ -230,7 +230,7 @@ def update(self): class VeSyncHumidifierSensorEntity(VeSyncBaseEntity, SensorEntity): """Representation of a sensor describing diagnostics of a VeSync humidifier.""" - def __init__(self, humidifier, coordinator): + def __init__(self, humidifier, coordinator) -> None: """Initialize the VeSync humidifier device.""" super().__init__(humidifier, coordinator) self.smarthumidifier = humidifier @@ -247,7 +247,7 @@ class VeSyncAirQualitySensor(VeSyncHumidifierSensorEntity): _attr_state_class = SensorStateClass.MEASUREMENT _attr_native_unit_of_measurement = " " - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync device.""" super().__init__(device, coordinator) self._numeric_quality = None @@ -292,7 +292,7 @@ class VeSyncAirQualityValueSensor(VeSyncHumidifierSensorEntity): _attr_device_class = SensorDeviceClass.AQI _attr_native_unit_of_measurement = " " - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync device.""" super().__init__(device, coordinator) @@ -325,7 +325,7 @@ def native_value(self): class VeSyncFilterLifeSensor(VeSyncHumidifierSensorEntity): """Representation of a filter life sensor.""" - def __init__(self, plug, coordinator): + def __init__(self, plug, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) @@ -376,7 +376,7 @@ def state_attributes(self): class VeSyncHumiditySensor(VeSyncHumidifierSensorEntity): """Representation of current humidity for a VeSync humidifier.""" - def __init__(self, humidity, coordinator): + def __init__(self, humidity, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(humidity, coordinator) diff --git a/custom_components/vesync/switch.py b/custom_components/vesync/switch.py index b3553e5..827aead 100644 --- a/custom_components/vesync/switch.py +++ b/custom_components/vesync/switch.py @@ -2,7 +2,7 @@ import logging from homeassistant.components.switch import SwitchEntity -from homeassistant.components.button import ButtonEntity + from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -15,7 +15,6 @@ _LOGGER = logging.getLogger(__name__) - async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, @@ -65,7 +64,7 @@ def _setup_entities(devices, async_add_entities, coordinator): class VeSyncBaseSwitch(VeSyncDevice, SwitchEntity): """Base class for VeSync switch Device Representations.""" - def __init__(self, plug, coordinator): + def __init__(self, plug, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) @@ -77,7 +76,7 @@ def turn_on(self, **kwargs): class VeSyncSwitchHA(VeSyncBaseSwitch, SwitchEntity): """Representation of a VeSync switch.""" - def __init__(self, plug, coordinator): + def __init__(self, plug, coordinator) -> None: """Initialize the VeSync switch device.""" super().__init__(plug, coordinator) self.smartplug = plug @@ -105,7 +104,7 @@ def update(self): class VeSyncLightSwitch(VeSyncBaseSwitch, SwitchEntity): """Handle representation of VeSync Light Switch.""" - def __init__(self, switch, coordinator): + def __init__(self, switch, coordinator) -> None: """Initialize Light Switch device class.""" super().__init__(switch, coordinator) self.switch = switch @@ -114,7 +113,7 @@ def __init__(self, switch, coordinator): class VeSyncSwitchEntity(VeSyncBaseEntity, SwitchEntity): """Representation of a switch for configuring a VeSync humidifier.""" - def __init__(self, humidifier, coordinator): + def __init__(self, humidifier, coordinator) -> None: """Initialize the VeSync humidifier device.""" super().__init__(humidifier, coordinator) self.smarthumidifier = humidifier @@ -128,7 +127,7 @@ def entity_category(self): class VeSyncFanChildLockHA(VeSyncSwitchEntity): """Representation of the child lock switch.""" - def __init__(self, lock, coordinator): + def __init__(self, lock, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(lock, coordinator) @@ -159,7 +158,7 @@ def turn_off(self, **kwargs): class VeSyncHumidifierDisplayHA(VeSyncSwitchEntity): """Representation of the child lock switch.""" - def __init__(self, lock, coordinator): + def __init__(self, lock, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(lock, coordinator) @@ -190,7 +189,7 @@ def turn_off(self, **kwargs): class VeSyncHumidifierAutomaticStopHA(VeSyncSwitchEntity): """Representation of the automatic stop toggle on a VeSync humidifier.""" - def __init__(self, automatic, coordinator): + def __init__(self, automatic, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(automatic, coordinator) @@ -221,7 +220,7 @@ def turn_off(self, **kwargs): class VeSyncHumidifierAutoOnHA(VeSyncSwitchEntity): """Provide switch to turn off auto mode and set manual mist level 1 on a VeSync humidifier.""" - def __init__(self, autooff, coordinator): + def __init__(self, autooff, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(autooff, coordinator) From 3dc0e63cc3229fa244563a04acd9379b12ed55c5 Mon Sep 17 00:00:00 2001 From: "[PT]GOODVIBE[PT]" Date: Thu, 26 Oct 2023 10:56:08 +0100 Subject: [PATCH 5/7] Fix Linters error --- custom_components/vesync/__init__.py | 2 - custom_components/vesync/binary_sensor.py | 48 +------------ custom_components/vesync/common.py | 55 ++++++--------- custom_components/vesync/config_flow.py | 2 +- custom_components/vesync/const.py | 82 ----------------------- custom_components/vesync/diagnostics.py | 21 +++--- custom_components/vesync/fan.py | 2 +- custom_components/vesync/humidifier.py | 2 +- custom_components/vesync/light.py | 6 +- custom_components/vesync/manifest.json | 2 +- custom_components/vesync/number.py | 10 +-- custom_components/vesync/sensor.py | 78 +++------------------ custom_components/vesync/switch.py | 17 +++-- 13 files changed, 62 insertions(+), 265 deletions(-) diff --git a/custom_components/vesync/__init__.py b/custom_components/vesync/__init__.py index 6c293cf..29e3ddc 100644 --- a/custom_components/vesync/__init__.py +++ b/custom_components/vesync/__init__.py @@ -23,7 +23,6 @@ VS_NUMBERS, VS_SENSORS, VS_SWITCHES, - VS_BUTTON, ) PLATFORMS = { @@ -34,7 +33,6 @@ Platform.HUMIDIFIER: VS_HUMIDIFIERS, Platform.NUMBER: VS_NUMBERS, Platform.BINARY_SENSOR: VS_BINARY_SENSORS, - Platform.BUTTON: VS_BUTTON, } _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/vesync/binary_sensor.py b/custom_components/vesync/binary_sensor.py index 9e2128a..f587dac 100644 --- a/custom_components/vesync/binary_sensor.py +++ b/custom_components/vesync/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .common import VeSyncBaseEntity, has_feature -from .const import DOMAIN, VS_BINARY_SENSORS, VS_DISCOVERY, BINARY_SENSOR_TYPES_AIRFRYER +from .const import DOMAIN, VS_BINARY_SENSORS, VS_DISCOVERY _LOGGER = logging.getLogger(__name__) @@ -44,15 +44,6 @@ def _setup_entities(devices, async_add_entities, coordinator): """Check if device is online and add entity.""" entities = [] for dev in devices: - if hasattr(dev, "fryer_status"): - for stype in BINARY_SENSOR_TYPES_AIRFRYER.values(): - entities.append( - VeSyncairfryerSensor( - dev, - coordinator, - stype, - ) - ) if has_feature(dev, "details", "water_lacks"): entities.append(VeSyncOutOfWaterSensor(dev, coordinator)) if has_feature(dev, "details", "water_tank_lifted"): @@ -61,45 +52,10 @@ def _setup_entities(devices, async_add_entities, coordinator): async_add_entities(entities, update_before_add=True) -class VeSyncairfryerSensor(VeSyncBaseEntity, BinarySensorEntity): - def __init__(self, airfryer, coordinator, stype) -> None: - """Initialize the VeSync humidifier device.""" - super().__init__(airfryer, coordinator) - self.airfryer = airfryer - self.stype = stype - - @property - def entity_category(self): - """Return the diagnostic entity category.""" - return EntityCategory.DIAGNOSTIC - - @property - def unique_id(self): - """Return unique ID for water tank lifted sensor on device.""" - return f"{super().unique_id}-" + self.stype[0] - - @property - def name(self): - """Return sensor name.""" - return self.stype[1] - - @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 self.smarthumidifier.details["water_tank_lifted"] - - @property - def icon(self): - """Return the icon to use in the frontend, if any.""" - return self.stype[2] - - class VeSyncBinarySensorEntity(VeSyncBaseEntity, BinarySensorEntity): """Representation of a binary sensor describing diagnostics of a VeSync humidifier.""" - def __init__(self, humidifier, coordinator) -> None: + def __init__(self, humidifier, coordinator): """Initialize the VeSync humidifier device.""" super().__init__(humidifier, coordinator) self.smarthumidifier = humidifier diff --git a/custom_components/vesync/common.py b/custom_components/vesync/common.py index e0a8154..1732c62 100644 --- a/custom_components/vesync/common.py +++ b/custom_components/vesync/common.py @@ -4,12 +4,10 @@ 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 pyvesync.vesyncfan import model_features from .const import ( DOMAIN, - VS_AIRFRYER_TYPES, VS_BINARY_SENSORS, VS_FAN_TYPES, VS_FANS, @@ -19,7 +17,6 @@ VS_NUMBERS, VS_SENSORS, VS_SWITCHES, - VS_BUTTON, ) _LOGGER = logging.getLogger(__name__) @@ -30,6 +27,16 @@ def has_feature(device, dictionary, attribute): return getattr(device, dictionary, {}).get(attribute, None) is not None +def is_humidifier(device_type: str) -> bool: + """Return true if the device type is a humidifier.""" + return model_features(device_type)["module"] in VS_HUMIDIFIERS_TYPES + + +def is_air_purifier(device_type: str) -> bool: + """Return true if the device type is a an air purifier.""" + return model_features(device_type)["module"] in VS_FAN_TYPES + + async def async_process_devices(hass, manager): """Assign devices to proper component.""" devices = { @@ -40,7 +47,6 @@ async def async_process_devices(hass, manager): VS_HUMIDIFIERS: [], VS_NUMBERS: [], VS_BINARY_SENSORS: [], - VS_BUTTON: [], } redacted = async_redact_data( @@ -48,15 +54,14 @@ async def async_process_devices(hass, manager): ["cid", "uuid", "mac_id"], ) - _LOGGER.warning( + _LOGGER.debug( "Found the following devices: %s", redacted, ) if ( - manager.bulbs is None - and manager.fans is None - and manager.kitchen is None + manager.fans is None + and manager.bulbs is None and manager.outlets is None and manager.switches is None ): @@ -65,13 +70,13 @@ async def async_process_devices(hass, manager): if manager.fans: for fan in manager.fans: # VeSync classifies humidifiers as fans - if fan_model_features(fan.device_type)["module"] in VS_HUMIDIFIERS_TYPES: + if is_humidifier(fan.device_type): devices[VS_HUMIDIFIERS].append(fan) - elif fan_model_features(fan.device_type)["module"] in VS_FAN_TYPES: + elif is_air_purifier(fan.device_type): devices[VS_FANS].append(fan) else: _LOGGER.warning( - "Unknown fan type %s %s (enable debug for more info)", + "Unknown device type %s %s (enable debug for more info)", fan.device_name, fan.device_type, ) @@ -97,33 +102,13 @@ async def async_process_devices(hass, manager): else: devices[VS_LIGHTS].append(switch) - if manager.kitchen: - for airfryer in manager.kitchen: - if ( - kitchen_model_features(airfryer.device_type)["module"] - in VS_AIRFRYER_TYPES - ): - _LOGGER.warning( - "Found air fryer %s, support in progress.\n%s", airfryer.device_name - ) - devices[VS_SENSORS].append(airfryer) - devices[VS_BINARY_SENSORS].append(airfryer) - devices[VS_SWITCHES].append(airfryer) - devices[VS_BUTTON].append(airfryer) - else: - _LOGGER.warning( - "Unknown device type %s %s (enable debug for more info)", - airfryer.device_name, - airfryer.device_type, - ) - return devices class VeSyncBaseEntity(CoordinatorEntity, Entity): """Base class for VeSync Entity Representations.""" - def __init__(self, device, coordinator) -> None: + def __init__(self, device, coordinator): """Initialize the VeSync device.""" self.device = device super().__init__(coordinator, context=device) @@ -145,7 +130,7 @@ def unique_id(self): @property def base_name(self): """Return the name of the device.""" - return self.device.device_type + return self.device.device_name @property def name(self): @@ -178,7 +163,7 @@ async def async_added_to_hass(self): class VeSyncDevice(VeSyncBaseEntity, ToggleEntity): """Base class for VeSync Device Representations.""" - def __init__(self, device, coordinator) -> None: + def __init__(self, device, coordinator): """Initialize the VeSync device.""" super().__init__(device, coordinator) diff --git a/custom_components/vesync/config_flow.py b/custom_components/vesync/config_flow.py index c1b34c7..edba11c 100644 --- a/custom_components/vesync/config_flow.py +++ b/custom_components/vesync/config_flow.py @@ -20,7 +20,7 @@ class VeSyncFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 - def __init__(self) -> None: + def __init__(self): """Instantiate config flow.""" self._username = None self._password = None diff --git a/custom_components/vesync/const.py b/custom_components/vesync/const.py index 4faa8ae..7ea7957 100644 --- a/custom_components/vesync/const.py +++ b/custom_components/vesync/const.py @@ -1,16 +1,9 @@ """Constants for VeSync Component.""" -from homeassistant.const import ( - TEMP_CELSIUS, - TIME_MINUTES, - DEVICE_CLASS_TEMPERATURE, -) - DOMAIN = "vesync" VS_DISCOVERY = "vesync_discovery_{}" SERVICE_UPDATE_DEVS = "update_devices" -VS_BUTTON = "button" VS_SWITCHES = "switches" VS_FAN = "fan" VS_FANS = "fans" @@ -33,8 +26,6 @@ VS_FAN_TYPES = ["VeSyncAirBypass", "VeSyncAir131", "VeSyncVital"] VS_HUMIDIFIERS_TYPES = ["VeSyncHumid200300S", "VeSyncHumid200S", "VeSyncHumid1000S"] -VS_AIRFRYER_TYPES = ["VeSyncAirFryer158"] - DEV_TYPE_TO_HA = { "ESL100": "bulb-dimmable", @@ -49,76 +40,3 @@ "ESD16": "walldimmer", "ESWD16": "walldimmer", } - - -BINARY_SENSOR_TYPES_AIRFRYER = { - # unique_id,name # icon, #attribute read, - "is_heating": [ - "is_heating", - "preheating", - "mdi:pot-steam-outline", - ], - "is_cooking": [ - "is_cooking", - "cooking", - "mdi:rice", - ], - "is_running": [ - "is_running", - "running", - "mdi:pause", - ], -} - - -SENSOR_TYPES_AIRFRYER = { - # unique_id ,#name ,# unit of measurement,# icon, # device class, #attribute read, - "current_temp": [ - "current_temperature", - "Current temperature", - TEMP_CELSIUS, - None, - DEVICE_CLASS_TEMPERATURE, - "current_temp", - ], - "cook_set_temp": [ - "set_temperature", - "Set temperature", - TEMP_CELSIUS, - None, - DEVICE_CLASS_TEMPERATURE, - "cook_set_temp", - ], - "cook_last_time": [ - "cook_last_time", - "Cook Remaining", - TIME_MINUTES, - "mdi:timer", - TIME_MINUTES, - "cook_last_time", - ], - "preheat_last_time": [ - "preheat_last_time", - "Preheat Remaining", - TIME_MINUTES, - "mdi:timer", - TIME_MINUTES, - "preheat_last_time", - ], - "cook_status": [ - "cook_status", - "Cook Status", - None, - "mdi:rotate-3d-variant", - None, - "cook_status", - ], - # "remaining_time": [ - # "remaining_time", - # "running:", - # TIME_MINUTES, - # "mdi:timer", - # TIME_MINUTES, - # "remaining_time", - # ], -} diff --git a/custom_components/vesync/diagnostics.py b/custom_components/vesync/diagnostics.py index ee418ac..ccaad25 100644 --- a/custom_components/vesync/diagnostics.py +++ b/custom_components/vesync/diagnostics.py @@ -7,8 +7,8 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -# from .common import is_humidifier -# from .const import DOMAIN +from .common import is_humidifier +from .const import DOMAIN TO_REDACT = {"cid", "uuid", "mac_id"} @@ -17,14 +17,13 @@ async def async_get_config_entry_diagnostics( hass: HomeAssistant, entry: ConfigEntry ) -> dict[str, Any]: """Return diagnostics for a config entry.""" - # data = hass.data[DOMAIN][entry.entry_id] + data = hass.data[DOMAIN][entry.entry_id] devices = {} - - # for type in ["fans", "outlets", "switches", "bulbs"]: - # for d in data["manager"]._dev_list[type]: - # t = "humidifier" if is_humidifier(d.device_type) else type - # devices = { - # **devices, - # **{t: [{k: v for k, v in d.__dict__.items() if k != "manager"}]}, - # } + for type in ["fans", "outlets", "switches", "bulbs"]: + for d in data["manager"]._dev_list[type]: + t = "humidifier" if is_humidifier(d.device_type) else type + devices = { + **devices, + **{t: [{k: v for k, v in d.__dict__.items() if k != "manager"}]}, + } return async_redact_data(devices, TO_REDACT) diff --git a/custom_components/vesync/fan.py b/custom_components/vesync/fan.py index 6b3e736..ea64b84 100644 --- a/custom_components/vesync/fan.py +++ b/custom_components/vesync/fan.py @@ -62,7 +62,7 @@ def _setup_entities(devices, async_add_entities, coordinator): class VeSyncFanHA(VeSyncDevice, FanEntity): """Representation of a VeSync fan.""" - def __init__(self, fan, coordinator) -> None: + def __init__(self, fan, coordinator): """Initialize the VeSync fan device.""" super().__init__(fan, coordinator) self.smartfan = fan diff --git a/custom_components/vesync/humidifier.py b/custom_components/vesync/humidifier.py index e8a7703..431e295 100644 --- a/custom_components/vesync/humidifier.py +++ b/custom_components/vesync/humidifier.py @@ -100,7 +100,7 @@ class VeSyncHumidifierHA(VeSyncDevice, HumidifierEntity): _attr_max_humidity = MAX_HUMIDITY _attr_min_humidity = MIN_HUMIDITY - def __init__(self, humidifier: VeSyncHumid200300S, coordinator) -> None: + def __init__(self, humidifier: VeSyncHumid200300S, coordinator): """Initialize the VeSync humidifier device.""" super().__init__(humidifier, coordinator) self.smarthumidifier = humidifier diff --git a/custom_components/vesync/light.py b/custom_components/vesync/light.py index 59ab5e5..fd45cd7 100644 --- a/custom_components/vesync/light.py +++ b/custom_components/vesync/light.py @@ -140,7 +140,7 @@ def turn_on(self, **kwargs): class VeSyncDimmableLightHA(VeSyncBaseLight, LightEntity): """Representation of a VeSync dimmable light device.""" - def __init__(self, device, coordinator) -> None: + def __init__(self, device, coordinator): """Initialize the VeSync dimmable light device.""" super().__init__(device, coordinator) @@ -158,7 +158,7 @@ def supported_color_modes(self): class VeSyncTunableWhiteLightHA(VeSyncBaseLight, LightEntity): """Representation of a VeSync Tunable White Light device.""" - def __init__(self, device, coordinator) -> None: + def __init__(self, device, coordinator): """Initialize the VeSync Tunable White Light device.""" super().__init__(device, coordinator) @@ -213,7 +213,7 @@ def supported_color_modes(self): class VeSyncNightLightHA(VeSyncDimmableLightHA): """Representation of the night light on a VeSync device.""" - def __init__(self, device, coordinator) -> None: + def __init__(self, device, coordinator): """Initialize the VeSync device.""" super().__init__(device, coordinator) self.device = device diff --git a/custom_components/vesync/manifest.json b/custom_components/vesync/manifest.json index 5c37b8d..d47f0b6 100644 --- a/custom_components/vesync/manifest.json +++ b/custom_components/vesync/manifest.json @@ -1,7 +1,7 @@ { "domain": "vesync", "name": "VeSync", - "codeowners": ["@markperdue", "@webdjoe", "@thegardenmonkey", "@vlebourl","@tv4you2016"], + "codeowners": ["@markperdue", "@webdjoe", "@thegardenmonkey", "@vlebourl", "@tv4you2016"], "config_flow": true, "dhcp": [ { diff --git a/custom_components/vesync/number.py b/custom_components/vesync/number.py index 1c9de09..306044a 100644 --- a/custom_components/vesync/number.py +++ b/custom_components/vesync/number.py @@ -61,7 +61,7 @@ def _setup_entities(devices, async_add_entities, coordinator): class VeSyncNumberEntity(VeSyncBaseEntity, NumberEntity): """Representation of a number for configuring a VeSync fan.""" - def __init__(self, device, coordinator) -> None: + def __init__(self, device, coordinator): """Initialize the VeSync fan device.""" super().__init__(device, coordinator) @@ -74,7 +74,7 @@ def entity_category(self): class VeSyncFanSpeedLevelHA(VeSyncNumberEntity): """Representation of the fan speed level of a VeSync fan.""" - def __init__(self, device, coordinator) -> None: + def __init__(self, device, coordinator): """Initialize the number entity.""" super().__init__(device, coordinator) self._attr_native_min_value = device.config_dict["levels"][0] @@ -109,7 +109,7 @@ def set_native_value(self, value): class VeSyncHumidifierMistLevelHA(VeSyncNumberEntity): """Representation of the mist level of a VeSync humidifier.""" - def __init__(self, device, coordinator) -> None: + def __init__(self, device, coordinator): """Initialize the number entity.""" super().__init__(device, coordinator) self._attr_native_min_value = device.config_dict["mist_levels"][0] @@ -144,7 +144,7 @@ def set_native_value(self, value): class VeSyncHumidifierWarmthLevelHA(VeSyncNumberEntity): """Representation of the warmth level of a VeSync humidifier.""" - def __init__(self, device, coordinator) -> None: + def __init__(self, device, coordinator): """Initialize the number entity.""" super().__init__(device, coordinator) self._attr_native_min_value = device.config_dict["warm_mist_levels"][0] @@ -179,7 +179,7 @@ def set_native_value(self, value): class VeSyncHumidifierTargetLevelHA(VeSyncNumberEntity): """Representation of the target humidity level of a VeSync humidifier.""" - def __init__(self, device, coordinator) -> None: + def __init__(self, device, coordinator): """Initialize the number entity.""" super().__init__(device, coordinator) self._attr_native_min_value = MIN_HUMIDITY diff --git a/custom_components/vesync/sensor.py b/custom_components/vesync/sensor.py index d56642e..e69a785 100644 --- a/custom_components/vesync/sensor.py +++ b/custom_components/vesync/sensor.py @@ -7,24 +7,14 @@ SensorStateClass, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ( - ENERGY_KILO_WATT_HOUR, - PERCENTAGE, - POWER_WATT, -) +from homeassistant.const import ENERGY_KILO_WATT_HOUR, PERCENTAGE, POWER_WATT from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity_platform import AddEntitiesCallback from .common import VeSyncBaseEntity, has_feature -from .const import ( - DEV_TYPE_TO_HA, - DOMAIN, - VS_DISCOVERY, - VS_SENSORS, - SENSOR_TYPES_AIRFRYER, -) +from .const import DEV_TYPE_TO_HA, DOMAIN, VS_DISCOVERY, VS_SENSORS _LOGGER = logging.getLogger(__name__) @@ -59,16 +49,6 @@ def _setup_entities(devices, async_add_entities, coordinator): """Check if device is online and add entity.""" entities = [] for dev in devices: - if hasattr(dev, "fryer_status"): - for stype in SENSOR_TYPES_AIRFRYER.values(): - entities.append( - VeSyncairfryerSensor( - dev, - coordinator, - stype, - ) - ) - if DEV_TYPE_TO_HA.get(dev.device_type) == "outlet": entities.extend( ( @@ -88,48 +68,10 @@ def _setup_entities(devices, async_add_entities, coordinator): async_add_entities(entities, update_before_add=True) -class VeSyncairfryerSensor(VeSyncBaseEntity, SensorEntity): - def __init__(self, airfryer, coordinator, stype) -> None: - """Initialize the VeSync outlet device.""" - - super().__init__(airfryer, coordinator) - self.airfryer = airfryer - self.stype = stype - - @property - def unique_id(self): - """Return unique ID for power sensor on device.""" - return f"{super().unique_id}-" + self.stype[0] - - @property - def name(self): - """Return sensor name.""" - return self.stype[1] - - @property - def device_class(self): - return self.stype[4] - - @property - def native_value(self): - value = getattr(self.airfryer, self.stype[5], None) - return value - - @property - def native_unit_of_measurement(self): - # return self.airfryer.temp_unit - return self.stype[2] - - @property - def icon(self): - """Return the icon to use in the frontend, if any.""" - return self.stype[3] - - class VeSyncOutletSensorEntity(VeSyncBaseEntity, SensorEntity): """Representation of a sensor describing diagnostics of a VeSync outlet.""" - def __init__(self, plug, coordinator) -> None: + def __init__(self, plug, coordinator): """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) self.smartplug = plug @@ -143,7 +85,7 @@ def entity_category(self): class VeSyncPowerSensor(VeSyncOutletSensorEntity): """Representation of current power use for a VeSync outlet.""" - def __init__(self, plug, coordinator) -> None: + def __init__(self, plug, coordinator): """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) @@ -186,7 +128,7 @@ def update(self): class VeSyncEnergySensor(VeSyncOutletSensorEntity): """Representation of current day's energy use for a VeSync outlet.""" - def __init__(self, plug, coordinator) -> None: + def __init__(self, plug, coordinator): """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) self.smartplug = plug @@ -230,7 +172,7 @@ def update(self): class VeSyncHumidifierSensorEntity(VeSyncBaseEntity, SensorEntity): """Representation of a sensor describing diagnostics of a VeSync humidifier.""" - def __init__(self, humidifier, coordinator) -> None: + def __init__(self, humidifier, coordinator): """Initialize the VeSync humidifier device.""" super().__init__(humidifier, coordinator) self.smarthumidifier = humidifier @@ -247,7 +189,7 @@ class VeSyncAirQualitySensor(VeSyncHumidifierSensorEntity): _attr_state_class = SensorStateClass.MEASUREMENT _attr_native_unit_of_measurement = " " - def __init__(self, device, coordinator) -> None: + def __init__(self, device, coordinator): """Initialize the VeSync device.""" super().__init__(device, coordinator) self._numeric_quality = None @@ -292,7 +234,7 @@ class VeSyncAirQualityValueSensor(VeSyncHumidifierSensorEntity): _attr_device_class = SensorDeviceClass.AQI _attr_native_unit_of_measurement = " " - def __init__(self, device, coordinator) -> None: + def __init__(self, device, coordinator): """Initialize the VeSync device.""" super().__init__(device, coordinator) @@ -325,7 +267,7 @@ def native_value(self): class VeSyncFilterLifeSensor(VeSyncHumidifierSensorEntity): """Representation of a filter life sensor.""" - def __init__(self, plug, coordinator) -> None: + def __init__(self, plug, coordinator): """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) @@ -376,7 +318,7 @@ def state_attributes(self): class VeSyncHumiditySensor(VeSyncHumidifierSensorEntity): """Representation of current humidity for a VeSync humidifier.""" - def __init__(self, humidity, coordinator) -> None: + def __init__(self, humidity, coordinator): """Initialize the VeSync outlet device.""" super().__init__(humidity, coordinator) diff --git a/custom_components/vesync/switch.py b/custom_components/vesync/switch.py index 827aead..65887b1 100644 --- a/custom_components/vesync/switch.py +++ b/custom_components/vesync/switch.py @@ -2,7 +2,6 @@ import logging from homeassistant.components.switch import SwitchEntity - from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -64,7 +63,7 @@ def _setup_entities(devices, async_add_entities, coordinator): class VeSyncBaseSwitch(VeSyncDevice, SwitchEntity): """Base class for VeSync switch Device Representations.""" - def __init__(self, plug, coordinator) -> None: + def __init__(self, plug, coordinator): """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) @@ -76,7 +75,7 @@ def turn_on(self, **kwargs): class VeSyncSwitchHA(VeSyncBaseSwitch, SwitchEntity): """Representation of a VeSync switch.""" - def __init__(self, plug, coordinator) -> None: + def __init__(self, plug, coordinator): """Initialize the VeSync switch device.""" super().__init__(plug, coordinator) self.smartplug = plug @@ -104,7 +103,7 @@ def update(self): class VeSyncLightSwitch(VeSyncBaseSwitch, SwitchEntity): """Handle representation of VeSync Light Switch.""" - def __init__(self, switch, coordinator) -> None: + def __init__(self, switch, coordinator): """Initialize Light Switch device class.""" super().__init__(switch, coordinator) self.switch = switch @@ -113,7 +112,7 @@ def __init__(self, switch, coordinator) -> None: class VeSyncSwitchEntity(VeSyncBaseEntity, SwitchEntity): """Representation of a switch for configuring a VeSync humidifier.""" - def __init__(self, humidifier, coordinator) -> None: + def __init__(self, humidifier, coordinator): """Initialize the VeSync humidifier device.""" super().__init__(humidifier, coordinator) self.smarthumidifier = humidifier @@ -127,7 +126,7 @@ def entity_category(self): class VeSyncFanChildLockHA(VeSyncSwitchEntity): """Representation of the child lock switch.""" - def __init__(self, lock, coordinator) -> None: + def __init__(self, lock, coordinator): """Initialize the VeSync outlet device.""" super().__init__(lock, coordinator) @@ -158,7 +157,7 @@ def turn_off(self, **kwargs): class VeSyncHumidifierDisplayHA(VeSyncSwitchEntity): """Representation of the child lock switch.""" - def __init__(self, lock, coordinator) -> None: + def __init__(self, lock, coordinator): """Initialize the VeSync outlet device.""" super().__init__(lock, coordinator) @@ -189,7 +188,7 @@ def turn_off(self, **kwargs): class VeSyncHumidifierAutomaticStopHA(VeSyncSwitchEntity): """Representation of the automatic stop toggle on a VeSync humidifier.""" - def __init__(self, automatic, coordinator) -> None: + def __init__(self, automatic, coordinator): """Initialize the VeSync outlet device.""" super().__init__(automatic, coordinator) @@ -220,7 +219,7 @@ def turn_off(self, **kwargs): class VeSyncHumidifierAutoOnHA(VeSyncSwitchEntity): """Provide switch to turn off auto mode and set manual mist level 1 on a VeSync humidifier.""" - def __init__(self, autooff, coordinator) -> None: + def __init__(self, autooff, coordinator): """Initialize the VeSync outlet device.""" super().__init__(autooff, coordinator) From 90f385f4e25fcdf5f64f2d9f3a42a870a75e457c Mon Sep 17 00:00:00 2001 From: "[PT]GOODVIBE[PT]" Date: Thu, 26 Oct 2023 11:27:31 +0100 Subject: [PATCH 6/7] pass in Linters (flake8, black, isort) --- custom_components/vesync/__init__.py | 2 + custom_components/vesync/binary_sensor.py | 50 ++++++++++++++- custom_components/vesync/button.py | 4 +- custom_components/vesync/common.py | 55 ++++++++++------ custom_components/vesync/config_flow.py | 2 +- custom_components/vesync/const.py | 78 +++++++++++++++++++++++ custom_components/vesync/diagnostics.py | 21 +++--- custom_components/vesync/fan.py | 2 +- custom_components/vesync/humidifier.py | 2 +- custom_components/vesync/light.py | 6 +- custom_components/vesync/manifest.json | 2 +- custom_components/vesync/number.py | 10 +-- custom_components/vesync/sensor.py | 76 +++++++++++++++++++--- custom_components/vesync/switch.py | 16 ++--- 14 files changed, 262 insertions(+), 64 deletions(-) diff --git a/custom_components/vesync/__init__.py b/custom_components/vesync/__init__.py index 29e3ddc..16bec23 100644 --- a/custom_components/vesync/__init__.py +++ b/custom_components/vesync/__init__.py @@ -15,6 +15,7 @@ DOMAIN, SERVICE_UPDATE_DEVS, VS_BINARY_SENSORS, + VS_BUTTON, VS_DISCOVERY, VS_FANS, VS_HUMIDIFIERS, @@ -33,6 +34,7 @@ Platform.HUMIDIFIER: VS_HUMIDIFIERS, Platform.NUMBER: VS_NUMBERS, Platform.BINARY_SENSOR: VS_BINARY_SENSORS, + Platform.BUTTON: VS_BUTTON, } _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/vesync/binary_sensor.py b/custom_components/vesync/binary_sensor.py index f587dac..a9dbd8f 100644 --- a/custom_components/vesync/binary_sensor.py +++ b/custom_components/vesync/binary_sensor.py @@ -9,7 +9,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .common import VeSyncBaseEntity, has_feature -from .const import DOMAIN, VS_BINARY_SENSORS, VS_DISCOVERY +from .const import BINARY_SENSOR_TYPES_AIRFRYER, DOMAIN, VS_BINARY_SENSORS, VS_DISCOVERY _LOGGER = logging.getLogger(__name__) @@ -44,6 +44,15 @@ def _setup_entities(devices, async_add_entities, coordinator): """Check if device is online and add entity.""" entities = [] for dev in devices: + if hasattr(dev, "fryer_status"): + for stype in BINARY_SENSOR_TYPES_AIRFRYER.values(): + entities.append( + VeSyncairfryerSensor( + dev, + coordinator, + stype, + ) + ) if has_feature(dev, "details", "water_lacks"): entities.append(VeSyncOutOfWaterSensor(dev, coordinator)) if has_feature(dev, "details", "water_tank_lifted"): @@ -52,10 +61,47 @@ def _setup_entities(devices, async_add_entities, coordinator): async_add_entities(entities, update_before_add=True) +class VeSyncairfryerSensor(VeSyncBaseEntity, BinarySensorEntity): + """Class representing a VeSyncairfryerSensor.""" + + def __init__(self, airfryer, coordinator, stype) -> None: + """Initialize the VeSync humidifier device.""" + super().__init__(airfryer, coordinator) + self.airfryer = airfryer + self.stype = stype + + @property + def entity_category(self): + """Return the diagnostic entity category.""" + return EntityCategory.DIAGNOSTIC + + @property + def unique_id(self): + """Return unique ID for water tank lifted sensor on device.""" + return f"{super().unique_id}-" + self.stype[0] + + @property + def name(self): + """Return sensor name.""" + return self.stype[1] + + @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 self.smarthumidifier.details["water_tank_lifted"] + + @property + def icon(self): + """Return the icon to use in the frontend, if any.""" + return self.stype[2] + + class VeSyncBinarySensorEntity(VeSyncBaseEntity, BinarySensorEntity): """Representation of a binary sensor describing diagnostics of a VeSync humidifier.""" - def __init__(self, humidifier, coordinator): + def __init__(self, humidifier, coordinator) -> None: """Initialize the VeSync humidifier device.""" super().__init__(humidifier, coordinator) self.smarthumidifier = humidifier diff --git a/custom_components/vesync/button.py b/custom_components/vesync/button.py index 74fc509..8109629 100644 --- a/custom_components/vesync/button.py +++ b/custom_components/vesync/button.py @@ -1,16 +1,14 @@ """Support for VeSync button.""" import logging - from homeassistant.components.button import ButtonEntity 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 .common import VeSyncBaseEntity -from .const import DOMAIN, VS_DISCOVERY, VS_BUTTON +from .const import DOMAIN, VS_BUTTON, VS_DISCOVERY _LOGGER = logging.getLogger(__name__) diff --git a/custom_components/vesync/common.py b/custom_components/vesync/common.py index 1732c62..e2c9dc5 100644 --- a/custom_components/vesync/common.py +++ b/custom_components/vesync/common.py @@ -4,11 +4,14 @@ 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 +from pyvesync.vesyncfan import model_features as fan_model_features +from pyvesync.vesynckitchen import model_features as kitchen_model_features from .const import ( DOMAIN, + VS_AIRFRYER_TYPES, VS_BINARY_SENSORS, + VS_BUTTON, VS_FAN_TYPES, VS_FANS, VS_HUMIDIFIERS, @@ -27,16 +30,6 @@ def has_feature(device, dictionary, attribute): return getattr(device, dictionary, {}).get(attribute, None) is not None -def is_humidifier(device_type: str) -> bool: - """Return true if the device type is a humidifier.""" - return model_features(device_type)["module"] in VS_HUMIDIFIERS_TYPES - - -def is_air_purifier(device_type: str) -> bool: - """Return true if the device type is a an air purifier.""" - return model_features(device_type)["module"] in VS_FAN_TYPES - - async def async_process_devices(hass, manager): """Assign devices to proper component.""" devices = { @@ -47,6 +40,7 @@ async def async_process_devices(hass, manager): VS_HUMIDIFIERS: [], VS_NUMBERS: [], VS_BINARY_SENSORS: [], + VS_BUTTON: [], } redacted = async_redact_data( @@ -54,14 +48,15 @@ async def async_process_devices(hass, manager): ["cid", "uuid", "mac_id"], ) - _LOGGER.debug( + _LOGGER.warning( "Found the following devices: %s", redacted, ) if ( - manager.fans is None - and manager.bulbs is None + manager.bulbs is None + and manager.fans is None + and manager.kitchen is None and manager.outlets is None and manager.switches is None ): @@ -70,13 +65,13 @@ async def async_process_devices(hass, manager): if manager.fans: for fan in manager.fans: # VeSync classifies humidifiers as fans - if is_humidifier(fan.device_type): + if fan_model_features(fan.device_type)["module"] in VS_HUMIDIFIERS_TYPES: devices[VS_HUMIDIFIERS].append(fan) - elif is_air_purifier(fan.device_type): + elif fan_model_features(fan.device_type)["module"] in VS_FAN_TYPES: devices[VS_FANS].append(fan) else: _LOGGER.warning( - "Unknown device type %s %s (enable debug for more info)", + "Unknown fan type %s %s (enable debug for more info)", fan.device_name, fan.device_type, ) @@ -102,13 +97,33 @@ async def async_process_devices(hass, manager): else: devices[VS_LIGHTS].append(switch) + if manager.kitchen: + for airfryer in manager.kitchen: + if ( + kitchen_model_features(airfryer.device_type)["module"] + in VS_AIRFRYER_TYPES + ): + _LOGGER.warning( + "Found air fryer %s, support in progress.\n%s", airfryer.device_name + ) + devices[VS_SENSORS].append(airfryer) + devices[VS_BINARY_SENSORS].append(airfryer) + devices[VS_SWITCHES].append(airfryer) + devices[VS_BUTTON].append(airfryer) + else: + _LOGGER.warning( + "Unknown device type %s %s (enable debug for more info)", + airfryer.device_name, + airfryer.device_type, + ) + return devices class VeSyncBaseEntity(CoordinatorEntity, Entity): """Base class for VeSync Entity Representations.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync device.""" self.device = device super().__init__(coordinator, context=device) @@ -130,7 +145,7 @@ def unique_id(self): @property def base_name(self): """Return the name of the device.""" - return self.device.device_name + return self.device.device_type @property def name(self): @@ -163,7 +178,7 @@ async def async_added_to_hass(self): class VeSyncDevice(VeSyncBaseEntity, ToggleEntity): """Base class for VeSync Device Representations.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync device.""" super().__init__(device, coordinator) diff --git a/custom_components/vesync/config_flow.py b/custom_components/vesync/config_flow.py index edba11c..c1b34c7 100644 --- a/custom_components/vesync/config_flow.py +++ b/custom_components/vesync/config_flow.py @@ -20,7 +20,7 @@ class VeSyncFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): VERSION = 1 - def __init__(self): + def __init__(self) -> None: """Instantiate config flow.""" self._username = None self._password = None diff --git a/custom_components/vesync/const.py b/custom_components/vesync/const.py index 7ea7957..65f07e2 100644 --- a/custom_components/vesync/const.py +++ b/custom_components/vesync/const.py @@ -1,9 +1,12 @@ """Constants for VeSync Component.""" +from homeassistant.const import DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, TIME_MINUTES + DOMAIN = "vesync" VS_DISCOVERY = "vesync_discovery_{}" SERVICE_UPDATE_DEVS = "update_devices" +VS_BUTTON = "button" VS_SWITCHES = "switches" VS_FAN = "fan" VS_FANS = "fans" @@ -26,6 +29,8 @@ VS_FAN_TYPES = ["VeSyncAirBypass", "VeSyncAir131", "VeSyncVital"] VS_HUMIDIFIERS_TYPES = ["VeSyncHumid200300S", "VeSyncHumid200S", "VeSyncHumid1000S"] +VS_AIRFRYER_TYPES = ["VeSyncAirFryer158"] + DEV_TYPE_TO_HA = { "ESL100": "bulb-dimmable", @@ -40,3 +45,76 @@ "ESD16": "walldimmer", "ESWD16": "walldimmer", } + + +BINARY_SENSOR_TYPES_AIRFRYER = { + # unique_id,name # icon, #attribute read, + "is_heating": [ + "is_heating", + "preheating", + "mdi:pot-steam-outline", + ], + "is_cooking": [ + "is_cooking", + "cooking", + "mdi:rice", + ], + "is_running": [ + "is_running", + "running", + "mdi:pause", + ], +} + + +SENSOR_TYPES_AIRFRYER = { + # unique_id ,#name ,# unit of measurement,# icon, # device class, #attribute read, + "current_temp": [ + "current_temperature", + "Current temperature", + TEMP_CELSIUS, + None, + DEVICE_CLASS_TEMPERATURE, + "current_temp", + ], + "cook_set_temp": [ + "set_temperature", + "Set temperature", + TEMP_CELSIUS, + None, + DEVICE_CLASS_TEMPERATURE, + "cook_set_temp", + ], + "cook_last_time": [ + "cook_last_time", + "Cook Remaining", + TIME_MINUTES, + "mdi:timer", + TIME_MINUTES, + "cook_last_time", + ], + "preheat_last_time": [ + "preheat_last_time", + "Preheat Remaining", + TIME_MINUTES, + "mdi:timer", + TIME_MINUTES, + "preheat_last_time", + ], + "cook_status": [ + "cook_status", + "Cook Status", + None, + "mdi:rotate-3d-variant", + None, + "cook_status", + ], + # "remaining_time": [ + # "remaining_time", + # "running:", + # TIME_MINUTES, + # "mdi:timer", + # TIME_MINUTES, + # "remaining_time", + # ], +} diff --git a/custom_components/vesync/diagnostics.py b/custom_components/vesync/diagnostics.py index ccaad25..ee418ac 100644 --- a/custom_components/vesync/diagnostics.py +++ b/custom_components/vesync/diagnostics.py @@ -7,8 +7,8 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from .common import is_humidifier -from .const import DOMAIN +# from .common import is_humidifier +# from .const import DOMAIN TO_REDACT = {"cid", "uuid", "mac_id"} @@ -17,13 +17,14 @@ async def async_get_config_entry_diagnostics( hass: HomeAssistant, entry: ConfigEntry ) -> dict[str, Any]: """Return diagnostics for a config entry.""" - data = hass.data[DOMAIN][entry.entry_id] + # data = hass.data[DOMAIN][entry.entry_id] devices = {} - for type in ["fans", "outlets", "switches", "bulbs"]: - for d in data["manager"]._dev_list[type]: - t = "humidifier" if is_humidifier(d.device_type) else type - devices = { - **devices, - **{t: [{k: v for k, v in d.__dict__.items() if k != "manager"}]}, - } + + # for type in ["fans", "outlets", "switches", "bulbs"]: + # for d in data["manager"]._dev_list[type]: + # t = "humidifier" if is_humidifier(d.device_type) else type + # devices = { + # **devices, + # **{t: [{k: v for k, v in d.__dict__.items() if k != "manager"}]}, + # } return async_redact_data(devices, TO_REDACT) diff --git a/custom_components/vesync/fan.py b/custom_components/vesync/fan.py index ea64b84..6b3e736 100644 --- a/custom_components/vesync/fan.py +++ b/custom_components/vesync/fan.py @@ -62,7 +62,7 @@ def _setup_entities(devices, async_add_entities, coordinator): class VeSyncFanHA(VeSyncDevice, FanEntity): """Representation of a VeSync fan.""" - def __init__(self, fan, coordinator): + def __init__(self, fan, coordinator) -> None: """Initialize the VeSync fan device.""" super().__init__(fan, coordinator) self.smartfan = fan diff --git a/custom_components/vesync/humidifier.py b/custom_components/vesync/humidifier.py index 431e295..e8a7703 100644 --- a/custom_components/vesync/humidifier.py +++ b/custom_components/vesync/humidifier.py @@ -100,7 +100,7 @@ class VeSyncHumidifierHA(VeSyncDevice, HumidifierEntity): _attr_max_humidity = MAX_HUMIDITY _attr_min_humidity = MIN_HUMIDITY - def __init__(self, humidifier: VeSyncHumid200300S, coordinator): + def __init__(self, humidifier: VeSyncHumid200300S, coordinator) -> None: """Initialize the VeSync humidifier device.""" super().__init__(humidifier, coordinator) self.smarthumidifier = humidifier diff --git a/custom_components/vesync/light.py b/custom_components/vesync/light.py index fd45cd7..59ab5e5 100644 --- a/custom_components/vesync/light.py +++ b/custom_components/vesync/light.py @@ -140,7 +140,7 @@ def turn_on(self, **kwargs): class VeSyncDimmableLightHA(VeSyncBaseLight, LightEntity): """Representation of a VeSync dimmable light device.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync dimmable light device.""" super().__init__(device, coordinator) @@ -158,7 +158,7 @@ def supported_color_modes(self): class VeSyncTunableWhiteLightHA(VeSyncBaseLight, LightEntity): """Representation of a VeSync Tunable White Light device.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync Tunable White Light device.""" super().__init__(device, coordinator) @@ -213,7 +213,7 @@ def supported_color_modes(self): class VeSyncNightLightHA(VeSyncDimmableLightHA): """Representation of the night light on a VeSync device.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync device.""" super().__init__(device, coordinator) self.device = device diff --git a/custom_components/vesync/manifest.json b/custom_components/vesync/manifest.json index d47f0b6..5c37b8d 100644 --- a/custom_components/vesync/manifest.json +++ b/custom_components/vesync/manifest.json @@ -1,7 +1,7 @@ { "domain": "vesync", "name": "VeSync", - "codeowners": ["@markperdue", "@webdjoe", "@thegardenmonkey", "@vlebourl", "@tv4you2016"], + "codeowners": ["@markperdue", "@webdjoe", "@thegardenmonkey", "@vlebourl","@tv4you2016"], "config_flow": true, "dhcp": [ { diff --git a/custom_components/vesync/number.py b/custom_components/vesync/number.py index 306044a..1c9de09 100644 --- a/custom_components/vesync/number.py +++ b/custom_components/vesync/number.py @@ -61,7 +61,7 @@ def _setup_entities(devices, async_add_entities, coordinator): class VeSyncNumberEntity(VeSyncBaseEntity, NumberEntity): """Representation of a number for configuring a VeSync fan.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync fan device.""" super().__init__(device, coordinator) @@ -74,7 +74,7 @@ def entity_category(self): class VeSyncFanSpeedLevelHA(VeSyncNumberEntity): """Representation of the fan speed level of a VeSync fan.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the number entity.""" super().__init__(device, coordinator) self._attr_native_min_value = device.config_dict["levels"][0] @@ -109,7 +109,7 @@ def set_native_value(self, value): class VeSyncHumidifierMistLevelHA(VeSyncNumberEntity): """Representation of the mist level of a VeSync humidifier.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the number entity.""" super().__init__(device, coordinator) self._attr_native_min_value = device.config_dict["mist_levels"][0] @@ -144,7 +144,7 @@ def set_native_value(self, value): class VeSyncHumidifierWarmthLevelHA(VeSyncNumberEntity): """Representation of the warmth level of a VeSync humidifier.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the number entity.""" super().__init__(device, coordinator) self._attr_native_min_value = device.config_dict["warm_mist_levels"][0] @@ -179,7 +179,7 @@ def set_native_value(self, value): class VeSyncHumidifierTargetLevelHA(VeSyncNumberEntity): """Representation of the target humidity level of a VeSync humidifier.""" - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the number entity.""" super().__init__(device, coordinator) self._attr_native_min_value = MIN_HUMIDITY diff --git a/custom_components/vesync/sensor.py b/custom_components/vesync/sensor.py index e69a785..b98b43c 100644 --- a/custom_components/vesync/sensor.py +++ b/custom_components/vesync/sensor.py @@ -14,7 +14,13 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .common import VeSyncBaseEntity, has_feature -from .const import DEV_TYPE_TO_HA, DOMAIN, VS_DISCOVERY, VS_SENSORS +from .const import ( + DEV_TYPE_TO_HA, + DOMAIN, + SENSOR_TYPES_AIRFRYER, + VS_DISCOVERY, + VS_SENSORS, +) _LOGGER = logging.getLogger(__name__) @@ -49,6 +55,16 @@ def _setup_entities(devices, async_add_entities, coordinator): """Check if device is online and add entity.""" entities = [] for dev in devices: + if hasattr(dev, "fryer_status"): + for stype in SENSOR_TYPES_AIRFRYER.values(): + entities.append( + VeSyncairfryerSensor( + dev, + coordinator, + stype, + ) + ) + if DEV_TYPE_TO_HA.get(dev.device_type) == "outlet": entities.extend( ( @@ -68,10 +84,52 @@ def _setup_entities(devices, async_add_entities, coordinator): async_add_entities(entities, update_before_add=True) +class VeSyncairfryerSensor(VeSyncBaseEntity, SensorEntity): + """Class representing a VeSyncairfryerSensor.""" + + def __init__(self, airfryer, coordinator, stype) -> None: + """Initialize the VeSync airfryer.""" + super().__init__(airfryer, coordinator) + self.airfryer = airfryer + self.stype = stype + + @property + def unique_id(self): + """Return unique ID for power sensor on device.""" + return f"{super().unique_id}-" + self.stype[0] + + @property + def name(self): + """Return sensor name.""" + return self.stype[1] + + @property + def device_class(self): + """Return the class.""" + return self.stype[4] + + @property + def native_value(self): + """Return the value.""" + value = getattr(self.airfryer, self.stype[5], None) + return value + + @property + def native_unit_of_measurement(self): + """Return the unit of measurement.""" + # return self.airfryer.temp_unit + return self.stype[2] + + @property + def icon(self): + """Return the icon to use in the frontend, if any.""" + return self.stype[3] + + class VeSyncOutletSensorEntity(VeSyncBaseEntity, SensorEntity): """Representation of a sensor describing diagnostics of a VeSync outlet.""" - def __init__(self, plug, coordinator): + def __init__(self, plug, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) self.smartplug = plug @@ -85,7 +143,7 @@ def entity_category(self): class VeSyncPowerSensor(VeSyncOutletSensorEntity): """Representation of current power use for a VeSync outlet.""" - def __init__(self, plug, coordinator): + def __init__(self, plug, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) @@ -128,7 +186,7 @@ def update(self): class VeSyncEnergySensor(VeSyncOutletSensorEntity): """Representation of current day's energy use for a VeSync outlet.""" - def __init__(self, plug, coordinator): + def __init__(self, plug, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) self.smartplug = plug @@ -172,7 +230,7 @@ def update(self): class VeSyncHumidifierSensorEntity(VeSyncBaseEntity, SensorEntity): """Representation of a sensor describing diagnostics of a VeSync humidifier.""" - def __init__(self, humidifier, coordinator): + def __init__(self, humidifier, coordinator) -> None: """Initialize the VeSync humidifier device.""" super().__init__(humidifier, coordinator) self.smarthumidifier = humidifier @@ -189,7 +247,7 @@ class VeSyncAirQualitySensor(VeSyncHumidifierSensorEntity): _attr_state_class = SensorStateClass.MEASUREMENT _attr_native_unit_of_measurement = " " - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync device.""" super().__init__(device, coordinator) self._numeric_quality = None @@ -234,7 +292,7 @@ class VeSyncAirQualityValueSensor(VeSyncHumidifierSensorEntity): _attr_device_class = SensorDeviceClass.AQI _attr_native_unit_of_measurement = " " - def __init__(self, device, coordinator): + def __init__(self, device, coordinator) -> None: """Initialize the VeSync device.""" super().__init__(device, coordinator) @@ -267,7 +325,7 @@ def native_value(self): class VeSyncFilterLifeSensor(VeSyncHumidifierSensorEntity): """Representation of a filter life sensor.""" - def __init__(self, plug, coordinator): + def __init__(self, plug, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) @@ -318,7 +376,7 @@ def state_attributes(self): class VeSyncHumiditySensor(VeSyncHumidifierSensorEntity): """Representation of current humidity for a VeSync humidifier.""" - def __init__(self, humidity, coordinator): + def __init__(self, humidity, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(humidity, coordinator) diff --git a/custom_components/vesync/switch.py b/custom_components/vesync/switch.py index 65887b1..bf7332e 100644 --- a/custom_components/vesync/switch.py +++ b/custom_components/vesync/switch.py @@ -63,7 +63,7 @@ def _setup_entities(devices, async_add_entities, coordinator): class VeSyncBaseSwitch(VeSyncDevice, SwitchEntity): """Base class for VeSync switch Device Representations.""" - def __init__(self, plug, coordinator): + def __init__(self, plug, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(plug, coordinator) @@ -75,7 +75,7 @@ def turn_on(self, **kwargs): class VeSyncSwitchHA(VeSyncBaseSwitch, SwitchEntity): """Representation of a VeSync switch.""" - def __init__(self, plug, coordinator): + def __init__(self, plug, coordinator) -> None: """Initialize the VeSync switch device.""" super().__init__(plug, coordinator) self.smartplug = plug @@ -103,7 +103,7 @@ def update(self): class VeSyncLightSwitch(VeSyncBaseSwitch, SwitchEntity): """Handle representation of VeSync Light Switch.""" - def __init__(self, switch, coordinator): + def __init__(self, switch, coordinator) -> None: """Initialize Light Switch device class.""" super().__init__(switch, coordinator) self.switch = switch @@ -112,7 +112,7 @@ def __init__(self, switch, coordinator): class VeSyncSwitchEntity(VeSyncBaseEntity, SwitchEntity): """Representation of a switch for configuring a VeSync humidifier.""" - def __init__(self, humidifier, coordinator): + def __init__(self, humidifier, coordinator) -> None: """Initialize the VeSync humidifier device.""" super().__init__(humidifier, coordinator) self.smarthumidifier = humidifier @@ -126,7 +126,7 @@ def entity_category(self): class VeSyncFanChildLockHA(VeSyncSwitchEntity): """Representation of the child lock switch.""" - def __init__(self, lock, coordinator): + def __init__(self, lock, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(lock, coordinator) @@ -157,7 +157,7 @@ def turn_off(self, **kwargs): class VeSyncHumidifierDisplayHA(VeSyncSwitchEntity): """Representation of the child lock switch.""" - def __init__(self, lock, coordinator): + def __init__(self, lock, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(lock, coordinator) @@ -188,7 +188,7 @@ def turn_off(self, **kwargs): class VeSyncHumidifierAutomaticStopHA(VeSyncSwitchEntity): """Representation of the automatic stop toggle on a VeSync humidifier.""" - def __init__(self, automatic, coordinator): + def __init__(self, automatic, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(automatic, coordinator) @@ -219,7 +219,7 @@ def turn_off(self, **kwargs): class VeSyncHumidifierAutoOnHA(VeSyncSwitchEntity): """Provide switch to turn off auto mode and set manual mist level 1 on a VeSync humidifier.""" - def __init__(self, autooff, coordinator): + def __init__(self, autooff, coordinator) -> None: """Initialize the VeSync outlet device.""" super().__init__(autooff, coordinator) From a0cb9b9cfcc661343b6e8794fae448bbff64becf Mon Sep 17 00:00:00 2001 From: Sourcery AI <> Date: Thu, 26 Oct 2023 10:28:14 +0000 Subject: [PATCH 7/7] 'Refactored by Sourcery' --- custom_components/vesync/binary_sensor.py | 19 +++++++++---------- custom_components/vesync/button.py | 17 ++++++++--------- custom_components/vesync/sensor.py | 20 +++++++++----------- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/custom_components/vesync/binary_sensor.py b/custom_components/vesync/binary_sensor.py index a9dbd8f..51f0e44 100644 --- a/custom_components/vesync/binary_sensor.py +++ b/custom_components/vesync/binary_sensor.py @@ -45,14 +45,14 @@ def _setup_entities(devices, async_add_entities, coordinator): entities = [] for dev in devices: if hasattr(dev, "fryer_status"): - for stype in BINARY_SENSOR_TYPES_AIRFRYER.values(): - entities.append( - VeSyncairfryerSensor( - dev, - coordinator, - stype, - ) + entities.extend( + VeSyncairfryerSensor( + dev, + coordinator, + stype, ) + for stype in BINARY_SENSOR_TYPES_AIRFRYER.values() + ) if has_feature(dev, "details", "water_lacks"): entities.append(VeSyncOutOfWaterSensor(dev, coordinator)) if has_feature(dev, "details", "water_tank_lifted"): @@ -78,7 +78,7 @@ def entity_category(self): @property def unique_id(self): """Return unique ID for water tank lifted sensor on device.""" - return f"{super().unique_id}-" + self.stype[0] + return f"{super().unique_id}-{self.stype[0]}" @property def name(self): @@ -88,8 +88,7 @@ def name(self): @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..c960e73 100644 --- a/custom_components/vesync/button.py +++ b/custom_components/vesync/button.py @@ -54,15 +54,14 @@ def _setup_entities(devices, async_add_entities, coordinator): entities = [] for dev in devices: if hasattr(dev, "cook_set_temp"): - for stype in SENSOR_TYPES_CS158.values(): - entities.append( - VeSyncairfryerButton( - dev, - coordinator, - stype, - ) + entities.extend( + VeSyncairfryerButton( + dev, + coordinator, + stype, ) - + for stype in SENSOR_TYPES_CS158.values() + ) async_add_entities(entities, update_before_add=True) @@ -78,7 +77,7 @@ def __init__(self, airfryer, coordinator, stype) -> None: @property def unique_id(self): """Return unique ID for water tank lifted sensor on device.""" - return f"{super().unique_id}-" + self.stype[0] + return f"{super().unique_id}-{self.stype[0]}" @property def name(self): diff --git a/custom_components/vesync/sensor.py b/custom_components/vesync/sensor.py index b98b43c..ef7348b 100644 --- a/custom_components/vesync/sensor.py +++ b/custom_components/vesync/sensor.py @@ -56,15 +56,14 @@ def _setup_entities(devices, async_add_entities, coordinator): entities = [] for dev in devices: if hasattr(dev, "fryer_status"): - for stype in SENSOR_TYPES_AIRFRYER.values(): - entities.append( - VeSyncairfryerSensor( - dev, - coordinator, - stype, - ) + entities.extend( + VeSyncairfryerSensor( + dev, + coordinator, + stype, ) - + for stype in SENSOR_TYPES_AIRFRYER.values() + ) if DEV_TYPE_TO_HA.get(dev.device_type) == "outlet": entities.extend( ( @@ -96,7 +95,7 @@ def __init__(self, airfryer, coordinator, stype) -> None: @property def unique_id(self): """Return unique ID for power sensor on device.""" - return f"{super().unique_id}-" + self.stype[0] + return f"{super().unique_id}-{self.stype[0]}" @property def name(self): @@ -111,8 +110,7 @@ def device_class(self): @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):