Govee BLE Thermometer/Hygrometer sensor

Home Assistant in May tried to “end of life” running it on a generic Linux platform, prefering their OS (the name has changes a few time in the past few months so I am not sure what they call it any more, HASS Home Assistant Operating System, something). After they relized how popular that method was, they stepped back and released it as supervised-installer. This is what I want running on an Rpi4 until July when I redid it using a straight Rpi4 HA install. Using Debian instead of HASS has its quirks but let me has a little more contro but became buggy over time as HA moved away from that install method. You are adding another layer by virtualizing the platform as well. I am not sure if you installed the full superior set up or only Home Assistant Core. There are too many variables that can be interfering or not playing nice with each other. What I would not suggest doing is running Home Assistant on Docker for Mac. I used to use that for work and man did it have bugs and that was without privileged mode you would need to run it in to access the bluetooth adapter. I would suggest using a prebuilt VM which is built on Home Assistant’s Operating system to remove at least one variable.

Additionally, the setcap command is for those who are running HA core directly on the operating system. As the docker containers will have their own version of python, changing the permission on the host python will not make any difference. You can try to enter the containers via Ubuntu or a HA terminal plugin but, at least on my instance setcap isn’t even an available command.

I use Home Assistant Core in a docker container on Ubuntu 20.04 LTS installed directly on an Intel Mac mini. It worked/works fine with both the internal bluetooth and the single I recommended earlier in the thread. I actually use that dongle in a separate HP MicroServer. I wanted bluetooth in HASS working on both so I could handle outages/maintenance of one or the other.

Home Assistant Core seems well supported still as a docker container (I don’t use Supervised). Like most troubleshooting involving layered systems, I recommend verifying at each layer that bluetooth is functional. So make sure you can see bluetooth traffic inside the Ubuntu VM using hcitool (as root) before trying get it accessible within docker.

With the permissions I use for my docker setup, iirc it was necessary to supply my own hcitool/hciconfig binaries (via a mount) that had had the recommended permissions set on them from outside the container. I generally try to keep docker permissions at a minimum. Agree in not trying to deal with Docker for MacOS. On mobile right now, so when I get back to a computer I’ll try to verify what I have in place.

1 Like

Are you still using V0.5 or have you updated yet? Since v0.6, hcitool/hciconfig have not been necessary.

Definitely still on V0.5.

let me know – Im new to hcitool but i’m curious to how to see traffic.

  • If i do a hcitool dev – i see hci0 00:1A:7D:DA:71:13
  • if i do a hcitool scan or hcitool inquire, i just get scanniing… or Inquiring… for what seems to be forever.
  • however bluetoothctl scan on does return devices in range.
1 Like

Thanks to this awesome component and work by @Thrilleratplay to figure out how to decode the ble packets, I found a way to do this within esphome with esp32 hardware:

1 Like

@Thrilleratplay The Govee app allows for calibration value changes, how do I change value in the component, I did the salt calibration (75%) on two of my sensors and noticed that they are below by 1 or 2%, how do I add that to the sensor value?

I do not know. The component only collects the data. There may be a way to alter the way Home Assistant displays the data but that is outside of the scope of the component.

Sorry for the delay, I ended up without access for a little while.

I have this as part of my Home Assistant docker image build (Dockerfile):

RUN apk add libcap && setcap 'cap_net_raw+ep' `readlink -f \`which hcidump\`` && setcap 'cap_net_raw+ep' `readlink -f \`which hcitool\``

The container itself is run in host networking mode, as a non-root user. HASS itself is run within a venv (in the container) so that the non-root user can install the necessary python packages etc.

Again this shouldn’t be necessary for newer versions of the component (>0.5) as they don’t use hcitool/hciconfig anymore. It works on both my Intel Mac Mini running Ubuntu 19.10, with HASS in a non-root docker container, with the built-in bluetooth or a USB bluetooth dongle, and also on a HP N40L Microserver running Ubuntu 20.04, with HASS in the same non-root docker container, using the USB bluetooth dongle I recommended earlier in the thread.

@WhichWayWazzit … I’ve never worked with esp32 devices… but does this mean i could get something like an M5stack (or other esp32 chipset), configure it to work with ESP home and have the bluetooth onboard the esp32 device feed the sensor info into home assistant? So no need to have it running off of linux from HASS directly?

Yes, I am using an ESP32 from Amazon, brand not important as long as it is supported by ESPHome, that ran about $7 USD. It feeds all of my govee devices into HA without anything running on the HA machine. Since it is in a small box, I was able to locate it in a central area of the house to “sense” 3 Govee sensors in different rooms (1 upstairs, 2 downstairs). Note, when I had this running on a Pi4 if could also “sense” all 3, so I am not saying the ESP is better, but it appears to be “as good” and avoids the issues I was having getting this to work when I shifted from the Pi4 to a laptop to run HA.

I just bumped into a minor unit_of_measurement issue…

After upgrading to 0.116.2, I noticed that the Govee temp readings were showing up in the history graph as “C”. I’m not sure if that was always the case, but I had recently added a Govee temp sensor to a graph with other temp souces – they originally overlaid on the same plot, all as ‘F’, but since 0.116.2 the Govee data were forced to a second plot with a ‘C’ axis. So my inference is it was previously displaying as ‘F’ but “something changed.”

Anyway, I hacked a fix by going into sensor.py and adding TEMP_FAHRENHEIT as a constant and then switching the return value of TemperatureSensor.unit_of_measurement to TEMP_FAHRENHEIT. Probably broke something else but at least my history graph looks good!

EDIT: Aha, yep, spoke too soon! LOL Graphs look good but of course now the actual numerical units are celsius! :man_facepalming:t3:

EDIT 2: Ghost in the machine? I backed out my change, restarted, and now not only are the display values in fahrenheit but the unit_of_measurement on the axes is back to F. :man_shrugging:t3:

I haven’t looked into it much, but for what it’s worth I’ve noticed that a lot in Home Assistant, I believe with other types of sensors/components too, where particularly after a restart or when a new sensor is added, they’ll be a duplicate celsius graph that appears. Checking the database, there’s usually an empty-value state entry with celsius as the measurement. Subsequent measurements are in F but having the one C entry dupes the graph.This has happened on many HASS versions, not just a recent thing.

1 Like

Thanks @Martso! I often notice on restarts that a data stream gets “split” into two adjacent figures, and that a couple refreshes fixes the problem. I never thought to check the y-axis units though. In today’s case the refreshes didn’t seem to help but all is well now for whichever reason.

This brings up a more basic question that I hadn’t thought about before: how does our custom component “know” we want F displayed? :thinking: The sensor config doesn’t include a unit_of_measurement option (right?) and IIUC the device broadcasts “celsius” values (once they’re read from binary). Here’s a dumb theory: do I control the display unit in HA by toggling it on the device? Seems too simple. I feel like I read somewhere “how to display Govee data in C” but I don’t remember where…moot point anyway!

It doesn’t, this component saves everything in Celsius. Part of the initial set up when configuring HA was setting the home location and metric or imperial units. The combination of the two determines what units are displayed. Both because there are a few areas where both imperial and metric units are used, I think you see this mainly with weather forecasts. This is also the reason why setting the number of decimal values for this component does not always work for Fahrenheit because the rounding is done on the original Celsius value.

When developing software, it is generally a good idea to keep data separate its displayed format. The overhead of converting these temperature values to Fahrenheit is minimal and far less error prone than saving it preformatted and trying to parse information after the fact.

1 Like

Aha, it’s grabbing the setting from locale. Now I see why it’s so stealthy (i.e., I didn’t spot the conversion).
I’m sure what led me astray was the option in the HA configuration to set the unit_of_measurement for other sensors.

@Thrilleratplay thanks for filling in the blanks!

@John.McDowell Would you mind posting the ESP code or a snippet of it?

@Thrilleratplay Not too surprisingly, my component won’t work side-by-side with yours on a basic Raspberry Pi, since bleson only allows 1 scan to be started per hci# interface. Since I use both Govee and Moat sensors here, I ended up keeping all of your Govee device support in my fork for Moat. I also ended up adding some additional configuration options that other folks might be interested in too:

  • Native support for Fahrenheit, which fixes the history graph flakiness (also noticed by @gadgetrants) and ensures that we easily get the desired number of digits when rounding.
  • Per-sensor calibration (@iamhueman recently asked for this too)
  • Easily add entities for tracking RSSI, number of samples per period, and battery level. I know template entities can be created for all of these, but that felt unpleasant to maintain for many sensors.
  • Able to report “unavailable” if no measurements are received from a device during a reporting period.

If anyone feels like taking a look or giving it a try, the custom component and documentation is at https://github.com/SteveOnorato/moat_temp_hum_ble (not on HACS yet).
After adding the code to custom_components, the only change you’d need to make to your configuration.yaml is to change from
platform: govee_ble_hci
to
platform: moat_temp_hum_ble
(and then enable any additional features that you want to try).

Thanks again for your work in making this all possible!

1 Like

Thanks. I’ll take a look at it later and integrate features that would not be disruptive. Some I do not see the value of, like tracking battery level.

As for the components not working side by side, this unfortunate but I am also not surprised. At one point, I thought about abstracting out the bleson observer into its own service but this seemed like over kill at the time. How it would work is in the init.py a check would be added to add a callback to the existing service or create a service then add the callback. Allowing multiple components to use the bleson same instance…damn. The more I think about this, the better of an idea that becomes. The base could provide a list of devices it found complete with mac addresses and device names.

Hi, I’m trying to run this on the docker container provided by home-assistant. I’m getting an error

Traceback (most recent call last):


  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 197, in _async_setup_platform


    await asyncio.shield(task)


  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run


    result = self.fn(*self.args, **self.kwargs)


  File "/config/custom_components/govee_ble_hci/sensor.py", line 202, in setup_platform


    adapter = get_provider().get_adapter(int(config[CONF_HCI_DEVICE][-1]))


  File "/usr/local/lib/python3.8/site-packages/bleson/providers/linux/linux_provider.py", line 11, in get_adapter


    adapter.off()


  File "/usr/local/lib/python3.8/site-packages/bleson/providers/linux/linux_adapter.py", line 100, in off


    self.send_cmd_value(HCIDEVDOWN, self.device_id)


  File "/usr/local/lib/python3.8/site-packages/bleson/providers/linux/linux_adapter.py", line 47, in send_cmd_value


    fcntl.ioctl(self._socket.fileno(), cmd, value)

I saw someone else ran into something similar, but I wasn’t sure if there was a resolution. Any idea how to go about fixing this?