-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ImplementDesDoorOpenerActuator (#98)
Co-authored-by: Adam Kingsley <[email protected]>
- Loading branch information
1 parent
4ab66eb
commit a332aa9
Showing
3 changed files
with
167 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
"""Free@Home DesDoorOpenerActuator Class.""" | ||
|
||
from typing import Any | ||
|
||
from ..api import FreeAtHomeApi | ||
from ..bin.pairing import Pairing | ||
from .base import Base | ||
|
||
|
||
class DesDoorOpenerActuator(Base): | ||
"""Free@Home DesDoorOpenerActuator Class.""" | ||
|
||
_state_refresh_output_pairings: list[Pairing] = [ | ||
Pairing.AL_INFO_ON_OFF, | ||
] | ||
|
||
def __init__( | ||
self, | ||
device_id: str, | ||
device_name: str, | ||
channel_id: str, | ||
channel_name: str, | ||
inputs: dict[str, dict[str, Any]], | ||
outputs: dict[str, dict[str, Any]], | ||
parameters: dict[str, dict[str, Any]], | ||
api: FreeAtHomeApi, | ||
floor_name: str | None = None, | ||
room_name: str | None = None, | ||
) -> None: | ||
"""Initialize the Free@Home DesDoorOpenerActuator class.""" | ||
self._state: bool | None = None | ||
|
||
super().__init__( | ||
device_id, | ||
device_name, | ||
channel_id, | ||
channel_name, | ||
inputs, | ||
outputs, | ||
parameters, | ||
api, | ||
floor_name, | ||
room_name, | ||
) | ||
|
||
@property | ||
def state(self) -> bool | None: | ||
"""Get the state of the DesDoorOpenerActuator.""" | ||
return self._state | ||
|
||
async def lock(self): | ||
"""Lock the door.""" | ||
await self._set_switching_datapoint("0") | ||
self._state = False | ||
|
||
async def unlock(self): | ||
"""Unlock the door.""" | ||
await self._set_switching_datapoint("1") | ||
self._state = True | ||
|
||
def _refresh_state_from_output(self, output: dict[str, Any]) -> bool: | ||
""" | ||
Refresh the state of the device from a given output. | ||
This will return whether the state was refreshed as a boolean value. | ||
""" | ||
if output.get("pairingID") == Pairing.AL_INFO_ON_OFF.value: | ||
self._state = output.get("value") == "1" | ||
return True | ||
return False | ||
|
||
async def _set_switching_datapoint(self, value: str): | ||
"""Set the switching datapoint on the api.""" | ||
_switch_input_id, _switch_input_value = self.get_input_by_pairing( | ||
pairing=Pairing.AL_TIMED_START_STOP | ||
) | ||
return await self._api.set_datapoint( | ||
device_id=self.device_id, | ||
channel_id=self.channel_id, | ||
datapoint=_switch_input_id, | ||
value=value, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
"""Test class to test the DesDoorOpenerActuator device.""" | ||
|
||
from unittest.mock import AsyncMock | ||
|
||
import pytest | ||
|
||
from src.abbfreeathome.api import FreeAtHomeApi | ||
from src.abbfreeathome.devices.des_door_opener_actuator import DesDoorOpenerActuator | ||
|
||
|
||
@pytest.fixture | ||
def mock_api(): | ||
"""Create a mock api function.""" | ||
return AsyncMock(spec=FreeAtHomeApi) | ||
|
||
|
||
@pytest.fixture | ||
def des_door_opener_actuator(mock_api): | ||
"""Set up the instance for testing the DesDoorOpenerActuator device.""" | ||
inputs = { | ||
"idp0000": {"pairingID": 2, "value": "0"}, | ||
} | ||
outputs = { | ||
"odp0000": {"pairingID": 256, "value": "0"}, | ||
"odp0001": {"pairingID": 0, "value": "0"}, | ||
} | ||
parameters = {} | ||
|
||
return DesDoorOpenerActuator( | ||
device_id="0007EE9503A4", | ||
device_name="Device Name", | ||
channel_id="ch0040", | ||
channel_name="Channel Name", | ||
inputs=inputs, | ||
outputs=outputs, | ||
parameters=parameters, | ||
api=mock_api, | ||
) | ||
|
||
|
||
@pytest.mark.asyncio | ||
async def test_initial_state(des_door_opener_actuator): | ||
"""Test the intial state of the DesDoorOpenerActuator.""" | ||
assert des_door_opener_actuator.state is False | ||
|
||
|
||
@pytest.mark.asyncio | ||
async def test_lock(des_door_opener_actuator): | ||
"""Test to lock.""" | ||
await des_door_opener_actuator.lock() | ||
assert des_door_opener_actuator.state is False | ||
des_door_opener_actuator._api.set_datapoint.assert_called_with( | ||
device_id="0007EE9503A4", | ||
channel_id="ch0040", | ||
datapoint="idp0000", | ||
value="0", | ||
) | ||
|
||
|
||
@pytest.mark.asyncio | ||
async def test_unlock(des_door_opener_actuator): | ||
"""Test to unlock.""" | ||
await des_door_opener_actuator.unlock() | ||
assert des_door_opener_actuator.state is True | ||
des_door_opener_actuator._api.set_datapoint.assert_called_with( | ||
device_id="0007EE9503A4", | ||
channel_id="ch0040", | ||
datapoint="idp0000", | ||
value="1", | ||
) | ||
|
||
|
||
@pytest.mark.asyncio | ||
async def test_refresh_state(des_door_opener_actuator): | ||
"""Test refreshing the state of the DesDoorOpenerActuator.""" | ||
des_door_opener_actuator._api.get_datapoint.return_value = ["1"] | ||
await des_door_opener_actuator.refresh_state() | ||
assert des_door_opener_actuator.state is True | ||
des_door_opener_actuator._api.get_datapoint.assert_called_with( | ||
device_id="0007EE9503A4", | ||
channel_id="ch0040", | ||
datapoint="odp0000", | ||
) |