Detecting rain

Hydreon RG-9


These are notes on a project that I am actively working on, and may change frequently.

This Hydreon RG-91 is a rain gauge that uses IR light sensors2 to detect rain falling on its curved plastic lens, and can reliably detect rain very fast.

Faster at detecting current rain than a "tipping-bucket" style sensor, more local and accurate than weather APIs.


I am using the RG-91 model, which is specifically designed for "is it raining now?"3 use cases.

The Hydreon RG-9 Solid State Rain Sensor is a rainfall sensing device intended to detect and communicate when a pre-selected rain intensity has been reached or exceeded. The RG-9 is rugged, reliable, and maintenance-free.

The RG-9 uses beams of infrared light within a plastic lens about the size of a tennis ball. The round surface of the lens discourages collection of debris, and the RG-9 has no moving parts to stick, and no water-pathways to clog.1

Hydreon also makes other models4 designed for other use cases5 (for example irrigation control and codensation sensing).

The rain gauge uses a serial protocol over UART6. There is also has an OUT header connected to open collector7 (NPN transistor) output.

The main output is NPN Transistor Collector, commonly known as an Open Collector.

When the output is activated (will differ on when this is done for the RG-9 and RG-15) the collector is pulled low and whatever load resistor is connected will also be pulled low.

The beauty of an open collector system is that it can be used for level translation. The internals of the RG-9 and RG-15 are 3.3VDC. You are not restricted to that range with the open collector. The only requirement is that the ground is common8.

— Hydreon RG-9 & RG-15 FAQ: What kind of output does the RG-9 and RG-15 have?

When the rain gauage detects rain, it will both send a command over the UART bus and pull the OUT pin LOW.


Supply voltage
Forward current (nominal)9
Forward current (raining)
Operating temperature range to
UART voltage
NPN transistor (OUT header) / / (max)


The J1 headers have screw terminals and are mounted horzontally, and does not have headers for the UART serial interface.

J1 GNDGNDSame as J2P1
J1 V+Power supplySame as J2P2

The J2 headers are standard Dupont dual-row 8P connectors with 2,54mm pitch.

J2P1GNDSame as J1 GND
J2P2Power supply, V+, voltage regulated. Same as J1 V+
J2P3NPN OUT, pulls HIGH for rainSame as J1 OUT
J2P7MCLRRestarts RG-9 if pulled HIGH
J2P8Bypasses voltage regulator

All of the headers in J1 are also available on J2.

ESPHome config

The rain guage uses UART for serial communication10, so first configure a UART bus:

  - id: ${uart_id}
      number: ${rg9_pin_tx}
      number: ${rg9_pin_rx}
    baud_rate: "9600"

Most ESP32 boards have 2+ hardware UART interfaces that can be used with any available GPIO pins. Avoid using any strapping pins, as they can be pulled HIGH/LOW on start.

The default baud rate used by the rain gauge for UART is 9600 bits/s, though it seems to support up to 57600bits/s9.

UART sensors

Then configure the hydreon_rgxx component for the sensor data that is read over serial:

  - platform: hydreon_rgxx
    model: "RG_9"
    id: "rg9"
    update_interval: 20s
    disable_led: false
      id: rg9_rain_lvl
      name: "Rain level"
      state_class: measurement
      name: "Device temperature"

  - platform: hydreon_rgxx
    hydreon_rgxx_id: "rg9"
      name: "Temperature status"
      name: "Lens status"
      name: "Emitter saturation"

Using the OUT header


This part is not working correctly at the moment.

To read the OUT pin, set up binary_sensor using the gpio platform.

  - platform: gpio
    id: rg9_rain_gpio
      number: "${rg9_pin_out}"
      inverted: true
        input: true
    name: "Rain detected GPIO OUT"
    entity_category: ""
    device_class: "moisture"
    publish_initial_state: true

The rain gauge will pull OUT to LOW to signal rain.

Template binary_sensors for rain detection

Use the template platform to create a binary_sensor using the rain level readings over UART:

  - platform: template
    id: rg9_rain_uart
    name: "Rain detected UART"
    device_class: moisture
    entity_category: "diagnostic"
    lambda: |-
      if (id(rg9_rain_lvl).has_state()) {
        int rain_lvl = id(rg9_rain_lvl).state;
        return rain_lvl > 0;
      else {
        return {};

To have one single sensor for "Is it raining?", make another binary_sensor using the template plateform:

  - platform: template
    id: rg9_rain
    name: "Rain"
    device_class: moisture
    lambda: |-
      bool uart = id(rg9_rain_uart).state;
      bool gpio = id(rg9_rain_gpio).state;
      return uart || gpio;
      #  Optionally set a delay for the binary_sensor to turn off
      - delayed_off: !lambda |-
          return id(rg9_rain_delay_off).state;

Using the MCLR pin

If you wired the MCLR pin, you can use that to restart the rain gauge:

  - platform: gpio
    id: rg9_mclr
    name: "${hostname} RG9 MCLR"
    entity_category: ""
      number: ${rg9_pin_mclr}
      - delay: 500ms
      - switch.turn_off: rg9_mclr

Since there is no button component for the gpio platform, you need to use an on_turn_on automation to pull the pin back to LOW after restarting the rain gauge.

Z-Wave tipping bucket: POPE700168

A tipping bucket-style Z-wave rain sensor.

Weather APIs

Using weather APIs.



RG-9 & RG-15 FAQ - Hydreon rain sensors, lists connector sockets for J2, input voltage specifications, open collector transistor specs and technical details.


Hydreon RG-15 rain sensor - Home Assistant forum: Information from Hydreon's support about power supply and how the models differ.


Home Assistant forum thread, posts from janick


Field Kit: Rain Gauge RG-9 - Mark Naylor's blog, The University of Edinburgh


UART button - ESPHome: send a pre-defined sequence of bytes on an UART bus.