Skip to content
Draft
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
28 changes: 0 additions & 28 deletions tests/test_heiman.py

This file was deleted.

26 changes: 1 addition & 25 deletions tests/test_sinope.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from zigpy.device import Device
import zigpy.types as t
from zigpy.zcl import foundation
from zigpy.zcl.clusters.general import DeviceTemperature
from zigpy.zcl.clusters.measurement import FlowMeasurement

from tests.common import ClusterListener
Expand All @@ -24,7 +23,7 @@
SinopeTechnologieslight,
SinopeTechnologiesManufacturerCluster,
)
from zhaquirks.sinope.switch import SinopeTechnologiesCalypso, SinopeTechnologiesValveG2
from zhaquirks.sinope.switch import SinopeTechnologiesValveG2

zhaquirks.setup()

Expand All @@ -33,29 +32,6 @@
SINOPE_MANUFACTURER_ID = 4508 # 0x119C


@pytest.mark.parametrize("quirk", (SinopeTechnologiesCalypso,))
async def test_sinope_device_temp(zigpy_device_from_quirk, quirk):
"""Test that device temperature is multiplied."""
device = zigpy_device_from_quirk(quirk)

dev_temp_cluster = device.endpoints[1].device_temperature
dev_temp_listener = ClusterListener(dev_temp_cluster)
dev_temp_attr_id = DeviceTemperature.AttributeDefs.current_temperature.id
dev_temp_other_attr_id = DeviceTemperature.AttributeDefs.min_temp_experienced.id

# verify current temperature is multiplied by 100
dev_temp_cluster.update_attribute(dev_temp_attr_id, 25)
assert len(dev_temp_listener.attribute_updates) == 1
assert dev_temp_listener.attribute_updates[0][0] == dev_temp_attr_id
assert dev_temp_listener.attribute_updates[0][1] == 2500 # multiplied by 100

# verify other attributes are not modified
dev_temp_cluster.update_attribute(dev_temp_other_attr_id, 25)
assert len(dev_temp_listener.attribute_updates) == 2
assert dev_temp_listener.attribute_updates[1][0] == dev_temp_other_attr_id
assert dev_temp_listener.attribute_updates[1][1] == 25 # not modified


@pytest.mark.parametrize("quirk", (SinopeTechnologiesValveG2,))
async def test_sinope_flow_measurement(zigpy_device_from_quirk, quirk):
"""Test that flow measurement measured value is divided."""
Expand Down
2 changes: 1 addition & 1 deletion tests/test_tuya_rcbo.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ async def test_command_rcbo(zigpy_device_from_quirk):
( # TuyaDatapointData(dp=105, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x1d\x00\x00\x00', *payload=29))
b"\x09\x09\x01\x02\x03i\x02\x00\x04\x00\x00\x00\x1d",
"device_temperature",
{0x0000: 2900},
{0x0000: 29},
),
( # TuyaDatapointData(dp=106, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x00\x00\x00\x00', *payload=0))
b"\x09\x0a\x01\x02\x03j\x02\x00\x04\x00\x00\x00\x00",
Expand Down
8 changes: 2 additions & 6 deletions tests/test_xiaomi.py
Original file line number Diff line number Diff line change
Expand Up @@ -1765,7 +1765,7 @@ async def test_xiaomi_weather(
[
"1C5F11C10A01FF41210121DB0B03281F0421A8430521B60006240B000000000A21CA356410000B210800",
[
3100, # temperature
31, # temperature
9031.899869919436, # illuminance
30.4, # battery voltage
154, # battery percent * 2
Expand Down Expand Up @@ -2717,15 +2717,11 @@ async def test_lumi_magnet_sensor_aq2_bad_direction(zigpy_device_from_quirk, cap


def test_air_monitor_attribute_scaling(zigpy_device_from_v2_quirk):
"""Test Aqara air monitor CO2 and temperature attribute scaling."""
"""Test Aqara air monitor CO2 attribute scaling."""
device = zigpy_device_from_v2_quirk("LUMI", "lumi.airm.fhac01")

co2 = device.endpoints[1].carbon_dioxide_concentration
co2._update_attribute(
CarbonDioxideConcentration.AttributeDefs.measured_value.id, 400_000_000
)
assert co2.get("measured_value") == 400.0

temp = device.endpoints[1].device_temperature
temp._update_attribute(DeviceTemperature.AttributeDefs.current_temperature.id, 25)
assert temp.get("current_temperature") == 2500
13 changes: 1 addition & 12 deletions zhaquirks/heiman/hs1rm_e.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Final

import zigpy.types as t
from zigpy.zcl.clusters.general import DeviceTemperature, OnOffConfiguration
from zigpy.zcl.clusters.general import OnOffConfiguration
from zigpy.zcl.foundation import BaseAttributeDefs, ZCLAttributeDef

from zhaquirks.builder import EntityType, QuirkBuilder
Expand All @@ -30,21 +30,10 @@ class AttributeDefs(BaseAttributeDefs):
)


class HeimanDeviceTemperature(CustomCluster, DeviceTemperature):
"""Heiman Device Temperature cluster that scales raw values by 100."""

def _update_attribute(self, attrid, value):
"""Scale current_temperature to centidegrees for ZHA's /100 divisor."""
if attrid == self.AttributeDefs.current_temperature.id and value is not None:
value = value * 100
super()._update_attribute(attrid, value)


(
QuirkBuilder()
.applies_to("HEIMAN", "RelayModule-EF-3.0")
.friendly_name(manufacturer="HEIMAN", model="HS1RM-E")
.replaces(HeimanDeviceTemperature)
.adds(HeimanSpecialCluster, endpoint_id=1)
.adds(HeimanSpecialCluster, endpoint_id=2)
# switch input type (Heiman manufacturer-specific cluster 0xFC90)
Expand Down
1 change: 1 addition & 0 deletions zhaquirks/namron/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Module for Namron quirks implementations."""
18 changes: 10 additions & 8 deletions zhaquirks/develco/power_plug.py → zhaquirks/namron/switch.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Develco smart plugs."""
"""Namron switches and relays."""

from zigpy.zcl.clusters.general import DeviceTemperature

Expand All @@ -11,25 +11,27 @@
)

(
QuirkBuilder("frient A/S", "SPLZB-141")
.applies_to("Develco Products A/S", "SPLZB-131")
QuirkBuilder("Namron AS", "4512785")
# The device reports current_temperature in units of 0.1 °C, violating the
# ZCL spec (whole degrees, range -200..200). Replace the default entity with
# one that applies the correct divisor.
.prevent_default_entity_creation(
endpoint_id=2,
endpoint_id=1,
cluster_id=DeviceTemperature.cluster_id,
function=lambda entity: entity.__class__.__name__ == "DeviceTemperature",
)
.sensor(
endpoint_id=2,
endpoint_id=1,
cluster_id=DeviceTemperature.cluster_id,
attribute_name=DeviceTemperature.AttributeDefs.current_temperature.name,
divisor=10,
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
unit=UnitOfTemperature.CELSIUS,
divisor=1, # This should be 100 but the device does not follow the spec
entity_type=EntityType.DIAGNOSTIC,
unique_id_suffix="2", # Replace the ZHA-native entity ({ieee}-1-2)
translation_key="device_temperature",
fallback_name="Device temperature",
entity_type=EntityType.DIAGNOSTIC,
unique_id_suffix="2", # Replace the ZHA entity
)
.add_to_registry()
)
11 changes: 0 additions & 11 deletions zhaquirks/sinope/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""Module for Sinope quirks implementations."""

import zigpy.types as t
from zigpy.zcl.clusters.general import DeviceTemperature

from zhaquirks.clusters import CustomCluster
from zhaquirks.const import (
ARGS,
ATTRIBUTE_ID,
Expand Down Expand Up @@ -133,12 +131,3 @@ class ButtonAction(t.enum8):
},
},
}


class CustomDeviceTemperatureCluster(CustomCluster, DeviceTemperature):
"""Custom device temperature cluster that multiplies temperature by 100."""

def _update_attribute(self, attrid, value):
if attrid == self.AttributeDefs.current_temperature.id:
value = value * 100
super()._update_attribute(attrid, value)
7 changes: 3 additions & 4 deletions zhaquirks/sinope/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
SINOPE,
SINOPE_MANUFACTURER_CLUSTER_ID,
ButtonAction,
CustomDeviceTemperatureCluster,
)

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -280,7 +279,7 @@ class SinopeTechnologieslight(CustomDevice):
DEVICE_TYPE: zha_p.DeviceType.ON_OFF_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
CustomDeviceTemperatureCluster,
DeviceTemperature.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
Expand Down Expand Up @@ -344,7 +343,7 @@ class SinopeDM2500ZB(CustomDevice):
DEVICE_TYPE: zha_p.DeviceType.DIMMABLE_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
CustomDeviceTemperatureCluster,
DeviceTemperature.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
Expand Down Expand Up @@ -411,7 +410,7 @@ class SinopeDM2550ZB(CustomDevice):
DEVICE_TYPE: zha_p.DeviceType.DIMMABLE_LIGHT,
INPUT_CLUSTERS: [
Basic.cluster_id,
CustomDeviceTemperatureCluster,
DeviceTemperature.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
Expand Down
10 changes: 3 additions & 7 deletions zhaquirks/sinope/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,7 @@
PROFILE_ID,
)
from zhaquirks.legacy import CustomDevice
from zhaquirks.sinope import (
SINOPE,
SINOPE_MANUFACTURER_CLUSTER_ID,
CustomDeviceTemperatureCluster,
)
from zhaquirks.sinope import SINOPE, SINOPE_MANUFACTURER_CLUSTER_ID


class KeypadLock(t.enum8):
Expand Down Expand Up @@ -458,7 +454,7 @@ class SinopeTechnologiesLoadController_V2(CustomDevice):
1: {
INPUT_CLUSTERS: [
Basic.cluster_id,
CustomDeviceTemperatureCluster,
DeviceTemperature.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
Expand Down Expand Up @@ -736,7 +732,7 @@ class SinopeTechnologiesCalypso(CustomDevice):
DEVICE_TYPE: zha_p.DeviceType.ON_OFF_OUTPUT,
INPUT_CLUSTERS: [
Basic.cluster_id,
CustomDeviceTemperatureCluster,
DeviceTemperature.cluster_id,
Identify.cluster_id,
Groups.cluster_id,
Scenes.cluster_id,
Expand Down
1 change: 0 additions & 1 deletion zhaquirks/tuya/ts0601_rcbo.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,6 @@ class TuyaRCBOManufCluster(TuyaMCUCluster):
TUYA_DP_TEMPERATURE: DPToAttributeMapping(
TuyaRCBODeviceTemperature.ep_attribute,
"current_temperature",
lambda x: x * 100,
),
TUYA_DP_REMAINING_ENERGY: DPToAttributeMapping(
TuyaRCBOMetering.ep_attribute,
Expand Down
2 changes: 1 addition & 1 deletion zhaquirks/xiaomi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ def _handle_attribute_event(
if hasattr(self.endpoint, "device_temperature"):
self.endpoint.device_temperature.update_attribute(
DeviceTemperature.AttributeDefs.current_temperature.id,
attributes[TEMPERATURE] * 100,
attributes[TEMPERATURE],
)

if BATTERY_PERCENTAGE_REMAINING_ATTRIBUTE in attributes:
Expand Down
13 changes: 0 additions & 13 deletions zhaquirks/xiaomi/aqara/airm_fhac01.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Quirk for LUMI lumi.airm.fhac01 air quality monitor."""

from zigpy.zcl.clusters.general import DeviceTemperature
from zigpy.zcl.clusters.measurement import CarbonDioxideConcentration

from zhaquirks.builder import QuirkBuilder
Expand All @@ -19,20 +18,8 @@ def _update_attribute(self, attrid, value):
super()._update_attribute(attrid, value)


class CustomDeviceTemperature(CustomCluster, DeviceTemperature):
"""Temperature measurement cluster that fixes the scaling issue."""

def _update_attribute(self, attrid, value):
"""Fix temperature scaling by multiplying by 100."""
if attrid == DeviceTemperature.AttributeDefs.current_temperature.id:
# The device reports temperature divided by 100, so multiply by 100
value = value * 100
super()._update_attribute(attrid, value)


(
QuirkBuilder(LUMI, "lumi.airm.fhac01")
.replaces(CarbonDioxideConcentrationCluster)
.replaces(CustomDeviceTemperature)
.add_to_registry()
)
Loading