Aqara W600

Hi,

Functionality (in ZHA) for the W600 is at this time extremely limited. You cannot set the temperature. This makes it not very useful.

I do not call this an integration. I only installed HA two weeks ago. I am experienced in Java, not in Python. Nevertheless.

The quirk included below seems to make it possible to

  • set the temperature
  • read local temperature
  • set local temperature calibration
  • set min temp
  • set max temp

Notes:

  • The issue with the default temp circle mentioning ‘inactive’ has not been resolved.
  • Not production ready code, may be an inspiration. It did not crash my machine, may it will yours.
  • Manufacturer specific attributes, it seems almost impossible to get those to work.
  • Remove the two blocks at the bottom where indicated.

regards,

Jan-Willem

from zigpy.quirks.v2 import QuirkBuilder
(
    QuirkBuilder("Aqara", "lumi.airrtc.aeu005")
    # interesting stuff in between
    .add_to_registry()
)

"""  thermostat_wt-a03e_jw02 """

# first attempt to add a simple attribute

# occupied_heating_setpoint
from typing import Final
from zigpy.quirks import CustomCluster
import zigpy.types as t
from zigpy.zcl.foundation import ZCLAttributeDef
from zigpy.quirks.v2.homeassistant import UnitOfTime
from zigpy.quirks.v2.homeassistant import UnitOfTemperature
from zigpy.quirks.v2.homeassistant import EntityType
from zigpy.zcl.clusters.hvac import Thermostat
from zigpy.zcl.clusters.general import AnalogInput

from zigpy.quirks.v2 import (
    QuirkBuilder,
    ReportingConfig,
    NumberDeviceClass,
    SensorDeviceClass,
    SensorStateClass
)



class SystemMode(t.enum8):
    Off = 0x00
    Auto = 0x01
    Cool = 0x03
    Heat = 0x04


class DisplayFlip(t.enum8):
    Off = 0x00
    On = 0x01


class ThermostatCluster(CustomCluster, Thermostat):

    class AttributeDefs(Thermostat.AttributeDefs):
        temp_setpoint_hold_duration: Final = ZCLAttributeDef(
          id=0x0024, type=t.uint16_t, access="rw")
        occupied_heating_setpoint: Final = ZCLAttributeDef(
          id=0x0012, type=t.int16s, access="rwp")
        system_mode: Final = ZCLAttributeDef(
          id=0x001c, type=SystemMode, access="rwp")


class ManufacturerSpecificCluster(CustomCluster, Thermostat):
    """manufacturer-specific cluster."""

    cluster_id = 0xFCC0
    name = "Aqara Manufacturer Specific"
    ep_attribute = "aqara_manufacturer_specific"

    class AttributeDefs(Thermostat.AttributeDefs):
        display_flip: Final = ZCLAttributeDef(
          id=0x0330, type=DisplayFlip, access="rwp",
          is_manufacturer_specific=True)
        child_lock: Final = ZCLAttributeDef(
          id=0x0277, type=t.uint8_t, access="rwp",
          is_manufacturer_specific=True)
        state: Final = ZCLAttributeDef(
          id=0x0271, type=t.uint8_t, access="rwp",
          is_manufacturer_specific=True)          
        calibrate: Final = ZCLAttributeDef( 
          id=0x0270, type=t.uint8_t, access="rwp",
          is_manufacturer_specific=True)
(
    QuirkBuilder("Aqara", "lumi.airrtc.aeu005")
    .replaces(ThermostatCluster, endpoint_id=1)
    .number(
        attribute_name=ThermostatCluster.AttributeDefs.temp_setpoint_hold_duration.name,  # JW: id = 0x0024
        cluster_id=ThermostatCluster.cluster_id,  # // JW: cluster = 0x0201
        endpoint_id=1,
        device_class=NumberDeviceClass.DURATION,
        unit=UnitOfTime.MINUTES,
        entity_type=EntityType.CONFIG,
        translation_key="temp_setpoint_hold_duration",  # JW: no idea of a translation key
        fallback_name="Min. constante periode - by JW",
        min_value=0,
        max_value=65535,
        step=1
    )
    .number(
        attribute_name=ThermostatCluster.AttributeDefs.occupied_heating_setpoint.name,  # JW: id = 0x0012
        cluster_id=ThermostatCluster.cluster_id,  # // JW: cluster = 0x0201
        endpoint_id=1,
        device_class=NumberDeviceClass.TEMPERATURE,
        unit=UnitOfTemperature.CELSIUS,
        translation_key="Heating",  # JW: wild guess
        fallback_name="Verwarmen",
        min_value=5,
        max_value=30,
        step=0.5,
        multiplier=1
    )
    .sensor(
        attribute_name="local_temperature",  # JW: id = 0x0012
        cluster_id=ThermostatCluster.cluster_id,  # // JW: cluster = 0x0201
        endpoint_id=1,
        state_class=SensorStateClass.MEASUREMENT,
        device_class=SensorDeviceClass.TEMPERATURE,
        unit=UnitOfTemperature.CELSIUS,
        reporting_config=ReportingConfig(
          min_interval=10, max_interval=120, reportable_change=1),
        multiplier=0.01,
        translation_key="Temperature",  # JW: wild guess..
        fallback_name="Temperatuur"
    )        
    .enum(
        attribute_name=ThermostatCluster.AttributeDefs.system_mode.name,
        cluster_id=ThermostatCluster.cluster_id,
        enum_class=SystemMode,
        entity_type=EntityType.CONFIG,
        translation_key="Mode",  # JW: wild guess
        fallback_name="Modus"
    )
    .switch(  # does not work: remove before integration
        attribute_name=ManufacturerSpecificCluster.AttributeDefs.state.name,
        cluster_id=ManufacturerSpecificCluster.cluster_id,
        endpoint_id=1,
        entity_type=EntityType.CONFIG,
        translation_key="State",  # JW: wild guess
        fallback_name="Status"
    )    
    .switch(  # does not work: remove before integration
        attribute_name=ManufacturerSpecificCluster.AttributeDefs.child_lock.name,
        cluster_id=ManufacturerSpecificCluster.cluster_id,
        endpoint_id=1,
        entity_type=EntityType.CONFIG,
        translation_key="Lock",  # JW: wild guess
        fallback_name="Slot"
    )
    .add_to_registry()
)

I’ve started playing around with HA and Aqara devices. The quirk I came up with allows to set the temperature as shown in the screenshots:

You can find the quirk here: homeassistant/custom_zha_quirks/aqara_w600_trv.py · develop · Joerg Hampel / My Personal HA Setup · GitLab