Zigbee soil moisture sensor (ZG-303Z by HOBEIAN)

I got this to work using this zha quirk. The only thing that is off is that the Humidity and the Soil moisture are swapped. Could be worse.
Reference to this to how to install zha quirks.

"""HOBEIAN ZG-303Z Soil Moisture Sensor quirk."""

from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import Basic, Identify, PowerConfiguration
from zigpy.zcl.clusters.measurement import RelativeHumidity, SoilMoisture, TemperatureMeasurement

from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    MODELS_INFO,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
)
from zhaquirks.tuya import TuyaLocalCluster
from zhaquirks.tuya.mcu import (
    DPToAttributeMapping,
    TuyaMCUCluster,
)


class TuyaSoilMoistureCluster(TuyaLocalCluster, SoilMoisture):
    """Tuya Soil Moisture cluster."""

    cluster_id = SoilMoisture.cluster_id


class SoilMoistureMCUCluster(TuyaMCUCluster):
    """Tuya MCU Cluster for ZG-303Z Soil Moisture Sensor."""

    dp_to_attribute: dict[int, DPToAttributeMapping] = {
        109: DPToAttributeMapping(
            TuyaSoilMoistureCluster.ep_attribute,
            "measured_value",
            converter=lambda x: x * 100,
        ),
    }

    data_point_handlers = {
        109: "_dp_2_attr_update",
    }


class HobeianZG303Z(CustomDevice):
    """HOBEIAN ZG-303Z Soil Moisture Sensor."""

    signature = {
        MODELS_INFO: [("HOBEIAN", "ZG-303Z")],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: 0x0302,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    Identify.cluster_id,
                    TemperatureMeasurement.cluster_id,
                    RelativeHumidity.cluster_id,
                    0xEF00,
                ],
                OUTPUT_CLUSTERS: [
                    Identify.cluster_id,
                ],
            }
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: 0x0302,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    Identify.cluster_id,
                    TemperatureMeasurement.cluster_id,
                    RelativeHumidity.cluster_id,
                    TuyaSoilMoistureCluster,
                    SoilMoistureMCUCluster,
                ],
                OUTPUT_CLUSTERS: [
                    Identify.cluster_id,
                ],
            }
        }
    }
2 Likes