I had the same problem as most of you, but managed to make it working.
Why don’t you see the needed configuration…well you most likely have a newer model named RDM004. Apparently this is not supported yet.
Here are my steps to make it work.
- Open you favourite file editor. I use Studio Code Server;
- Make a new folder. In my case the folder is named “custom_zha_quirks”;
- Make a new file named MYFILE.PY
- Paste the following content into it:
"""Signify RDM004 device."""
import logging
from typing import Any, List, Optional, Union
from zigpy.profiles import zha
from zigpy.quirks import CustomCluster, CustomDevice
import zigpy.types as t
from zigpy.zcl import foundation
from zigpy.zcl.clusters.general import (
Basic,
Groups,
Identify,
LevelControl,
OnOff,
Ota,
PowerConfiguration,
)
from zhaquirks.const import (
ARGS,
BUTTON,
COMMAND,
COMMAND_ID,
DEVICE_TYPE,
DOUBLE_PRESS,
ENDPOINTS,
INPUT_CLUSTERS,
LONG_PRESS,
LONG_RELEASE,
MODELS_INFO,
OUTPUT_CLUSTERS,
PRESS_TYPE,
PROFILE_ID,
QUADRUPLE_PRESS,
QUINTUPLE_PRESS,
RIGHT,
SHORT_PRESS,
SHORT_RELEASE,
TRIPLE_PRESS,
TURN_ON,
ZHA_SEND_EVENT,
)
from zhaquirks.philips import PHILIPS, SIGNIFY
DEVICE_SPECIFIC_UNKNOWN = 64512
_LOGGER = logging.getLogger(__name__)
class PhilipsBasicCluster(CustomCluster, Basic):
"""Philips Basic cluster."""
attributes = Basic.attributes.copy()
attributes.update(
{
0x0031: ("philips", t.bitmap16, True),
0x0034: ("mode", t.enum8, True),
}
)
attr_config = {0x0031: 0x000B, 0x0034: 0x02}
async def bind(self):
"""Bind cluster."""
result = await super().bind()
await self.write_attributes(self.attr_config, manufacturer=0x100B)
return result
class PhilipsRemoteCluster(CustomCluster):
"""Philips remote cluster."""
cluster_id = 64512
name = "PhilipsRemoteCluster"
ep_attribute = "philips_remote_cluster"
client_commands = {
0x00: foundation.ZCLCommandDef(
"notification",
{
"param1": t.uint8_t,
"param2": t.uint24_t,
"param3": t.uint8_t,
"param4": t.uint8_t,
"param5": t.uint8_t,
"param6": t.uint8_t,
},
is_manufacturer_specific=True,
direction=foundation.Direction.Server_to_Client,
)
}
BUTTONS = {
1: "left",
2: "right",
}
PRESS_TYPES = {0: "press", 1: "hold", 2: "press_release", 3: "hold_release"}
def handle_cluster_request(
self,
hdr: foundation.ZCLHeader,
args: List[Any],
*,
dst_addressing: Optional[
Union[t.Addressing.Group, t.Addressing.IEEE, t.Addressing.NWK]
] = None,
):
"""Handle the cluster command."""
_LOGGER.debug(
"PhilipsRemoteCluster - handle_cluster_request tsn: [%s] command id: %s - args: [%s]",
hdr.tsn,
hdr.command_id,
args,
)
button = self.BUTTONS.get(args[0], args[0])
press_type = self.PRESS_TYPES.get(args[2], args[2])
event_args = {
BUTTON: button,
PRESS_TYPE: press_type,
COMMAND_ID: hdr.command_id,
ARGS: args,
}
action = f"{button}_{press_type}"
self.listener_event(ZHA_SEND_EVENT, action, event_args)
class PhilipsROM004(CustomDevice):
"""Philips ROM004 device."""
signature = {
# <SimpleDescriptor endpoint=1 profile=260 device_type=2080
# device_version=1
# input_clusters=[0, 1, 3, 64512]
# output_clusters=[3, 4, 6, 8, 25]>
MODELS_INFO: [(PHILIPS, "RDM004"), (SIGNIFY, "RDM004")],
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.NON_COLOR_SCENE_CONTROLLER,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
DEVICE_SPECIFIC_UNKNOWN,
],
OUTPUT_CLUSTERS: [
Basic.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
OnOff.cluster_id,
LevelControl.cluster_id,
Ota.cluster_id,
],
}
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER,
INPUT_CLUSTERS: [
PhilipsBasicCluster,
PowerConfiguration.cluster_id,
Identify.cluster_id,
PhilipsRemoteCluster,
],
OUTPUT_CLUSTERS: [
Ota.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
OnOff.cluster_id,
LevelControl.cluster_id,
],
}
}
}
device_automation_triggers = {
(SHORT_PRESS, TURN_ON): {COMMAND: "left_press"},
(LONG_PRESS, TURN_ON): {COMMAND: "left_hold"},
(DOUBLE_PRESS, TURN_ON): {COMMAND: "left_double_press"},
(TRIPLE_PRESS, TURN_ON): {COMMAND: "left_triple_press"},
(QUADRUPLE_PRESS, TURN_ON): {COMMAND: "left_quadruple_press"},
(QUINTUPLE_PRESS, TURN_ON): {COMMAND: "left_quintuple_press"},
(SHORT_RELEASE, TURN_ON): {COMMAND: "left_short_release"},
(LONG_RELEASE, TURN_ON): {COMMAND: "left_long_release"},
(SHORT_PRESS, RIGHT): {COMMAND: "right_press"},
(LONG_PRESS, RIGHT): {COMMAND: "right_hold"},
(DOUBLE_PRESS, RIGHT): {COMMAND: "right_double_press"},
(TRIPLE_PRESS, RIGHT): {COMMAND: "right_triple_press"},
(QUADRUPLE_PRESS, RIGHT): {COMMAND: "right_quadruple_press"},
(QUINTUPLE_PRESS, RIGHT): {COMMAND: "right_quintuple_press"},
(SHORT_RELEASE, RIGHT): {COMMAND: "right_short_release"},
(LONG_RELEASE, RIGHT): {COMMAND: "right_long_release"},
}
- Open configuration. yaml
- add the following lines:
zha:
enable_quirks: true
custom_quirks_path: /config/custom_zha_quirks
- remove the HUE module from you devices;
- Restart home assistant;
- Go back to devices. Right now alle names mentioned in this topic should be visible.
- follow the steps in this blog post: Make the Philips Hue wall switch module work with push button switches in Home Assistant — Rudd-O.com
- please note:
- Select in Cluster: PhilipsBasicCluster << should be available now
- Attributes: MODE (ID: 0x0034) << should be avaible now
- Value: enter 2. This value enables a double rocker switch
- NOW WAIT
- if i’m correct one of the two switches is working, or at lease it should be. You can see it in the log of the device. Figure out which one is working.
- Now before you click “write attribute” you first click the button that is working. This wakes up the device. If you don’t do this, HA/Zigbee can’t communicate with the device.
- Within half a second after you clicked the button of the device to wake it up, you press write.
All done, you have two rocker type buttons working perfectly.