1
0
mirror of https://github.com/home-assistant/core.git synced 2026-05-08 17:49:37 +01:00

Add sensor description for Lock state in Switchbot Cloud (#168607)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
Samuel Xiao
2026-04-24 05:34:47 +08:00
committed by GitHub
parent e1a73fbeed
commit 5a9bb972d0
6 changed files with 97 additions and 8 deletions
@@ -61,3 +61,25 @@ class Humidifier2Mode(Enum):
def get_modes(cls) -> list[str]:
"""Return a list of available humidifier2 modes as lowercase strings."""
return [mode.name.lower() for mode in cls]
class SwitchbotCloudDeviceLockState(Enum):
"""Lock State."""
LOCKED = "locked"
UNLOCKED = "unlocked"
LOCKING = "locking"
UNLOCKING = "unlocking"
JAMMED = "jammed"
LATCH_BOLT_LOCKED = "latchBoltLocked"
HALF_LOCKED = "halfLocked"
@classmethod
def get_states(cls) -> list[SwitchbotCloudDeviceLockState]:
"""Get lock states."""
return list(cls)
@classmethod
def get_values(cls) -> list[str]:
"""Get lock value."""
return [mode.value for mode in cls]
@@ -26,7 +26,7 @@ from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import SwitchbotCloudConfigEntry
from .const import DOMAIN
from .const import DOMAIN, SwitchbotCloudDeviceLockState
from .coordinator import SwitchBotCoordinator
from .entity import SwitchBotCloudEntity
@@ -47,6 +47,8 @@ RELAY_SWITCH_2PM_SENSOR_TYPE_VOLTAGE = "Voltage"
RELAY_SWITCH_2PM_SENSOR_TYPE_CURRENT = "ElectricCurrent"
RELAY_SWITCH_2PM_SENSOR_TYPE_ELECTRICITY = "UsedElectricity"
LOCK_SENSOR_TYPE_LOCK_STATE = "lockState"
@dataclass(frozen=True, kw_only=True)
class SwitchbotCloudSensorEntityDescription(SensorEntityDescription):
@@ -165,6 +167,21 @@ LIGHTLEVEL_DESCRIPTION = SwitchbotCloudSensorEntityDescription(
state_class=SensorStateClass.MEASUREMENT,
)
LOCK_SENSOR_TYPE_LOCK_STATE_DESCRIPTION = SwitchbotCloudSensorEntityDescription(
key=LOCK_SENSOR_TYPE_LOCK_STATE,
device_class=SensorDeviceClass.ENUM,
translation_key="lock_state",
options=[
value.name.lower() for value in SwitchbotCloudDeviceLockState.get_states()
],
value_fn=lambda value: (
SwitchbotCloudDeviceLockState(value).name.lower()
if value in SwitchbotCloudDeviceLockState.get_values()
else None
),
)
SENSOR_DESCRIPTIONS_BY_DEVICE_TYPES = {
"Bot": (BATTERY_DESCRIPTION,),
"Battery Circulator Fan": (BATTERY_DESCRIPTION,),
@@ -224,7 +241,10 @@ SENSOR_DESCRIPTIONS_BY_DEVICE_TYPES = {
"Smart Lock": (BATTERY_DESCRIPTION,),
"Smart Lock Lite": (BATTERY_DESCRIPTION,),
"Smart Lock Pro": (BATTERY_DESCRIPTION,),
"Smart Lock Ultra": (BATTERY_DESCRIPTION,),
"Smart Lock Ultra": (
BATTERY_DESCRIPTION,
LOCK_SENSOR_TYPE_LOCK_STATE_DESCRIPTION,
),
"Smart Lock Vision": (BATTERY_DESCRIPTION,),
"Smart Lock Vision Pro": (BATTERY_DESCRIPTION,),
"Lock Vision": (BATTERY_DESCRIPTION,),
@@ -314,7 +334,6 @@ class SwitchBotCloudSensor(SwitchBotCloudEntity, SensorEntity):
if not self.coordinator.data:
return
value = self.coordinator.data.get(self.entity_description.key)
self._attr_native_value = self.entity_description.value_fn(value)
@@ -76,6 +76,18 @@
"sensor": {
"light_level": {
"name": "Light level"
},
"lock_state": {
"name": "Lock state",
"state": {
"half_locked": "Half locked",
"jammed": "Jammed",
"latch_bolt_locked": "Latch bolt locked",
"locked": "[%key:common::state::locked%]",
"locking": "Locking",
"unlocked": "[%key:common::state::unlocked%]",
"unlocking": "Unlocking"
}
}
}
}
@@ -113,3 +113,11 @@ HUMIDIFIER2_INFO = Device(
deviceType="Humidifier2",
hubDeviceId="test-hub-id",
)
LOCK_ULTRA_INFO = Device(
version="V1.0",
deviceId="lock-id-1",
deviceName="Lock Ultra",
deviceType="Smart Lock Ultra",
hubDeviceId="test-hub-id",
)
+31 -5
View File
@@ -2,6 +2,7 @@
from unittest.mock import patch
import pytest
from switchbot_api import Device
from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN, LockState
@@ -18,14 +19,28 @@ from homeassistant.core import HomeAssistant
from . import configure_integration
async def test_lock(hass: HomeAssistant, mock_list_devices, mock_get_status) -> None:
@pytest.mark.parametrize(
("device_info", "test_index"),
[
("Smart Lock", 0),
("Smart Lock Lite", 1),
("Smart Lock Pro", 2),
("Smart Lock Ultra", 3),
("Lock Vision", 4),
("Lock Vision Pro", 5),
("Smart Lock Pro Wifi", 6),
],
)
async def test_lock(
hass: HomeAssistant, mock_list_devices, mock_get_status, device_info, test_index
) -> None:
"""Test locking and unlocking."""
mock_list_devices.return_value = [
Device(
version="V1.0",
deviceId="lock-id-1",
deviceName="lock-1",
deviceType="Smart Lock",
deviceType=device_info,
hubDeviceId="test-hub-id",
),
]
@@ -52,16 +67,27 @@ async def test_lock(hass: HomeAssistant, mock_list_devices, mock_get_status) ->
assert hass.states.get(lock_id).state == LockState.LOCKED
@pytest.mark.parametrize(
("device_info", "test_index"),
[
("Smart Lock", 0),
("Smart Lock Pro", 1),
("Smart Lock Ultra", 2),
("Lock Vision", 3),
("Lock Vision Pro", 4),
("Smart Lock Pro Wifi", 5),
],
)
async def test_lock_open(
hass: HomeAssistant, mock_list_devices, mock_get_status
hass: HomeAssistant, mock_list_devices, mock_get_status, device_info, test_index
) -> None:
"""Test lock open."""
"""Test locking and unlocking."""
mock_list_devices.return_value = [
Device(
version="V1.0",
deviceId="lock-id-1",
deviceName="lock-1",
deviceType="Smart Lock Pro",
deviceType=device_info,
hubDeviceId="test-hub-id",
),
]
@@ -14,6 +14,7 @@ from homeassistant.helpers import entity_registry as er
from . import (
CONTACT_SENSOR_INFO,
HUB3_INFO,
LOCK_ULTRA_INFO,
METER_INFO,
MOTION_SENSOR_INFO,
WATER_DETECTOR_INFO,
@@ -32,6 +33,7 @@ from tests.common import snapshot_platform
(HUB3_INFO, 3),
(MOTION_SENSOR_INFO, 4),
(WATER_DETECTOR_INFO, 5),
(LOCK_ULTRA_INFO, 5),
],
)
async def test_meter(