Skip to content

Commit 1ef9018

Browse files
authored
Add plug mini eu for switchbot integration (home-assistant#151130)
1 parent 4c1364d commit 1ef9018

File tree

5 files changed

+155
-1
lines changed

5 files changed

+155
-1
lines changed

homeassistant/components/switchbot/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
SupportedModels.STRIP_LIGHT_3.value: [Platform.LIGHT, Platform.SENSOR],
9898
SupportedModels.RGBICWW_FLOOR_LAMP.value: [Platform.LIGHT, Platform.SENSOR],
9999
SupportedModels.RGBICWW_STRIP_LIGHT.value: [Platform.LIGHT, Platform.SENSOR],
100+
SupportedModels.PLUG_MINI_EU.value: [Platform.SWITCH, Platform.SENSOR],
100101
}
101102
CLASS_BY_DEVICE = {
102103
SupportedModels.CEILING_LIGHT.value: switchbot.SwitchbotCeilingLight,
@@ -127,6 +128,7 @@
127128
SupportedModels.STRIP_LIGHT_3.value: switchbot.SwitchbotStripLight3,
128129
SupportedModels.RGBICWW_FLOOR_LAMP.value: switchbot.SwitchbotRgbicLight,
129130
SupportedModels.RGBICWW_STRIP_LIGHT.value: switchbot.SwitchbotRgbicLight,
131+
SupportedModels.PLUG_MINI_EU.value: switchbot.SwitchbotRelaySwitch,
130132
}
131133

132134

homeassistant/components/switchbot/const.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class SupportedModels(StrEnum):
5353
STRIP_LIGHT_3 = "strip_light_3"
5454
RGBICWW_STRIP_LIGHT = "rgbicww_strip_light"
5555
RGBICWW_FLOOR_LAMP = "rgbicww_floor_lamp"
56+
PLUG_MINI_EU = "plug_mini_eu"
5657

5758

5859
CONNECTABLE_SUPPORTED_MODEL_TYPES = {
@@ -85,6 +86,7 @@ class SupportedModels(StrEnum):
8586
SwitchbotModel.STRIP_LIGHT_3: SupportedModels.STRIP_LIGHT_3,
8687
SwitchbotModel.RGBICWW_STRIP_LIGHT: SupportedModels.RGBICWW_STRIP_LIGHT,
8788
SwitchbotModel.RGBICWW_FLOOR_LAMP: SupportedModels.RGBICWW_FLOOR_LAMP,
89+
SwitchbotModel.PLUG_MINI_EU: SupportedModels.PLUG_MINI_EU,
8890
}
8991

9092
NON_CONNECTABLE_SUPPORTED_MODEL_TYPES = {
@@ -118,6 +120,7 @@ class SupportedModels(StrEnum):
118120
SwitchbotModel.STRIP_LIGHT_3,
119121
SwitchbotModel.RGBICWW_STRIP_LIGHT,
120122
SwitchbotModel.RGBICWW_FLOOR_LAMP,
123+
SwitchbotModel.PLUG_MINI_EU,
121124
}
122125

123126
ENCRYPTED_SWITCHBOT_MODEL_TO_CLASS: dict[
@@ -136,6 +139,7 @@ class SupportedModels(StrEnum):
136139
SwitchbotModel.STRIP_LIGHT_3: switchbot.SwitchbotStripLight3,
137140
SwitchbotModel.RGBICWW_STRIP_LIGHT: switchbot.SwitchbotRgbicLight,
138141
SwitchbotModel.RGBICWW_FLOOR_LAMP: switchbot.SwitchbotRgbicLight,
142+
SwitchbotModel.PLUG_MINI_EU: switchbot.SwitchbotRelaySwitch,
139143
}
140144

141145
HASS_SENSOR_TYPE_TO_SWITCHBOT_MODEL = {

tests/components/switchbot/__init__.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,3 +1056,27 @@ def make_advertisement(
10561056
connectable=True,
10571057
tx_power=-127,
10581058
)
1059+
1060+
PLUG_MINI_EU_SERVICE_INFO = BluetoothServiceInfoBleak(
1061+
name="Plug Mini (EU)",
1062+
manufacturer_data={
1063+
2409: b"\x94\xa9\x90T\x85^?\xa1\x00\x00\x04\xe6\x00\x00\x00\x00",
1064+
},
1065+
service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"?\x00\x00\x00"},
1066+
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
1067+
address="AA:BB:CC:DD:EE:FF",
1068+
rssi=-60,
1069+
source="local",
1070+
advertisement=generate_advertisement_data(
1071+
local_name="Plug Mini (EU)",
1072+
manufacturer_data={
1073+
2409: b"\x94\xa9\x90T\x85^?\xa1\x00\x00\x04\xe6\x00\x00\x00\x00",
1074+
},
1075+
service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"?\x00\x00\x00"},
1076+
service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"],
1077+
),
1078+
device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Plug Mini (EU)"),
1079+
time=0,
1080+
connectable=True,
1081+
tx_power=-127,
1082+
)

tests/components/switchbot/test_sensor.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
HUB3_SERVICE_INFO,
2929
HUBMINI_MATTER_SERVICE_INFO,
3030
LEAK_SERVICE_INFO,
31+
PLUG_MINI_EU_SERVICE_INFO,
3132
REMOTE_SERVICE_INFO,
3233
WOHAND_SERVICE_INFO,
3334
WOHUB2_SERVICE_INFO,
@@ -542,3 +543,77 @@ async def test_evaporative_humidifier_sensor(hass: HomeAssistant) -> None:
542543

543544
assert await hass.config_entries.async_unload(entry.entry_id)
544545
await hass.async_block_till_done()
546+
547+
548+
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
549+
async def test_plug_mini_eu_sensor(hass: HomeAssistant) -> None:
550+
"""Test setting up creates the plug mini eu sensor."""
551+
await async_setup_component(hass, DOMAIN, {})
552+
inject_bluetooth_service_info(hass, PLUG_MINI_EU_SERVICE_INFO)
553+
554+
with patch(
555+
"homeassistant.components.switchbot.switch.switchbot.SwitchbotRelaySwitch.get_basic_info",
556+
new=AsyncMock(
557+
return_value={
558+
"power": 500,
559+
"current": 0.5,
560+
"voltage": 230,
561+
"energy": 0.4,
562+
}
563+
),
564+
):
565+
entry = MockConfigEntry(
566+
domain=DOMAIN,
567+
data={
568+
CONF_ADDRESS: "aa:bb:cc:dd:ee:ff",
569+
CONF_NAME: "test-name",
570+
CONF_SENSOR_TYPE: "plug_mini_eu",
571+
CONF_KEY_ID: "ff",
572+
CONF_ENCRYPTION_KEY: "ffffffffffffffffffffffffffffffff",
573+
},
574+
unique_id="aabbccddeeaa",
575+
)
576+
entry.add_to_hass(hass)
577+
578+
assert await hass.config_entries.async_setup(entry.entry_id)
579+
await hass.async_block_till_done()
580+
581+
assert len(hass.states.async_all("sensor")) == 5
582+
583+
power_sensor = hass.states.get("sensor.test_name_power")
584+
power_sensor_attrs = power_sensor.attributes
585+
assert power_sensor.state == "500"
586+
assert power_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Power"
587+
assert power_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "W"
588+
assert power_sensor_attrs[ATTR_STATE_CLASS] == "measurement"
589+
590+
voltage_sensor = hass.states.get("sensor.test_name_voltage")
591+
voltage_sensor_attrs = voltage_sensor.attributes
592+
assert voltage_sensor.state == "230"
593+
assert voltage_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Voltage"
594+
assert voltage_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "V"
595+
assert voltage_sensor_attrs[ATTR_STATE_CLASS] == "measurement"
596+
597+
current_sensor = hass.states.get("sensor.test_name_current")
598+
current_sensor_attrs = current_sensor.attributes
599+
assert current_sensor.state == "0.5"
600+
assert current_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Current"
601+
assert current_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "A"
602+
assert current_sensor_attrs[ATTR_STATE_CLASS] == "measurement"
603+
604+
energy_sensor = hass.states.get("sensor.test_name_energy")
605+
energy_sensor_attrs = energy_sensor.attributes
606+
assert energy_sensor.state == "0.4"
607+
assert energy_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Energy"
608+
assert energy_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "kWh"
609+
assert energy_sensor_attrs[ATTR_STATE_CLASS] == "total_increasing"
610+
611+
rssi_sensor = hass.states.get("sensor.test_name_bluetooth_signal")
612+
rssi_sensor_attrs = rssi_sensor.attributes
613+
assert rssi_sensor.state == "-60"
614+
assert rssi_sensor_attrs[ATTR_FRIENDLY_NAME] == "test-name Bluetooth signal"
615+
assert rssi_sensor_attrs[ATTR_UNIT_OF_MEASUREMENT] == "dBm"
616+
assert rssi_sensor_attrs[ATTR_STATE_CLASS] == "measurement"
617+
618+
assert await hass.config_entries.async_unload(entry.entry_id)
619+
await hass.async_block_till_done()

tests/components/switchbot/test_switch.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import pytest
77
from switchbot.devices.device import SwitchbotOperationError
88

9+
from homeassistant.components.bluetooth import BluetoothServiceInfoBleak
910
from homeassistant.components.switch import (
1011
DOMAIN as SWITCH_DOMAIN,
1112
SERVICE_TURN_OFF,
@@ -16,7 +17,7 @@
1617
from homeassistant.core import HomeAssistant, State
1718
from homeassistant.exceptions import HomeAssistantError
1819

19-
from . import WOHAND_SERVICE_INFO
20+
from . import PLUG_MINI_EU_SERVICE_INFO, WOHAND_SERVICE_INFO
2021

2122
from tests.common import MockConfigEntry, mock_restore_cache
2223
from tests.components.bluetooth import inject_bluetooth_service_info
@@ -103,3 +104,51 @@ async def test_exception_handling_switch(
103104
{ATTR_ENTITY_ID: entity_id},
104105
blocking=True,
105106
)
107+
108+
109+
@pytest.mark.parametrize(
110+
("sensor_type", "service_info"),
111+
[
112+
("plug_mini_eu", PLUG_MINI_EU_SERVICE_INFO),
113+
],
114+
)
115+
@pytest.mark.parametrize(
116+
("service", "mock_method"),
117+
[
118+
(SERVICE_TURN_ON, "turn_on"),
119+
(SERVICE_TURN_OFF, "turn_off"),
120+
],
121+
)
122+
async def test_relay_switch_control(
123+
hass: HomeAssistant,
124+
mock_entry_encrypted_factory: Callable[[str], MockConfigEntry],
125+
sensor_type: str,
126+
service_info: BluetoothServiceInfoBleak,
127+
service: str,
128+
mock_method: str,
129+
) -> None:
130+
"""Test Relay Switch control."""
131+
inject_bluetooth_service_info(hass, service_info)
132+
133+
entry = mock_entry_encrypted_factory(sensor_type=sensor_type)
134+
entry.add_to_hass(hass)
135+
136+
mocked_instance = AsyncMock(return_value=True)
137+
with patch.multiple(
138+
"homeassistant.components.switchbot.switch.switchbot.SwitchbotRelaySwitch",
139+
update=AsyncMock(return_value=None),
140+
**{mock_method: mocked_instance},
141+
):
142+
assert await hass.config_entries.async_setup(entry.entry_id)
143+
await hass.async_block_till_done()
144+
145+
entity_id = "switch.test_name"
146+
147+
await hass.services.async_call(
148+
SWITCH_DOMAIN,
149+
service,
150+
{ATTR_ENTITY_ID: entity_id},
151+
blocking=True,
152+
)
153+
154+
mocked_instance.assert_awaited_once()

0 commit comments

Comments
 (0)