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

Hello,

Recently i got myself some zigbee soil moisture sensors from AliExpress.
https://www.aliexpress.com/item/1005009760936017.html

Devices paired successfully with ZHA and exposed two sensors, humidity and temperature, as well as battery.

I placed two of them in some indoor flowerpots and started monitoring. The temperature sensor is supposed to measure ambient temperature and they look OK. The humidity sensor is supposed to measure soil humidity, and it is behaving weird. The spike on the yellow line is me watering the plants. The red sensor was placed the following morning, but both pots were watered at the same time. It doesn’t seem right to me that the soil is still saturated with water even after all those hours. Furthermore, it is constantly rising. Something is very odd here.

The blue lines are from another ambient temperature/humidity sensor in the same room, for reference.

I have two of those still unopened and i can use them for testing

1 Like

I don’t believe the Humidity means soil Humidity, it seems to me to mean air humidity.
There should be a sensor that tells you moisture, and it appears to be missing.

These are likely Tuya based sensors, so you would have to ask the Tuya Spirits where that sensor is, but that is my guess. Does the Tuya smart life app show a moisture sensor on these?

1 Like

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

Haven’t tried the Tuya app as i don’t have a Tuya zigbee gateway. I will try the quirk suggested by @pluggedinn. I don’t think that the sensor is measuring ambient humidity as it doesn’t correspond at all with the humidity measured by the other humidity sensor i have in the room. Maybe the devices are just broken, or they require a quirk to function properly.

I re-paired the devices with the coordinator yesterday and the measurements looked kind of normalized. The red one required two attempts. I also added another one in a third pot for comparison. There is a spike this morning from watering (just slightly, for testing).

I have a fourth one that i will try to use as a testing device. Move it from pot to pot, submerging it in water directly, leaving it in the open…

I will try this later. Is re-pairing of the devices required or just a HA restart is enough?

UPDATE

  • Applied the quirk provided by @pluggedinn
  • Restarted HA
  • Devices received one additional sensor named Soil Moisture

The values are still funny

I’ll give it some time

1 Like

I had to delete the device and re-pair it yes. My values are pretty accurate for my room humidity (in this case showed as Soil temperature :roll_eyes:). Probably off by 2% from my other humidity sensors in my room.

1 Like

This quirk seems to be working better for me:
https://raw.githubusercontent.com/nschimme/zha-device-handlers/a9059575d5ec1ad1c43535f8fcec69830b38b15f/zhaquirks/tuya/tuya_sensor.py

Found Here:

It seems to get the humidity and soil moisture sensors correct.
It also adds a moisture alarm, and a bunch of configuration to calibrate the sensors.

I had to remove and re-pair after installing the quirk.

2 Likes

Hey, thanks for this. I am having some problems, it keeps saying 0% in soil moisture (humidity and temp shows what i believe is correct values), and moisture is dry. first it said unknown, then I removed them and they re-paired automatically, and got 0% value instead. Am I missing something?

It’s the same on both ZG-303Z that I bought.

Edit; Tried some different offsets without success, and picture attached

How exactly do you calibrate this device? I put it in a glass of water and it said 100% moisture so…great, but in some damp soil it says 3% and dry. But its damp. Soooo…IDK :slight_smile:

the same, shows moisture always 0.0%

Yep think this will be a return, they don’t seem to work very well or at all.

1 Like

yep gave up and returned. The moisture sensor would spike with watering, drop to 20% and then stay there for a week. Maybe with some calibration they’d work but no idea how to do this.

1 Like

Finally found some time to test this quirk.
Looks like it did the trick. Apart from exposing a bunch of sensors, it looks like that soil humidity behaves in a logical manner. Here are the 3 active sensors right after HA restart and Zigbee devices re-pair and watering the pots…

An expected spike in the soil humidity and then a decline. The decline rate depends on the actual pot and the various combinations of pot size, plant root system, soil density and such.

And the sensor list…

I will be monitoring this in the following days

I am having an issue with this sensor as well. Not sure if I need to update something, but what is going on is that the “Dry” flag is not set to true when the soil moisture goes below the “Soil Warning” threshold. I may be misinterpreting how this works, but I am lost on where to look
Any help would be greatly appreciated
Thank you

Hi
Sorry, quirck question, how to enable this quirk?
If I only copy the tuya_sensor.py file, it complains about endpoint_id as it seems some other changes happened in the QuirkBuilder.
Is there some other files to bring in?

This looks like a great quirk, but I cannot get it to load.
I have it in /homeassistant/zha_quirks/tuya_sensor.py
And my configuration.yaml is set to:
zha:
custom_quirks_path: /config/zha_quirks/

Whenever I re-add the device, I get the Quirk: zhaquirks.tuya.builder.EnchantedDeviceV2

The behavior is the same with me, on ZHA (you have Z2M).

I just installed this HACS addon with all the optional integration and i don’t have the need for that sensor. Configured properly, it downloads the moisture data from an Internet database and creates alarm statuses based on the actual plant species.

GitHub - Olen/homeassistant-plant: Alternative Plant component of home assistant · GitHub

Final update on this topic. I’ve been fiddling for a week with the sensors, doing tests, posting data to Gemini, analysing the data and the conclusion is the following:

  • The sensors work fine
  • Erratic behaviour is due to my misunderstanding how the sensors are supposed to work and how plant biology works with different species, different soil types and different pots
  • The way you pour water in the pot makes a difference
  • The sensor should not be treated as a thermometer style of sensor. Values should be interpreted in broader context, not as an instant reading of the current state


According to Google Gemini, this chart, together with some photos of the plans, the soil, and the environment, shows normal and healthy behaviour of both the plants and the sensors.

Started with removing the sensors to record 0%. I tested this previously and they always record 0% outside the pot and 100% submerged in water. When re-seating the sensors in the pot there are some considerations:

  • The blade should be placed vertically in the soil
  • The sensor should be positioned midway between the plant root and the edge of the pot
  • One must ensure firm contact between the sensor blade and the soil, pressing the soil to the blade by hand, if needed

Once properly seated, the sensors need some time to “settle in”. It takes time for capillary action to re-distribute moisture into the disturbed soil around the sensor. It usually takes 24 - 48 hours for this to happen. This is why frequent sensor removal or physical disturbance should be avoided. Capacitive sensors create an electromagnetic field in the soil immediately surrounding the blades. Moving them breaks the “bond” with the soil structure and resets the electrical baseline. If removal/disturbance is necessary, once should take note of this and interpret the data accordingly.

After about a day i watered the plants, that is the recorded peak on the chart. Depending on the actual water flow in the pot, the type of plant, soil and pot, the content of the “water”, whether it is clean water or has fertilizer in it (mine had some aquarium water for some flowers), the readings would be different. Some will peak, and start do decline, as the plat is sucking in the moisture, with or without a small climb (like the red Snake Plant or the yellow Yucca here). Heavy fertilization may oversaturate the sensor. The Yucca’s soil is good, not “swampy” as the numbers might indicate. Some will rise sharp and continue to climb. In some cases, the sensor will record water movement inside the plant as increased soil moisture (the Ficus and the Peace Lilly). As long as the rise stops and transforms into a decline, all should be good.

Changes in soil moisture should be observed in tandem with the changes in the local air moisture in and around the pot (that is why most devices like this have those sensors as well). The plant feeding process include a transpiration phase where the plant releases excess water through the leaves.

One final note. All sensor data should be verified in person. Inspect the soil, try to estimate using fingers or a stick. Also, have in mind that these processes are slow. Waiting a day to confirm the moisture trend should not kill the plant. Overwatering it, on the other hand, will.

Happy gardening!