Skip to content

Commit df03ecb

Browse files
authored
Add initial power socket support (#27)
1 parent 68d41df commit df03ecb

File tree

6 files changed

+70
-5
lines changed

6 files changed

+70
-5
lines changed

elro/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Elro connects P1 API."""
22

3-
__version__ = "0.5.5.3"
3+
__version__ = "0.6.0"

elro/command.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,26 @@ class CommandAttributes(TypedDict):
155155
content_transformer=None,
156156
)
157157

158+
SOCKET_OFF = CommandAttributes(
159+
cmd_id=Command.EQUIPMENT_CONTROL,
160+
attribute_transformer=None,
161+
additional_attributes={"device_ID": 0, "device_status": "01000000"},
162+
receive_types=[Command.ANSWER_YES_OR_NO],
163+
content_field="answer_yes_or_no",
164+
content_sync_finished=2,
165+
content_transformer=None,
166+
)
167+
168+
SOCKET_ON = CommandAttributes(
169+
cmd_id=Command.EQUIPMENT_CONTROL,
170+
attribute_transformer=None,
171+
additional_attributes={"device_ID": 0, "device_status": "01010000"},
172+
receive_types=[Command.ANSWER_YES_OR_NO],
173+
content_field="answer_yes_or_no",
174+
content_sync_finished=2,
175+
content_transformer=None,
176+
)
177+
158178
# GET_SCENES returns a dict[{scene_id}, None]
159179
# NOTE: If queried frequently not all data is provisioned all the time
160180
GET_SCENES = CommandAttributes(

elro/device.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ def __repr__(self):
6161
ATTR_BATTERY_LEVEL = "battery"
6262
ATTR_DEVICE_TYPE = "device_type"
6363
ATTR_DEVICE_STATE = "device_state"
64+
ATTR_DEVICE_VALUE = "device_value"
6465
ATTR_SIGNAL = "signal"
6566

6667
STATE_ALARM = "ALARM"
@@ -75,6 +76,9 @@ def __repr__(self):
7576
STATES_ON = (STATE_ALARM, STATE_FIRE_ALARM, STATE_TEST_ALARM)
7677
STATES_OFFLINE = (STATE_OFFLINE,)
7778

79+
DEVICE_VALUE_OFF = "off"
80+
DEVICE_VALUE_ON = "on"
81+
7882
# Represent the state of a device.
7983
DEVICE_STATE = {
8084
"01": STATE_NORMAL,
@@ -91,3 +95,8 @@ def __repr__(self):
9195
"FE": STATE_UNKNOWN,
9296
"FF": STATE_OFFLINE,
9397
}
98+
99+
DEVICE_VALUE = {
100+
0: DEVICE_VALUE_OFF,
101+
1: DEVICE_VALUE_ON,
102+
}

elro/utils.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import collections
88
from typing import Any
99

10-
from elro.device import DeviceType, DEVICE_STATE
10+
from elro.device import DEVICE_VALUE, DeviceType, DEVICE_STATE
1111

1212

1313
# From the ByteUtil class, needed by CRC_maker
@@ -281,15 +281,19 @@ def get_device_states(content: list) -> dict[str, Any]:
281281
# Unsupported record, skip and continue silently
282282
continue
283283
device_state = hexdata["device_status"][4:6]
284+
device_value_data = int(hexdata["device_status"][6:8], 16)
284285
return_dict[hexdata["device_ID"]] = {
285286
"device_type": device_type,
286287
"signal": int(hexdata["device_status"][0:2], 16),
287288
"battery": int(hexdata["device_status"][2:4], 16),
288289
"device_state": DEVICE_STATE.get(
289290
device_state, device_state
290291
), # return hex device state if it is not known
292+
"device_value": DEVICE_VALUE.get(
293+
device_value_data, hex(device_value_data)
294+
), # return hex device value if it is not known
291295
"device_status_data": hexdata,
292-
"device_value_data": int(hexdata["device_status"][6:8], 16),
296+
"device_value_data": device_value_data,
293297
}
294298
return return_dict
295299

examples/socket_demo.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,12 @@ async def async_test_socket(self, device_id: int, command_code_hex: str) -> None
6464

6565

6666
if __name__ == "__main__":
67-
# argv: 1 = IP_ADDRESS, 2 = API_KEY, 3 = device_id, 4 = command_hex
67+
# argv: 1=IP_ADDRESS, 2=API_KEY, 3=device_id, 4=command_hex (0100=off, 0101=on)
6868
if len(sys.argv) == 1:
6969
print(
7070
f"Elro Connects socket test util.\n"
7171
f"Query only:\n{sys.argv[0]} ip-adress api-key\n\n"
72-
f"Execute a command:\n{sys.argv[0]} "
72+
f"Execute a command (0100=off, 0101=on):\n{sys.argv[0]} "
7373
"ip-adress api-key device_id command_hex"
7474
)
7575
sys.exit(0)

tests/test_api.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,38 @@ async def test_sync_device_status(mock_k1_connector):
202202
assert result[3]["device_state"] == "UNKNOWN"
203203

204204

205+
@pytest.mark.asyncio
206+
async def test_sync_socket_status(mock_k1_connector):
207+
"""Test get device status."""
208+
await mock_k1_connector.async_connect()
209+
210+
help_mock_command_reply(mock_k1_connector, MOCK_SOCKET_STATUS_OFF_RESPONSE)
211+
212+
result = await mock_k1_connector.async_process_command(
213+
SYN_DEVICE_STATUS, sence_group=0
214+
)
215+
216+
assert result[1]["device_type"] == "SOCKET"
217+
assert result[1]["signal"] == 4
218+
assert result[1]["battery"] == 255
219+
assert result[1]["device_state"] == "NORMAL"
220+
assert result[1]["device_value_data"] == 0
221+
assert result[1]["device_value"] == "off"
222+
223+
help_mock_command_reply(mock_k1_connector, MOCK_SOCKET_STATUS_ON_RESPONSE)
224+
225+
result = await mock_k1_connector.async_process_command(
226+
SYN_DEVICE_STATUS, sence_group=0
227+
)
228+
229+
assert result[1]["device_type"] == "SOCKET"
230+
assert result[1]["signal"] == 4
231+
assert result[1]["battery"] == 255
232+
assert result[1]["device_state"] == "NORMAL"
233+
assert result[1]["device_value_data"] == 1
234+
assert result[1]["device_value"] == "on"
235+
236+
205237
@pytest.mark.asyncio
206238
async def test_api_access_properties(mock_k1_connector):
207239
"""Test api access properties."""

0 commit comments

Comments
 (0)