mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Add support for air purifiers to HomeKit Device (#109880)
This commit is contained in:
parent
aea81a180c
commit
1ea9b1a158
@ -55,6 +55,7 @@ HOMEKIT_ACCESSORY_DISPATCH = {
|
||||
ServicesTypes.DOORBELL: "event",
|
||||
ServicesTypes.STATELESS_PROGRAMMABLE_SWITCH: "event",
|
||||
ServicesTypes.SERVICE_LABEL: "event",
|
||||
ServicesTypes.AIR_PURIFIER: "fan",
|
||||
}
|
||||
|
||||
CHARACTERISTIC_PLATFORMS = {
|
||||
@ -104,6 +105,8 @@ CHARACTERISTIC_PLATFORMS = {
|
||||
CharacteristicsTypes.FILTER_LIFE_LEVEL: "sensor",
|
||||
CharacteristicsTypes.VENDOR_AIRVERSA_SLEEP_MODE: "switch",
|
||||
CharacteristicsTypes.TEMPERATURE_UNITS: "select",
|
||||
CharacteristicsTypes.AIR_PURIFIER_STATE_CURRENT: "sensor",
|
||||
CharacteristicsTypes.AIR_PURIFIER_STATE_TARGET: "select",
|
||||
}
|
||||
|
||||
STARTUP_EXCEPTIONS = (
|
||||
|
@ -206,6 +206,7 @@ class HomeKitFanV2(BaseHomeKitFan):
|
||||
ENTITY_TYPES = {
|
||||
ServicesTypes.FAN: HomeKitFanV1,
|
||||
ServicesTypes.FAN_V2: HomeKitFanV2,
|
||||
ServicesTypes.AIR_PURIFIER: HomeKitFanV2,
|
||||
}
|
||||
|
||||
|
||||
|
@ -5,7 +5,10 @@ from dataclasses import dataclass
|
||||
from enum import IntEnum
|
||||
|
||||
from aiohomekit.model.characteristics import Characteristic, CharacteristicsTypes
|
||||
from aiohomekit.model.characteristics.const import TemperatureDisplayUnits
|
||||
from aiohomekit.model.characteristics.const import (
|
||||
TargetAirPurifierStateValues,
|
||||
TemperatureDisplayUnits,
|
||||
)
|
||||
|
||||
from homeassistant.components.select import SelectEntity, SelectEntityDescription
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
@ -47,6 +50,16 @@ SELECT_ENTITIES: dict[str, HomeKitSelectEntityDescription] = {
|
||||
"fahrenheit": TemperatureDisplayUnits.FAHRENHEIT,
|
||||
},
|
||||
),
|
||||
CharacteristicsTypes.AIR_PURIFIER_STATE_TARGET: HomeKitSelectEntityDescription(
|
||||
key="air_purifier_state_target",
|
||||
translation_key="air_purifier_state_target",
|
||||
name="Air Purifier Mode",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
choices={
|
||||
"automatic": TargetAirPurifierStateValues.AUTOMATIC,
|
||||
"manual": TargetAirPurifierStateValues.MANUAL,
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
_ECOBEE_MODE_TO_TEXT = {
|
||||
|
@ -3,10 +3,15 @@ from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from enum import IntEnum
|
||||
|
||||
from aiohomekit.model import Accessory, Transport
|
||||
from aiohomekit.model.characteristics import Characteristic, CharacteristicsTypes
|
||||
from aiohomekit.model.characteristics.const import ThreadNodeCapabilities, ThreadStatus
|
||||
from aiohomekit.model.characteristics.const import (
|
||||
CurrentAirPurifierStateValues,
|
||||
ThreadNodeCapabilities,
|
||||
ThreadStatus,
|
||||
)
|
||||
from aiohomekit.model.services import Service, ServicesTypes
|
||||
|
||||
from homeassistant.components.bluetooth import (
|
||||
@ -52,6 +57,7 @@ class HomeKitSensorEntityDescription(SensorEntityDescription):
|
||||
|
||||
probe: Callable[[Characteristic], bool] | None = None
|
||||
format: Callable[[Characteristic], str] | None = None
|
||||
enum: dict[IntEnum, str] | None = None
|
||||
|
||||
|
||||
def thread_node_capability_to_str(char: Characteristic) -> str:
|
||||
@ -324,6 +330,18 @@ SIMPLE_SENSOR: dict[str, HomeKitSensorEntityDescription] = {
|
||||
],
|
||||
translation_key="thread_status",
|
||||
),
|
||||
CharacteristicsTypes.AIR_PURIFIER_STATE_CURRENT: HomeKitSensorEntityDescription(
|
||||
key=CharacteristicsTypes.AIR_PURIFIER_STATE_CURRENT,
|
||||
name="Air Purifier Status",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
device_class=SensorDeviceClass.ENUM,
|
||||
enum={
|
||||
CurrentAirPurifierStateValues.INACTIVE: "inactive",
|
||||
CurrentAirPurifierStateValues.IDLE: "idle",
|
||||
CurrentAirPurifierStateValues.ACTIVE: "purifying",
|
||||
},
|
||||
translation_key="air_purifier_state_current",
|
||||
),
|
||||
CharacteristicsTypes.VENDOR_NETATMO_NOISE: HomeKitSensorEntityDescription(
|
||||
key=CharacteristicsTypes.VENDOR_NETATMO_NOISE,
|
||||
name="Noise",
|
||||
@ -535,6 +553,8 @@ class SimpleSensor(CharacteristicEntity, SensorEntity):
|
||||
) -> None:
|
||||
"""Initialise a secondary HomeKit characteristic sensor."""
|
||||
self.entity_description = description
|
||||
if self.entity_description.enum:
|
||||
self._attr_options = list(self.entity_description.enum.values())
|
||||
super().__init__(conn, info, char)
|
||||
|
||||
def get_characteristic_types(self) -> list[str]:
|
||||
@ -551,10 +571,11 @@ class SimpleSensor(CharacteristicEntity, SensorEntity):
|
||||
@property
|
||||
def native_value(self) -> str | int | float:
|
||||
"""Return the current sensor value."""
|
||||
val = self._char.value
|
||||
if self.entity_description.enum:
|
||||
return self.entity_description.enum[self._char.value]
|
||||
if self.entity_description.format:
|
||||
return self.entity_description.format(val)
|
||||
return val
|
||||
return self.entity_description.format(self._char)
|
||||
return self._char.value
|
||||
|
||||
|
||||
ENTITY_TYPES = {
|
||||
|
@ -108,6 +108,12 @@
|
||||
"celsius": "Celsius",
|
||||
"fahrenheit": "Fahrenheit"
|
||||
}
|
||||
},
|
||||
"air_purifier_state_target": {
|
||||
"state": {
|
||||
"automatic": "Automatic",
|
||||
"manual": "Manual"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sensor": {
|
||||
@ -131,6 +137,13 @@
|
||||
"leader": "Leader",
|
||||
"router": "Router"
|
||||
}
|
||||
},
|
||||
"air_purifier_state_current": {
|
||||
"state": {
|
||||
"inactive": "Inactive",
|
||||
"idle": "Idle",
|
||||
"purifying": "Purifying"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -101,6 +101,142 @@
|
||||
'state': 'unknown',
|
||||
}),
|
||||
}),
|
||||
dict({
|
||||
'entry': dict({
|
||||
'aliases': list([
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'preset_modes': None,
|
||||
}),
|
||||
'config_entry_id': 'TestData',
|
||||
'device_class': None,
|
||||
'disabled_by': None,
|
||||
'domain': 'fan',
|
||||
'entity_category': None,
|
||||
'entity_id': 'fan.airversa_ap2_1808_airpurifier',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Airversa AP2 1808 AirPurifier',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <FanEntityFeature: 1>,
|
||||
'translation_key': None,
|
||||
'unique_id': '00:00:00:00:00:00_1_32832',
|
||||
'unit_of_measurement': None,
|
||||
}),
|
||||
'state': dict({
|
||||
'attributes': dict({
|
||||
'friendly_name': 'Airversa AP2 1808 AirPurifier',
|
||||
'percentage': 0,
|
||||
'percentage_step': 20.0,
|
||||
'preset_mode': None,
|
||||
'preset_modes': None,
|
||||
'supported_features': <FanEntityFeature: 1>,
|
||||
}),
|
||||
'entity_id': 'fan.airversa_ap2_1808_airpurifier',
|
||||
'state': 'off',
|
||||
}),
|
||||
}),
|
||||
dict({
|
||||
'entry': dict({
|
||||
'aliases': list([
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'automatic',
|
||||
'manual',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': 'TestData',
|
||||
'device_class': None,
|
||||
'disabled_by': None,
|
||||
'domain': 'select',
|
||||
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||
'entity_id': 'select.airversa_ap2_1808_air_purifier_mode',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': 'Airversa AP2 1808 Air Purifier Mode',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'air_purifier_state_target',
|
||||
'unique_id': '00:00:00:00:00:00_1_32832_32837',
|
||||
'unit_of_measurement': None,
|
||||
}),
|
||||
'state': dict({
|
||||
'attributes': dict({
|
||||
'friendly_name': 'Airversa AP2 1808 Air Purifier Mode',
|
||||
'options': list([
|
||||
'automatic',
|
||||
'manual',
|
||||
]),
|
||||
}),
|
||||
'entity_id': 'select.airversa_ap2_1808_air_purifier_mode',
|
||||
'state': 'automatic',
|
||||
}),
|
||||
}),
|
||||
dict({
|
||||
'entry': dict({
|
||||
'aliases': list([
|
||||
]),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'inactive',
|
||||
'idle',
|
||||
'purifying',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': 'TestData',
|
||||
'device_class': None,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.airversa_ap2_1808_air_purifier_status',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Airversa AP2 1808 Air Purifier Status',
|
||||
'platform': 'homekit_controller',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'air_purifier_state_current',
|
||||
'unique_id': '00:00:00:00:00:00_1_32832_32836',
|
||||
'unit_of_measurement': None,
|
||||
}),
|
||||
'state': dict({
|
||||
'attributes': dict({
|
||||
'device_class': 'enum',
|
||||
'friendly_name': 'Airversa AP2 1808 Air Purifier Status',
|
||||
'options': list([
|
||||
'inactive',
|
||||
'idle',
|
||||
'purifying',
|
||||
]),
|
||||
}),
|
||||
'entity_id': 'sensor.airversa_ap2_1808_air_purifier_status',
|
||||
'state': 'inactive',
|
||||
}),
|
||||
}),
|
||||
dict({
|
||||
'entry': dict({
|
||||
'aliases': list([
|
||||
|
Loading…
x
Reference in New Issue
Block a user