Skip to content

Commit

Permalink
Fix for locks
Browse files Browse the repository at this point in the history
 * Update to aiohubspace that fixes an issue around locks being managed

Sem-Ver: bugfix
  • Loading branch information
Expl0dingBanana committed Jan 15, 2025
1 parent 7118346 commit 284fe09
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 14 deletions.
9 changes: 4 additions & 5 deletions custom_components/hubspace/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,13 @@ def __init__(
self.bridge = bridge
self.controller = controller
self.resource = resource
self.device = controller.get_device(resource.id)
self.logger = bridge.logger.getChild(resource.type.value)

# Entity class attributes
unique_id = f"{resource.id}.{instance}" if instance else resource.id
self._attr_unique_id = unique_id or resource.id
self._attr_has_entity_name = (
True if self.device.device_information.name else False
True if self.resource.device_information.name else False
)

if instance is not False:
Expand All @@ -66,7 +65,7 @@ async def async_added_to_hass(self) -> None:
self.async_on_remove(
self.controller.subscribe(
self._handle_event,
self.device.id,
self.resource.id,
EventType.RESOURCE_UPDATED,
)
)
Expand All @@ -75,9 +74,9 @@ async def async_added_to_hass(self) -> None:
def available(self) -> bool:
"""Return entity availability."""
# entities without a device attached should be always available
if self.device is None:
if self.resource is None:
return True
return self.device.available
return self.resource.available

@callback
def on_update(self) -> None:
Expand Down
4 changes: 2 additions & 2 deletions custom_components/hubspace/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ async def async_unlock(self, **kwargs) -> None:
await self.bridge.async_request_call(
self.controller.set_state,
device_id=self.resource.id,
lock_position=features.CurrentPositionEnum.LOCKING,
lock_position=features.CurrentPositionEnum.UNLOCKING,
)

@update_decorator
Expand All @@ -65,7 +65,7 @@ async def async_lock(self, **kwargs) -> None:
await self.bridge.async_request_call(
self.controller.set_state,
device_id=self.resource.id,
lock_position=features.CurrentPositionEnum.UNLOCKING,
lock_position=features.CurrentPositionEnum.LOCKING,
)


Expand Down
2 changes: 1 addition & 1 deletion custom_components/hubspace/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/jdeath/Hubspace-Homeassistant/issues",
"loggers": ["aiohubspace"],
"requirements": ["aiohubspace==0.6.2", "aiofiles==24.1.0"],
"requirements": ["aiohubspace==0.6.4", "aiofiles==24.1.0"],
"version": "4.1.0"
}
66 changes: 60 additions & 6 deletions tests/test_lock.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import pytest
from aiohubspace.v1.controllers.lock import features
from aiohubspace.v1.device import HubspaceState
from homeassistant.helpers import entity_registry as er

from .utils import create_devices_from_data
from .utils import create_devices_from_data, modify_state

lock_tbd = create_devices_from_data("door-lock-TBD.json")
lock_tbd_instance = lock_tbd[0]
lock_id = "lock.friendly_device_0_lock"


@pytest.fixture
async def transformer_entity(mocked_entry):
async def lock_entity(mocked_entry):
hass, entry, bridge = mocked_entry
await bridge.locks.initialize_elem(lock_tbd_instance)
await bridge.devices.initialize_elem(lock_tbd_instance)
Expand Down Expand Up @@ -48,8 +50,8 @@ async def test_async_setup_entry(dev, expected_entities, mocked_entry):


@pytest.mark.asyncio
async def test_unlock(transformer_entity):
hass, entry, bridge = transformer_entity
async def test_unlock(lock_entity):
hass, entry, bridge = lock_entity
await hass.services.async_call(
"lock",
"unlock",
Expand All @@ -60,11 +62,37 @@ async def test_unlock(transformer_entity):
assert update_call.args[0] == "put"
payload = update_call.kwargs["json"]
assert payload["metadeviceId"] == lock_tbd_instance.id
update = payload["values"][0]
assert update["functionClass"] == "lock-control"
assert update["functionInstance"] is None
assert update["value"] == "unlocking"
# Now generate update event by emitting the json we've sent as incoming event
lock_update = create_devices_from_data("door-lock-TBD.json")[0]
modify_state(
lock_update,
HubspaceState(
functionClass="lock-control",
functionInstance=None,
value="unlocking",
),
)
event = {
"type": "update",
"device_id": lock_update.id,
"device": lock_update,
}
bridge.emit_event("update", event)
await hass.async_block_till_done()
assert (
bridge.locks._items[lock_update.id].position.position
== features.CurrentPositionEnum.UNLOCKING
)
assert hass.states.get(lock_id).state == "opening"


@pytest.mark.asyncio
async def test_lock(transformer_entity):
hass, entry, bridge = transformer_entity
async def test_lock(lock_entity):
hass, entry, bridge = lock_entity
await hass.services.async_call(
"lock",
"lock",
Expand All @@ -75,3 +103,29 @@ async def test_lock(transformer_entity):
assert update_call.args[0] == "put"
payload = update_call.kwargs["json"]
assert payload["metadeviceId"] == lock_tbd_instance.id
update = payload["values"][0]
assert update["functionClass"] == "lock-control"
assert update["functionInstance"] is None
assert update["value"] == "locking"
# Now generate update event by emitting the json we've sent as incoming event
lock_update = create_devices_from_data("door-lock-TBD.json")[0]
modify_state(
lock_update,
HubspaceState(
functionClass="lock-control",
functionInstance=None,
value="locking",
),
)
event = {
"type": "update",
"device_id": lock_update.id,
"device": lock_update,
}
bridge.emit_event("update", event)
await hass.async_block_till_done()
assert (
bridge.locks._items[lock_update.id].position.position
== features.CurrentPositionEnum.LOCKING
)
assert hass.states.get(lock_id).state == "locking"

0 comments on commit 284fe09

Please sign in to comment.