Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions tests/test_xiaomi.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@
AqaraFeederAcn001,
OppleCluster,
)
from zhaquirks.xiaomi.aqara.led_strip_t1 import (
AqaraLedStripT1,
LedStripT1Audio,
LedStripT1AudioEffect,
LedStripT1AudioSensitivity,
LedStripT1PowerOnStateMode,
LedStripT1Preset,
)
from zhaquirks.xiaomi.aqara.light_acn import AqaraLightT1M, LumiPowerOnStateMode
import zhaquirks.xiaomi.aqara.magnet_ac01
import zhaquirks.xiaomi.aqara.magnet_acn001
Expand Down Expand Up @@ -2282,3 +2290,116 @@ async def test_lumi_magnet_sensor_aq2_bad_direction(zigpy_device_from_quirk, cap

# Our matching logic should be forgiving
assert listener.attribute_updates == [(0, t.Bool.true)]


def test_t1_led_strip(zigpy_device_from_v2_quirk):
"""Test Aqara T1 led strip adds missing endpoints."""

# create the device
device = zigpy_device_from_v2_quirk(AQARA, "lumi.light.acn132")
assert AqaraLedStripT1.cluster_id in device.endpoints[1].in_clusters

aqara_cluster = device.endpoints[1].opple_cluster
cluster_listener = ClusterListener(aqara_cluster)

# Checking min_brightness attribute update
aqara_cluster.update_attribute(AqaraLedStripT1.AttributeDefs.min_brightness.id, 12)
assert len(cluster_listener.attribute_updates) == 1
assert (
cluster_listener.attribute_updates[0][0]
== AqaraLedStripT1.AttributeDefs.min_brightness.id
)

assert cluster_listener.attribute_updates[0][1] == 12

# Checking max_brightness attribute update
aqara_cluster.update_attribute(AqaraLedStripT1.AttributeDefs.max_brightness.id, 88)
assert len(cluster_listener.attribute_updates) == 2
assert (
cluster_listener.attribute_updates[1][0]
== AqaraLedStripT1.AttributeDefs.max_brightness.id
)

assert cluster_listener.attribute_updates[1][1] == 88

# Checking power on state attribute update
aqara_cluster.update_attribute(
AqaraLedStripT1.AttributeDefs.power_on_state.id,
LedStripT1PowerOnStateMode.Toggle,
)
assert len(cluster_listener.attribute_updates) == 3
assert (
cluster_listener.attribute_updates[2][0]
== AqaraLedStripT1.AttributeDefs.power_on_state.id
)

assert cluster_listener.attribute_updates[2][1] == LedStripT1PowerOnStateMode.Toggle

# Checking length attribute update
aqara_cluster.update_attribute(AqaraLedStripT1.AttributeDefs.length.id, 3.2)
assert len(cluster_listener.attribute_updates) == 4
assert (
cluster_listener.attribute_updates[3][0]
== AqaraLedStripT1.AttributeDefs.length.id
)

assert cluster_listener.attribute_updates[3][1] == 3.2

# Checking audio attribute update
aqara_cluster.update_attribute(
AqaraLedStripT1.AttributeDefs.audio.id, LedStripT1Audio.On
)
assert len(cluster_listener.attribute_updates) == 5
assert (
cluster_listener.attribute_updates[4][0]
== AqaraLedStripT1.AttributeDefs.audio.id
)

assert cluster_listener.attribute_updates[4][1] == LedStripT1Audio.On

# Checking audio_sensitivity attribute update
aqara_cluster.update_attribute(
AqaraLedStripT1.AttributeDefs.audio_sensitivity.id,
LedStripT1AudioSensitivity.Medium,
)
assert len(cluster_listener.attribute_updates) == 6
assert (
cluster_listener.attribute_updates[5][0]
== AqaraLedStripT1.AttributeDefs.audio_sensitivity.id
)

assert cluster_listener.attribute_updates[5][1] == LedStripT1AudioSensitivity.Medium

# Checking audio_effect attribute update
aqara_cluster.update_attribute(
AqaraLedStripT1.AttributeDefs.audio_effect.id, LedStripT1AudioEffect.Rainbow
)
assert len(cluster_listener.attribute_updates) == 7
assert (
cluster_listener.attribute_updates[6][0]
== AqaraLedStripT1.AttributeDefs.audio_effect.id
)

assert cluster_listener.attribute_updates[6][1] == LedStripT1AudioEffect.Rainbow

# Checking preset attribute update
aqara_cluster.update_attribute(
AqaraLedStripT1.AttributeDefs.preset.id, LedStripT1Preset.Sweep
)
assert len(cluster_listener.attribute_updates) == 8
assert (
cluster_listener.attribute_updates[7][0]
== AqaraLedStripT1.AttributeDefs.preset.id
)

assert cluster_listener.attribute_updates[7][1] == LedStripT1Preset.Sweep

# Checking speed attribute update
aqara_cluster.update_attribute(AqaraLedStripT1.AttributeDefs.speed.id, 77)
assert len(cluster_listener.attribute_updates) == 9
assert (
cluster_listener.attribute_updates[8][0]
== AqaraLedStripT1.AttributeDefs.speed.id
)

assert cluster_listener.attribute_updates[8][1] == 77
208 changes: 208 additions & 0 deletions zhaquirks/xiaomi/aqara/led_strip_t1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
"""Aqara led strip T1."""

from typing import Final

from zigpy import types as t
from zigpy.quirks.v2 import QuirkBuilder
from zigpy.quirks.v2.homeassistant import PERCENTAGE, UnitOfLength
from zigpy.zcl.foundation import DataTypeId, ZCLAttributeDef

from zhaquirks.xiaomi import XiaomiAqaraE1Cluster


class LedStripT1PowerOnStateMode(t.enum8):
"""Aqara led strip power on state."""

On = 0x00
Previous = 0x01
Off = 0x02
Toggle = 0x03


class LedStripT1Audio(t.enum8):
"""Aqara led strip audio enabled."""

Off = 0x00
On = 0x01


class LedStripT1AudioSensitivity(t.enum8):
"Aqara led strip audio sensitivity."

Low = 0x00
Medium = 0x01
High = 0x02


class LedStripT1AudioEffect(t.enum32):
"Aqara led strip audio effect."

Random = 0x00
Blink = 0x01
Rainbow = 0x02
Wave = 0x03


class LedStripT1Preset(t.enum32):
"Aqara led strip preset."

Breathe = 0x00
Rainbow = 0x01
Sweep = 0x02
Flashing = 0x03
Strobe = 0x04
ReversedRainbow = 0x05
Colorful = 0x06
Scan = 0x07


MIN_BRIGHTNESS_ID = 0x0515
MAX_BRIGHTNESS_ID = 0x0516
POWER_ON_STATE_ID = 0x0517
STRIP_LENGTH_ID = 0x051B
ENABLE_AUDIO_ID = 0x051C
AUDIO_EFECT_ID = 0x051D
AUDIO_SENSITIVITY_ID = 0x051E
PRESET_ID = 0x051F
SPEED_ID = 0x0520


class AqaraLedStripT1(XiaomiAqaraE1Cluster):
"""Opple cluster."""

class AttributeDefs(XiaomiAqaraE1Cluster.AttributeDefs):
"""Attribute definitions."""

min_brightness: Final = ZCLAttributeDef(
id=MIN_BRIGHTNESS_ID, type=t.uint8_t, is_manufacturer_specific=True
)

max_brightness: Final = ZCLAttributeDef(
id=MAX_BRIGHTNESS_ID, type=t.uint8_t, is_manufacturer_specific=True
)

power_on_state: Final = ZCLAttributeDef(
id=POWER_ON_STATE_ID,
type=LedStripT1PowerOnStateMode,
zcl_type=DataTypeId.uint8,
is_manufacturer_specific=True,
)

length: Final = ZCLAttributeDef(
id=STRIP_LENGTH_ID, type=t.uint8_t, is_manufacturer_specific=True
)

audio: Final = ZCLAttributeDef(
id=ENABLE_AUDIO_ID,
type=LedStripT1Audio,
zcl_type=DataTypeId.uint8,
is_manufacturer_specific=True,
)

audio_sensitivity: Final = ZCLAttributeDef(
id=AUDIO_SENSITIVITY_ID,
type=LedStripT1AudioSensitivity,
zcl_type=DataTypeId.uint8,
is_manufacturer_specific=True,
)

audio_effect: Final = ZCLAttributeDef(
id=AUDIO_EFECT_ID,
type=LedStripT1AudioEffect,
zcl_type=DataTypeId.uint32,
is_manufacturer_specific=True,
)

preset: Final = ZCLAttributeDef(
id=PRESET_ID,
type=LedStripT1Preset,
zcl_type=DataTypeId.uint32,
is_manufacturer_specific=True,
)

speed: Final = ZCLAttributeDef(
id=SPEED_ID, type=t.uint8_t, is_manufacturer_specific=True
)


(
QuirkBuilder("Aqara", "lumi.light.acn132")
.friendly_name(manufacturer="Aqara", model="Led strip T1")
.replaces(AqaraLedStripT1)
.number(
AqaraLedStripT1.AttributeDefs.min_brightness.name,
AqaraLedStripT1.cluster_id,
min_value=0,
max_value=99,
step=1.0,
unit=PERCENTAGE,
translation_key="min_brightness",
fallback_name="Minimum brightness",
)
.number(
AqaraLedStripT1.AttributeDefs.max_brightness.name,
AqaraLedStripT1.cluster_id,
min_value=0,
max_value=99,
step=1.0,
unit=PERCENTAGE,
translation_key="max_brightness",
fallback_name="Maximum brightness",
)
.enum(
AqaraLedStripT1.AttributeDefs.power_on_state.name,
LedStripT1PowerOnStateMode,
AqaraLedStripT1.cluster_id,
translation_key="power_on_state",
fallback_name="Power on state",
)
.number(
AqaraLedStripT1.AttributeDefs.length.name,
AqaraLedStripT1.cluster_id,
min_value=1,
max_value=10,
step=0.2,
multiplier=0.2,
unit=UnitOfLength.METERS,
translation_key="length",
fallback_name="Length",
)
.enum(
AqaraLedStripT1.AttributeDefs.audio.name,
LedStripT1Audio,
AqaraLedStripT1.cluster_id,
translation_key="audio",
fallback_name="Audio",
)
.enum(
AqaraLedStripT1.AttributeDefs.audio_sensitivity.name,
LedStripT1AudioSensitivity,
AqaraLedStripT1.cluster_id,
translation_key="audio_sensitivity",
fallback_name="Audio sensitivity",
)
.enum(
AqaraLedStripT1.AttributeDefs.audio_effect.name,
LedStripT1AudioEffect,
AqaraLedStripT1.cluster_id,
translation_key="audio_effect",
fallback_name="Audio effect",
)
.enum(
AqaraLedStripT1.AttributeDefs.preset.name,
LedStripT1Preset,
AqaraLedStripT1.cluster_id,
translation_key="preset",
fallback_name="Preset",
)
.number(
AqaraLedStripT1.AttributeDefs.speed.name,
AqaraLedStripT1.cluster_id,
min_value=1,
max_value=100,
step=1,
translation_key="speed",
fallback_name="Speed",
)
.add_to_registry()
)
Loading