Air Fryer Properties (AirFryer158) (#175)

* Air Fryer Properties (AirFryer158)

* Fix icon error

[*] Fix icon error
[*] Frist BETA Air Fryer Methods

* Add olther model AIRFRYER

* Fix Linters error

* Fix Linters error

* pass in Linters (flake8, black, isort)
This commit is contained in:
[PT]GOODVIBE[PT] 2023-10-27 08:33:05 +01:00 committed by GitHub
parent 2f014ef5a7
commit 8ef52f3962
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 365 additions and 61 deletions

View File

@ -1,3 +1,4 @@
# **Important message** # **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. > 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 pyvesync: debug
``` ```
## TODO LIST
```
- [x] Air Fryer Properties (AirFryer158)
- [ ] Air Fryer Methods
- [ ] Create the Card
```
### Contributing ### Contributing
All contributions are very welcomed! All contributions are very welcomed!
@ -54,3 +62,4 @@ pip install pre-commit
pre-commit install pre-commit install
pre-commit run --all-files pre-commit run --all-files
``` ```

View File

@ -15,6 +15,7 @@ from .const import (
DOMAIN, DOMAIN,
SERVICE_UPDATE_DEVS, SERVICE_UPDATE_DEVS,
VS_BINARY_SENSORS, VS_BINARY_SENSORS,
VS_BUTTON,
VS_DISCOVERY, VS_DISCOVERY,
VS_FANS, VS_FANS,
VS_HUMIDIFIERS, VS_HUMIDIFIERS,
@ -33,6 +34,7 @@ PLATFORMS = {
Platform.HUMIDIFIER: VS_HUMIDIFIERS, Platform.HUMIDIFIER: VS_HUMIDIFIERS,
Platform.NUMBER: VS_NUMBERS, Platform.NUMBER: VS_NUMBERS,
Platform.BINARY_SENSOR: VS_BINARY_SENSORS, Platform.BINARY_SENSOR: VS_BINARY_SENSORS,
Platform.BUTTON: VS_BUTTON,
} }
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)

View File

@ -9,7 +9,7 @@ from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .common import VeSyncBaseEntity, has_feature 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__) _LOGGER = logging.getLogger(__name__)
@ -44,6 +44,15 @@ def _setup_entities(devices, async_add_entities, coordinator):
"""Check if device is online and add entity.""" """Check if device is online and add entity."""
entities = [] entities = []
for dev in devices: 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"): if has_feature(dev, "details", "water_lacks"):
entities.append(VeSyncOutOfWaterSensor(dev, coordinator)) entities.append(VeSyncOutOfWaterSensor(dev, coordinator))
if has_feature(dev, "details", "water_tank_lifted"): 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) 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): class VeSyncBinarySensorEntity(VeSyncBaseEntity, BinarySensorEntity):
"""Representation of a binary sensor describing diagnostics of a VeSync humidifier.""" """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.""" """Initialize the VeSync humidifier device."""
super().__init__(humidifier, coordinator) super().__init__(humidifier, coordinator)
self.smarthumidifier = humidifier self.smarthumidifier = humidifier

View File

@ -0,0 +1,95 @@
"""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_BUTTON, VS_DISCOVERY
_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) -> None:
"""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()

View File

@ -4,11 +4,14 @@ import logging
from homeassistant.components.diagnostics import async_redact_data from homeassistant.components.diagnostics import async_redact_data
from homeassistant.helpers.entity import Entity, ToggleEntity from homeassistant.helpers.entity import Entity, ToggleEntity
from homeassistant.helpers.update_coordinator import CoordinatorEntity 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 ( from .const import (
DOMAIN, DOMAIN,
VS_AIRFRYER_TYPES,
VS_BINARY_SENSORS, VS_BINARY_SENSORS,
VS_BUTTON,
VS_FAN_TYPES, VS_FAN_TYPES,
VS_FANS, VS_FANS,
VS_HUMIDIFIERS, VS_HUMIDIFIERS,
@ -27,16 +30,6 @@ def has_feature(device, dictionary, attribute):
return getattr(device, dictionary, {}).get(attribute, None) is not None 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): async def async_process_devices(hass, manager):
"""Assign devices to proper component.""" """Assign devices to proper component."""
devices = { devices = {
@ -47,6 +40,7 @@ async def async_process_devices(hass, manager):
VS_HUMIDIFIERS: [], VS_HUMIDIFIERS: [],
VS_NUMBERS: [], VS_NUMBERS: [],
VS_BINARY_SENSORS: [], VS_BINARY_SENSORS: [],
VS_BUTTON: [],
} }
redacted = async_redact_data( redacted = async_redact_data(
@ -54,14 +48,15 @@ async def async_process_devices(hass, manager):
["cid", "uuid", "mac_id"], ["cid", "uuid", "mac_id"],
) )
_LOGGER.debug( _LOGGER.warning(
"Found the following devices: %s", "Found the following devices: %s",
redacted, redacted,
) )
if ( if (
manager.fans is None manager.bulbs is None
and manager.bulbs is None and manager.fans is None
and manager.kitchen is None
and manager.outlets is None and manager.outlets is None
and manager.switches is None and manager.switches is None
): ):
@ -70,13 +65,13 @@ async def async_process_devices(hass, manager):
if manager.fans: if manager.fans:
for fan in manager.fans: for fan in manager.fans:
# VeSync classifies humidifiers as 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) 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) devices[VS_FANS].append(fan)
else: else:
_LOGGER.warning( _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_name,
fan.device_type, fan.device_type,
) )
@ -102,13 +97,33 @@ async def async_process_devices(hass, manager):
else: else:
devices[VS_LIGHTS].append(switch) 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 return devices
class VeSyncBaseEntity(CoordinatorEntity, Entity): class VeSyncBaseEntity(CoordinatorEntity, Entity):
"""Base class for VeSync Entity Representations.""" """Base class for VeSync Entity Representations."""
def __init__(self, device, coordinator): def __init__(self, device, coordinator) -> None:
"""Initialize the VeSync device.""" """Initialize the VeSync device."""
self.device = device self.device = device
super().__init__(coordinator, context=device) super().__init__(coordinator, context=device)
@ -130,7 +145,7 @@ class VeSyncBaseEntity(CoordinatorEntity, Entity):
@property @property
def base_name(self): def base_name(self):
"""Return the name of the device.""" """Return the name of the device."""
return self.device.device_name return self.device.device_type
@property @property
def name(self): def name(self):
@ -163,7 +178,7 @@ class VeSyncBaseEntity(CoordinatorEntity, Entity):
class VeSyncDevice(VeSyncBaseEntity, ToggleEntity): class VeSyncDevice(VeSyncBaseEntity, ToggleEntity):
"""Base class for VeSync Device Representations.""" """Base class for VeSync Device Representations."""
def __init__(self, device, coordinator): def __init__(self, device, coordinator) -> None:
"""Initialize the VeSync device.""" """Initialize the VeSync device."""
super().__init__(device, coordinator) super().__init__(device, coordinator)

View File

@ -20,7 +20,7 @@ class VeSyncFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
VERSION = 1 VERSION = 1
def __init__(self): def __init__(self) -> None:
"""Instantiate config flow.""" """Instantiate config flow."""
self._username = None self._username = None
self._password = None self._password = None

View File

@ -1,9 +1,12 @@
"""Constants for VeSync Component.""" """Constants for VeSync Component."""
from homeassistant.const import DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, TIME_MINUTES
DOMAIN = "vesync" DOMAIN = "vesync"
VS_DISCOVERY = "vesync_discovery_{}" VS_DISCOVERY = "vesync_discovery_{}"
SERVICE_UPDATE_DEVS = "update_devices" SERVICE_UPDATE_DEVS = "update_devices"
VS_BUTTON = "button"
VS_SWITCHES = "switches" VS_SWITCHES = "switches"
VS_FAN = "fan" VS_FAN = "fan"
VS_FANS = "fans" VS_FANS = "fans"
@ -26,6 +29,8 @@ VS_TO_HA_ATTRIBUTES = {"humidity": "current_humidity"}
VS_FAN_TYPES = ["VeSyncAirBypass", "VeSyncAir131", "VeSyncVital"] VS_FAN_TYPES = ["VeSyncAirBypass", "VeSyncAir131", "VeSyncVital"]
VS_HUMIDIFIERS_TYPES = ["VeSyncHumid200300S", "VeSyncHumid200S", "VeSyncHumid1000S"] VS_HUMIDIFIERS_TYPES = ["VeSyncHumid200300S", "VeSyncHumid200S", "VeSyncHumid1000S"]
VS_AIRFRYER_TYPES = ["VeSyncAirFryer158"]
DEV_TYPE_TO_HA = { DEV_TYPE_TO_HA = {
"ESL100": "bulb-dimmable", "ESL100": "bulb-dimmable",
@ -40,3 +45,76 @@ DEV_TYPE_TO_HA = {
"ESD16": "walldimmer", "ESD16": "walldimmer",
"ESWD16": "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",
# ],
}

View File

@ -7,8 +7,8 @@ from homeassistant.components.diagnostics import async_redact_data
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from .common import is_humidifier # from .common import is_humidifier
from .const import DOMAIN # from .const import DOMAIN
TO_REDACT = {"cid", "uuid", "mac_id"} TO_REDACT = {"cid", "uuid", "mac_id"}
@ -17,13 +17,14 @@ async def async_get_config_entry_diagnostics(
hass: HomeAssistant, entry: ConfigEntry hass: HomeAssistant, entry: ConfigEntry
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Return diagnostics for a config entry.""" """Return diagnostics for a config entry."""
data = hass.data[DOMAIN][entry.entry_id] # data = hass.data[DOMAIN][entry.entry_id]
devices = {} devices = {}
for type in ["fans", "outlets", "switches", "bulbs"]:
for d in data["manager"]._dev_list[type]: # for type in ["fans", "outlets", "switches", "bulbs"]:
t = "humidifier" if is_humidifier(d.device_type) else type # for d in data["manager"]._dev_list[type]:
devices = { # 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"}]}, # **devices,
} # **{t: [{k: v for k, v in d.__dict__.items() if k != "manager"}]},
# }
return async_redact_data(devices, TO_REDACT) return async_redact_data(devices, TO_REDACT)

View File

@ -62,7 +62,7 @@ def _setup_entities(devices, async_add_entities, coordinator):
class VeSyncFanHA(VeSyncDevice, FanEntity): class VeSyncFanHA(VeSyncDevice, FanEntity):
"""Representation of a VeSync fan.""" """Representation of a VeSync fan."""
def __init__(self, fan, coordinator): def __init__(self, fan, coordinator) -> None:
"""Initialize the VeSync fan device.""" """Initialize the VeSync fan device."""
super().__init__(fan, coordinator) super().__init__(fan, coordinator)
self.smartfan = fan self.smartfan = fan

View File

@ -100,7 +100,7 @@ class VeSyncHumidifierHA(VeSyncDevice, HumidifierEntity):
_attr_max_humidity = MAX_HUMIDITY _attr_max_humidity = MAX_HUMIDITY
_attr_min_humidity = MIN_HUMIDITY _attr_min_humidity = MIN_HUMIDITY
def __init__(self, humidifier: VeSyncHumid200300S, coordinator): def __init__(self, humidifier: VeSyncHumid200300S, coordinator) -> None:
"""Initialize the VeSync humidifier device.""" """Initialize the VeSync humidifier device."""
super().__init__(humidifier, coordinator) super().__init__(humidifier, coordinator)
self.smarthumidifier = humidifier self.smarthumidifier = humidifier

View File

@ -140,7 +140,7 @@ class VeSyncBaseLight(VeSyncDevice, LightEntity):
class VeSyncDimmableLightHA(VeSyncBaseLight, LightEntity): class VeSyncDimmableLightHA(VeSyncBaseLight, LightEntity):
"""Representation of a VeSync dimmable light device.""" """Representation of a VeSync dimmable light device."""
def __init__(self, device, coordinator): def __init__(self, device, coordinator) -> None:
"""Initialize the VeSync dimmable light device.""" """Initialize the VeSync dimmable light device."""
super().__init__(device, coordinator) super().__init__(device, coordinator)
@ -158,7 +158,7 @@ class VeSyncDimmableLightHA(VeSyncBaseLight, LightEntity):
class VeSyncTunableWhiteLightHA(VeSyncBaseLight, LightEntity): class VeSyncTunableWhiteLightHA(VeSyncBaseLight, LightEntity):
"""Representation of a VeSync Tunable White Light device.""" """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.""" """Initialize the VeSync Tunable White Light device."""
super().__init__(device, coordinator) super().__init__(device, coordinator)
@ -213,7 +213,7 @@ class VeSyncTunableWhiteLightHA(VeSyncBaseLight, LightEntity):
class VeSyncNightLightHA(VeSyncDimmableLightHA): class VeSyncNightLightHA(VeSyncDimmableLightHA):
"""Representation of the night light on a VeSync device.""" """Representation of the night light on a VeSync device."""
def __init__(self, device, coordinator): def __init__(self, device, coordinator) -> None:
"""Initialize the VeSync device.""" """Initialize the VeSync device."""
super().__init__(device, coordinator) super().__init__(device, coordinator)
self.device = device self.device = device

View File

@ -1,7 +1,7 @@
{ {
"domain": "vesync", "domain": "vesync",
"name": "VeSync", "name": "VeSync",
"codeowners": ["@markperdue", "@webdjoe", "@thegardenmonkey", "@vlebourl"], "codeowners": ["@markperdue", "@webdjoe", "@thegardenmonkey", "@vlebourl","@tv4you2016"],
"config_flow": true, "config_flow": true,
"dhcp": [ "dhcp": [
{ {

View File

@ -61,7 +61,7 @@ def _setup_entities(devices, async_add_entities, coordinator):
class VeSyncNumberEntity(VeSyncBaseEntity, NumberEntity): class VeSyncNumberEntity(VeSyncBaseEntity, NumberEntity):
"""Representation of a number for configuring a VeSync fan.""" """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.""" """Initialize the VeSync fan device."""
super().__init__(device, coordinator) super().__init__(device, coordinator)
@ -74,7 +74,7 @@ class VeSyncNumberEntity(VeSyncBaseEntity, NumberEntity):
class VeSyncFanSpeedLevelHA(VeSyncNumberEntity): class VeSyncFanSpeedLevelHA(VeSyncNumberEntity):
"""Representation of the fan speed level of a VeSync fan.""" """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.""" """Initialize the number entity."""
super().__init__(device, coordinator) super().__init__(device, coordinator)
self._attr_native_min_value = device.config_dict["levels"][0] self._attr_native_min_value = device.config_dict["levels"][0]
@ -109,7 +109,7 @@ class VeSyncFanSpeedLevelHA(VeSyncNumberEntity):
class VeSyncHumidifierMistLevelHA(VeSyncNumberEntity): class VeSyncHumidifierMistLevelHA(VeSyncNumberEntity):
"""Representation of the mist level of a VeSync humidifier.""" """Representation of the mist level of a VeSync humidifier."""
def __init__(self, device, coordinator): def __init__(self, device, coordinator) -> None:
"""Initialize the number entity.""" """Initialize the number entity."""
super().__init__(device, coordinator) super().__init__(device, coordinator)
self._attr_native_min_value = device.config_dict["mist_levels"][0] self._attr_native_min_value = device.config_dict["mist_levels"][0]
@ -144,7 +144,7 @@ class VeSyncHumidifierMistLevelHA(VeSyncNumberEntity):
class VeSyncHumidifierWarmthLevelHA(VeSyncNumberEntity): class VeSyncHumidifierWarmthLevelHA(VeSyncNumberEntity):
"""Representation of the warmth level of a VeSync humidifier.""" """Representation of the warmth level of a VeSync humidifier."""
def __init__(self, device, coordinator): def __init__(self, device, coordinator) -> None:
"""Initialize the number entity.""" """Initialize the number entity."""
super().__init__(device, coordinator) super().__init__(device, coordinator)
self._attr_native_min_value = device.config_dict["warm_mist_levels"][0] self._attr_native_min_value = device.config_dict["warm_mist_levels"][0]
@ -179,7 +179,7 @@ class VeSyncHumidifierWarmthLevelHA(VeSyncNumberEntity):
class VeSyncHumidifierTargetLevelHA(VeSyncNumberEntity): class VeSyncHumidifierTargetLevelHA(VeSyncNumberEntity):
"""Representation of the target humidity level of a VeSync humidifier.""" """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.""" """Initialize the number entity."""
super().__init__(device, coordinator) super().__init__(device, coordinator)
self._attr_native_min_value = MIN_HUMIDITY self._attr_native_min_value = MIN_HUMIDITY

View File

@ -14,7 +14,13 @@ from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .common import VeSyncBaseEntity, has_feature 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__) _LOGGER = logging.getLogger(__name__)
@ -49,6 +55,16 @@ def _setup_entities(devices, async_add_entities, coordinator):
"""Check if device is online and add entity.""" """Check if device is online and add entity."""
entities = [] entities = []
for dev in devices: 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": if DEV_TYPE_TO_HA.get(dev.device_type) == "outlet":
entities.extend( entities.extend(
( (
@ -68,10 +84,52 @@ def _setup_entities(devices, async_add_entities, coordinator):
async_add_entities(entities, update_before_add=True) 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): class VeSyncOutletSensorEntity(VeSyncBaseEntity, SensorEntity):
"""Representation of a sensor describing diagnostics of a VeSync outlet.""" """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.""" """Initialize the VeSync outlet device."""
super().__init__(plug, coordinator) super().__init__(plug, coordinator)
self.smartplug = plug self.smartplug = plug
@ -85,7 +143,7 @@ class VeSyncOutletSensorEntity(VeSyncBaseEntity, SensorEntity):
class VeSyncPowerSensor(VeSyncOutletSensorEntity): class VeSyncPowerSensor(VeSyncOutletSensorEntity):
"""Representation of current power use for a VeSync outlet.""" """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.""" """Initialize the VeSync outlet device."""
super().__init__(plug, coordinator) super().__init__(plug, coordinator)
@ -128,7 +186,7 @@ class VeSyncPowerSensor(VeSyncOutletSensorEntity):
class VeSyncEnergySensor(VeSyncOutletSensorEntity): class VeSyncEnergySensor(VeSyncOutletSensorEntity):
"""Representation of current day's energy use for a VeSync outlet.""" """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.""" """Initialize the VeSync outlet device."""
super().__init__(plug, coordinator) super().__init__(plug, coordinator)
self.smartplug = plug self.smartplug = plug
@ -172,7 +230,7 @@ class VeSyncEnergySensor(VeSyncOutletSensorEntity):
class VeSyncHumidifierSensorEntity(VeSyncBaseEntity, SensorEntity): class VeSyncHumidifierSensorEntity(VeSyncBaseEntity, SensorEntity):
"""Representation of a sensor describing diagnostics of a VeSync humidifier.""" """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.""" """Initialize the VeSync humidifier device."""
super().__init__(humidifier, coordinator) super().__init__(humidifier, coordinator)
self.smarthumidifier = humidifier self.smarthumidifier = humidifier
@ -189,7 +247,7 @@ class VeSyncAirQualitySensor(VeSyncHumidifierSensorEntity):
_attr_state_class = SensorStateClass.MEASUREMENT _attr_state_class = SensorStateClass.MEASUREMENT
_attr_native_unit_of_measurement = " " _attr_native_unit_of_measurement = " "
def __init__(self, device, coordinator): def __init__(self, device, coordinator) -> None:
"""Initialize the VeSync device.""" """Initialize the VeSync device."""
super().__init__(device, coordinator) super().__init__(device, coordinator)
self._numeric_quality = None self._numeric_quality = None
@ -234,7 +292,7 @@ class VeSyncAirQualityValueSensor(VeSyncHumidifierSensorEntity):
_attr_device_class = SensorDeviceClass.AQI _attr_device_class = SensorDeviceClass.AQI
_attr_native_unit_of_measurement = " " _attr_native_unit_of_measurement = " "
def __init__(self, device, coordinator): def __init__(self, device, coordinator) -> None:
"""Initialize the VeSync device.""" """Initialize the VeSync device."""
super().__init__(device, coordinator) super().__init__(device, coordinator)
@ -267,7 +325,7 @@ class VeSyncAirQualityValueSensor(VeSyncHumidifierSensorEntity):
class VeSyncFilterLifeSensor(VeSyncHumidifierSensorEntity): class VeSyncFilterLifeSensor(VeSyncHumidifierSensorEntity):
"""Representation of a filter life sensor.""" """Representation of a filter life sensor."""
def __init__(self, plug, coordinator): def __init__(self, plug, coordinator) -> None:
"""Initialize the VeSync outlet device.""" """Initialize the VeSync outlet device."""
super().__init__(plug, coordinator) super().__init__(plug, coordinator)
@ -318,7 +376,7 @@ class VeSyncFilterLifeSensor(VeSyncHumidifierSensorEntity):
class VeSyncHumiditySensor(VeSyncHumidifierSensorEntity): class VeSyncHumiditySensor(VeSyncHumidifierSensorEntity):
"""Representation of current humidity for a VeSync humidifier.""" """Representation of current humidity for a VeSync humidifier."""
def __init__(self, humidity, coordinator): def __init__(self, humidity, coordinator) -> None:
"""Initialize the VeSync outlet device.""" """Initialize the VeSync outlet device."""
super().__init__(humidity, coordinator) super().__init__(humidity, coordinator)

View File

@ -63,7 +63,7 @@ def _setup_entities(devices, async_add_entities, coordinator):
class VeSyncBaseSwitch(VeSyncDevice, SwitchEntity): class VeSyncBaseSwitch(VeSyncDevice, SwitchEntity):
"""Base class for VeSync switch Device Representations.""" """Base class for VeSync switch Device Representations."""
def __init__(self, plug, coordinator): def __init__(self, plug, coordinator) -> None:
"""Initialize the VeSync outlet device.""" """Initialize the VeSync outlet device."""
super().__init__(plug, coordinator) super().__init__(plug, coordinator)
@ -75,7 +75,7 @@ class VeSyncBaseSwitch(VeSyncDevice, SwitchEntity):
class VeSyncSwitchHA(VeSyncBaseSwitch, SwitchEntity): class VeSyncSwitchHA(VeSyncBaseSwitch, SwitchEntity):
"""Representation of a VeSync switch.""" """Representation of a VeSync switch."""
def __init__(self, plug, coordinator): def __init__(self, plug, coordinator) -> None:
"""Initialize the VeSync switch device.""" """Initialize the VeSync switch device."""
super().__init__(plug, coordinator) super().__init__(plug, coordinator)
self.smartplug = plug self.smartplug = plug
@ -103,7 +103,7 @@ class VeSyncSwitchHA(VeSyncBaseSwitch, SwitchEntity):
class VeSyncLightSwitch(VeSyncBaseSwitch, SwitchEntity): class VeSyncLightSwitch(VeSyncBaseSwitch, SwitchEntity):
"""Handle representation of VeSync Light Switch.""" """Handle representation of VeSync Light Switch."""
def __init__(self, switch, coordinator): def __init__(self, switch, coordinator) -> None:
"""Initialize Light Switch device class.""" """Initialize Light Switch device class."""
super().__init__(switch, coordinator) super().__init__(switch, coordinator)
self.switch = switch self.switch = switch
@ -112,7 +112,7 @@ class VeSyncLightSwitch(VeSyncBaseSwitch, SwitchEntity):
class VeSyncSwitchEntity(VeSyncBaseEntity, SwitchEntity): class VeSyncSwitchEntity(VeSyncBaseEntity, SwitchEntity):
"""Representation of a switch for configuring a VeSync humidifier.""" """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.""" """Initialize the VeSync humidifier device."""
super().__init__(humidifier, coordinator) super().__init__(humidifier, coordinator)
self.smarthumidifier = humidifier self.smarthumidifier = humidifier
@ -126,7 +126,7 @@ class VeSyncSwitchEntity(VeSyncBaseEntity, SwitchEntity):
class VeSyncFanChildLockHA(VeSyncSwitchEntity): class VeSyncFanChildLockHA(VeSyncSwitchEntity):
"""Representation of the child lock switch.""" """Representation of the child lock switch."""
def __init__(self, lock, coordinator): def __init__(self, lock, coordinator) -> None:
"""Initialize the VeSync outlet device.""" """Initialize the VeSync outlet device."""
super().__init__(lock, coordinator) super().__init__(lock, coordinator)
@ -157,7 +157,7 @@ class VeSyncFanChildLockHA(VeSyncSwitchEntity):
class VeSyncHumidifierDisplayHA(VeSyncSwitchEntity): class VeSyncHumidifierDisplayHA(VeSyncSwitchEntity):
"""Representation of the child lock switch.""" """Representation of the child lock switch."""
def __init__(self, lock, coordinator): def __init__(self, lock, coordinator) -> None:
"""Initialize the VeSync outlet device.""" """Initialize the VeSync outlet device."""
super().__init__(lock, coordinator) super().__init__(lock, coordinator)
@ -188,7 +188,7 @@ class VeSyncHumidifierDisplayHA(VeSyncSwitchEntity):
class VeSyncHumidifierAutomaticStopHA(VeSyncSwitchEntity): class VeSyncHumidifierAutomaticStopHA(VeSyncSwitchEntity):
"""Representation of the automatic stop toggle on a VeSync humidifier.""" """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.""" """Initialize the VeSync outlet device."""
super().__init__(automatic, coordinator) super().__init__(automatic, coordinator)
@ -219,7 +219,7 @@ class VeSyncHumidifierAutomaticStopHA(VeSyncSwitchEntity):
class VeSyncHumidifierAutoOnHA(VeSyncSwitchEntity): class VeSyncHumidifierAutoOnHA(VeSyncSwitchEntity):
"""Provide switch to turn off auto mode and set manual mist level 1 on a VeSync humidifier.""" """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.""" """Initialize the VeSync outlet device."""
super().__init__(autooff, coordinator) super().__init__(autooff, coordinator)