Skip to content

Commit

Permalink
Merge branch 'release/0.0.84'
Browse files Browse the repository at this point in the history
  • Loading branch information
dmulcahey committed Oct 26, 2022
2 parents b7c9d4d + 39f5d23 commit 4ba33e3
Show file tree
Hide file tree
Showing 20 changed files with 748 additions and 32 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from setuptools import find_packages, setup

VERSION = "0.0.83"
VERSION = "0.0.84"


setup(
Expand Down
74 changes: 74 additions & 0 deletions tests/test_ikea.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""Tests for Ikea Starkvind quirks."""

import zhaquirks.ikea.starkvind


def test_ikea_starkvind(assert_signature_matches_quirk):
"""Test new 'STARKVIND Air purifier table' signature is matched to its quirk."""

signature = {
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4476, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
"endpoints": {
"1": {
"profile_id": 260,
"device_type": "0x0007",
"in_clusters": [
"0x0000",
"0x0003",
"0x0004",
"0x0005",
"0x0202",
"0xfc57",
"0xfc7d",
],
"out_clusters": ["0x0019", "0x0400", "0x042a"],
},
"242": {
"profile_id": 41440,
"device_type": "0x0061",
"in_clusters": [],
"out_clusters": ["0x0021"],
},
},
"manufacturer": "IKEA of Sweden",
"model": "STARKVIND Air purifier",
"class": "ikea.starkvind.IkeaSTARKVIND",
}

assert_signature_matches_quirk(zhaquirks.ikea.starkvind.IkeaSTARKVIND, signature)


def test_ikea_starkvind_v2(assert_signature_matches_quirk):
"""Test new 'STARKVIND Air purifier table' signature is matched to its quirk."""

signature = {
"node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4476, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
"endpoints": {
"1": {
"profile_id": 260,
"device_type": "0x0007",
"in_clusters": [
"0x0000",
"0x0003",
"0x0004",
"0x0005",
"0x0202",
"0xfc57",
"0xfc7c",
"0xfc7d",
],
"out_clusters": ["0x0019", "0x0400", "0x042a"],
},
"242": {
"profile_id": 41440,
"device_type": "0x0061",
"in_clusters": [],
"out_clusters": ["0x0021"],
},
},
"manufacturer": "IKEA of Sweden",
"model": "STARKVIND Air purifier table",
"class": "ikea.starkvind.IkeaSTARKVIND_v2",
}

assert_signature_matches_quirk(zhaquirks.ikea.starkvind.IkeaSTARKVIND_v2, signature)
2 changes: 1 addition & 1 deletion zhaquirks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ async def write_attributes(self, attributes, manufacturer=None):
"""Prevent remote writes."""
for attrid, value in attributes.items():
if isinstance(attrid, str):
attrid = self.attributes[attrid].id
attrid = self.attributes_by_name[attrid].id
elif attrid not in self.attributes:
self.error("%d is not a valid attribute id", attrid)
continue
Expand Down
57 changes: 57 additions & 0 deletions zhaquirks/heiman/smoke.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,60 @@ class HeimanSmokYDLV10(CustomDevice):
},
},
}


class HeimanSmokCO_V15(CustomDevice):
"""CO_V15 quirk."""

# NodeDescriptor(
# logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0,
# frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|MainsPowered: 132>,
# manufacturer_code=48042, maximum_buffer_size=64, maximum_incoming_transfer_size=0, server_mask=0, maximum_outgoing_transfer_size=0,
# descriptor_capability_field=<DescriptorCapability.ExtendedSimpleDescriptorListAvailable|ExtendedActiveEndpointListAvailable: 3>,
# *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False,
# *is_mains_powered=True, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False
# )"
signature = {
MODELS_INFO: [(HEIMAN, "CO_V15")],
ENDPOINTS: {
# "profile_id": 260,"device_type": "0x0402",
# "in_clusters": ["0x0000","0x0001","0x0003","0x0009","0x0500"],
# "out_clusters": ["0x0019"]
1: {
PROFILE_ID: zigpy.profiles.zha.PROFILE_ID,
DEVICE_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
Alarms.cluster_id,
IasZone.cluster_id,
],
OUTPUT_CLUSTERS: [
Ota.cluster_id,
],
},
},
}

replacement = {
NODE_DESCRIPTOR: zigpy.zdo.types.NodeDescriptor(
0x02, 0x40, 0x84 & 0b1111_1011, 0xBBAA, 0x40, 0x0000, 0x0000, 0x0000, 0x03
),
ENDPOINTS: {
1: {
PROFILE_ID: zigpy.profiles.zha.PROFILE_ID,
DEVICE_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE,
INPUT_CLUSTERS: [
Basic.cluster_id,
PowerConfiguration.cluster_id,
Identify.cluster_id,
Alarms.cluster_id,
IasZone.cluster_id,
],
OUTPUT_CLUSTERS: [
Ota.cluster_id,
],
},
},
}
3 changes: 3 additions & 0 deletions zhaquirks/ikea/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
from zhaquirks import DoublingPowerConfigurationCluster

_LOGGER = logging.getLogger(__name__)

IKEA = "IKEA of Sweden"
IKEA_CLUSTER_ID = 0xFC7C # decimal = 64636
WWAH_CLUSTER_ID = 0xFC57 # decimal = 64599 ('Works with all Hubs' cluster)


class LightLinkCluster(CustomCluster, LightLink):
Expand Down
4 changes: 1 addition & 3 deletions zhaquirks/ikea/blinds.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@
OUTPUT_CLUSTERS,
PROFILE_ID,
)
from zhaquirks.ikea import IKEA

IKEA_CLUSTER_ID = 0xFC7C # decimal = 64636
from zhaquirks.ikea import IKEA, IKEA_CLUSTER_ID


class IkeaTradfriRollerBlinds(CustomDevice):
Expand Down
3 changes: 1 addition & 2 deletions zhaquirks/ikea/fivebtnremotezha.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,12 @@
)
from zhaquirks.ikea import (
IKEA,
IKEA_CLUSTER_ID,
LightLinkCluster,
PowerConfiguration1CRCluster,
ScenesCluster,
)

IKEA_CLUSTER_ID = 0xFC7C # decimal = 64636


class IkeaTradfriRemote1(CustomDevice):
"""Custom device representing IKEA of Sweden TRADFRI remote control."""
Expand Down
9 changes: 6 additions & 3 deletions zhaquirks/ikea/fourbtnremote.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,12 @@
TURN_OFF,
TURN_ON,
)
from zhaquirks.ikea import IKEA, PowerConfiguration2AAACluster, ScenesCluster

WWAH_CLUSTER_ID = 0xFC57 # decimal = 64599
from zhaquirks.ikea import (
IKEA,
WWAH_CLUSTER_ID,
PowerConfiguration2AAACluster,
ScenesCluster,
)


class IkeaTradfriRemote(CustomDevice):
Expand Down
9 changes: 6 additions & 3 deletions zhaquirks/ikea/motionzha.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@
OUTPUT_CLUSTERS,
PROFILE_ID,
)
from zhaquirks.ikea import IKEA, LightLinkCluster, PowerConfiguration2CRCluster

IKEA_CLUSTER_ID = 0xFC7C # decimal = 64636
from zhaquirks.ikea import (
IKEA,
IKEA_CLUSTER_ID,
LightLinkCluster,
PowerConfiguration2CRCluster,
)


class IkeaTradfriMotion(CustomDevice):
Expand Down
3 changes: 1 addition & 2 deletions zhaquirks/ikea/opencloseremote.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,12 @@
SHORT_PRESS,
ZHA_SEND_EVENT,
)
from zhaquirks.ikea import IKEA, PowerConfiguration1CRCluster
from zhaquirks.ikea import IKEA, IKEA_CLUSTER_ID, PowerConfiguration1CRCluster

COMMAND_CLOSE = "down_close"
COMMAND_STOP_OPENING = "stop_opening"
COMMAND_STOP_CLOSING = "stop_closing"
COMMAND_OPEN = "up_open"
IKEA_CLUSTER_ID = 0xFC7C # decimal = 64636


class IkeaWindowCovering(CustomCluster, WindowCovering):
Expand Down
82 changes: 79 additions & 3 deletions zhaquirks/ikea/starkvind.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@
OUTPUT_CLUSTERS,
PROFILE_ID,
)
from zhaquirks.ikea import IKEA
from zhaquirks.ikea import IKEA, IKEA_CLUSTER_ID, WWAH_CLUSTER_ID

WWAH_CLUSTER_ID = 0xFC57 # decimal = 64599
_LOGGER = logging.getLogger(__name__)


Expand Down Expand Up @@ -83,7 +82,7 @@ async def write_attributes(
"""Override wrong writes to thermostat attributes."""
if "fan_mode" in attributes:
fan_mode = attributes.get("fan_mode")
if fan_mode > 1 and fan_mode < 11:
if fan_mode and fan_mode > 1 and fan_mode < 11:
fan_mode = fan_mode * 5
return await super().write_attributes(
{"fan_mode": fan_mode}, manufacturer
Expand Down Expand Up @@ -220,3 +219,80 @@ def __init__(self, *args, **kwargs):
},
},
}


class IkeaSTARKVIND_v2(IkeaSTARKVIND):
"""STARKVIND Air purifier by IKEA of Sweden."""

signature = {
# <SimpleDescriptor endpoint=1 profile=260 device_type=7 (0x0007)
# device_version=0
# input_clusters=[0, 3, 4, 5, 514, 64599, 64637] output_clusters=[25, 1024, 1066]>
MODELS_INFO: IkeaSTARKVIND.signature[MODELS_INFO].copy(),
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE,
INPUT_CLUSTERS: [
Basic.cluster_id, # 0
Identify.cluster_id, # 3
Groups.cluster_id, # 4
Scenes.cluster_id, # 5
Fan.cluster_id, # 514 0x0202
WWAH_CLUSTER_ID, # 64599 0xFC57
IKEA_CLUSTER_ID, # 64636 0xFC7C
IkeaAirpurifier.cluster_id, # 64637 0xFC7D
],
OUTPUT_CLUSTERS: [
Ota.cluster_id, # 25 0x0019
IlluminanceMeasurement.cluster_id, # 1024 0x0400
PM25.cluster_id, # 1066 0x042A PM2.5 Measurement Cluster
],
},
# <SimpleDescriptor endpoint=242 profile=41440 device_type=97
# device_version=0
# input_clusters=[33] output_clusters=[33]>
242: {
PROFILE_ID: 0xA1E0, # 41440 (dec)
DEVICE_TYPE: 0x0061,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [
GreenPowerProxy.cluster_id, # 0x0021 = GreenPowerProxy.cluster_id
],
},
},
}

replacement = {
ENDPOINTS: {
1: {
PROFILE_ID: zha.PROFILE_ID,
DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE,
INPUT_CLUSTERS: [
Basic.cluster_id, # 0
Identify.cluster_id, # 3
Groups.cluster_id, # 4
Scenes.cluster_id, # 5
WWAH_CLUSTER_ID, # 64599 0xFC57
IKEA_CLUSTER_ID, # 64636 0xFC7C
IkeaAirpurifier, # 64637 0xFC7D control air purifier with manufacturer-specific attributes
PM25Cluster, # 1066 0x042A PM2.5 Measurement Cluster
],
OUTPUT_CLUSTERS: [
Ota.cluster_id, # 25 0x0019
IlluminanceMeasurement.cluster_id, # 1024 0x0400
],
},
# <SimpleDescriptor endpoint=242 profile=41440 device_type=97
# device_version=0
# input_clusters=[33] output_clusters=[33]>
242: {
PROFILE_ID: 0xA1E0, # 41440 (dec)
DEVICE_TYPE: 0x0061,
INPUT_CLUSTERS: [],
OUTPUT_CLUSTERS: [
GreenPowerProxy.cluster_id, # 0x0021 = GreenPowerProxy.cluster_id
],
},
},
}
4 changes: 1 addition & 3 deletions zhaquirks/ikea/symfonisk.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@
TRIPLE_PRESS,
TURN_ON,
)
from zhaquirks.ikea import IKEA, PowerConfiguration1CRCluster

IKEA_CLUSTER_ID = 0xFC7C # decimal = 64636
from zhaquirks.ikea import IKEA, IKEA_CLUSTER_ID, PowerConfiguration1CRCluster


class IkeaSYMFONISK1(CustomDevice):
Expand Down
4 changes: 1 addition & 3 deletions zhaquirks/ikea/tradfriplug.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
)
from zigpy.zcl.clusters.lightlink import LightLink

from zhaquirks.ikea import IKEA

IKEA_CLUSTER_ID = 0xFC7C # decimal = 64636
from zhaquirks.ikea import IKEA, IKEA_CLUSTER_ID


class TradfriPlug(CustomDevice):
Expand Down
9 changes: 6 additions & 3 deletions zhaquirks/ikea/twobtnremote.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,12 @@
TURN_OFF,
TURN_ON,
)
from zhaquirks.ikea import IKEA, LightLinkCluster, PowerConfiguration1CRCluster

IKEA_CLUSTER_ID = 0xFC7C # decimal = 64636
from zhaquirks.ikea import (
IKEA,
IKEA_CLUSTER_ID,
LightLinkCluster,
PowerConfiguration1CRCluster,
)


class IkeaTradfriRemote2Btn(CustomDevice):
Expand Down
Loading

0 comments on commit 4ba33e3

Please sign in to comment.