mirror of
https://github.com/home-assistant/core.git
synced 2026-04-02 00:20:30 +01:00
Add fan speed percentage control to SwitchBot Air Purifier (#166953)
This commit is contained in:
@@ -114,7 +114,10 @@ PLATFORMS_BY_TYPE = {
|
||||
SupportedModels.AIR_PURIFIER_US.value: [Platform.FAN, Platform.SENSOR],
|
||||
SupportedModels.AIR_PURIFIER_TABLE_JP.value: [Platform.FAN, Platform.SENSOR],
|
||||
SupportedModels.AIR_PURIFIER_TABLE_US.value: [Platform.FAN, Platform.SENSOR],
|
||||
SupportedModels.EVAPORATIVE_HUMIDIFIER: [Platform.HUMIDIFIER, Platform.SENSOR],
|
||||
SupportedModels.EVAPORATIVE_HUMIDIFIER.value: [
|
||||
Platform.HUMIDIFIER,
|
||||
Platform.SENSOR,
|
||||
],
|
||||
SupportedModels.FLOOR_LAMP.value: [Platform.LIGHT, Platform.SENSOR],
|
||||
SupportedModels.STRIP_LIGHT_3.value: [Platform.LIGHT, Platform.SENSOR],
|
||||
SupportedModels.RGBICWW_FLOOR_LAMP.value: [Platform.LIGHT, Platform.SENSOR],
|
||||
@@ -171,7 +174,7 @@ CLASS_BY_DEVICE = {
|
||||
SupportedModels.AIR_PURIFIER_US.value: switchbot.SwitchbotAirPurifier,
|
||||
SupportedModels.AIR_PURIFIER_TABLE_JP.value: switchbot.SwitchbotAirPurifier,
|
||||
SupportedModels.AIR_PURIFIER_TABLE_US.value: switchbot.SwitchbotAirPurifier,
|
||||
SupportedModels.EVAPORATIVE_HUMIDIFIER: switchbot.SwitchbotEvaporativeHumidifier,
|
||||
SupportedModels.EVAPORATIVE_HUMIDIFIER.value: switchbot.SwitchbotEvaporativeHumidifier,
|
||||
SupportedModels.FLOOR_LAMP.value: switchbot.SwitchbotStripLight3,
|
||||
SupportedModels.STRIP_LIGHT_3.value: switchbot.SwitchbotStripLight3,
|
||||
SupportedModels.RGBICWW_FLOOR_LAMP.value: switchbot.SwitchbotRgbicLight,
|
||||
|
||||
@@ -206,3 +206,16 @@ CONF_KEY_ID = "key_id"
|
||||
CONF_ENCRYPTION_KEY = "encryption_key"
|
||||
CONF_LOCK_NIGHTLATCH = "lock_force_nightlatch"
|
||||
CONF_CURTAIN_SPEED = "curtain_speed"
|
||||
|
||||
AIRPURIFIER_BASIC_MODELS = {
|
||||
SwitchbotModel.AIR_PURIFIER_JP,
|
||||
SwitchbotModel.AIR_PURIFIER_US,
|
||||
}
|
||||
AIRPURIFIER_TABLE_MODELS = {
|
||||
SwitchbotModel.AIR_PURIFIER_TABLE_JP,
|
||||
SwitchbotModel.AIR_PURIFIER_TABLE_US,
|
||||
}
|
||||
AIRPURIFIER_PM25_MODELS = {
|
||||
SwitchbotModel.AIR_PURIFIER_US,
|
||||
SwitchbotModel.AIR_PURIFIER_TABLE_US,
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@ class SwitchBotAirPurifierEntity(SwitchbotEntity, FanEntity):
|
||||
_device: switchbot.SwitchbotAirPurifier
|
||||
_attr_supported_features = (
|
||||
FanEntityFeature.PRESET_MODE
|
||||
| FanEntityFeature.SET_SPEED
|
||||
| FanEntityFeature.TURN_OFF
|
||||
| FanEntityFeature.TURN_ON
|
||||
)
|
||||
@@ -148,6 +149,11 @@ class SwitchBotAirPurifierEntity(SwitchbotEntity, FanEntity):
|
||||
"""Return the current preset mode."""
|
||||
return self._device.get_current_mode()
|
||||
|
||||
@property
|
||||
def percentage(self) -> int | None:
|
||||
"""Return the speed percentage of the air purifier."""
|
||||
return self._device.get_current_percentage()
|
||||
|
||||
@exception_handler
|
||||
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||
"""Set the preset mode of the air purifier."""
|
||||
@@ -160,6 +166,16 @@ class SwitchBotAirPurifierEntity(SwitchbotEntity, FanEntity):
|
||||
self._last_run_success = bool(await self._device.set_preset_mode(preset_mode))
|
||||
self.async_write_ha_state()
|
||||
|
||||
@exception_handler
|
||||
async def async_set_percentage(self, percentage: int) -> None:
|
||||
"""Set the speed percentage of the air purifier."""
|
||||
|
||||
_LOGGER.debug(
|
||||
"Switchbot air purifier to set percentage %d %s", percentage, self._address
|
||||
)
|
||||
await self._device.set_percentage(percentage)
|
||||
self.async_write_ha_state()
|
||||
|
||||
@exception_handler
|
||||
async def async_turn_on(
|
||||
self,
|
||||
|
||||
@@ -785,8 +785,8 @@ LOCK_ULTRA_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
)
|
||||
|
||||
|
||||
AIR_PURIFIER_TABLE_PM25_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
name="Air Purifier Table PM25",
|
||||
AIR_PURIFIER_TABLE_US_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
name="Air Purifier Table US",
|
||||
manufacturer_data={
|
||||
2409: b"\xf0\x9e\x9e\x96j\xd6\xa1\x81\x88\xe4\x00\x01\x95\x00\x00",
|
||||
},
|
||||
@@ -796,22 +796,22 @@ AIR_PURIFIER_TABLE_PM25_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
rssi=-60,
|
||||
source="local",
|
||||
advertisement=generate_advertisement_data(
|
||||
local_name="Air Purifier Table PM25",
|
||||
local_name="Air Purifier Table US",
|
||||
manufacturer_data={
|
||||
2409: b"\xf0\x9e\x9e\x96j\xd6\xa1\x81\x88\xe4\x00\x01\x95\x00\x00",
|
||||
},
|
||||
service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"7\x00\x00\x95-\x00"},
|
||||
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
|
||||
),
|
||||
device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Air Purifier Table PM25"),
|
||||
device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Air Purifier Table US"),
|
||||
time=0,
|
||||
connectable=True,
|
||||
tx_power=-127,
|
||||
)
|
||||
|
||||
|
||||
AIR_PURIFIER_PM25_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
name="Air Purifier PM25",
|
||||
AIR_PURIFIER_US_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
name="Air Purifier US",
|
||||
manufacturer_data={
|
||||
2409: b'\xcc\x8d\xa2\xa7\x92>\t"\x80\x000\x00\x0f\x00\x00',
|
||||
},
|
||||
@@ -821,22 +821,22 @@ AIR_PURIFIER_PM25_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
rssi=-60,
|
||||
source="local",
|
||||
advertisement=generate_advertisement_data(
|
||||
local_name="Air Purifier PM25",
|
||||
local_name="Air Purifier US",
|
||||
manufacturer_data={
|
||||
2409: b'\xcc\x8d\xa2\xa7\x92>\t"\x80\x000\x00\x0f\x00\x00',
|
||||
},
|
||||
service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"*\x00\x00\x15\x04\x00"},
|
||||
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
|
||||
),
|
||||
device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Air Purifier PM25"),
|
||||
device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Air Purifier US"),
|
||||
time=0,
|
||||
connectable=True,
|
||||
tx_power=-127,
|
||||
)
|
||||
|
||||
|
||||
AIR_PURIFIER_VOC_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
name="Air Purifier VOC",
|
||||
AIR_PURIFIER_JP_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
name="Air Purifier JP",
|
||||
manufacturer_data={
|
||||
2409: b"\xcc\x8d\xa2\xa7\xe4\xa6\x0b\x83\x88d\x00\xea`\x00\x00",
|
||||
},
|
||||
@@ -846,22 +846,22 @@ AIR_PURIFIER_VOC_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
rssi=-60,
|
||||
source="local",
|
||||
advertisement=generate_advertisement_data(
|
||||
local_name="Air Purifier VOC",
|
||||
local_name="Air Purifier JP",
|
||||
manufacturer_data={
|
||||
2409: b"\xcc\x8d\xa2\xa7\xe4\xa6\x0b\x83\x88d\x00\xea`\x00\x00",
|
||||
},
|
||||
service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"+\x00\x00\x15\x04\x00"},
|
||||
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
|
||||
),
|
||||
device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Air Purifier VOC"),
|
||||
device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Air Purifier JP"),
|
||||
time=0,
|
||||
connectable=True,
|
||||
tx_power=-127,
|
||||
)
|
||||
|
||||
|
||||
AIR_PURIFIER_TABLE_VOC_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
name="Air Purifier Table VOC",
|
||||
AIR_PURIFIER_TABLE_JP_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
name="Air Purifier Table JP",
|
||||
manufacturer_data={
|
||||
2409: b"\xcc\x8d\xa2\xa7\xc1\xae\x9b\x81\x8c\xb2\x00\x01\x94\x00\x00",
|
||||
},
|
||||
@@ -871,14 +871,14 @@ AIR_PURIFIER_TABLE_VOC_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
rssi=-60,
|
||||
source="local",
|
||||
advertisement=generate_advertisement_data(
|
||||
local_name="Air Purifier Table VOC",
|
||||
local_name="Air Purifier Table JP",
|
||||
manufacturer_data={
|
||||
2409: b"\xcc\x8d\xa2\xa7\xc1\xae\x9b\x81\x8c\xb2\x00\x01\x94\x00\x00",
|
||||
},
|
||||
service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"8\x00\x00\x95-\x00"},
|
||||
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
|
||||
),
|
||||
device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Air Purifier Table VOC"),
|
||||
device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Air Purifier Table JP"),
|
||||
time=0,
|
||||
connectable=True,
|
||||
tx_power=-127,
|
||||
|
||||
@@ -21,10 +21,10 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
from . import (
|
||||
AIR_PURIFIER_PM25_SERVICE_INFO,
|
||||
AIR_PURIFIER_TABLE_PM25_SERVICE_INFO,
|
||||
AIR_PURIFIER_TABLE_VOC_SERVICE_INFO,
|
||||
AIR_PURIFIER_VOC_SERVICE_INFO,
|
||||
AIR_PURIFIER_JP_SERVICE_INFO,
|
||||
AIR_PURIFIER_TABLE_JP_SERVICE_INFO,
|
||||
AIR_PURIFIER_TABLE_US_SERVICE_INFO,
|
||||
AIR_PURIFIER_US_SERVICE_INFO,
|
||||
CIRCULATOR_FAN_SERVICE_INFO,
|
||||
)
|
||||
|
||||
@@ -103,10 +103,10 @@ async def test_circulator_fan_controlling(
|
||||
@pytest.mark.parametrize(
|
||||
("service_info", "sensor_type"),
|
||||
[
|
||||
(AIR_PURIFIER_VOC_SERVICE_INFO, "air_purifier_jp"),
|
||||
(AIR_PURIFIER_TABLE_VOC_SERVICE_INFO, "air_purifier_table_jp"),
|
||||
(AIR_PURIFIER_PM25_SERVICE_INFO, "air_purifier_us"),
|
||||
(AIR_PURIFIER_TABLE_PM25_SERVICE_INFO, "air_purifier_table_us"),
|
||||
(AIR_PURIFIER_JP_SERVICE_INFO, "air_purifier_jp"),
|
||||
(AIR_PURIFIER_TABLE_JP_SERVICE_INFO, "air_purifier_table_jp"),
|
||||
(AIR_PURIFIER_US_SERVICE_INFO, "air_purifier_us"),
|
||||
(AIR_PURIFIER_TABLE_US_SERVICE_INFO, "air_purifier_table_us"),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
@@ -117,6 +117,11 @@ async def test_circulator_fan_controlling(
|
||||
{ATTR_PRESET_MODE: "sleep"},
|
||||
"set_preset_mode",
|
||||
),
|
||||
(
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
{ATTR_PERCENTAGE: 27},
|
||||
"set_percentage",
|
||||
),
|
||||
(
|
||||
SERVICE_TURN_OFF,
|
||||
{},
|
||||
@@ -169,10 +174,10 @@ async def test_air_purifier_controlling(
|
||||
@pytest.mark.parametrize(
|
||||
("service_info", "sensor_type"),
|
||||
[
|
||||
(AIR_PURIFIER_VOC_SERVICE_INFO, "air_purifier_jp"),
|
||||
(AIR_PURIFIER_TABLE_VOC_SERVICE_INFO, "air_purifier_table_jp"),
|
||||
(AIR_PURIFIER_PM25_SERVICE_INFO, "air_purifier_us"),
|
||||
(AIR_PURIFIER_TABLE_PM25_SERVICE_INFO, "air_purifier_table_us"),
|
||||
(AIR_PURIFIER_JP_SERVICE_INFO, "air_purifier_jp"),
|
||||
(AIR_PURIFIER_TABLE_JP_SERVICE_INFO, "air_purifier_table_jp"),
|
||||
(AIR_PURIFIER_US_SERVICE_INFO, "air_purifier_us"),
|
||||
(AIR_PURIFIER_TABLE_US_SERVICE_INFO, "air_purifier_table_us"),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
|
||||
@@ -20,10 +20,10 @@ from homeassistant.const import CONF_ADDRESS, CONF_NAME, CONF_SENSOR_TYPE
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import (
|
||||
AIR_PURIFIER_PM25_SERVICE_INFO,
|
||||
AIR_PURIFIER_TABLE_PM25_SERVICE_INFO,
|
||||
AIR_PURIFIER_TABLE_VOC_SERVICE_INFO,
|
||||
AIR_PURIFIER_VOC_SERVICE_INFO,
|
||||
AIR_PURIFIER_JP_SERVICE_INFO,
|
||||
AIR_PURIFIER_TABLE_JP_SERVICE_INFO,
|
||||
AIR_PURIFIER_TABLE_US_SERVICE_INFO,
|
||||
AIR_PURIFIER_US_SERVICE_INFO,
|
||||
HUBMINI_MATTER_SERVICE_INFO,
|
||||
LOCK_SERVICE_INFO,
|
||||
WOCURTAIN_SERVICE_INFO,
|
||||
@@ -253,22 +253,22 @@ async def test_migrate_entry_fails_for_future_version(
|
||||
[
|
||||
(
|
||||
DEPRECATED_SENSOR_TYPE_AIR_PURIFIER,
|
||||
AIR_PURIFIER_VOC_SERVICE_INFO,
|
||||
AIR_PURIFIER_JP_SERVICE_INFO,
|
||||
"air_purifier_jp",
|
||||
),
|
||||
(
|
||||
DEPRECATED_SENSOR_TYPE_AIR_PURIFIER,
|
||||
AIR_PURIFIER_PM25_SERVICE_INFO,
|
||||
AIR_PURIFIER_US_SERVICE_INFO,
|
||||
"air_purifier_us",
|
||||
),
|
||||
(
|
||||
DEPRECATED_SENSOR_TYPE_AIR_PURIFIER_TABLE,
|
||||
AIR_PURIFIER_TABLE_VOC_SERVICE_INFO,
|
||||
AIR_PURIFIER_TABLE_JP_SERVICE_INFO,
|
||||
"air_purifier_table_jp",
|
||||
),
|
||||
(
|
||||
DEPRECATED_SENSOR_TYPE_AIR_PURIFIER_TABLE,
|
||||
AIR_PURIFIER_TABLE_PM25_SERVICE_INFO,
|
||||
AIR_PURIFIER_TABLE_US_SERVICE_INFO,
|
||||
"air_purifier_table_us",
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user