mirror of
https://github.com/home-assistant/core.git
synced 2025-07-08 05:47:10 +00:00
Add support for SwitchBot Relay Switch 1 and Relay Switch 1PM (#132327)
This commit is contained in:
parent
3bb6256572
commit
be25cb7aa7
@ -75,9 +75,11 @@ def make_device_data(
|
|||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
isinstance(device, Device)
|
isinstance(device, Device)
|
||||||
and device.device_type.startswith("Plug")
|
and (
|
||||||
or isinstance(device, Remote)
|
device.device_type.startswith("Plug")
|
||||||
):
|
or device.device_type in ["Relay Switch 1PM", "Relay Switch 1"]
|
||||||
|
)
|
||||||
|
) or isinstance(device, Remote):
|
||||||
devices_data.switches.append(
|
devices_data.switches.append(
|
||||||
prepare_device(hass, api, device, coordinators_by_id)
|
prepare_device(hass, api, device, coordinators_by_id)
|
||||||
)
|
)
|
||||||
@ -88,6 +90,7 @@ def make_device_data(
|
|||||||
"Hub 2",
|
"Hub 2",
|
||||||
"MeterPro",
|
"MeterPro",
|
||||||
"MeterPro(CO2)",
|
"MeterPro(CO2)",
|
||||||
|
"Relay Switch 1PM",
|
||||||
]:
|
]:
|
||||||
devices_data.sensors.append(
|
devices_data.sensors.append(
|
||||||
prepare_device(hass, api, device, coordinators_by_id)
|
prepare_device(hass, api, device, coordinators_by_id)
|
||||||
|
@ -12,6 +12,9 @@ from homeassistant.config_entries import ConfigEntry
|
|||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONCENTRATION_PARTS_PER_MILLION,
|
CONCENTRATION_PARTS_PER_MILLION,
|
||||||
PERCENTAGE,
|
PERCENTAGE,
|
||||||
|
UnitOfElectricCurrent,
|
||||||
|
UnitOfElectricPotential,
|
||||||
|
UnitOfPower,
|
||||||
UnitOfTemperature,
|
UnitOfTemperature,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
@ -26,38 +29,97 @@ SENSOR_TYPE_TEMPERATURE = "temperature"
|
|||||||
SENSOR_TYPE_HUMIDITY = "humidity"
|
SENSOR_TYPE_HUMIDITY = "humidity"
|
||||||
SENSOR_TYPE_BATTERY = "battery"
|
SENSOR_TYPE_BATTERY = "battery"
|
||||||
SENSOR_TYPE_CO2 = "CO2"
|
SENSOR_TYPE_CO2 = "CO2"
|
||||||
|
SENSOR_TYPE_POWER = "power"
|
||||||
|
SENSOR_TYPE_VOLTAGE = "voltage"
|
||||||
|
SENSOR_TYPE_CURRENT = "electricCurrent"
|
||||||
|
|
||||||
METER_PLUS_SENSOR_DESCRIPTIONS = (
|
TEMPERATURE_DESCRIPTION = SensorEntityDescription(
|
||||||
SensorEntityDescription(
|
key=SENSOR_TYPE_TEMPERATURE,
|
||||||
key=SENSOR_TYPE_TEMPERATURE,
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
device_class=SensorDeviceClass.TEMPERATURE,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
|
||||||
),
|
|
||||||
SensorEntityDescription(
|
|
||||||
key=SENSOR_TYPE_HUMIDITY,
|
|
||||||
device_class=SensorDeviceClass.HUMIDITY,
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
|
||||||
),
|
|
||||||
SensorEntityDescription(
|
|
||||||
key=SENSOR_TYPE_BATTERY,
|
|
||||||
device_class=SensorDeviceClass.BATTERY,
|
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
native_unit_of_measurement=PERCENTAGE,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
METER_PRO_CO2_SENSOR_DESCRIPTIONS = (
|
HUMIDITY_DESCRIPTION = SensorEntityDescription(
|
||||||
*METER_PLUS_SENSOR_DESCRIPTIONS,
|
key=SENSOR_TYPE_HUMIDITY,
|
||||||
SensorEntityDescription(
|
device_class=SensorDeviceClass.HUMIDITY,
|
||||||
key=SENSOR_TYPE_CO2,
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
state_class=SensorStateClass.MEASUREMENT,
|
|
||||||
device_class=SensorDeviceClass.CO2,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
BATTERY_DESCRIPTION = SensorEntityDescription(
|
||||||
|
key=SENSOR_TYPE_BATTERY,
|
||||||
|
device_class=SensorDeviceClass.BATTERY,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=PERCENTAGE,
|
||||||
|
)
|
||||||
|
|
||||||
|
POWER_DESCRIPTION = SensorEntityDescription(
|
||||||
|
key=SENSOR_TYPE_POWER,
|
||||||
|
device_class=SensorDeviceClass.POWER,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=UnitOfPower.WATT,
|
||||||
|
)
|
||||||
|
|
||||||
|
VOLATGE_DESCRIPTION = SensorEntityDescription(
|
||||||
|
key=SENSOR_TYPE_VOLTAGE,
|
||||||
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=UnitOfElectricPotential.VOLT,
|
||||||
|
)
|
||||||
|
|
||||||
|
CURRENT_DESCRIPTION = SensorEntityDescription(
|
||||||
|
key=SENSOR_TYPE_CURRENT,
|
||||||
|
device_class=SensorDeviceClass.CURRENT,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=UnitOfElectricCurrent.MILLIAMPERE,
|
||||||
|
)
|
||||||
|
|
||||||
|
CO2_DESCRIPTION = SensorEntityDescription(
|
||||||
|
key=SENSOR_TYPE_CO2,
|
||||||
|
device_class=SensorDeviceClass.CO2,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
||||||
|
)
|
||||||
|
|
||||||
|
SENSOR_DESCRIPTIONS_BY_DEVICE_TYPES = {
|
||||||
|
"Meter": (
|
||||||
|
TEMPERATURE_DESCRIPTION,
|
||||||
|
HUMIDITY_DESCRIPTION,
|
||||||
|
BATTERY_DESCRIPTION,
|
||||||
|
),
|
||||||
|
"MeterPlus": (
|
||||||
|
TEMPERATURE_DESCRIPTION,
|
||||||
|
HUMIDITY_DESCRIPTION,
|
||||||
|
BATTERY_DESCRIPTION,
|
||||||
|
),
|
||||||
|
"WoIOSensor": (
|
||||||
|
TEMPERATURE_DESCRIPTION,
|
||||||
|
HUMIDITY_DESCRIPTION,
|
||||||
|
BATTERY_DESCRIPTION,
|
||||||
|
),
|
||||||
|
"Relay Switch 1PM": (
|
||||||
|
POWER_DESCRIPTION,
|
||||||
|
VOLATGE_DESCRIPTION,
|
||||||
|
CURRENT_DESCRIPTION,
|
||||||
|
),
|
||||||
|
"Hub 2": (
|
||||||
|
TEMPERATURE_DESCRIPTION,
|
||||||
|
HUMIDITY_DESCRIPTION,
|
||||||
|
),
|
||||||
|
"MeterPro": (
|
||||||
|
TEMPERATURE_DESCRIPTION,
|
||||||
|
HUMIDITY_DESCRIPTION,
|
||||||
|
BATTERY_DESCRIPTION,
|
||||||
|
),
|
||||||
|
"MeterPro(CO2)": (
|
||||||
|
TEMPERATURE_DESCRIPTION,
|
||||||
|
HUMIDITY_DESCRIPTION,
|
||||||
|
BATTERY_DESCRIPTION,
|
||||||
|
CO2_DESCRIPTION,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@ -70,11 +132,7 @@ async def async_setup_entry(
|
|||||||
async_add_entities(
|
async_add_entities(
|
||||||
SwitchBotCloudSensor(data.api, device, coordinator, description)
|
SwitchBotCloudSensor(data.api, device, coordinator, description)
|
||||||
for device, coordinator in data.devices.sensors
|
for device, coordinator in data.devices.sensors
|
||||||
for description in (
|
for description in SENSOR_DESCRIPTIONS_BY_DEVICE_TYPES[device.device_type]
|
||||||
METER_PRO_CO2_SENSOR_DESCRIPTIONS
|
|
||||||
if device.device_type == "MeterPro(CO2)"
|
|
||||||
else METER_PLUS_SENSOR_DESCRIPTIONS
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,6 +69,18 @@ class SwitchBotCloudPlugSwitch(SwitchBotCloudSwitch):
|
|||||||
_attr_device_class = SwitchDeviceClass.OUTLET
|
_attr_device_class = SwitchDeviceClass.OUTLET
|
||||||
|
|
||||||
|
|
||||||
|
class SwitchBotCloudRelaySwitchSwitch(SwitchBotCloudSwitch):
|
||||||
|
"""Representation of a SwitchBot relay switch."""
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _handle_coordinator_update(self) -> None:
|
||||||
|
"""Handle updated data from the coordinator."""
|
||||||
|
if not self.coordinator.data:
|
||||||
|
return
|
||||||
|
self._attr_is_on = self.coordinator.data.get("switchStatus") == 1
|
||||||
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def _async_make_entity(
|
def _async_make_entity(
|
||||||
api: SwitchBotAPI, device: Device | Remote, coordinator: SwitchBotCoordinator
|
api: SwitchBotAPI, device: Device | Remote, coordinator: SwitchBotCoordinator
|
||||||
@ -78,4 +90,9 @@ def _async_make_entity(
|
|||||||
return SwitchBotCloudRemoteSwitch(api, device, coordinator)
|
return SwitchBotCloudRemoteSwitch(api, device, coordinator)
|
||||||
if "Plug" in device.device_type:
|
if "Plug" in device.device_type:
|
||||||
return SwitchBotCloudPlugSwitch(api, device, coordinator)
|
return SwitchBotCloudPlugSwitch(api, device, coordinator)
|
||||||
|
if device.device_type in [
|
||||||
|
"Relay Switch 1PM",
|
||||||
|
"Relay Switch 1",
|
||||||
|
]:
|
||||||
|
return SwitchBotCloudRelaySwitchSwitch(api, device, coordinator)
|
||||||
raise NotImplementedError(f"Unsupported device type: {device.device_type}")
|
raise NotImplementedError(f"Unsupported device type: {device.device_type}")
|
||||||
|
56
tests/components/switchbot_cloud/test_switch.py
Normal file
56
tests/components/switchbot_cloud/test_switch.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
"""Test for the switchbot_cloud relay switch."""
|
||||||
|
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from switchbot_api import Device
|
||||||
|
|
||||||
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||||
|
from homeassistant.components.switchbot_cloud import SwitchBotAPI
|
||||||
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_ENTITY_ID,
|
||||||
|
SERVICE_TURN_OFF,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from . import configure_integration
|
||||||
|
|
||||||
|
|
||||||
|
async def test_relay_switch(
|
||||||
|
hass: HomeAssistant, mock_list_devices, mock_get_status
|
||||||
|
) -> None:
|
||||||
|
"""Test turn on and turn off."""
|
||||||
|
mock_list_devices.return_value = [
|
||||||
|
Device(
|
||||||
|
deviceId="relay-switch-id-1",
|
||||||
|
deviceName="relay-switch-1",
|
||||||
|
deviceType="Relay Switch 1",
|
||||||
|
hubDeviceId="test-hub-id",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
mock_get_status.return_value = {"switchStatus": 0}
|
||||||
|
|
||||||
|
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.relay_switch_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
|
Loading…
x
Reference in New Issue
Block a user