mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Add support for Bot in SwitchBot Cloud (#135606)
This commit is contained in:
parent
e822f5de6e
commit
33a2fa2c85
@ -16,6 +16,7 @@ from .coordinator import SwitchBotCoordinator
|
||||
|
||||
_LOGGER = getLogger(__name__)
|
||||
PLATFORMS: list[Platform] = [
|
||||
Platform.BUTTON,
|
||||
Platform.CLIMATE,
|
||||
Platform.LOCK,
|
||||
Platform.SENSOR,
|
||||
@ -28,6 +29,7 @@ PLATFORMS: list[Platform] = [
|
||||
class SwitchbotDevices:
|
||||
"""Switchbot devices data."""
|
||||
|
||||
buttons: list[Device] = field(default_factory=list)
|
||||
climates: list[Remote] = field(default_factory=list)
|
||||
switches: list[Device | Remote] = field(default_factory=list)
|
||||
sensors: list[Device] = field(default_factory=list)
|
||||
@ -136,6 +138,16 @@ async def make_device_data(
|
||||
)
|
||||
devices_data.locks.append((device, coordinator))
|
||||
|
||||
if isinstance(device, Device) and device.device_type in ["Bot"]:
|
||||
coordinator = await coordinator_for_device(
|
||||
hass, api, device, coordinators_by_id
|
||||
)
|
||||
if coordinator.data is not None:
|
||||
if coordinator.data.get("deviceMode") == "pressMode":
|
||||
devices_data.buttons.append((device, coordinator))
|
||||
else:
|
||||
devices_data.switches.append((device, coordinator))
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, config: ConfigEntry) -> bool:
|
||||
"""Set up SwitchBot via API from a config entry."""
|
||||
|
41
homeassistant/components/switchbot_cloud/button.py
Normal file
41
homeassistant/components/switchbot_cloud/button.py
Normal file
@ -0,0 +1,41 @@
|
||||
"""Support for the Switchbot Bot as a Button."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from switchbot_api import BotCommands
|
||||
|
||||
from homeassistant.components.button import ButtonEntity
|
||||
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
|
||||
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(
|
||||
SwitchBotCloudBot(data.api, device, coordinator)
|
||||
for device, coordinator in data.devices.buttons
|
||||
)
|
||||
|
||||
|
||||
class SwitchBotCloudBot(SwitchBotCloudEntity, ButtonEntity):
|
||||
"""Representation of a SwitchBot Bot."""
|
||||
|
||||
_attr_name = None
|
||||
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
|
||||
async def async_press(self, **kwargs: Any) -> None:
|
||||
"""Bot press command."""
|
||||
await self.send_api_command(BotCommands.PRESS)
|
@ -90,4 +90,6 @@ def _async_make_entity(
|
||||
"Relay Switch 1",
|
||||
]:
|
||||
return SwitchBotCloudRelaySwitchSwitch(api, device, coordinator)
|
||||
if "Bot" in device.device_type:
|
||||
return SwitchBotCloudSwitch(api, device, coordinator)
|
||||
raise NotImplementedError(f"Unsupported device type: {device.device_type}")
|
||||
|
71
tests/components/switchbot_cloud/test_button.py
Normal file
71
tests/components/switchbot_cloud/test_button.py
Normal file
@ -0,0 +1,71 @@
|
||||
"""Test for the switchbot_cloud bot as a button."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from switchbot_api import BotCommands, Device
|
||||
|
||||
from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS
|
||||
from homeassistant.components.switchbot_cloud import SwitchBotAPI
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import configure_integration
|
||||
|
||||
|
||||
async def test_pressmode_bot(
|
||||
hass: HomeAssistant, mock_list_devices, mock_get_status
|
||||
) -> None:
|
||||
"""Test press."""
|
||||
mock_list_devices.return_value = [
|
||||
Device(
|
||||
deviceId="bot-id-1",
|
||||
deviceName="bot-1",
|
||||
deviceType="Bot",
|
||||
hubDeviceId="test-hub-id",
|
||||
),
|
||||
]
|
||||
|
||||
mock_get_status.return_value = {"deviceMode": "pressMode"}
|
||||
|
||||
entry = configure_integration(hass)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
|
||||
entity_id = "button.bot_1"
|
||||
assert hass.states.get(entity_id).state == STATE_UNKNOWN
|
||||
|
||||
with patch.object(SwitchBotAPI, "send_command") as mock_send_command:
|
||||
await hass.services.async_call(
|
||||
BUTTON_DOMAIN, SERVICE_PRESS, {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||||
)
|
||||
mock_send_command.assert_called_once_with(
|
||||
"bot-id-1", BotCommands.PRESS, "command", "default"
|
||||
)
|
||||
|
||||
assert hass.states.get(entity_id).state != STATE_UNKNOWN
|
||||
|
||||
|
||||
async def test_switchmode_bot_no_button_entity(
|
||||
hass: HomeAssistant, mock_list_devices, mock_get_status
|
||||
) -> None:
|
||||
"""Test a switchMode bot isn't added as a button."""
|
||||
mock_list_devices.return_value = [
|
||||
Device(
|
||||
deviceId="bot-id-1",
|
||||
deviceName="bot-1",
|
||||
deviceType="Bot",
|
||||
hubDeviceId="test-hub-id",
|
||||
),
|
||||
]
|
||||
|
||||
mock_get_status.return_value = {"deviceMode": "switchMode"}
|
||||
|
||||
entry = configure_integration(hass)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
assert not hass.states.async_entity_ids(BUTTON_DOMAIN)
|
@ -1,4 +1,4 @@
|
||||
"""Test for the switchbot_cloud relay switch."""
|
||||
"""Test for the switchbot_cloud relay switch & bot."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
@ -54,3 +54,63 @@ async def test_relay_switch(
|
||||
SWITCH_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
|
||||
async def test_switchmode_bot(
|
||||
hass: HomeAssistant, mock_list_devices, mock_get_status
|
||||
) -> None:
|
||||
"""Test turn on and turn off."""
|
||||
mock_list_devices.return_value = [
|
||||
Device(
|
||||
deviceId="bot-id-1",
|
||||
deviceName="bot-1",
|
||||
deviceType="Bot",
|
||||
hubDeviceId="test-hub-id",
|
||||
),
|
||||
]
|
||||
|
||||
mock_get_status.return_value = {"deviceMode": "switchMode", "power": "off"}
|
||||
|
||||
entry = configure_integration(hass)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
|
||||
entity_id = "switch.bot_1"
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
with patch.object(SwitchBotAPI, "send_command"):
|
||||
await hass.services.async_call(
|
||||
SWITCH_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == STATE_ON
|
||||
|
||||
with patch.object(SwitchBotAPI, "send_command"):
|
||||
await hass.services.async_call(
|
||||
SWITCH_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
|
||||
async def test_pressmode_bot_no_switch_entity(
|
||||
hass: HomeAssistant, mock_list_devices, mock_get_status
|
||||
) -> None:
|
||||
"""Test a pressMode bot isn't added as a switch."""
|
||||
mock_list_devices.return_value = [
|
||||
Device(
|
||||
deviceId="bot-id-1",
|
||||
deviceName="bot-1",
|
||||
deviceType="Bot",
|
||||
hubDeviceId="test-hub-id",
|
||||
),
|
||||
]
|
||||
|
||||
mock_get_status.return_value = {"deviceMode": "pressMode"}
|
||||
|
||||
entry = configure_integration(hass)
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
assert not hass.states.async_entity_ids(SWITCH_DOMAIN)
|
||||
|
Loading…
x
Reference in New Issue
Block a user