Skip to content

Instantly share code, notes, and snippets.

@enyone
Created December 12, 2023 19:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enyone/e1e0182f41ab9924d33fd24d77765aa6 to your computer and use it in GitHub Desktop.
Save enyone/e1e0182f41ab9924d33fd24d77765aa6 to your computer and use it in GitHub Desktop.
"""$ cat config/quirks/lidltuyaeffects.py"""
"""Quirk for LIDL Melinera (Tuya) LED String Lights."""
import logging
from typing import Any, Union, Optional
import zigpy.types as t
from zigpy.profiles import zha
from zigpy.quirks import CustomCluster, CustomDevice
from zigpy.zcl import foundation
from zigpy.zcl.clusters.general import (
Basic,
GreenPowerProxy,
Groups,
Identify,
LevelControl,
OnOff,
Ota,
Scenes,
Time,
)
from zigpy.zcl.clusters.lighting import Color
from zigpy.zcl.clusters.lightlink import LightLink
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
INPUT_CLUSTERS,
MODELS_INFO,
OUTPUT_CLUSTERS,
PROFILE_ID,
)
from zhaquirks.tuya import (
TUYA_SET_DATA,
TUYA_CLUSTER_ID,
TuyaManufCluster,
)
from zhaquirks.tuya.mcu import (
TUYA_MCU_COMMAND
)
TUYA_EFFECT_COMMAND = 0x0603
_LOGGER = logging.getLogger(__name__)
class LidlRGBColorCluster(CustomCluster, Color):
"""LIDL Melinera (Tuya) LED String Lights custom cluster."""
# Set correct capabilities to xy, ct
# LIDL Melinera (Tuya) LED String Lights does not correctly report this attribute (reported as hs only)
_CONSTANT_ATTRIBUTES = {0x400A: 0b01000}
class LidlEffectCluster(TuyaManufCluster):
"""Tuya MCU Effect cluster."""
name: str = "Tuya Effect"
cluster_id: t.uint16_t = TUYA_CLUSTER_ID
ep_attribute: str = "tuya_manufacturer"
server_commands = TuyaManufCluster.server_commands.copy()
server_commands.update(
{
0xFC: foundation.ZCLCommandDef(
"effect",
{"effect_id": t.uint8_t},
False,
is_manufacturer_specific=True,
),
}
)
async def command(
self,
command_id: Union[foundation.GeneralCommand, int, t.uint8_t],
*args,
manufacturer: Optional[Union[int, t.uint16_t]] = None,
expect_reply: bool = True,
tsn: Optional[Union[int, t.uint8_t]] = None,
**kwargs: Any,
):
"""Override the default Cluster command."""
_LOGGER.debug(
"Sending Tuya Cluster Command.. Cluster Command is %x, Arguments are %s, %s",
command_id,
args,
kwargs,
)
if command_id == 0x00FC:
tuya_payload = TuyaManufCluster.Command()
tuya_payload.status = 0
tuya_payload.tsn = tsn if tsn else self.endpoint.device.application.get_sequence()
#tuya_payload.tsn = 0
tuya_payload.command_id = TUYA_SET_DATA
tuya_payload.function = TUYA_EFFECT_COMMAND
tuya_payload.data = [0x00, 0x0A, 0x30, 0x31, 0x30, 0x30, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40]
_LOGGER.debug(
"%s Sending Tuya Command. Paylod values [endpoint_id : %s, "
"Status : %s, TSN: %s, Command: 0x%04x, Function: %s, Data: %s]",
self.endpoint.device.ieee,
self.endpoint.endpoint_id,
tuya_payload.status,
tuya_payload.tsn,
tuya_payload.command_id,
tuya_payload.function,
tuya_payload.data,
)
await self.endpoint.tuya_manufacturer.command(
TUYA_SET_DATA, tuya_payload, expect_reply=False
)
return foundation.GENERAL_COMMANDS[
foundation.GeneralCommand.Default_Response
].schema(command_id=command_id, status=foundation.Status.SUCCESS)
return foundation.GENERAL_COMMANDS[
foundation.GeneralCommand.Default_Response
].schema(command_id=command_id, status=foundation.Status.UNSUP_CLUSTER_COMMAND)
class RGBCCTLightStrip(CustomDevice):
"""LIDL Melinera (Tuya) LED String Lights device."""
signature = {
MODELS_INFO: [("_TZE200_s8gkrkxk", "TS0601")],
ENDPOINTS: {
1: {
# <SimpleDescriptor endpoint=1 profile=260 device_type=258
# device_version=1
# input_clusters=[0, 3, 4, 5, 6, 8, 768, 61184]
# output_clusters=[10, 25]
PROFILE_ID: 260,
DEVICE_TYPE: 258,
INPUT_CLUSTERS: [
Basic.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
LevelControl.cluster_id,
Color.cluster_id,
TuyaManufCluster.cluster_id,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
242: {
# <SimpleDescriptor endpoint=242 profile=41440 device_type=258
# device_version=0
# input_clusters=[]
# output_clusters=[33]
PROFILE_ID: 41440,
DEVICE_TYPE: 258,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
},
}
replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: 260,
DEVICE_TYPE: 258,
INPUT_CLUSTERS: [
Basic.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
OnOff.cluster_id,
LevelControl.cluster_id,
LidlRGBColorCluster,
LidlEffectCluster,
],
OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
},
242: {
PROFILE_ID: 41440,
DEVICE_TYPE: 258,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
},
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment