Skip to content

Commit f58654e

Browse files
committed
Merge branch 'release/0.0.29'
2 parents f4b071e + 4551bef commit f58654e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1429
-238
lines changed

Contributors.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Contributors
2+
- [David F. Mulcahey] (https://github.com/dmulcahey)
3+
- [roblandry] (https://github.com/roblandry)
4+
- [presslab-us] (https://github.com/presslab-us)
5+
- [Alexei Chetroi] (https://github.com/Adminiuga)
6+
- [Abílio Costa] (https://github.com/abmantis)
7+
- [Andreas Setterlind] (https://github.com/Gamester17)
8+
- [prairiesnpr] (https://github.com/prairiesnpr)
9+
- [Daniel Lashua] (https://github.com/dlashua)
10+
- [bballwiz5] (https://github.com/bballwiz5)
11+
- [Ross Patterson] (https://github.com/rpatterson)
12+
- [Marc Egli] (https://github.com/frog32)
13+
- [Dinko Bajric] (https://github.com/dbajric)
14+
- [brg468] (https://github.com/brg468)
15+
- [James Riley] (https://github.com/Thalagyrt)
16+
- [Shulyaka] (https://github.com/Shulyaka)
17+
- [Nemesis24] (https://github.com/Nemesis24)
18+
- [Andy Zickler](https://github.com/andyzickler)

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@ ZHA device handlers bridge the functionality gap created when manufacturers devi
88

99
Custom quirks implementations for zigpy implemented as ZHA Device Handlers are a similar concept to that of [Hub-connected Device Handlers for the SmartThings Classics platform](https://docs.smartthings.com/en/latest/device-type-developers-guide/) as well that of [Zigbee-Shepherd Converters as used by Zigbee2mqtt](https://www.zigbee2mqtt.io/how_tos/how_to_support_new_devices.html), meaning they are virtual representation of a physical device that expose additional functionality that is not provided out-of-the-box by the existing integration between these platforms. See [Device Specifics](#Device-Specifics) for details.
1010

11-
# Contributing
12-
[guidelines](./CONTRIBUTING.md)
11+
# How to contribute
12+
13+
For specific Zigbee debugging instructions on capturing logs and more, see the contributing guidelines in the CONTRIBUTING.md file:
14+
- [Guidelines in CONTRIBUTING.md](./CONTRIBUTING.md)
15+
16+
If you are looking to make your first code contribution to this project then we also suggest that you follow the steps in these guides:
17+
- https://github.com/firstcontributions/first-contributions/blob/master/README.md
18+
- https://github.com/firstcontributions/first-contributions/blob/master/github-desktop-tutorial.md
1319

1420
# Currently Supported Devices:
1521

@@ -109,6 +115,7 @@ Custom quirks implementations for zigpy implemented as ZHA Device Handlers are a
109115

110116
- Some functionality requires a coordinator device to be XBee as well
111117
- GPIO pins are exposed to Home Assistant as switches
118+
- Analog inputs are exposed as sensors
112119
- Outgoing UART data can be sent with `zha.issue_zigbee_cluster_command` service
113120
- Incoming UART data will generate `zha_event` event.
114121

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from setuptools import find_packages, setup
44

5-
VERSION = "0.0.28"
5+
VERSION = "0.0.29"
66

77

88
def readme():

tests/test_kof.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
"""Tests for KOF."""
2+
from unittest import mock
3+
4+
import zigpy.device
5+
import zigpy.endpoint
6+
import zigpy.quirks
7+
8+
9+
def test_kof_no_reply():
10+
"""Test KOF No reply."""
11+
12+
class TestCluster(zigpy.quirks.kof.NoReplyMixin, zigpy.quirks.CustomCluster):
13+
"""Test Cluster Class."""
14+
15+
cluster_id = 0x1234
16+
void_input_commands = [0x0002]
17+
server_commands = {
18+
0x0001: ("noop", (), False),
19+
0x0002: ("noop_noreply", (), False),
20+
}
21+
client_commands = {}
22+
23+
end_point = mock.MagicMock()
24+
cluster = TestCluster(end_point)
25+
26+
cluster.command(0x0001)
27+
end_point.request.assert_called_with(
28+
mock.ANY, mock.ANY, mock.ANY, expect_reply=True, command_id=mock.ANY
29+
)
30+
end_point.reset_mock()
31+
32+
cluster.command(0x0001, expect_reply=False)
33+
end_point.request.assert_called_with(
34+
mock.ANY, mock.ANY, mock.ANY, expect_reply=False, command_id=mock.ANY
35+
)
36+
end_point.reset_mock()
37+
38+
cluster.command(0x0002)
39+
end_point.request.assert_called_with(
40+
mock.ANY, mock.ANY, mock.ANY, expect_reply=False, command_id=mock.ANY
41+
)
42+
end_point.reset_mock()
43+
44+
cluster.command(0x0002, expect_reply=True)
45+
end_point.request.assert_called_with(
46+
mock.ANY, mock.ANY, mock.ANY, expect_reply=True, command_id=mock.ANY
47+
)
48+
end_point.reset_mock()

zhaquirks/__init__.py

100644100755
Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Quirks implementations for the ZHA component of Homeassistant."""
2+
import logging
23
import importlib
34
import pkgutil
45

@@ -17,6 +18,8 @@
1718
ZHA_SEND_EVENT,
1819
)
1920

21+
_LOGGER = logging.getLogger(__name__)
22+
2023

2124
class Bus(ListenableMixin):
2225
"""Event bus implementation."""
@@ -116,8 +119,8 @@ class PowerConfigurationCluster(CustomCluster, PowerConfiguration):
116119
cluster_id = PowerConfiguration.cluster_id
117120
BATTERY_VOLTAGE_ATTR = 0x0020
118121
BATTERY_PERCENTAGE_REMAINING = 0x0021
119-
MIN_VOLTS = 2.1
120-
MAX_VOLTS = 3.2
122+
MIN_VOLTS = 1.5 # old 2.1
123+
MAX_VOLTS = 2.8 # old 3.2
121124

122125
def _update_attribute(self, attrid, value):
123126
super()._update_attribute(attrid, value)
@@ -131,14 +134,24 @@ def _calculate_battery_percentage(self, raw_value):
131134
if raw_value in (0, 255):
132135
return -1
133136
volts = raw_value / 10
134-
if volts < self.MIN_VOLTS:
135-
volts = self.MIN_VOLTS
136-
elif volts > self.MAX_VOLTS:
137-
volts = self.MAX_VOLTS
137+
volts = max(volts, self.MIN_VOLTS)
138+
volts = min(volts, self.MAX_VOLTS)
139+
140+
percent = round(
141+
((volts - self.MIN_VOLTS) / (self.MAX_VOLTS - self.MIN_VOLTS)) * 200
142+
)
138143

139-
percent = ((volts - self.MIN_VOLTS) / (self.MAX_VOLTS - self.MIN_VOLTS)) * 200
144+
_LOGGER.debug(
145+
"%s %s, Voltage [RAW]:%s [Max]:%s [Min]:%s, Battery Percent: %s",
146+
self.endpoint.device.manufacturer,
147+
self.endpoint.device.model,
148+
raw_value,
149+
self.MAX_VOLTS,
150+
self.MIN_VOLTS,
151+
percent / 2,
152+
)
140153

141-
return round(min(200, percent), 2)
154+
return percent
142155

143156

144157
NAME = __name__

zhaquirks/centralite/3130.py

100644100755
Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
)
1212
from zigpy.zcl.clusters.measurement import TemperatureMeasurement
1313

14-
from zhaquirks.centralite import CENTRALITE, PowerConfigurationCluster
14+
from zhaquirks import PowerConfigurationCluster
15+
from zhaquirks.centralite import CENTRALITE
1516
from zhaquirks.const import (
1617
COMMAND,
1718
COMMAND_MOVE,
@@ -35,6 +36,14 @@
3536
DIAGNOSTICS_CLUSTER_ID = 0x0B05 # decimal = 2821
3637

3738

39+
class CustomPowerConfigurationCluster(PowerConfigurationCluster):
40+
"""Custom PowerConfigurationCluster."""
41+
42+
cluster_id = PowerConfigurationCluster.cluster_id
43+
MIN_VOLTS = 2.1
44+
MAX_VOLTS = 3.0
45+
46+
3847
class CentraLite3130(CustomDevice):
3948
"""Custom device representing centralite 3130."""
4049

@@ -50,7 +59,7 @@ class CentraLite3130(CustomDevice):
5059
DEVICE_TYPE: zha.DeviceType.LEVEL_CONTROL_SWITCH,
5160
INPUT_CLUSTERS: [
5261
Basic.cluster_id,
53-
PowerConfigurationCluster.cluster_id,
62+
CustomPowerConfigurationCluster.cluster_id,
5463
Identify.cluster_id,
5564
PollControl.cluster_id,
5665
TemperatureMeasurement.cluster_id,
@@ -70,7 +79,7 @@ class CentraLite3130(CustomDevice):
7079
1: {
7180
INPUT_CLUSTERS: [
7281
Basic.cluster_id,
73-
PowerConfigurationCluster,
82+
CustomPowerConfigurationCluster,
7483
Identify.cluster_id,
7584
PollControl.cluster_id,
7685
DIAGNOSTICS_CLUSTER_ID,

zhaquirks/centralite/3157100.py

100644100755
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl, Time
55
from zigpy.zcl.clusters.hvac import Fan, Thermostat, UserInterface
66

7-
from zhaquirks.centralite import CENTRALITE, PowerConfigurationCluster
7+
from zhaquirks import PowerConfigurationCluster
8+
from zhaquirks.centralite import CENTRALITE
89
from zhaquirks.const import (
910
DEVICE_TYPE,
1011
ENDPOINTS,

zhaquirks/centralite/3300S.py

100644100755
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
from zigpy.zcl.clusters.measurement import TemperatureMeasurement
66
from zigpy.zcl.clusters.security import IasZone
77

8-
from zhaquirks.centralite import CENTRALITE, PowerConfigurationCluster
8+
from zhaquirks import PowerConfigurationCluster
9+
from zhaquirks.centralite import CENTRALITE
910
from zhaquirks.const import (
1011
DEVICE_TYPE,
1112
ENDPOINTS,

zhaquirks/centralite/3305S.py

100644100755
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
from zigpy.zcl.clusters.measurement import OccupancySensing, TemperatureMeasurement
66
from zigpy.zcl.clusters.security import IasZone
77

8-
from zhaquirks.centralite import CENTRALITE, PowerConfigurationCluster
8+
from zhaquirks import PowerConfigurationCluster
9+
from zhaquirks.centralite import CENTRALITE
910
from zhaquirks.const import (
1011
DEVICE_TYPE,
1112
ENDPOINTS,

zhaquirks/centralite/3310S.py

100644100755
Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
"""Centralite 3310S implementation."""
2-
from zigpy import quirks
32
from zigpy.profiles import zha
4-
from zigpy.quirks import CustomDevice
5-
from zigpy.quirks.smartthings import (
6-
SmartthingsRelativeHumidityCluster,
7-
SmartthingsTemperatureHumiditySensor,
8-
)
3+
from zigpy.quirks import CustomDevice, CustomCluster
94
from zigpy.zcl.clusters.general import Basic, Identify, Ota, PollControl
105
from zigpy.zcl.clusters.measurement import TemperatureMeasurement
6+
import zigpy.types as t
117

12-
from zhaquirks.centralite import CENTRALITE, PowerConfigurationCluster
8+
from zhaquirks import PowerConfigurationCluster
9+
from zhaquirks.centralite import CENTRALITE
1310
from zhaquirks.const import (
1411
DEVICE_TYPE,
1512
ENDPOINTS,
@@ -20,11 +17,21 @@
2017
)
2118

2219
DIAGNOSTICS_CLUSTER_ID = 0x0B05 # decimal = 2821
20+
SMRT_THINGS_REL_HUM_CLSTR = 0xFC45
21+
2322

23+
class SmartthingsRelativeHumidityCluster(CustomCluster):
24+
"""Smart Things Relative Humidity Cluster."""
2425

25-
# remove the zigpy version of this device handler
26-
if SmartthingsTemperatureHumiditySensor in quirks._DEVICE_REGISTRY:
27-
quirks._DEVICE_REGISTRY.remove(SmartthingsTemperatureHumiditySensor)
26+
cluster_id = SMRT_THINGS_REL_HUM_CLSTR
27+
name = "Smartthings Relative Humidity Measurement"
28+
ep_attribute = "humidity"
29+
attributes = {
30+
# Relative Humidity Measurement Information
31+
0x0000: ("measured_value", t.int16s)
32+
}
33+
server_commands = {}
34+
client_commands = {}
2835

2936

3037
class CentraLite3310S(CustomDevice):

0 commit comments

Comments
 (0)