Add k10+ vacuum in switchbot cloud integration (#125457)
* Add k10+ vacuum in switchbot cloud integration * Change label fan speed, Mapping state HA, Add others vacuums * Update homeassistant/components/switchbot_cloud/vacuum.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Remove comments and add mapping for fan speed --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>pull/125962/head
parent
5fb9a24f22
commit
a24db20c64
|
@ -1436,8 +1436,8 @@ build.json @home-assistant/supervisor
|
||||||
/tests/components/switchbee/ @jafar-atili
|
/tests/components/switchbee/ @jafar-atili
|
||||||
/homeassistant/components/switchbot/ @danielhiversen @RenierM26 @murtas @Eloston @dsypniewski
|
/homeassistant/components/switchbot/ @danielhiversen @RenierM26 @murtas @Eloston @dsypniewski
|
||||||
/tests/components/switchbot/ @danielhiversen @RenierM26 @murtas @Eloston @dsypniewski
|
/tests/components/switchbot/ @danielhiversen @RenierM26 @murtas @Eloston @dsypniewski
|
||||||
/homeassistant/components/switchbot_cloud/ @SeraphicRav @laurence-presland
|
/homeassistant/components/switchbot_cloud/ @SeraphicRav @laurence-presland @Gigatrappeur
|
||||||
/tests/components/switchbot_cloud/ @SeraphicRav @laurence-presland
|
/tests/components/switchbot_cloud/ @SeraphicRav @laurence-presland @Gigatrappeur
|
||||||
/homeassistant/components/switcher_kis/ @thecode
|
/homeassistant/components/switcher_kis/ @thecode
|
||||||
/tests/components/switcher_kis/ @thecode
|
/tests/components/switcher_kis/ @thecode
|
||||||
/homeassistant/components/switchmate/ @danielhiversen @qiz-li
|
/homeassistant/components/switchmate/ @danielhiversen @qiz-li
|
||||||
|
|
|
@ -15,7 +15,12 @@ from .const import DOMAIN
|
||||||
from .coordinator import SwitchBotCoordinator
|
from .coordinator import SwitchBotCoordinator
|
||||||
|
|
||||||
_LOGGER = getLogger(__name__)
|
_LOGGER = getLogger(__name__)
|
||||||
PLATFORMS: list[Platform] = [Platform.CLIMATE, Platform.SENSOR, Platform.SWITCH]
|
PLATFORMS: list[Platform] = [
|
||||||
|
Platform.CLIMATE,
|
||||||
|
Platform.SENSOR,
|
||||||
|
Platform.SWITCH,
|
||||||
|
Platform.VACUUM,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@ -25,6 +30,7 @@ class SwitchbotDevices:
|
||||||
climates: list[Remote] = field(default_factory=list)
|
climates: list[Remote] = field(default_factory=list)
|
||||||
switches: list[Device | Remote] = field(default_factory=list)
|
switches: list[Device | Remote] = field(default_factory=list)
|
||||||
sensors: list[Device] = field(default_factory=list)
|
sensors: list[Device] = field(default_factory=list)
|
||||||
|
vacuums: list[Device] = field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@ -81,6 +87,16 @@ def make_device_data(
|
||||||
devices_data.sensors.append(
|
devices_data.sensors.append(
|
||||||
prepare_device(hass, api, device, coordinators_by_id)
|
prepare_device(hass, api, device, coordinators_by_id)
|
||||||
)
|
)
|
||||||
|
if isinstance(device, Device) and device.device_type in [
|
||||||
|
"K10+",
|
||||||
|
"K10+ Pro",
|
||||||
|
"Robot Vacuum Cleaner S1",
|
||||||
|
"Robot Vacuum Cleaner S1 Plus",
|
||||||
|
]:
|
||||||
|
devices_data.vacuums.append(
|
||||||
|
prepare_device(hass, api, device, coordinators_by_id)
|
||||||
|
)
|
||||||
|
|
||||||
return devices_data
|
return devices_data
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -95,7 +95,7 @@ class SwitchBotCloudAirConditioner(SwitchBotCloudEntity, ClimateEntity):
|
||||||
new_fan_speed = _SWITCHBOT_FAN_MODES.get(
|
new_fan_speed = _SWITCHBOT_FAN_MODES.get(
|
||||||
fan_mode or self._attr_fan_mode, _DEFAULT_SWITCHBOT_FAN_MODE
|
fan_mode or self._attr_fan_mode, _DEFAULT_SWITCHBOT_FAN_MODE
|
||||||
)
|
)
|
||||||
await self.send_command(
|
await self.send_api_command(
|
||||||
AirConditionerCommands.SET_ALL,
|
AirConditionerCommands.SET_ALL,
|
||||||
parameters=f"{new_temperature},{new_mode},{new_fan_speed},on",
|
parameters=f"{new_temperature},{new_mode},{new_fan_speed},on",
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,3 +10,8 @@ DEFAULT_SCAN_INTERVAL = timedelta(seconds=600)
|
||||||
SENSOR_KIND_TEMPERATURE = "temperature"
|
SENSOR_KIND_TEMPERATURE = "temperature"
|
||||||
SENSOR_KIND_HUMIDITY = "humidity"
|
SENSOR_KIND_HUMIDITY = "humidity"
|
||||||
SENSOR_KIND_BATTERY = "battery"
|
SENSOR_KIND_BATTERY = "battery"
|
||||||
|
|
||||||
|
VACUUM_FAN_SPEED_QUIET = "quiet"
|
||||||
|
VACUUM_FAN_SPEED_STANDARD = "standard"
|
||||||
|
VACUUM_FAN_SPEED_STRONG = "strong"
|
||||||
|
VACUUM_FAN_SPEED_MAX = "max"
|
||||||
|
|
|
@ -35,7 +35,7 @@ class SwitchBotCloudEntity(CoordinatorEntity[SwitchBotCoordinator]):
|
||||||
model=device.device_type,
|
model=device.device_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def send_command(
|
async def send_api_command(
|
||||||
self,
|
self,
|
||||||
command: Commands,
|
command: Commands,
|
||||||
command_type: str = "command",
|
command_type: str = "command",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"domain": "switchbot_cloud",
|
"domain": "switchbot_cloud",
|
||||||
"name": "SwitchBot Cloud",
|
"name": "SwitchBot Cloud",
|
||||||
"codeowners": ["@SeraphicRav", "@laurence-presland"],
|
"codeowners": ["@SeraphicRav", "@laurence-presland", "@Gigatrappeur"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/switchbot_cloud",
|
"documentation": "https://www.home-assistant.io/integrations/switchbot_cloud",
|
||||||
"integration_type": "hub",
|
"integration_type": "hub",
|
||||||
|
|
|
@ -36,13 +36,13 @@ class SwitchBotCloudSwitch(SwitchBotCloudEntity, SwitchEntity):
|
||||||
|
|
||||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||||
"""Turn the device on."""
|
"""Turn the device on."""
|
||||||
await self.send_command(CommonCommands.ON)
|
await self.send_api_command(CommonCommands.ON)
|
||||||
self._attr_is_on = True
|
self._attr_is_on = True
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Turn the device off."""
|
"""Turn the device off."""
|
||||||
await self.send_command(CommonCommands.OFF)
|
await self.send_api_command(CommonCommands.OFF)
|
||||||
self._attr_is_on = False
|
self._attr_is_on = False
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
"""Support for SwitchBot vacuum."""
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from switchbot_api import Device, Remote, SwitchBotAPI, VacuumCommands
|
||||||
|
|
||||||
|
from homeassistant.components.vacuum import (
|
||||||
|
STATE_CLEANING,
|
||||||
|
STATE_DOCKED,
|
||||||
|
STATE_ERROR,
|
||||||
|
STATE_IDLE,
|
||||||
|
STATE_PAUSED,
|
||||||
|
STATE_RETURNING,
|
||||||
|
StateVacuumEntity,
|
||||||
|
VacuumEntityFeature,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from . import SwitchbotCloudData
|
||||||
|
from .const import (
|
||||||
|
DOMAIN,
|
||||||
|
VACUUM_FAN_SPEED_MAX,
|
||||||
|
VACUUM_FAN_SPEED_QUIET,
|
||||||
|
VACUUM_FAN_SPEED_STANDARD,
|
||||||
|
VACUUM_FAN_SPEED_STRONG,
|
||||||
|
)
|
||||||
|
from .coordinator import SwitchBotCoordinator
|
||||||
|
from .entity import SwitchBotCloudEntity
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up SwitchBot Cloud entry."""
|
||||||
|
data: SwitchbotCloudData = hass.data[DOMAIN][config.entry_id]
|
||||||
|
async_add_entities(
|
||||||
|
_async_make_entity(data.api, device, coordinator)
|
||||||
|
for device, coordinator in data.devices.vacuums
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
VACUUM_SWITCHBOT_STATE_TO_HA_STATE: dict[str, str] = {
|
||||||
|
"StandBy": STATE_IDLE,
|
||||||
|
"Clearing": STATE_CLEANING,
|
||||||
|
"Paused": STATE_PAUSED,
|
||||||
|
"GotoChargeBase": STATE_RETURNING,
|
||||||
|
"Charging": STATE_DOCKED,
|
||||||
|
"ChargeDone": STATE_DOCKED,
|
||||||
|
"Dormant": STATE_IDLE,
|
||||||
|
"InTrouble": STATE_ERROR,
|
||||||
|
"InRemoteControl": STATE_CLEANING,
|
||||||
|
"InDustCollecting": STATE_DOCKED,
|
||||||
|
}
|
||||||
|
|
||||||
|
VACUUM_FAN_SPEED_TO_SWITCHBOT_FAN_SPEED: dict[str, str] = {
|
||||||
|
VACUUM_FAN_SPEED_QUIET: "0",
|
||||||
|
VACUUM_FAN_SPEED_STANDARD: "1",
|
||||||
|
VACUUM_FAN_SPEED_STRONG: "2",
|
||||||
|
VACUUM_FAN_SPEED_MAX: "3",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# https://github.com/OpenWonderLabs/SwitchBotAPI?tab=readme-ov-file#robot-vacuum-cleaner-s1-plus-1
|
||||||
|
class SwitchBotCloudVacuum(SwitchBotCloudEntity, StateVacuumEntity):
|
||||||
|
"""Representation of a SwitchBot vacuum."""
|
||||||
|
|
||||||
|
_attr_supported_features: VacuumEntityFeature = (
|
||||||
|
VacuumEntityFeature.BATTERY
|
||||||
|
| VacuumEntityFeature.FAN_SPEED
|
||||||
|
| VacuumEntityFeature.PAUSE
|
||||||
|
| VacuumEntityFeature.RETURN_HOME
|
||||||
|
| VacuumEntityFeature.START
|
||||||
|
| VacuumEntityFeature.STATE
|
||||||
|
)
|
||||||
|
|
||||||
|
_attr_name = None
|
||||||
|
_attr_fan_speed_list: list[str] = list(
|
||||||
|
VACUUM_FAN_SPEED_TO_SWITCHBOT_FAN_SPEED.keys()
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_set_fan_speed(self, fan_speed: str, **kwargs: Any) -> None:
|
||||||
|
"""Set fan speed."""
|
||||||
|
self._attr_fan_speed = fan_speed
|
||||||
|
if fan_speed in VACUUM_FAN_SPEED_TO_SWITCHBOT_FAN_SPEED:
|
||||||
|
await self.send_api_command(
|
||||||
|
VacuumCommands.POW_LEVEL,
|
||||||
|
parameters=VACUUM_FAN_SPEED_TO_SWITCHBOT_FAN_SPEED[fan_speed],
|
||||||
|
)
|
||||||
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
async def async_pause(self) -> None:
|
||||||
|
"""Pause the cleaning task."""
|
||||||
|
await self.send_api_command(VacuumCommands.STOP)
|
||||||
|
|
||||||
|
async def async_return_to_base(self, **kwargs: Any) -> None:
|
||||||
|
"""Set the vacuum cleaner to return to the dock."""
|
||||||
|
await self.send_api_command(VacuumCommands.DOCK)
|
||||||
|
|
||||||
|
async def async_start(self) -> None:
|
||||||
|
"""Start or resume the cleaning task."""
|
||||||
|
await self.send_api_command(VacuumCommands.START)
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _handle_coordinator_update(self) -> None:
|
||||||
|
"""Handle updated data from the coordinator."""
|
||||||
|
if not self.coordinator.data:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._attr_battery_level = self.coordinator.data.get("battery")
|
||||||
|
self._attr_available = self.coordinator.data.get("onlineStatus") == "online"
|
||||||
|
|
||||||
|
switchbot_state = str(self.coordinator.data.get("workingStatus"))
|
||||||
|
self._attr_state = VACUUM_SWITCHBOT_STATE_TO_HA_STATE.get(switchbot_state)
|
||||||
|
|
||||||
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _async_make_entity(
|
||||||
|
api: SwitchBotAPI, device: Device | Remote, coordinator: SwitchBotCoordinator
|
||||||
|
) -> SwitchBotCloudVacuum:
|
||||||
|
"""Make a SwitchBotCloudVacuum."""
|
||||||
|
return SwitchBotCloudVacuum(api, device, coordinator)
|
Loading…
Reference in New Issue