Govee BLE Thermometer/Hygrometer sensor

Sensor for the Govee H5075, H5074 and H5072Bluetooth Thermometer/Hygrometer

This is a my first attempt as a custom component and a recipe for disaster as I am also new Python development and Home Assistant itself. I would appreciate any constructive criticism however I do know that hcitools and hcidump are deprecated. I am hoping the Alpine docker support for socket AF_BLUETOOTH in python standard lib would allow using Python natively to monitor Bluetooth advertisements and would be included in HASS at some point.

EDIT: H5074 support was added Feb 6,2020.
EDIT: H5072 support was added Jun 27,2020.
EDIT: As of V0.6, hcitool and hcidump have been removed as dependencies.
EDIT: H5051(ble only) and H5102 support added Sept 8,2020.
EDIT: H5177 verified to work
EDIT: H5179 support added Feb, 9, 2021

6 Likes

Hi @Thrilleratplay,

Thanks for putting this together! I obtained an H5075 and gave your component a try. After a couple tweaks for my setup, it’s successfully collecting data.

I’ve noticed one larger issue though – at least on my system, the averaging over a period functionality doesn’t seem to work. HASS gets an update for what appears to be every H5075 message, resulting in 3-20 state changes per minute. As such, I’ve accumulated 27,244 state changes for temperature over the last 48 hours (~10/min) and the same number for humidity. As you can imagine this has side effects like slowing down graph generation.

I’m not too well versed in python, so I may be missing something, but looking at discovery_ble_devices, I’m not seeing anything that would suppress the call to async_schedule_update_ha_state() from occurring on every message. It seems like the only qualification is that a temp/hum reading within bounds be present, which certainly seems to be the behavior I’m seeing.

In case it’s relevant, though I don’t think so, my setup is slightly modified in that my HASS host doesn’t have bluetooth locally, so I modified it to ssh to another host with the bluetooth interface and run hcitool/hcidump there. By default the component closes and reopens the interfaces on every cycle of discover_ble_devices, which was causing the BT hci interface to get hung up on the remote host (probably due to some issue with the way the connection/processes get shutdown), so I commented out scanner.stop and scanner.start. The SSH connections are now persistent and have been working fine (other than excess state changes, as mentioned above).

I might add a check to see if the connections are still open, and then do a slow restart, if not, so it can recover in the event the ssh connections go down.

Thanks again!

1 Like

I submitted a PR with a fix that works for me.

Thank you for noticing this. My database currently have 4.5M records from 5 govee devices running for a month. Like I commented in the PR, I am not sure why it is not obeying track_point_in_utc_time.

No problem, thanks for making the component! The H5705 is really responsive and fairly inexpensive so it’s nice to be able to use it.

As far as I can tell, it is obeying track_point_in_utc_time.

update_ble and thus discover_ble_devices(config) are being called once per minute on my system.

The excess updates problem is that discover_ble_devices loops through all the scanner messages (for msg in scanner.messages()) and if either m_temp or m_hum are true, it previously called sensors[x].async_schedule_update_ha_state().

Given that scanner.messages() returns all the BLE messages for the last collection period, m_temp and m_hum are true many times per discover_ble_devices call, and thus HASS gets the updated state many times. Now we just update HASS at the end of discover_ble_devices, outside the loop.

1 Like

I see it now. That explains it. Thanks.

Here is an example of how I have some of my thermometers displayed in using the lovelace-multiple-entity-row card.

govve_multiline

Here is the Entities Card Configuration:

entities:
  - entities:
      - entity: sensor.bedroom_temp
        name: null
    entity: sensor.bedroom_humidity
    icon: 'mdi:thermometer'
    name: Master Bedroom
    secondary_info:
      attribute: battery_level
      name: Battery
      unit: '%'
    type: 'custom:multiple-entity-row'
  - entities:
      - entity: sensor.bathroom_temp_2
        name: null
    entity: sensor.bathroom_humidity_2
    icon: 'mdi:thermometer'
    name: Bathroom
    secondary_info:
      attribute: battery_level
      name: Battery
      unit: '%'
    type: 'custom:multiple-entity-row'
1 Like

Hi i have the H5075 and i’m wondering how did you get the mac address of the device itself to yous in home assistant i’ve tried everything i could think of any help please

I run Linux and used sudo bluetoothctl scan on to find the MAC addresses. Apparently, Home Assistant my not have bluetoothctl or hcitool avaialble in a terminal depending on how you have it set up. I am not sure where in the documentation this is being referenced but if you look at this post it using BLE scanners available on the Google Play Store and for Windows in the Windows Store. I was able to use BLE Explorer from F-droid on my Android phone to find the MAC address. I am not sure what is available if you only have Apple products

1 Like

If you have a system with hcitool, which Home Assistant needs for the component to work, you can run the same command the component does. You may need to stop Home Assistant or run it with the custom component disabled while you scan.

hcitool -i hci0 lescan --duplicates --passive | grep -i Govee

You should see MAC starting with A4C138.

1 Like

Recently picked up an H5074, added a mac entry for it, but I’m not seeing any data for it. It shows up in the OrderedDict list of macs but there’s never any NEW DATA, DUPLICATE or updating sensor for its mac address.

If I run hcitool -i hc0 lescan --duplicates --passive on it I can see Govee-H5074_xxxx broadcasts regularly, so it’s not that the packets aren’t arriving.

Maybe the message contents are different than expected? Shows up in the Govee app and works normally. Any tips or info I can capture?

Edit: Firmware version says 1.01.00

The MAC address vendor prefix for the H5074 if different, I want first make sure that the address used does not start with A4:C1:38. My H5074 MAC starts with E0:12:1D however I am not sure how universal this is.

The only other suggestions I would have is try using adding hcitool_active: True to the sensor configuration. If that does not solve it, try rebooting the device to ensure there are no processes keeping a Bluetooth socket open in the background.

The MAC does indeed start with E0:12:1D. I tried hcitool_active: True with no change. The component is successfully picking up the broadcasts of other H5075 devices I have, just not the H5074.

I’m sorry, I cannot think of any other reason this would not be working.

Is your H5074 running the same firmware version? Wondering if the message format has changed.

I just double checked, it same firmware version.

Hrm. If I disable the check for 043E170201040 and instead just filter on 88EC, I get these result packets with the mac address matching my device.

2020-03-30 16:28:29 DEBUG (SyncWorker_9) [custom_components.goveetemp_bt_hci.sensor] {'rssi': -79, 'mac': 'E0121D61xxxx', 'temperature': 61.54, 'humidity': 652.69, 'battery': 136.0, 'packet': '180AFEF5'}
2020-03-30 16:28:29 DEBUG (SyncWorker_9) [custom_components.goveetemp_bt_hci.sensor] {'rssi': -78, 'mac': 'E0121D61xxxx', 'temperature': 61.54, 'humidity': 652.69, 'battery': 136.0, 'packet': '180AFEF5'}
2020-03-30 16:28:29 DEBUG (SyncWorker_9) [custom_components.goveetemp_bt_hci.sensor] {'rssi': -78, 'mac': 'E0121D61xxxx', 'temperature': 61.54, 'humidity': 652.69, 'battery': 136.0, 'packet': '180AFEF5'}

The parsed packet is:
043E2902010000xxxx611D12E01D02010607030A18F5FE88EC1109476F7665655F48353037345F44383043B2

Edit:
For reference, a valid reading from a 5075 sitting next to the 5074 was
{‘rssi’: -79, ‘mac’: ‘A4C138F2xxxx’, ‘temperature’: 19.5483, ‘humidity’: 48.3, ‘battery’: 88.0, ‘packet’: 195483}

If I remember correctly, there are three types of packets the H5074 broadcasts. The two others are similar but did not have all of the same data. The sensor is looking for a specific packet to parse, that is why the numbers are incorrect. Is the Govee app still connected to the H5074? I wonder if that packet is only broadcast when it is not connected.

The Govee app is not connected (bluetooth is disabled on the phone). From packets caught by the 88EC filter, the only thing that seemed to vary from that one-interval set was the last two bytes of the packet: A6, A7, B1, B2, B3.

From a btsnoop capture I took from my phone, I do see what appear to be 4 different packets with that MAC, though I’m not sure why only one type seems to be captured since at least 3 of the 4 have 88EC in them.

From the phone’s btsnoop:
043e2902010000xxxx611d12e01d02010607030a18f5fe88ec1109476f7665655f48353037345f44383043a2
043e2702010400xxxx611d12e01b1aff4c000215494e54454c4c495f524f434b535f485750740cd8c29f
043e2902010000xxxx611d12e01d02010607030a18f5fe88ec1109476f7665655f48353037345f44383043a7
043e1702010400xxxx611d12e00b0aff88ec0088078c116402a6

Yeah, for reasons unbeknownst to me, only the longest form messages (1st and 3rd) seem to be appearing in the scanner.messages() buffer.

The 2nd, nor the 4th (which I’m guessing is the needed one) don’t appear. Regardless of whether the Govee Home app is open or not. Weird.