Skip to content

Commit

Permalink
Update constants add socket test script (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbouwh authored Dec 29, 2023
1 parent a94d646 commit bf6a738
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 20 deletions.
2 changes: 1 addition & 1 deletion elro/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Elro connects P1 API."""

__version__ = "0.5.4.1"
__version__ = "0.5.5"
4 changes: 2 additions & 2 deletions elro/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ class Command(Enum):
SWITCH_TIMER = -34
DELETE_EQUIPMENT_DETAIL = -4
EQUIPMENT_CONTROL = 1
INCREACE_EQUIPMENT = 2
INCREASE_EQUIPMENT = 2
REPLACE_EQUIPMENT = 3
DELETE_EQUIPMENT = 4
MODIFY_EQUIPMENT_NAME = 5
CHOOSE_SCENE_GROUP = 6
CANCEL_INCREACE_EQUIPMENT = 7
CANCEL_INCREASE_EQUIPMENT = 7
INCREACE_SCENE = 8
MODIFY_SCENE = 9
DELETE_SCENE = 10
Expand Down
34 changes: 18 additions & 16 deletions elro/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,29 +55,14 @@ def __repr__(self):
ALARM_HEAT = "HEAT_ALARM"
ALARM_SMOKE = "SMOKE_ALARM"
ALARM_WATER = "WATER_ALARM"
DOOR_WINDOW_SENSOR = "DOOR_WINDOW_SENSOR"

# Represent device state attributes
ATTR_BATTERY_LEVEL = "battery"
ATTR_DEVICE_TYPE = "device_type"
ATTR_DEVICE_STATE = "device_state"
ATTR_SIGNAL = "signal"

# Represent the state of a device.
DEVICE_STATE = {
"12": "FAULT",
"15": "SILENCE",
"17": "TEST ALARM",
"19": "FIRE ALARM",
"22": "FIRE ALARM",
"66": "NORMAL",
"1B": "SILENCE",
"BB": "TEST ALARM",
"55": "ALARM", # OPEN window sensor
"AA": "NORMAL", # CLOSED window sensor
"FE": "UNKNOWN",
"FF": "OFFLINE",
}

STATE_ALARM = "ALARM"
STATE_FAULT = "FAULT"
STATE_FIRE_ALARM = "FIRE ALARM"
Expand All @@ -89,3 +74,20 @@ def __repr__(self):

STATES_ON = (STATE_ALARM, STATE_FIRE_ALARM, STATE_TEST_ALARM)
STATES_OFFLINE = (STATE_OFFLINE,)

# Represent the state of a device.
DEVICE_STATE = {
"01": STATE_NORMAL,
"12": STATE_FAULT,
"15": STATE_SILENCE,
"17": STATE_TEST_ALARM,
"19": STATE_FIRE_ALARM,
"22": STATE_FIRE_ALARM,
"66": STATE_NORMAL,
"1B": STATE_SILENCE,
"BB": STATE_TEST_ALARM,
"55": STATE_ALARM, # OPEN window sensor
"AA": STATE_NORMAL, # CLOSED window sensor
"FE": STATE_UNKNOWN,
"FF": STATE_OFFLINE,
}
3 changes: 2 additions & 1 deletion elro/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ def set_device_name(argv: dict) -> None:
raise ValueError("Value for device_name is not set!")


def get_device_states(content: list) -> dict:
def get_device_states(content: list) -> dict[str, Any]:
"""Return device states."""
return_dict = {}
for hexdata in content:
Expand All @@ -289,6 +289,7 @@ def get_device_states(content: list) -> dict:
device_state, device_state
), # return hex device state if it is not known
"device_status_data": hexdata,
"device_value_data": int(hexdata["device_status"][6:8], 16),
}
return return_dict

Expand Down
74 changes: 74 additions & 0 deletions examples/socket_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""Socket demo test code."""

import asyncio
import sys
from datetime import datetime

from elro.api import K1
from elro.command import (
GET_ALL_EQUIPMENT_STATUS,
GET_DEVICE_NAMES,
Command,
CommandAttributes,
)
from elro.utils import get_device_states, update_state_data


class SocketDemo(K1):
"""Class to test Elro connects sockets."""

async def async_show_status(self) -> None:
"""Main routine to demonstrate the API code."""
# You can call await self.async_connect() but if there is no actice session
# await self.async_connect() will be called for you

await self.async_connect()
try:
data = await self.async_process_command(GET_ALL_EQUIPMENT_STATUS)
names = await self.async_process_command(GET_DEVICE_NAMES)
update_state_data(data, names)
device_states = get_device_states(
[device_data["device_status_data"] for _, device_data in data.items()]
)
print(f"=={datetime.now()}")
for key, item in data.items():
print(
f"{key} ({item.get('name')}): status={item['device_state']} data={item['device_status_data']}"
)
print(f"> {device_states[key]}")
except Exception as err: # pylint: disable=broad-except
print(f"Exception caught {err.args}")
await self.async_disconnect()

async def async_test_socket(self, device_id: int, command_code_hex: str) -> None:
"""Test socket command."""
# TEST_ALARM for fire alarms
command = CommandAttributes(
cmd_id=Command.EQUIPMENT_CONTROL,
attribute_transformer=None,
additional_attributes={
"device_ID": 0,
"device_status": f"{command_code_hex}000000",
},
receive_types=[Command.ANSWER_YES_OR_NO],
content_field="answer_yes_or_no",
content_sync_finished=2,
content_transformer=None,
)
await self.async_connect()
print(f"Send command {command_code_hex} to device with ID: {device_id}")
await self.async_process_command(command, device_ID=device_id)
await self.async_disconnect()
await asyncio.sleep(4)
await self.async_show_status()


if __name__ == "__main__":
# argv: 1 = IP_ADDRESS, 2 = API_KEY, 3 = device_id
ARG_DEVICE_ID = int(sys.argv.get[3]) if len(sys.argv) > 3 else None
ARG_COMMAND_HEX = sys.argv[4] if len(sys.argv) > 4 else None
k1_hub = SocketDemo(sys.argv[1], sys.argv[2])
if ARG_COMMAND_HEX is not None:
asyncio.run(k1_hub.async_test_socket(ARG_DEVICE_ID, ARG_COMMAND_HEX))
else:
asyncio.run(k1_hub.async_show_status())
9 changes: 9 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@
b'{"msgId" : 3651,"action" : "devSend","params" : {"devTid" : "ST_1234567890ab","appTid" : [],"data" : {"cmdId" : 17,"answer_content" : "NAME_OVER" }}}\n',
]

MOCK_SOCKET_STATUS_ON_RESPONSE = [
b'{"msgId" : 3652,"action" : "devSend","params" : {"devTid" : "ST_1234567890ab","appTid" : [],"data" : {"cmdId" : 19,"device_ID" : 1,"device_name" : "1200","device_status" : "04FF0101" }}}\n',
b'{"msgId" : 3653,"action" : "devSend","params" : {"devTid" : "ST_1234567890ab","appTid" : [],"data" : {"cmdId" : 19,"device_ID" : 65535,"device_name" : "STATUES","device_status" : "OVER" }}}\n',
]
MOCK_SOCKET_STATUS_OFF_RESPONSE = [
b'{"msgId" : 3654,"action" : "devSend","params" : {"devTid" : "ST_1234567890ab","appTid" : [],"data" : {"cmdId" : 19,"device_ID" : 1,"device_name" : "1200","device_status" : "04FF0100" }}}\n',
b'{"msgId" : 3655,"action" : "devSend","params" : {"devTid" : "ST_1234567890ab","appTid" : [],"data" : {"cmdId" : 19,"device_ID" : 65535,"device_name" : "STATUES","device_status" : "OVER" }}}\n',
]

MOCK_SET_EQUIPMENT_RESPONSE = [
b'{"msgId" : 8,"action" : "devSend","params" : {"devTid" : "ST_1234567890ab","appTid" : [],"data" : {"cmdId" : 11,"answer_yes_or_no" : 2 }}}\n'
]
Expand Down

0 comments on commit bf6a738

Please sign in to comment.