Skip to content

Commit

Permalink
Made HA events backward compatible. Also send more information as arg…
Browse files Browse the repository at this point in the history
…uments of the `zha_event`: Added "description" containing the ButtonAction name.

Got rid of deprecation warnings in test_sinope.py
  • Loading branch information
bassdr committed Oct 22, 2024
1 parent 493c1b4 commit 3cab468
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 43 deletions.
40 changes: 33 additions & 7 deletions tests/test_sinope.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ def _get_packet_data(
@pytest.mark.parametrize(
"press_type,button,exp_event",
(
(ButtonAction.Single_off, TURN_OFF, COMMAND_M_INITIAL_PRESS),
(ButtonAction.Single_on, TURN_ON, COMMAND_M_INITIAL_PRESS),
(ButtonAction.Single_release_off, TURN_OFF, COMMAND_M_SHORT_RELEASE),
(ButtonAction.Single_release_on, TURN_ON, COMMAND_M_SHORT_RELEASE),
(ButtonAction.Pressed_off, TURN_OFF, COMMAND_M_INITIAL_PRESS),
(ButtonAction.Pressed_on, TURN_ON, COMMAND_M_INITIAL_PRESS),
(ButtonAction.Released_off, TURN_OFF, COMMAND_M_SHORT_RELEASE),
(ButtonAction.Released_on, TURN_ON, COMMAND_M_SHORT_RELEASE),
(ButtonAction.Double_on, TURN_ON, COMMAND_M_MULTI_PRESS_COMPLETE),
(ButtonAction.Double_off, TURN_OFF, COMMAND_M_MULTI_PRESS_COMPLETE),
(ButtonAction.Long_on, TURN_ON, COMMAND_M_LONG_RELEASE),
Expand Down Expand Up @@ -135,7 +135,16 @@ class Listener:
),
)
data = _get_packet_data(foundation.GeneralCommand.Report_Attributes, attr)
device.handle_message(260, cluster_id, endpoint_id, endpoint_id, data)

device.packet_received(
t.ZigbeePacket(
profile_id=260,
cluster_id=cluster_id,
src_ep=endpoint_id,
dst_ep=endpoint_id,
data=t.SerializableBytes(data),
)
)

if exp_event is None:
assert cluster_listener.zha_send_event.call_count == 0
Expand All @@ -147,6 +156,7 @@ class Listener:
"attribute_id": 84,
"attribute_name": "action_report",
"button": button,
"description": press_type.name,
"value": press_type.value,
},
)
Expand All @@ -172,7 +182,15 @@ class Listener:

# read attributes general command
data = _get_packet_data(foundation.GeneralCommand.Read_Attributes)
device.handle_message(260, cluster_id, endpoint_id, endpoint_id, data)
device.packet_received(
t.ZigbeePacket(
profile_id=260,
cluster_id=cluster_id,
src_ep=endpoint_id,
dst_ep=endpoint_id,
data=t.SerializableBytes(data),
)
)
# no ZHA events emitted because we only handle Report_Attributes
assert cluster_listener.zha_send_event.call_count == 0

Expand All @@ -184,7 +202,15 @@ class Listener:
), # 0x29 = t.int16s
)
data = _get_packet_data(foundation.GeneralCommand.Report_Attributes, attr)
device.handle_message(260, cluster_id, endpoint_id, endpoint_id, data)
device.packet_received(
t.ZigbeePacket(
profile_id=260,
cluster_id=cluster_id,
src_ep=endpoint_id,
dst_ep=endpoint_id,
data=t.SerializableBytes(data),
)
)
# ZHA event emitted because we pass non "action_report"
# reports to the base class handler.
assert cluster_listener.zha_send_event.call_count == 1
Expand Down
37 changes: 26 additions & 11 deletions zhaquirks/sinope/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Module for Sinope quirks implementations."""

from zigpy.quirks import CustomCluster
import zigpy.types as t
from zigpy.zcl.clusters.general import DeviceTemperature

from zhaquirks.const import (
Expand All @@ -16,7 +17,7 @@
COMMAND_M_SHORT_RELEASE,
DOUBLE_PRESS,
ENDPOINT_ID,
LONG_RELEASE,
LONG_PRESS,
SHORT_PRESS,
SHORT_RELEASE,
TURN_OFF,
Expand All @@ -28,6 +29,20 @@
SINOPE_MANUFACTURER_CLUSTER_ID = 0xFF01
ATTRIBUTE_ACTION = "action_report"


class ButtonAction(t.enum8):
"""Action_report values."""

Pressed_on = 0x01
Released_on = 0x02
Long_on = 0x03
Double_on = 0x04
Pressed_off = 0x11
Released_off = 0x12
Long_off = 0x13
Double_off = 0x14


LIGHT_DEVICE_TRIGGERS = {
(SHORT_PRESS, TURN_ON): {
ENDPOINT_ID: 1,
Expand All @@ -37,7 +52,7 @@
ATTRIBUTE_ID: 84,
ATTRIBUTE_NAME: ATTRIBUTE_ACTION,
BUTTON: TURN_ON,
VALUE: 1,
VALUE: ButtonAction.Pressed_on,
},
},
(SHORT_PRESS, TURN_OFF): {
Expand All @@ -48,7 +63,7 @@
ATTRIBUTE_ID: 84,
ATTRIBUTE_NAME: ATTRIBUTE_ACTION,
BUTTON: TURN_OFF,
VALUE: 17,
VALUE: ButtonAction.Pressed_off,
},
},
(SHORT_RELEASE, TURN_ON): {
Expand All @@ -59,7 +74,7 @@
ATTRIBUTE_ID: 84,
ATTRIBUTE_NAME: ATTRIBUTE_ACTION,
BUTTON: TURN_ON,
VALUE: 2,
VALUE: ButtonAction.Released_on,
},
},
(SHORT_RELEASE, TURN_OFF): {
Expand All @@ -70,7 +85,7 @@
ATTRIBUTE_ID: 84,
ATTRIBUTE_NAME: ATTRIBUTE_ACTION,
BUTTON: TURN_OFF,
VALUE: 18,
VALUE: ButtonAction.Released_off,
},
},
(DOUBLE_PRESS, TURN_ON): {
Expand All @@ -81,7 +96,7 @@
ATTRIBUTE_ID: 84,
ATTRIBUTE_NAME: ATTRIBUTE_ACTION,
BUTTON: TURN_ON,
VALUE: 4,
VALUE: ButtonAction.Double_on,
},
},
(DOUBLE_PRESS, TURN_OFF): {
Expand All @@ -92,29 +107,29 @@
ATTRIBUTE_ID: 84,
ATTRIBUTE_NAME: ATTRIBUTE_ACTION,
BUTTON: TURN_OFF,
VALUE: 20,
VALUE: ButtonAction.Double_off,
},
},
(LONG_RELEASE, TURN_ON): {
(LONG_PRESS, TURN_ON): {
ENDPOINT_ID: 1,
CLUSTER_ID: 65281,
COMMAND: COMMAND_M_LONG_RELEASE,
ARGS: {
ATTRIBUTE_ID: 84,
ATTRIBUTE_NAME: ATTRIBUTE_ACTION,
BUTTON: TURN_ON,
VALUE: 3,
VALUE: ButtonAction.Long_on,
},
},
(LONG_RELEASE, TURN_OFF): {
(LONG_PRESS, TURN_OFF): {
ENDPOINT_ID: 1,
CLUSTER_ID: 65281,
COMMAND: COMMAND_M_LONG_RELEASE,
ARGS: {
ATTRIBUTE_ID: 84,
ATTRIBUTE_NAME: ATTRIBUTE_ACTION,
BUTTON: TURN_OFF,
VALUE: 19,
VALUE: ButtonAction.Long_off,
},
},
}
Expand Down
41 changes: 16 additions & 25 deletions zhaquirks/sinope/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@
ATTRIBUTE_ID,
ATTRIBUTE_NAME,
BUTTON,
COMMAND,
COMMAND_M_INITIAL_PRESS,
COMMAND_M_LONG_RELEASE,
COMMAND_M_MULTI_PRESS_COMPLETE,
COMMAND_M_SHORT_RELEASE,
DESCRIPTION,
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
Expand All @@ -51,6 +53,7 @@
LIGHT_DEVICE_TRIGGERS,
SINOPE,
SINOPE_MANUFACTURER_CLUSTER_ID,
ButtonAction,
CustomDeviceTemperatureCluster,
)

Expand Down Expand Up @@ -79,19 +82,6 @@ class DoubleFull(t.enum8):
On = 0x01


class ButtonAction(t.enum8):
"""Action_report values."""

Single_on = 0x01
Single_release_on = 0x02
Long_on = 0x03
Double_on = 0x04
Single_off = 0x11
Single_release_off = 0x12
Long_off = 0x13
Double_off = 0x14


class SinopeTechnologiesManufacturerCluster(CustomCluster):
"""SinopeTechnologiesManufacturerCluster manufacturer cluster."""

Expand Down Expand Up @@ -163,7 +153,7 @@ class AttributeDefs(foundation.BaseAttributeDefs):
server_commands = {
0x54: foundation.ZCLCommandDef(
"button_press",
{"command": t.uint8_t},
{COMMAND: t.uint8_t},
direction=foundation.Direction.Server_to_Client,
is_manufacturer_specific=True,
)
Expand Down Expand Up @@ -197,40 +187,41 @@ def handle_cluster_general_request(
hdr, args, dst_addressing=dst_addressing
)

value = attr.value.value
action = self.Action(attr.value.value)

action, button = self._get_command_from_action(self.Action(value))
if not action or not button:
command, button = self._get_command_from_action(action)
if not command or not button:
return

event_args = {
ATTRIBUTE_ID: 84,
ATTRIBUTE_NAME: ATTRIBUTE_ACTION,
BUTTON: button,
VALUE: value.value,
DESCRIPTION: action.name,
VALUE: action.value,
}

self.debug(
"SINOPE ZHA_SEND_EVENT action: '%s' event_args: %s",
self.Action(value),
"SINOPE ZHA_SEND_EVENT command: '%s' event_args: %s",
command,
event_args,
)

self.listener_event(ZHA_SEND_EVENT, action, event_args)
self.listener_event(ZHA_SEND_EVENT, command, event_args)

def _get_command_from_action(
self, action: ButtonAction
) -> tuple[str | None, str | None]:
# const lookup = {1: 'up_single', 2: 'up_single_released', 3: 'up_hold', 4: 'up_double',
# 17: 'down_single, 18: 'down_single_released', 19: 'down_hold', 20: 'down_double'};
match action:
case self.Action.Single_off:
case self.Action.Pressed_off:
return COMMAND_M_INITIAL_PRESS, TURN_OFF
case self.Action.Single_on:
case self.Action.Pressed_on:
return COMMAND_M_INITIAL_PRESS, TURN_ON
case self.Action.Single_release_off:
case self.Action.Released_off:
return COMMAND_M_SHORT_RELEASE, TURN_OFF
case self.Action.Single_release_on:
case self.Action.Released_on:
return COMMAND_M_SHORT_RELEASE, TURN_ON
case self.Action.Double_off:
return COMMAND_M_MULTI_PRESS_COMPLETE, TURN_OFF
Expand Down

0 comments on commit 3cab468

Please sign in to comment.