Govee WiFi Water Sensor

I just started out with Home Assistant and this was one of my first real projects to get set up. Everyone’s information here and a few other places were invaluable in getting this working. However, it seemed a bit piecemeal where I was grabbing bits of information from different comments and pages trying to put it all together. So hopefully I can assemble it a little bit for someone else like me who’s not as familiar with the individual parts of getting something like this running.

My setup has Home Assistant and all of the relevant services running in docker-compose, so I don’t have access to any of the add-ons. I picked up the Nooelec NESDR Mini 2+ RTL-SDR dongle and 10 of the Govee water sensors.

My first hurdle was getting rtl_433 running so I could receive the messages from the devices. As I mentioned, I have no access to add-ons which seems to be where most suggestions lead to. Exploring that and a few others that seemed like they added some unnecessary complexity for docker, I discovered GitHub - hertzg/rtl_433_docker: Repository containing multiarch docker images definitions of rtl_4 which just builds and runs the binary with no special logic or fluff, since I found out rtl_433 already supports MQTT. The doc suggests using the specific usb bus but that can change, so I just gave the whole thing.

#docker-compose

  rtl-433-mqtt:
    image: hertzg/rtl_433
    restart: unless-stopped
    volumes:
      - /host/path/to/rtl-433-mqtt:/etc/rtl_433
    devices:
      - /dev/bus/usb:/dev/bus/usb
    environment:
      - TZ=America/New_York

Note: as of writing, the latest image is missing a library. I’m using tag alpine-3.13-21.05 until it’s fixed.

#rtl_433.conf

#config_file
config_file /etc/rtl_433/govee_rm433.conf

report_meta level
report_meta noise
report_meta stats
report_meta time:iso:usec:utc:tz
report_meta protocol

output mqtt://mosquitto:1883,user=USER,pass=PASS,retain=1,events=rtl_433[/model][/id][/subtype]

convert si

The important parts are the link to the second config file and the output, which defines the MQTT broker and the topic. Subtype is one of the few variables supported for value expansion for the topic, and it’s what I use for grouping the messages as one of sensor, battery, or heartbeat.

#govee_rm433.conf

decoder {
    name=Govee_H5054,
    modulation=OOK_PWM,
    short=440,
    long=940,
    reset=9000,
    gap=900,
    bits=48,
    get=id:@0:{16},
    get=subtype:@16:{16}:[1285:sensor 1028:sensor        1022:battery 999:battery    997:battery    950:battery    956:battery    964:battery    923:battery 514:heartbeat],
    get=event:@16:{16}:[  1285:button 1028:leak_detected 1022:empty   999:25_percent 997:50_percent 950:75_percent 956:75_percent 964:75_percent 923:full    514:heartbeat],
    unique
}

I got this decoder from this comment on the rtl_433 github, but modified it so that I could use retain and have the values saved individually on separate topics. So my entities’ values would survive restart.

Now on the home assistant side I made two entities for each of my physical sensors, a binary_sensor and a battery sensor.

#binary_sensors.yaml

- platform: mqtt
  name: "Water Heater Water Sensor"
  state_topic: "rtl_433/Govee_H5054/ID/sensor"
  unique_id: "Govee_H5054_ID"
  icon: mdi:water
  payload_on: "leak_detected"
  payload_off: "button"
  value_template: "{{ value_json.event }}"
  json_attributes_topic: "rtl_433/Govee_H5054/ID/+"
  json_attributes_template: >
    {
      "id": "{{ value_json.id }}",
      "model": "{{ value_json.model }}",
      {%- if value_json.subtype == "heartbeat" %}
        "heartbeat": "{{ as_timestamp(value_json.time) | timestamp_custom("%Y-%m-%d %H:%M:%S.%f") }}",
      {%- endif %}
      "time": "{{ as_timestamp(value_json.time) | timestamp_custom("%Y-%m-%d %H:%M:%S.%f") }}"
    }

Like others, I use the button to turn it off instead of a timeout. I want to make sure someone goes and checks on it. I like having the id and model as attributes for if I need to reference things in the future. Also, I plan on making an automation to send a notification to check on the device if time is older than a month. I haven’t seen any heartbeat messages so I probably won’t be able to rely on that.

#sensors.yaml

- platform: mqtt
  name: "Water Heater Water Sensor Battery"
  state_topic: "rtl_433/Govee_H5054/ID/battery"
  unique_id: "Govee_H5054_ID"
  device_class: battery
  unit_of_measurement: '%'
  value_template: >
      {%- if value_json.event == "full" -%}
        100
      {%- elif value_json.event == "75_percent" -%}
        75
      {%- elif value_json.event == "50_percent" -%}
        50
      {%- elif value_json.event == "25_percent" -%}
        25
      {%- elif value_json.event == "empty" -%}
        0
      {%- endif %}
  json_attributes_topic: "rtl_433/Govee_H5054/ID/+"
  json_attributes_template: >
    {
      "id": "{{ value_json.id }}",
      "model": "{{ value_json.model }}",
      {%- if value_json.subtype == "heartbeat" %}
        "heartbeat": "{{ as_timestamp(value_json.time) | timestamp_custom("%Y-%m-%d %H:%M:%S.%f") }}",
      {%- endif %}
      "time": "{{ as_timestamp(value_json.time) | timestamp_custom("%Y-%m-%d %H:%M:%S.%f") }}"
    }

image

Then I set up a simple automation to watch for any of them turning on.

#automation

alias: Water Sensor Alarm
description: ''
trigger:
  - platform: state
    entity_id:
      - binary_sensor.water_shutoff_water_sensor
      - binary_sensor.water_heater_water_sensor
    to: 'on'
    from: 'off'
condition: []
action:
  - service: script.emergency_alarm
    data:
      title: Water Detected
      message: >-
        Water was detected by the {{ state_attr(trigger.entity_id,
        'friendly_name') }}
mode: single

This calls a script I set up for any emergency messages, which sends TTS and an alarm to my wife and I.

#script

alias: Emergency Alarm
description: Send an emergency alert notification to all devices and TTS the message
mode: queued
max: 10
icon: mdi:alert
fields:
  title:
    description: Title of the notification
    example: Alarm!
  message:
    description: The message content
    example: The house is on fire!
sequence:
  - service: notify.all_devices
    data:
      title: '{{ message }}'
      message: TTS
      data:
        ttl: 0
        priority: high
        channel: alarm_stream_max
  - service: notify.all_devices
    data:
      title: '{{ title }}'
      message: '{{ message }}'
      data:
        ttl: 0
        priority: high
        channel: alarm_stream_max

I don’t know if that was all overly verbose, but hopefully it saves someone else a bit of time.

1 Like

Thanks to CodingSquirrel’s detective work, I’ve managed to get the rtl_433 hassio addon by pbkhrv working beautifully with minimal configuration and easy access to multiple (or all) sdr protocols. Just use the cofiguration in the post above me, and save the config to config/rtl_433/rtl_433.conf. I was unable to get any battery readings. Maybe they are infrequent?

Modify the govee sensor line in rtl_433.conf to read the following, and also save govee_433.conf to this location:

config_file /config/rtl_433/govee_433.conf

To avoid logging tire pressure readings and other random nonsense from my neighborhood, I also modify rtl_433.conf to limit the protocols it logs to acurite (protocol 40) and govee (via the custom file above) by adding this to the config file. You can add others by repeating the same thing multiple times.

protocol 40

For my leak notification, I use the following:

- id: leak
  alias: WATER Leak!
  trigger:
    platform: state
    entity_id: binary_sensor.leak_guest_bedroom, binary_sensor.leak_kitchen_sink, binary_sensor.leak_dishwasher, binary_sensor.leak_master_bath
    to: 'on'
  action:
    service: notify.mobile_app_pixel
    data_template:
      message: '{{ trigger.to_state.attributes.friendly_name }} detected water'

Hey all.

I picked up a few of the Govee sensors and base station.
I was reading the above chat but didnt see where anyone was modding / flashing the Govee hub.

From what I can tell it uses a ESP8266EX with a CMT2210LB for the RF decoding. It looks like the demodulated data from the CMT chip is routed to pin 10 of the ESP8266EX.

Deos anyone know what I would need to get this working?

Note the Serial lines are easily accessible for programming with esphome.

Battery readings are sent when you put batteries in and when the state changes. The easiest way to get one is to remove and put back in one of the batteries. Conveniently, this means it’s sent when you first remove the pull tab. So if you have retain set to true then you don’t even have to open it up when setting up a new one (assuming you have rtl_433 configured and running first).

Well shit, you’re right. I reluctantly pulled the batteries on one of them and it reported a few seconds later. Now I’m debating pulling another 16 screws (4 per unit!) or just letting them read unavailable for a few months until they dip to 75%. I think I’m taking the lazy option. Thanks again!

I was able to get the govee working with rtl_433, but for some reason it crashes on me after a few hours. Does anybody else have this problem? Im not sure if its related to the 2nd conf for the govees or not. Does anybody know how i can restart rtl_433 along with a -c command whenever it crashes?

anyone have the H5179001 ?

I have one of these.

1 Like

After upgrading to the latest Home Assistant, all of my previously working binary leak sensors are now showing as unknown. When you push the test button, they show up again. It appears to be related to this breaking change?

Previously, binary_sensor entities could have the state on, off, and in case the device was unreachable: unavailable.

However, compared to other entities, it wasn’t able to have the unknown state, which has been added this release.

So, a binary_sensor entity can now have the on, off, unavailable, or unknown state.

You might need to adapt your automations or scripts to take this new unknown state into account.

Any idea how to fix this or change new unknown to off? Below is my code:

binary_sensor:
  - platform: mqtt
    unique_id: 8877698c-5ec1-436e-8977-5171599c982d
    state_topic: rtl_433/Govee-Water/35794/event
    json_attributes_topic: rtl_433/Govee-Water/35794
    name: "Basement Utility Leak Sensor"
    device_class: moisture
    payload_on: "Water Leak"
    payload_off: "Button Press"

Thanks

Noticed today that I have the same issue. Ever find a fix?

Unfortunately I personally have not. Although hitting the button returns them to off. Not sure how long that lasts

@seasideCT Thank you for highlighting this. I think you are correct in your diagnosis of the issue’s origin. The docs were updated to clarify as well: “… the initial state displayed in Home Assistant will be unknown .”

It took a month for me to realize I had this issue. I’m going to have to also update some notifications that should occur if critical sensors are unavailable or unknown!

I have quite a few binary sensors it seems that the 2022.2.x applies to, including the govee ones. I am using the mqtt implementation through the Sonoff RF bridge for the govee sensors. The solutions I have thought of initiall (though have not tried yet):

  • Update RF bridge to send retain messages
    • Though, I don’t think this will work because I am using an off_delay: to turn off my sensor
  • Update a payload template to default to off unless the on payload is received.
  • Set the state upon start up with an automation.
    • I am not seeing an easy way to do this. There doesn’t seem to be a “set state” service. (like what you can do in the developer tools)
  • Add availability info to the sensors.
    • I am thinking of trying to either, make the sensors always online, or make the sensor availability linked to if the RF bridge is online.
    • This is the solution that is probably ‘best practice’ barring a deciphering of periodic codes sent by the sensors themselves

Here is my yaml binary sensor:

  - platform: mqtt
    state_topic: "tele/SonoffRFBridge/RESULT"
    name: "Govee Water 1"
    unique_id: "xxxxxxxx" 
    device_class: moisture
    value_template: '{{value_json.RfReceived.Data}}'
    payload_on: 'ACBFFB'
    off_delay: 10
    qos: 1
1 Like

-deleted-
I created a new topic for my question here:

MQTT State - Configuration - Home Assistant Community (home-assistant.io)

Hopefully it is ok to bring up an older post. Have any of you encountered issues with reading these on with RTL_433?

Using RTL_433 with a USB sdr or OpenMQTTgateway with RTL_433 only one device outputs as expected. I have 4 others from the same batch that do not report anything. I purchased a second set and they too do not report anything.

I have a SONOFF RF bridge with ESPHome on it and it does report more raw data like
code: efb8fb
code: fffffb
I have been using those in my automations but do not feel like this is the most reliable approach. I have just ordered the Govee WiFi set will see if it works as advertised in the state I don’t like (running from app on phone). I would like to use the API but that doesn’t seem promising for my skill set. Has anyone tried to use the API?

EDIT:
Got the official WiFi half of it, one device paired without issue and reports “button pressed” in rtl_433 but 4/5 did not pair so I suspect this batch had something really off about them.

1 Like

No mqtt data coming in from a 5 pack I purchased as well. I’m tracking an issue on github it looks like a board revision was made and the commands were changed.

Can see my acurite temp sensors and my home security sensors

if they get govee wifi water sensor working, i hope they can get govee wifi hygrometer working

hey - anyone have a yaml example of the battery for sonoff rf bridge (not rtl_433)

I don’t know if this helps anyone, but I just connected mine up to Alexa with no issue at all, and then I just have my Alexa trigger whatever I need done. For some things, Home Assistant just sucks. I couple Home Assistant, Alexa, and many other automations and usually one or another works for me. If HA is the only good way (Like for Govee Home switches), I just have it turn on/off a different switch that my Alexa can see, then have Alexa trigger the things that HA is too difficult to setup. I didn’t want to buy another dongle, so this works for me. I’m having my Alexa turn off my main water valve if there’s a leak detected in the basement or behind my washer and dryer. I used to use IFTTT for that, but ever since they started charging, I dropped it and just use Alexa.

How did you connect the H5040 to Alexa? I don’t where that device is supported.

Hello -

Sorry if this is an old Thread but i got some Govee Wifi Water Sensors, they work fine in the app and everything, but i would like to bring them into home assistant, to eventually add a water valve close on water detection, i have a RTL 433 USB v5 stick and i plugged it in, added the two addons, and this is where i am at… i am unable to view RTL 433 devices into MQTT Explorer?

see below log from RTL 433
Starting rtl_433 with rtl_433.conf…
[rtl_433] rtl_433 version 23.11-168-g322e04ff branch master at 202410160342 inputs file rtl_tcp RTL-SDR
[rtl_433] MQTT: Publishing MQTT data to 192.168.1.7 port 1883
[rtl_433] MQTT: Publishing device info to MQTT topic “rtl_433/9b13b3f4-rtl433-next/devices[/type][/model][/subtype][/channel][/id]”.
[rtl_433] MQTT: Publishing events info to MQTT topic “rtl_433/9b13b3f4-rtl433-next/events”.
[rtl_433] MQTT: Publishing states info to MQTT topic “rtl_433/9b13b3f4-rtl433-next/states”.
[rtl_433] Use “-F log” if you want any messages, warnings, and errors in the console.
[rtl_433] Found Rafael Micro R820T tuner
[rtl_433] Exact sample rate is: 250000.000414 Hz
[rtl_433] [R82XX] PLL not locked!

from RTL 433 Auto Discovery
Starting rtl_433_mqtt_hass.py…
[2024-10-21T09:59:08-0400] INFO:root:Discovering all devices
[2024-10-21T09:59:08-0400] INFO:root:MQTT connected: Connection Accepted.
[2024-10-21T09:59:08-0400] INFO:root:Subscribing to: rtl_433/+/events
s6-rc: info: service legacy-services: stopping
s6-rc: info: service legacy-services successfully stopped
s6-rc: info: service legacy-cont-init: stopping
s6-rc: info: service legacy-cont-init successfully stopped
s6-rc: info: service fix-attrs: stopping
s6-rc: info: service fix-attrs successfully stopped
s6-rc: info: service s6rc-oneshot-runner: stopping
s6-rc: info: service s6rc-oneshot-runner successfully stopped
s6-rc: info: service s6rc-oneshot-runner: starting
s6-rc: info: service s6rc-oneshot-runner successfully started
s6-rc: info: service fix-attrs: starting
s6-rc: info: service fix-attrs successfully started
s6-rc: info: service legacy-cont-init: starting
s6-rc: info: service legacy-cont-init successfully started
s6-rc: info: service legacy-services: starting
s6-rc: info: service legacy-services successfully started
[2024-10-21T11:34:25-0400] INFO:root:Discovering all devices
[2024-10-21T11:34:26-0400] INFO:root:MQTT connected: Connection Accepted.
[2024-10-21T11:34:26-0400] INFO:root:Subscribing to: rtl_433/+/events

Current Config on RTL 433
output mqtt://192.168.1.7:1883,user=mqttuser,pass=Parolamqtt -C si

Let me know what i need to do … thanks!

Running Home Assistant on Synology Nas with Virtual Machine…