Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change lock state to an enum #126379

Merged
merged 7 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions homeassistant/components/alexa/capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
CodeFormat,
)
from homeassistant.components.climate import HVACMode
from homeassistant.components.lock import LockState
from homeassistant.const import (
ATTR_CODE_FORMAT,
ATTR_SUPPORTED_FEATURES,
Expand All @@ -40,16 +41,12 @@
STATE_ALARM_ARMED_HOME,
STATE_ALARM_ARMED_NIGHT,
STATE_IDLE,
STATE_LOCKED,
STATE_LOCKING,
STATE_OFF,
STATE_ON,
STATE_PAUSED,
STATE_PLAYING,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
STATE_UNLOCKED,
STATE_UNLOCKING,
UnitOfLength,
UnitOfMass,
UnitOfTemperature,
Expand Down Expand Up @@ -500,10 +497,10 @@ def get_property(self, name: str) -> Any:
raise UnsupportedProperty(name)

# If its unlocking its still locked and not unlocked yet
if self.entity.state in (STATE_UNLOCKING, STATE_LOCKED):
if self.entity.state in (LockState.UNLOCKING, LockState.LOCKED):
return "LOCKED"
# If its locking its still unlocked and not locked yet
if self.entity.state in (STATE_LOCKING, STATE_UNLOCKED):
if self.entity.state in (LockState.LOCKING, LockState.UNLOCKED):
return "UNLOCKED"
return "JAMMED"

Expand Down
45 changes: 18 additions & 27 deletions homeassistant/components/demo/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,8 @@
import asyncio
from typing import Any

from homeassistant.components.lock import LockEntity, LockEntityFeature
from homeassistant.components.lock import LockEntity, LockEntityFeature, LockState
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
STATE_JAMMED,
STATE_LOCKED,
STATE_LOCKING,
STATE_OPEN,
STATE_OPENING,
STATE_UNLOCKED,
STATE_UNLOCKING,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

Expand All @@ -30,10 +21,10 @@ async def async_setup_entry(
"""Set up the Demo config entry."""
async_add_entities(
[
DemoLock("Front Door", STATE_LOCKED),
DemoLock("Kitchen Door", STATE_UNLOCKED),
DemoLock("Poorly Installed Door", STATE_UNLOCKED, False, True),
DemoLock("Openable Lock", STATE_LOCKED, True),
DemoLock("Front Door", LockState.LOCKED),
DemoLock("Kitchen Door", LockState.UNLOCKED),
DemoLock("Poorly Installed Door", LockState.UNLOCKED, False, True),
DemoLock("Openable Lock", LockState.LOCKED, True),
]
)

Expand Down Expand Up @@ -61,56 +52,56 @@ def __init__(
@property
def is_locking(self) -> bool:
"""Return true if lock is locking."""
return self._state == STATE_LOCKING
return self._state == LockState.LOCKING

@property
def is_unlocking(self) -> bool:
"""Return true if lock is unlocking."""
return self._state == STATE_UNLOCKING
return self._state == LockState.UNLOCKING

@property
def is_jammed(self) -> bool:
"""Return true if lock is jammed."""
return self._state == STATE_JAMMED
return self._state == LockState.JAMMED

@property
def is_locked(self) -> bool:
"""Return true if lock is locked."""
return self._state == STATE_LOCKED
return self._state == LockState.LOCKED

@property
def is_open(self) -> bool:
"""Return true if lock is open."""
return self._state == STATE_OPEN
return self._state == LockState.OPEN

@property
def is_opening(self) -> bool:
"""Return true if lock is opening."""
return self._state == STATE_OPENING
return self._state == LockState.OPENING

async def async_lock(self, **kwargs: Any) -> None:
"""Lock the device."""
self._state = STATE_LOCKING
self._state = LockState.LOCKING
self.async_write_ha_state()
await asyncio.sleep(LOCK_UNLOCK_DELAY)
if self._jam_on_operation:
self._state = STATE_JAMMED
self._state = LockState.JAMMED
else:
self._state = STATE_LOCKED
self._state = LockState.LOCKED
self.async_write_ha_state()

async def async_unlock(self, **kwargs: Any) -> None:
"""Unlock the device."""
self._state = STATE_UNLOCKING
self._state = LockState.UNLOCKING
self.async_write_ha_state()
await asyncio.sleep(LOCK_UNLOCK_DELAY)
self._state = STATE_UNLOCKED
self._state = LockState.UNLOCKED
self.async_write_ha_state()

async def async_open(self, **kwargs: Any) -> None:
"""Open the door latch."""
self._state = STATE_OPENING
self._state = LockState.OPENING
self.async_write_ha_state()
await asyncio.sleep(LOCK_UNLOCK_DELAY)
self._state = STATE_OPEN
self._state = LockState.OPEN
self.async_write_ha_state()
7 changes: 3 additions & 4 deletions homeassistant/components/google_assistant/trait.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
from homeassistant.components.fan import FanEntityFeature
from homeassistant.components.humidifier import HumidifierEntityFeature
from homeassistant.components.light import LightEntityFeature
from homeassistant.components.lock import STATE_JAMMED, STATE_UNLOCKING
from homeassistant.components.lock import LockState
from homeassistant.components.media_player import MediaPlayerEntityFeature, MediaType
from homeassistant.components.vacuum import VacuumEntityFeature
from homeassistant.components.valve import ValveEntityFeature
Expand Down Expand Up @@ -71,7 +71,6 @@
STATE_ALARM_PENDING,
STATE_ALARM_TRIGGERED,
STATE_IDLE,
STATE_LOCKED,
STATE_OFF,
STATE_ON,
STATE_PAUSED,
Expand Down Expand Up @@ -1524,11 +1523,11 @@ def sync_attributes(self) -> dict[str, Any]:

def query_attributes(self) -> dict[str, Any]:
"""Return LockUnlock query attributes."""
if self.state.state == STATE_JAMMED:
if self.state.state == LockState.JAMMED:
return {"isJammed": True}

# If its unlocking its not yet unlocked so we consider is locked
return {"isLocked": self.state.state in (STATE_UNLOCKING, STATE_LOCKED)}
return {"isLocked": self.state.state in (LockState.UNLOCKING, LockState.LOCKED)}

async def execute(self, command, data, params, challenge):
"""Execute an LockUnlock command."""
Expand Down
19 changes: 7 additions & 12 deletions homeassistant/components/group/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
PLATFORM_SCHEMA as LOCK_PLATFORM_SCHEMA,
LockEntity,
LockEntityFeature,
LockState,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
Expand All @@ -22,14 +23,8 @@
SERVICE_LOCK,
SERVICE_OPEN,
SERVICE_UNLOCK,
STATE_JAMMED,
STATE_LOCKED,
STATE_LOCKING,
STATE_OPEN,
STATE_OPENING,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
STATE_UNLOCKING,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import config_validation as cv, entity_registry as er
Expand Down Expand Up @@ -183,11 +178,11 @@ def async_update_group_state(self) -> None:
self._attr_is_locked = None
else:
# Set attributes based on member states and let the lock entity sort out the correct state
self._attr_is_jammed = STATE_JAMMED in states
self._attr_is_locking = STATE_LOCKING in states
self._attr_is_opening = STATE_OPENING in states
self._attr_is_open = STATE_OPEN in states
self._attr_is_unlocking = STATE_UNLOCKING in states
self._attr_is_locked = all(state == STATE_LOCKED for state in states)
self._attr_is_jammed = LockState.JAMMED in states
self._attr_is_locking = LockState.LOCKING in states
self._attr_is_opening = LockState.OPENING in states
self._attr_is_open = LockState.OPEN in states
self._attr_is_unlocking = LockState.UNLOCKING in states
self._attr_is_locked = all(state == LockState.LOCKED for state in states)

self._attr_available = any(state != STATE_UNAVAILABLE for state in states)
20 changes: 8 additions & 12 deletions homeassistant/components/group/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from typing import Protocol

from homeassistant.components.climate import HVACMode
from homeassistant.components.lock import LockState
from homeassistant.components.vacuum import STATE_CLEANING, STATE_ERROR, STATE_RETURNING
from homeassistant.components.water_heater import (
STATE_ECO,
Expand All @@ -28,19 +29,14 @@
STATE_CLOSED,
STATE_HOME,
STATE_IDLE,
STATE_LOCKED,
STATE_LOCKING,
STATE_NOT_HOME,
STATE_OFF,
STATE_OK,
STATE_ON,
STATE_OPEN,
STATE_OPENING,
STATE_PAUSED,
STATE_PLAYING,
STATE_PROBLEM,
STATE_UNLOCKED,
STATE_UNLOCKING,
Platform,
)
from homeassistant.core import HomeAssistant, callback
Expand Down Expand Up @@ -90,14 +86,14 @@
Platform.DEVICE_TRACKER: ({STATE_HOME}, STATE_HOME, STATE_NOT_HOME),
Platform.LOCK: (
{
STATE_LOCKING,
STATE_OPEN,
STATE_OPENING,
STATE_UNLOCKED,
STATE_UNLOCKING,
LockState.LOCKING,
LockState.OPEN,
LockState.OPENING,
LockState.UNLOCKED,
LockState.UNLOCKING,
},
STATE_UNLOCKED,
STATE_LOCKED,
LockState.UNLOCKED,
LockState.LOCKED,
),
Platform.MEDIA_PLAYER: (
{
Expand Down
50 changes: 24 additions & 26 deletions homeassistant/components/homekit/type_locks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,7 @@

from pyhap.const import CATEGORY_DOOR_LOCK

from homeassistant.components.lock import (
DOMAIN as LOCK_DOMAIN,
STATE_JAMMED,
STATE_LOCKED,
STATE_LOCKING,
STATE_UNLOCKED,
STATE_UNLOCKING,
)
from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN, LockState
from homeassistant.const import ATTR_CODE, ATTR_ENTITY_ID, STATE_UNKNOWN
from homeassistant.core import State, callback

Expand All @@ -22,35 +15,40 @@
_LOGGER = logging.getLogger(__name__)

HASS_TO_HOMEKIT_CURRENT = {
STATE_UNLOCKED: 0,
STATE_UNLOCKING: 1,
STATE_LOCKING: 0,
STATE_LOCKED: 1,
STATE_JAMMED: 2,
LockState.UNLOCKED.value: 0,
LockState.UNLOCKING.value: 1,
LockState.LOCKING.value: 0,
LockState.LOCKED.value: 1,
LockState.JAMMED.value: 2,
STATE_UNKNOWN: 3,
}

HASS_TO_HOMEKIT_TARGET = {
STATE_UNLOCKED: 0,
STATE_UNLOCKING: 0,
STATE_LOCKING: 1,
STATE_LOCKED: 1,
LockState.UNLOCKED.value: 0,
LockState.UNLOCKING.value: 0,
LockState.LOCKING.value: 1,
LockState.LOCKED.value: 1,
}

VALID_TARGET_STATES = {STATE_LOCKING, STATE_UNLOCKING, STATE_LOCKED, STATE_UNLOCKED}
VALID_TARGET_STATES = {
LockState.LOCKING.value,
LockState.UNLOCKING.value,
LockState.LOCKED.value,
LockState.UNLOCKED.value,
}

HOMEKIT_TO_HASS = {
0: STATE_UNLOCKED,
1: STATE_LOCKED,
2: STATE_JAMMED,
0: LockState.UNLOCKED.value,
1: LockState.LOCKED.value,
2: LockState.JAMMED.value,
3: STATE_UNKNOWN,
}

STATE_TO_SERVICE = {
STATE_LOCKING: "unlock",
STATE_LOCKED: "lock",
STATE_UNLOCKING: "lock",
STATE_UNLOCKED: "unlock",
LockState.LOCKING.value: "unlock",
LockState.LOCKED.value: "lock",
LockState.UNLOCKING.value: "lock",
LockState.UNLOCKED.value: "unlock",
}


Expand All @@ -74,7 +72,7 @@ def __init__(self, *args: Any) -> None:
)
self.char_target_state = serv_lock_mechanism.configure_char(
CHAR_LOCK_TARGET_STATE,
value=HASS_TO_HOMEKIT_CURRENT[STATE_LOCKED],
value=HASS_TO_HOMEKIT_CURRENT[LockState.LOCKED.value],
setter_callback=self.set_state,
)
self.async_update_state(state)
Expand Down
Loading