Skip to content

Commit

Permalink
Merge branch 'release/0.0.63'
Browse files Browse the repository at this point in the history
  • Loading branch information
dmulcahey committed Oct 26, 2021
2 parents dd42eaa + f72b8ce commit d4dde16
Show file tree
Hide file tree
Showing 30 changed files with 1,204 additions and 124 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from setuptools import find_packages, setup

VERSION = "0.0.62"
VERSION = "0.0.63"


def readme():
Expand Down
32 changes: 18 additions & 14 deletions tests/test_tuya.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
ZONE_STATE,
)
from zhaquirks.tuya import Data, TuyaManufClusterAttributes
import zhaquirks.tuya.electric_heating
import zhaquirks.tuya.motion
import zhaquirks.tuya.siren
import zhaquirks.tuya.ts0042
import zhaquirks.tuya.ts0043
import zhaquirks.tuya.valve
import zhaquirks.tuya.ts0601_electric_heating
import zhaquirks.tuya.ts0601_motion
import zhaquirks.tuya.ts0601_siren
import zhaquirks.tuya.ts0601_trv

from tests.common import ClusterListener

Expand Down Expand Up @@ -81,7 +81,7 @@ def utcnow(cls):
return cls(1970, 1, 1, 2, 0, 0)


@pytest.mark.parametrize("quirk", (zhaquirks.tuya.motion.TuyaMotion,))
@pytest.mark.parametrize("quirk", (zhaquirks.tuya.ts0601_motion.TuyaMotion,))
async def test_motion(zigpy_device_from_quirk, quirk):
"""Test tuya motion sensor."""

Expand Down Expand Up @@ -109,7 +109,9 @@ async def test_motion(zigpy_device_from_quirk, quirk):
assert motion_listener.cluster_commands[1][2][0] == OFF


@pytest.mark.parametrize("quirk", (zhaquirks.tuya.singleswitch.TuyaSingleSwitch,))
@pytest.mark.parametrize(
"quirk", (zhaquirks.tuya.ts0601_singleswitch.TuyaSingleSwitch,)
)
async def test_singleswitch_state_report(zigpy_device_from_quirk, quirk):
"""Test tuya single switch."""

Expand All @@ -133,7 +135,9 @@ async def test_singleswitch_state_report(zigpy_device_from_quirk, quirk):
assert switch_listener.attribute_updates[1][1] == OFF


@pytest.mark.parametrize("quirk", (zhaquirks.tuya.singleswitch.TuyaSingleSwitch,))
@pytest.mark.parametrize(
"quirk", (zhaquirks.tuya.ts0601_singleswitch.TuyaSingleSwitch,)
)
async def test_singleswitch_requests(zigpy_device_from_quirk, quirk):
"""Test tuya single switch."""

Expand Down Expand Up @@ -256,7 +260,7 @@ async def async_success(*args, **kwargs):
]


@pytest.mark.parametrize("quirk", (zhaquirks.tuya.siren.TuyaSiren,))
@pytest.mark.parametrize("quirk", (zhaquirks.tuya.ts0601_siren.TuyaSiren,))
async def test_siren_state_report(zigpy_device_from_quirk, quirk):
"""Test tuya siren standard state reporting from incoming commands."""

Expand Down Expand Up @@ -295,7 +299,7 @@ async def test_siren_state_report(zigpy_device_from_quirk, quirk):
assert switch_listener.attribute_updates[1][1] == OFF


@pytest.mark.parametrize("quirk", (zhaquirks.tuya.siren.TuyaSiren,))
@pytest.mark.parametrize("quirk", (zhaquirks.tuya.ts0601_siren.TuyaSiren,))
async def test_siren_send_attribute(zigpy_device_from_quirk, quirk):
"""Test tuya siren outgoing commands."""

Expand Down Expand Up @@ -334,7 +338,7 @@ async def async_success(*args, **kwargs):
assert status == foundation.Status.UNSUP_CLUSTER_COMMAND


@pytest.mark.parametrize("quirk", (zhaquirks.tuya.valve.SiterwellGS361_Type1,))
@pytest.mark.parametrize("quirk", (zhaquirks.tuya.ts0601_trv.SiterwellGS361_Type1,))
async def test_valve_state_report(zigpy_device_from_quirk, quirk):
"""Test thermostatic valves standard reporting from incoming commands."""

Expand Down Expand Up @@ -384,7 +388,7 @@ async def test_valve_state_report(zigpy_device_from_quirk, quirk):
assert thermostat_listener.attribute_updates[12][1] == 0x01


@pytest.mark.parametrize("quirk", (zhaquirks.tuya.valve.SiterwellGS361_Type1,))
@pytest.mark.parametrize("quirk", (zhaquirks.tuya.ts0601_trv.SiterwellGS361_Type1,))
async def test_valve_send_attribute(zigpy_device_from_quirk, quirk):
"""Test thermostatic valve outgoing commands."""

Expand Down Expand Up @@ -480,7 +484,7 @@ async def async_success(*args, **kwargs):
assert status == foundation.Status.UNSUP_CLUSTER_COMMAND


@pytest.mark.parametrize("quirk", (zhaquirks.tuya.valve.MoesHY368_Type1,))
@pytest.mark.parametrize("quirk", (zhaquirks.tuya.ts0601_trv.MoesHY368_Type1,))
async def test_moes(zigpy_device_from_quirk, quirk):
"""Test thermostatic valve outgoing commands."""

Expand Down Expand Up @@ -1005,7 +1009,7 @@ async def async_success(*args, **kwargs):
datetime.datetime = origdatetime


@pytest.mark.parametrize("quirk", (zhaquirks.tuya.electric_heating.MoesBHT,))
@pytest.mark.parametrize("quirk", (zhaquirks.tuya.ts0601_electric_heating.MoesBHT,))
async def test_eheating_state_report(zigpy_device_from_quirk, quirk):
"""Test thermostatic valves standard reporting from incoming commands."""

Expand All @@ -1027,7 +1031,7 @@ async def test_eheating_state_report(zigpy_device_from_quirk, quirk):
assert thermostat_listener.attribute_updates[1][1] == 2100


@pytest.mark.parametrize("quirk", (zhaquirks.tuya.electric_heating.MoesBHT,))
@pytest.mark.parametrize("quirk", (zhaquirks.tuya.ts0601_electric_heating.MoesBHT,))
async def test_eheat_send_attribute(zigpy_device_from_quirk, quirk):
"""Test electric thermostat outgoing commands."""

Expand Down
42 changes: 39 additions & 3 deletions xbee.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ If you want the pin to work as input, it must be configured as input with XCTU.

If you want the pin to work as output, it is still important to configure the sample reporting in order to know the state of the switch.

Currently digital output requires the coordinator to be XBee as well. THe input should work with any coordinator but this is untested.

## Analog Input

The analog input pins are exposed as sensors.
Expand Down Expand Up @@ -76,7 +74,6 @@ automation:
attribute: 85
value: '{{ trigger.to_state.state }}'
```
Currently PWM output requires the coordinator to be XBee as well.

## UART

Expand Down Expand Up @@ -106,3 +103,42 @@ automation:
command_type: server
args: Assistant
```

## Raw AT Commands

Like with UART, you can send remote AT commands with `zha.issue_zigbee_cluster_command` service.
If the command is unsuccessful, you will get an exception in the logs. If it is successful, the response will be available as `zha_event` event.

You can check the AT-to-Command_ID mapping in Device info screen. Click on `Manage clusters`, then select XBeeRemoteATRequest cluster, and you would find the mapping in the `Cluster Commands` dropdown list.

Here is an example for the temperature sensor of an XBee Pro, you can get its value with TP command:
```
template:
- trigger:
- platform: event
event_type: zha_event
event_data:
device_ieee: 00:13:a2:00:41:98:23:f9
command: tp_command_response
sensor:
- name: "XBee Temperature"
state: '{{ trigger.event.data.args }}'
unit_of_measurement: "°C"
device_class: temperature
state_class: measurement
automation:
- alias: Update XBee Temperature
trigger:
platform: time_pattern
minutes: "/5"
action:
service: zha.issue_zigbee_cluster_command
data:
ieee: 00:13:a2:00:41:98:23:f9
endpoint_id: 230
command: 0x43
command_type: server
cluster_type: out
cluster_id: 33
```
60 changes: 60 additions & 0 deletions zhaquirks/ikea/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from zigpy.zcl.clusters.general import Scenes
from zigpy.zcl.clusters.lightlink import LightLink

from zhaquirks import DoublingPowerConfigurationCluster

_LOGGER = logging.getLogger(__name__)
IKEA = "IKEA of Sweden"
ROTATED = "device_rotated"
Expand Down Expand Up @@ -46,3 +48,61 @@ class ScenesCluster(CustomCluster, Scenes):
0x0008: ("hold", (t.int16s, t.int8s), False),
0x0009: ("release", (t.int16s,), False),
}


class PowerConfiguration2AAACluster(DoublingPowerConfigurationCluster):
"""Updating Power attributes 2 AAA."""

BATTERY_SIZES = 0x0031
BATTERY_QUANTITY = 0x0033
BATTERY_RATED_VOLTAGE = 0x0034

_CONSTANT_ATTRIBUTES = {
BATTERY_SIZES: 4,
BATTERY_QUANTITY: 2,
BATTERY_RATED_VOLTAGE: 15,
}


class PowerConfiguration2CRCluster(DoublingPowerConfigurationCluster):
"""Updating Power attributes 2 CR2032."""

BATTERY_SIZES = 0x0031
BATTERY_QUANTITY = 0x0033
BATTERY_RATED_VOLTAGE = 0x0034

_CONSTANT_ATTRIBUTES = {
BATTERY_SIZES: 10,
BATTERY_QUANTITY: 2,
BATTERY_RATED_VOLTAGE: 30,
}


class PowerConfiguration1CRCluster(DoublingPowerConfigurationCluster):
"""Updating Power attributes 1 CR2032."""

BATTERY_SIZES = 0x0031
BATTERY_QUANTITY = 0x0033
BATTERY_RATED_VOLTAGE = 0x0034

_CONSTANT_ATTRIBUTES = {
BATTERY_SIZES: 10,
BATTERY_QUANTITY: 1,
BATTERY_RATED_VOLTAGE: 30,
}


class PowerConfiguration1CRXCluster(DoublingPowerConfigurationCluster):
"""Updating Power attributes 1 CR2032 and Zero voltage."""

BATTERY_VOLTAGE = 0x0020
BATTERY_SIZES = 0x0031
BATTERY_QUANTITY = 0x0033
BATTERY_RATED_VOLTAGE = 0x0034

_CONSTANT_ATTRIBUTES = {
BATTERY_VOLTAGE: 0,
BATTERY_SIZES: 10,
BATTERY_QUANTITY: 1,
BATTERY_RATED_VOLTAGE: 30,
}
5 changes: 2 additions & 3 deletions zhaquirks/ikea/dimmer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
)
from zigpy.zcl.clusters.lightlink import LightLink

from zhaquirks import DoublingPowerConfigurationCluster
from zhaquirks.const import (
ARGS,
CLUSTER_ID,
Expand All @@ -29,7 +28,7 @@
PROFILE_ID,
RIGHT,
)
from zhaquirks.ikea import IKEA, ROTATED
from zhaquirks.ikea import IKEA, ROTATED, PowerConfiguration1CRXCluster


class IkeaDimmer(CustomDevice):
Expand Down Expand Up @@ -71,7 +70,7 @@ class IkeaDimmer(CustomDevice):
DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER,
INPUT_CLUSTERS: [
Basic.cluster_id,
DoublingPowerConfigurationCluster,
PowerConfiguration1CRXCluster,
Identify.cluster_id,
PollControl.cluster_id,
LightLink.cluster_id,
Expand Down
12 changes: 8 additions & 4 deletions zhaquirks/ikea/fivebtnremotezha.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from zigpy.zcl.clusters.homeautomation import Diagnostic
from zigpy.zcl.clusters.lightlink import LightLink

from zhaquirks import DoublingPowerConfigurationCluster
from zhaquirks.const import (
ARGS,
CLUSTER_ID,
Expand Down Expand Up @@ -43,7 +42,12 @@
SHORT_PRESS,
TURN_ON,
)
from zhaquirks.ikea import IKEA, LightLinkCluster, ScenesCluster
from zhaquirks.ikea import (
IKEA,
LightLinkCluster,
PowerConfiguration1CRCluster,
ScenesCluster,
)

IKEA_CLUSTER_ID = 0xFC7C # decimal = 64636

Expand Down Expand Up @@ -88,7 +92,7 @@ class IkeaTradfriRemote(CustomDevice):
DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER,
INPUT_CLUSTERS: [
Basic.cluster_id,
DoublingPowerConfigurationCluster,
PowerConfiguration1CRCluster,
Identify.cluster_id,
PollControl.cluster_id,
LightLinkCluster,
Expand Down Expand Up @@ -210,7 +214,7 @@ class IkeaTradfriRemote2(IkeaTradfriRemote):
DEVICE_TYPE: zha.DeviceType.COLOR_SCENE_CONTROLLER,
INPUT_CLUSTERS: [
Basic.cluster_id,
DoublingPowerConfigurationCluster,
PowerConfiguration1CRCluster,
Identify.cluster_id,
Alarms.cluster_id,
LightLinkCluster,
Expand Down
5 changes: 2 additions & 3 deletions zhaquirks/ikea/fourbtnremote.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
)
from zigpy.zcl.clusters.lightlink import LightLink

from zhaquirks import DoublingPowerConfigurationCluster
from zhaquirks.const import (
ARGS,
CLUSTER_ID,
Expand Down Expand Up @@ -41,7 +40,7 @@
TURN_OFF,
TURN_ON,
)
from zhaquirks.ikea import IKEA, ScenesCluster
from zhaquirks.ikea import IKEA, PowerConfiguration2AAACluster, ScenesCluster

WWAH_CLUSTER_ID = 0xFC57 # decimal = 64599

Expand Down Expand Up @@ -85,7 +84,7 @@ class IkeaTradfriRemote(CustomDevice):
DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER,
INPUT_CLUSTERS: [
Basic.cluster_id,
DoublingPowerConfigurationCluster,
PowerConfiguration2AAACluster,
Identify.cluster_id,
PollControl.cluster_id,
LightLink.cluster_id,
Expand Down
5 changes: 2 additions & 3 deletions zhaquirks/ikea/motion.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
)
from zigpy.zcl.clusters.lightlink import LightLink

from zhaquirks import DoublingPowerConfigurationCluster
from zhaquirks.const import (
DEVICE_TYPE,
ENDPOINTS,
Expand All @@ -21,7 +20,7 @@
OUTPUT_CLUSTERS,
PROFILE_ID,
)
from zhaquirks.ikea import IKEA, LightLinkCluster
from zhaquirks.ikea import IKEA, LightLinkCluster, PowerConfiguration2CRCluster

DIAGNOSTICS_CLUSTER_ID = 0x0B05 # decimal = 2821

Expand Down Expand Up @@ -65,7 +64,7 @@ class IkeaTradfriMotion(CustomDevice):
DEVICE_TYPE: zll.DeviceType.ON_OFF_SENSOR,
INPUT_CLUSTERS: [
Basic.cluster_id,
DoublingPowerConfigurationCluster,
PowerConfiguration2CRCluster,
Identify.cluster_id,
Alarms.cluster_id,
DIAGNOSTICS_CLUSTER_ID,
Expand Down
Loading

0 comments on commit d4dde16

Please sign in to comment.