mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 18:57:06 +00:00
Add floor lamp and strip light 3 for switchbot integration (#147517)
This commit is contained in:
parent
e210681751
commit
c05d8aab1c
@ -93,6 +93,8 @@ PLATFORMS_BY_TYPE = {
|
||||
SupportedModels.AIR_PURIFIER.value: [Platform.FAN, Platform.SENSOR],
|
||||
SupportedModels.AIR_PURIFIER_TABLE.value: [Platform.FAN, Platform.SENSOR],
|
||||
SupportedModels.EVAPORATIVE_HUMIDIFIER: [Platform.HUMIDIFIER, Platform.SENSOR],
|
||||
SupportedModels.FLOOR_LAMP.value: [Platform.LIGHT, Platform.SENSOR],
|
||||
SupportedModels.STRIP_LIGHT_3.value: [Platform.LIGHT, Platform.SENSOR],
|
||||
}
|
||||
CLASS_BY_DEVICE = {
|
||||
SupportedModels.CEILING_LIGHT.value: switchbot.SwitchbotCeilingLight,
|
||||
@ -119,6 +121,8 @@ CLASS_BY_DEVICE = {
|
||||
SupportedModels.AIR_PURIFIER.value: switchbot.SwitchbotAirPurifier,
|
||||
SupportedModels.AIR_PURIFIER_TABLE.value: switchbot.SwitchbotAirPurifier,
|
||||
SupportedModels.EVAPORATIVE_HUMIDIFIER: switchbot.SwitchbotEvaporativeHumidifier,
|
||||
SupportedModels.FLOOR_LAMP.value: switchbot.SwitchbotStripLight3,
|
||||
SupportedModels.STRIP_LIGHT_3.value: switchbot.SwitchbotStripLight3,
|
||||
}
|
||||
|
||||
|
||||
|
@ -49,6 +49,8 @@ class SupportedModels(StrEnum):
|
||||
AIR_PURIFIER = "air_purifier"
|
||||
AIR_PURIFIER_TABLE = "air_purifier_table"
|
||||
EVAPORATIVE_HUMIDIFIER = "evaporative_humidifier"
|
||||
FLOOR_LAMP = "floor_lamp"
|
||||
STRIP_LIGHT_3 = "strip_light_3"
|
||||
|
||||
|
||||
CONNECTABLE_SUPPORTED_MODEL_TYPES = {
|
||||
@ -77,6 +79,8 @@ CONNECTABLE_SUPPORTED_MODEL_TYPES = {
|
||||
SwitchbotModel.AIR_PURIFIER: SupportedModels.AIR_PURIFIER,
|
||||
SwitchbotModel.AIR_PURIFIER_TABLE: SupportedModels.AIR_PURIFIER_TABLE,
|
||||
SwitchbotModel.EVAPORATIVE_HUMIDIFIER: SupportedModels.EVAPORATIVE_HUMIDIFIER,
|
||||
SwitchbotModel.FLOOR_LAMP: SupportedModels.FLOOR_LAMP,
|
||||
SwitchbotModel.STRIP_LIGHT_3: SupportedModels.STRIP_LIGHT_3,
|
||||
}
|
||||
|
||||
NON_CONNECTABLE_SUPPORTED_MODEL_TYPES = {
|
||||
@ -106,6 +110,8 @@ ENCRYPTED_MODELS = {
|
||||
SwitchbotModel.AIR_PURIFIER,
|
||||
SwitchbotModel.AIR_PURIFIER_TABLE,
|
||||
SwitchbotModel.EVAPORATIVE_HUMIDIFIER,
|
||||
SwitchbotModel.FLOOR_LAMP,
|
||||
SwitchbotModel.STRIP_LIGHT_3,
|
||||
}
|
||||
|
||||
ENCRYPTED_SWITCHBOT_MODEL_TO_CLASS: dict[
|
||||
@ -120,6 +126,8 @@ ENCRYPTED_SWITCHBOT_MODEL_TO_CLASS: dict[
|
||||
SwitchbotModel.AIR_PURIFIER: switchbot.SwitchbotAirPurifier,
|
||||
SwitchbotModel.AIR_PURIFIER_TABLE: switchbot.SwitchbotAirPurifier,
|
||||
SwitchbotModel.EVAPORATIVE_HUMIDIFIER: switchbot.SwitchbotEvaporativeHumidifier,
|
||||
SwitchbotModel.FLOOR_LAMP: switchbot.SwitchbotStripLight3,
|
||||
SwitchbotModel.STRIP_LIGHT_3: switchbot.SwitchbotStripLight3,
|
||||
}
|
||||
|
||||
HASS_SENSOR_TYPE_TO_SWITCHBOT_MODEL = {
|
||||
|
@ -941,3 +941,61 @@ CEILING_LIGHT_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
connectable=True,
|
||||
tx_power=-127,
|
||||
)
|
||||
|
||||
|
||||
STRIP_LIGHT_3_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
name="Strip Light 3",
|
||||
manufacturer_data={
|
||||
2409: b'\xc0N0\xe0U\x9a\x85\x9e"\xd0\x00\x00\x00\x00\x00\x00\x12\x91\x00',
|
||||
},
|
||||
service_data={
|
||||
"0000fd3d-0000-1000-8000-00805f9b34fb": b"\x00\x00\x00\x00\x10\xd0\xb1"
|
||||
},
|
||||
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
|
||||
address="AA:BB:CC:DD:EE:FF",
|
||||
rssi=-60,
|
||||
source="local",
|
||||
advertisement=generate_advertisement_data(
|
||||
local_name="Strip Light 3",
|
||||
manufacturer_data={
|
||||
2409: b'\xc0N0\xe0U\x9a\x85\x9e"\xd0\x00\x00\x00\x00\x00\x00\x12\x91\x00',
|
||||
},
|
||||
service_data={
|
||||
"0000fd3d-0000-1000-8000-00805f9b34fb": b"\x00\x00\x00\x00\x10\xd0\xb1"
|
||||
},
|
||||
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
|
||||
),
|
||||
device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Strip Light 3"),
|
||||
time=0,
|
||||
connectable=True,
|
||||
tx_power=-127,
|
||||
)
|
||||
|
||||
|
||||
FLOOR_LAMP_SERVICE_INFO = BluetoothServiceInfoBleak(
|
||||
name="Floor Lamp",
|
||||
manufacturer_data={
|
||||
2409: b'\xa0\x85\xe3e,\x06P\xaa"\xd4\x00\x00\x00\x00\x00\x00\r\x93\x00',
|
||||
},
|
||||
service_data={
|
||||
"0000fd3d-0000-1000-8000-00805f9b34fb": b"\x00\x00\x00\x00\x10\xd0\xb0"
|
||||
},
|
||||
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
|
||||
address="AA:BB:CC:DD:EE:FF",
|
||||
rssi=-60,
|
||||
source="local",
|
||||
advertisement=generate_advertisement_data(
|
||||
local_name="Floor Lamp",
|
||||
manufacturer_data={
|
||||
2409: b'\xa0\x85\xe3e,\x06P\xaa"\xd4\x00\x00\x00\x00\x00\x00\r\x93\x00',
|
||||
},
|
||||
service_data={
|
||||
"0000fd3d-0000-1000-8000-00805f9b34fb": b"\x00\x00\x00\x00\x10\xd0\xb0"
|
||||
},
|
||||
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
|
||||
),
|
||||
device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Floor Lamp"),
|
||||
time=0,
|
||||
connectable=True,
|
||||
tx_power=-127,
|
||||
)
|
||||
|
@ -7,6 +7,7 @@ from unittest.mock import AsyncMock, patch
|
||||
import pytest
|
||||
from switchbot.devices.device import SwitchbotOperationError
|
||||
|
||||
from homeassistant.components.bluetooth import BluetoothServiceInfoBleak
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS,
|
||||
ATTR_COLOR_TEMP_KELVIN,
|
||||
@ -20,7 +21,13 @@ from homeassistant.const import ATTR_ENTITY_ID
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
from . import BULB_SERVICE_INFO, CEILING_LIGHT_SERVICE_INFO, WOSTRIP_SERVICE_INFO
|
||||
from . import (
|
||||
BULB_SERVICE_INFO,
|
||||
CEILING_LIGHT_SERVICE_INFO,
|
||||
FLOOR_LAMP_SERVICE_INFO,
|
||||
STRIP_LIGHT_3_SERVICE_INFO,
|
||||
WOSTRIP_SERVICE_INFO,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.bluetooth import inject_bluetooth_service_info
|
||||
@ -71,9 +78,9 @@ BULB_PARAMETERS = (
|
||||
SET_COLOR_TEMP_PARAMETERS,
|
||||
(
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_EFFECT: "Breathing"},
|
||||
{ATTR_EFFECT: "breathing"},
|
||||
"set_effect",
|
||||
("Breathing",),
|
||||
("breathing",),
|
||||
),
|
||||
],
|
||||
)
|
||||
@ -95,9 +102,25 @@ STRIP_LIGHT_PARAMETERS = (
|
||||
SET_RGB_PARAMETERS,
|
||||
(
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_EFFECT: "Halloween"},
|
||||
{ATTR_EFFECT: "halloween"},
|
||||
"set_effect",
|
||||
("Halloween",),
|
||||
("halloween",),
|
||||
),
|
||||
],
|
||||
)
|
||||
FLOOR_LAMP_PARAMETERS = (
|
||||
COMMON_PARAMETERS,
|
||||
[
|
||||
TURN_ON_PARAMETERS,
|
||||
TURN_OFF_PARAMETERS,
|
||||
SET_BRIGHTNESS_PARAMETERS,
|
||||
SET_RGB_PARAMETERS,
|
||||
SET_COLOR_TEMP_PARAMETERS,
|
||||
(
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_EFFECT: "halloween"},
|
||||
"set_effect",
|
||||
("halloween",),
|
||||
),
|
||||
],
|
||||
)
|
||||
@ -317,3 +340,91 @@ async def test_strip_light_services_exception(
|
||||
{**service_data, ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("sensor_type", "service_info"),
|
||||
[
|
||||
("strip_light_3", STRIP_LIGHT_3_SERVICE_INFO),
|
||||
("floor_lamp", FLOOR_LAMP_SERVICE_INFO),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(*FLOOR_LAMP_PARAMETERS)
|
||||
async def test_floor_lamp_services(
|
||||
hass: HomeAssistant,
|
||||
mock_entry_encrypted_factory: Callable[[str], MockConfigEntry],
|
||||
sensor_type: str,
|
||||
service_info: BluetoothServiceInfoBleak,
|
||||
service: str,
|
||||
service_data: dict,
|
||||
mock_method: str,
|
||||
expected_args: Any,
|
||||
) -> None:
|
||||
"""Test all SwitchBot floor lamp services."""
|
||||
inject_bluetooth_service_info(hass, service_info)
|
||||
|
||||
entry = mock_entry_encrypted_factory(sensor_type=sensor_type)
|
||||
entry.add_to_hass(hass)
|
||||
entity_id = "light.test_name"
|
||||
|
||||
mocked_instance = AsyncMock(return_value=True)
|
||||
|
||||
with patch.multiple(
|
||||
"homeassistant.components.switchbot.light.switchbot.SwitchbotStripLight3",
|
||||
**{mock_method: mocked_instance},
|
||||
update=AsyncMock(return_value=None),
|
||||
):
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
service,
|
||||
{**service_data, ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
mocked_instance.assert_awaited_once_with(*expected_args)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("sensor_type", "service_info"),
|
||||
[
|
||||
("strip_light_3", STRIP_LIGHT_3_SERVICE_INFO),
|
||||
("floor_lamp", FLOOR_LAMP_SERVICE_INFO),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize(*FLOOR_LAMP_PARAMETERS)
|
||||
async def test_floor_lamp_services_exception(
|
||||
hass: HomeAssistant,
|
||||
mock_entry_encrypted_factory: Callable[[str], MockConfigEntry],
|
||||
sensor_type: str,
|
||||
service_info: BluetoothServiceInfoBleak,
|
||||
service: str,
|
||||
service_data: dict,
|
||||
mock_method: str,
|
||||
expected_args: Any,
|
||||
) -> None:
|
||||
"""Test all SwitchBot floor lamp services with exception."""
|
||||
inject_bluetooth_service_info(hass, service_info)
|
||||
|
||||
entry = mock_entry_encrypted_factory(sensor_type=sensor_type)
|
||||
entry.add_to_hass(hass)
|
||||
entity_id = "light.test_name"
|
||||
exception = SwitchbotOperationError("Operation failed")
|
||||
error_message = "An error occurred while performing the action: Operation failed"
|
||||
with patch.multiple(
|
||||
"homeassistant.components.switchbot.light.switchbot.SwitchbotStripLight3",
|
||||
**{mock_method: AsyncMock(side_effect=exception)},
|
||||
update=AsyncMock(return_value=None),
|
||||
):
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with pytest.raises(HomeAssistantError, match=error_message):
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
service,
|
||||
{**service_data, ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user