And if you have Nabu Casa and Google Home, Alexa or Siir it is kind of nice to just ask what the backyard temperature is …
I didn’t see the H5102 details mentioned yet, so I’ll add the version of the ESP Home BLE tracker that worked for me on that version of the sensor. Should be the right version for H5101 or H5102, which is actually very close to the H5072/H5075, with the data location just off by a byte.
esp32_ble_tracker:
on_ble_manufacturer_data_advertise:
- mac_address: A4:C1:38:xx:xx:xx # Office Govee 5102
manufacturer_id: '0001'
then:
- lambda: |-
const int basenum = (int16_t(x[2]) << 16) + (int16_t(x[3]) << 8) + int16_t(x[4]);
const float temperature = (basenum / 10000.0f)*9.0/5.0 + 32.0;
const float humidity = (basenum % 1000) / 10.0f;
const float battery_level = uint16_t(x[5]) / 1.0f;
id(office_humidity).publish_state(humidity);
id(office_temperature).publish_state(temperature);
id(office_battery).publish_state(battery_level);
I am coming late to this discussion. I have read through the whole post. What I did not understand is where I should be putting this. I have H5075s downstairs and they do not reach my upstairs system. I have esphome and esp32 boards, just not sure what to do with the above.
the_badluck - If you have a functional esphome running, you’d need to edit that esphome code, adding some sensor definitions and a corresponding “esp32_ble_tracker” section which defines how to get at the specific data values for those sensors. Maybe start with John.McDowell’s example but swap in the H5075 specific section from mwildrick (adjusting the names of the locations and the MAC address to match your usage).
I have to say thanks for all those that contributed code here. I got a couple 5075s on Amazon and they were up and running in about 15 minutes thanks to all the code snippets here!
Has anyone tackled the H5179? I have the following data from the tracker:
[15:54:00][VV][esp32_ble_tracker:493]: Parse Result:
[15:54:00][VV][esp32_ble_tracker:510]: Address: E3:8C:81:93:80:7A (PUBLIC)
[15:54:00][VV][esp32_ble_tracker:512]: RSSI: -65
[15:54:00][VV][esp32_ble_tracker:513]: Name: 'Govee_H5179_807A'
[15:54:00][VV][esp32_ble_tracker:521]: Ad Flag: 6
[15:54:00][VV][esp32_ble_tracker:524]: Service UUID: 0x180A
[15:54:00][VV][esp32_ble_tracker:524]: Service UUID: 0xFEF5
[15:54:00][VV][esp32_ble_tracker:524]: Service UUID: 0xEC88
[15:54:00][VV][esp32_ble_tracker:527]: Manufacturer data: EC.00.01.01.3E.08.B4.0A.64 (9)
[15:54:00][VV][esp32_ble_tracker:543]: Adv data: 02.01.06.07.03.0A.18.F5.FE.88.EC.11.09.47.6F.76.65.65.5F.48.35.31.37.39.5F.38.30.37.41.0C.FF.01.88.EC.00.01.01.3E.08.B4.0A.64 (42)
I’ve tried a couple of the lambda’s for anything that has a length of 9 for the manufacturer data and I’m not having any luck.
Has anyone else already tackled the H5179 and can share their lambda setup?
To add some more clarity - in the example above the 3E hex value (5th byte in manf. adv.) seems to change with temp and the B4 value (7 in manf. adv.) changes with humidity.
The problem is that whenever I convert these to integer it never relates to an accurate temp. or humidity. I’ve tried 2 pair and 3 pair values with divisors and modulus with what prior examples in this thread.
I’ve also looked at other examples which seem to point to a message payload that is 13 bytes long - none of the messages that broadcast when the verbose logging is enabled show this…they are all 9 bytes for the manf. and 42 bytes for the service data.
Am I just missing something here? In the example posted above the temp should be around 20.1C and humidity would be around 35.5%…
Is there a way to display the entire message payload with esp_ble_tracker? I’ve created lambda’s that convert x[?] to display each position but the decoding always gives a result (whether 16 bit or 8 bit) that’s not accurate…
More detail - here’s an example of a python decode:
elif self.check_is_gvh5179():
temp, hum, batt = unpack_from("<HHB", self.mfg_data, 6)
self.packet = hex(temp)[2:] + hex(hum)[2:]
# Negative temperature stored an two's complement
self.temperature = float(twos_complement(temp) / 100.0)
self.humidity = float(hum / 100.0)
self.battery = int(batt)
self.model = "Govee H5179"
Along with the check function:
def check_is_gvh5179(self) -> bool:
"""Check if mfg data is that of Govee H5179."""
return self._mfg_data_check(11, 6) and self._mfg_data_id_check("0188")
And the twos compliment:
def twos_complement(n: int, w: int = 16) -> int:
"""Two's complement integer conversion."""
# Adapted from: https://stackoverflow.com/a/33716541.
if n & (1 << (w - 1)):
n = n - (1 << w)
return n
This code is located here:
Can anyone interpret this and take a stab at a lambda that I could test?
Bought some 5075s but still can’t get them running after days. Can you please share the code you used to get it working in 15mins? thanks!
thanks to you i got my 5075 to work, I have 4 of them running on on ESP32…
Thanks guys I have 4 Govee 5075 working on this script that i put together from code posted in here… Here is mine that works… you can keep adding more as as needed see comments in code
esphome:
# Name Is From When you Setup The ESP32
name: esp-govee
esp32:
board: esp32dev
framework:
type: arduino
sensor:
# GOVEE Sensor1 CHANGE NAMES AS NEEDED here and in Lamda Section
- platform: template
name: "govee1 Humidity"
id: govee1_humidity
unit_of_measurement: '%'
icon: "mdi:water-percent"
- platform: template
name: "govee1 Temperature"
id: govee1_temperature
unit_of_measurement: '° F'
icon: "mdi:thermometer"
- platform: template
name: "govee1 Battery"
id: govee1_battery
unit_of_measurement: '%'
icon: "mdi:battery"
# GOVEE Sensor2 CHANGE NAMES AS NEEDED here and in Lamda Section
- platform: template
name: "govee2 Humidity"
id: govee2_humidity
unit_of_measurement: '%'
icon: "mdi:water-percent"
- platform: template
name: "govee2 Temperature"
id: govee2_temperature
unit_of_measurement: '° F'
icon: "mdi:thermometer"
- platform: template
name: "govee2 Battery"
id: govee2_battery
unit_of_measurement: '%'
icon: "mdi:battery"
# GOVEE Sensor3 CHANGE NAMES AS NEEDED here and in Lamda Section
- platform: template
name: "govee3 Humidity"
id: govee3_humidity
unit_of_measurement: '%'
icon: "mdi:water-percent"
- platform: template
name: "govee3 Temperature"
id: govee3_temperature
unit_of_measurement: '° F'
icon: "mdi:thermometer"
- platform: template
name: "govee3 Battery"
id: govee3_battery
unit_of_measurement: '%'
icon: "mdi:battery"
# GOVEE Sensor4 CHANGE NAMES AS NEEDED here and in Lamda Section
- platform: template
name: "govee4 Humidity"
id: govee4_humidity
unit_of_measurement: '%'
icon: "mdi:water-percent"
- platform: template
name: "govee4 Temperature"
id: govee4_temperature
unit_of_measurement: '° F'
icon: "mdi:thermometer"
- platform: template
name: "govee4 Battery"
id: govee4_battery
unit_of_measurement: '%'
icon: "mdi:battery"
# Enable logging
logger:
# Enable Home Assistant API
api:
# Your Over The Air Password
ota:
password: "861291xx35895xx43ea2xxxx80b12"
# Wifi login and Password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esp-Govee Fallback Hotspot"
password: "z3nfxBoGdDub"
# Script For The First 5075 Govee Themometer/Humidity Sensor
esp32_ble_tracker:
on_ble_advertise:
- mac_address: A4:C1:38:xx:xx:xx #MAC Adress of First Sensor
then:
- lambda: |-
for (auto data : x.get_manufacturer_datas()) {
if(data.data.size()==6) {
const int basenum = (int16_t(data.data[1]) << 16) + (int16_t(data.data[2]) << 8) + int16_t(data.data[3]);
const float temperature = ((basenum / 10000.0f)*9.0/5.0 + 32.0);
const float humidity = (basenum % 1000) / 10.0f;
const float battery_level = uint16_t(data.data[4]) / 1.0f;
int16_t rssi=x.get_rssi();
id(govee1_humidity).publish_state(humidity);
id(govee1_temperature).publish_state(temperature);
id(govee1_battery).publish_state(battery_level);
}
}
# Script For The Second 5075 Govee Themometer/Humidity Sensor
- mac_address: A4:C1:38:xx:xx:xx #MAC Adress of Second Sensor
then:
- lambda: |-
for (auto data : x.get_manufacturer_datas()) {
if(data.data.size()==6) {
const int basenum = (int16_t(data.data[1]) << 16) + (int16_t(data.data[2]) << 8) + int16_t(data.data[3]);
const float temperature = ((basenum / 10000.0f)*9.0/5.0 + 32.0);
const float humidity = (basenum % 1000) / 10.0f;
const float battery_level = uint16_t(data.data[4]) / 1.0f;
int16_t rssi=x.get_rssi();
id(govee2_humidity).publish_state(humidity);
id(govee2_temperature).publish_state(temperature);
id(govee2_battery).publish_state(battery_level);
}
}
# Script For The Third 5075 Govee Themometer/Humidity Sensor
- mac_address: A4:C1:38:xx:xx:xx #MAC Adress of Third Sensor
then:
- lambda: |-
for (auto data : x.get_manufacturer_datas()) {
if(data.data.size()==6) {
const int basenum = (int16_t(data.data[1]) << 16) + (int16_t(data.data[2]) << 8) + int16_t(data.data[3]);
const float temperature = ((basenum / 10000.0f)*9.0/5.0 + 32.0);
const float humidity = (basenum % 1000) / 10.0f;
const float battery_level = uint16_t(data.data[4]) / 1.0f;
int16_t rssi=x.get_rssi();
id(govee3_humidity).publish_state(humidity);
id(govee3_temperature).publish_state(temperature);
id(govee3_battery).publish_state(battery_level);
}
}
# Script For The Forth 5075 Govee Themometer/Humidity Sensor
- mac_address: A4:C1:38:xx:xx:xx #MAC Adress of Forth Sensor
then:
- lambda: |-
for (auto data : x.get_manufacturer_datas()) {
if(data.data.size()==6) {
const int basenum = (int16_t(data.data[1]) << 16) + (int16_t(data.data[2]) << 8) + int16_t(data.data[3]);
const float temperature = ((basenum / 10000.0f)*9.0/5.0 + 32.0);
const float humidity = (basenum % 1000) / 10.0f;
const float battery_level = uint16_t(data.data[4]) / 1.0f;
int16_t rssi=x.get_rssi();
id(govee4_humidity).publish_state(humidity);
id(govee4_temperature).publish_state(temperature);
id(govee4_battery).publish_state(battery_level);
}
}
I posted my code that works for 5075 and you can keep adding more as needed
FYI
Here is my code for the Govee 5183 meat thermometer.
If the probe is not connected or the target temp is not set then I show a number to big to be right.
Also, currently, the only way to set the target temp is with the app.
Not sure how to send a BLE or what that message would look like.
I left some debug code.
esp32_ble_tracker:
on_ble_advertise:
- mac_address: A4:C1:xx:xx:xx:xx
then:
- lambda: |-
ESP_LOGD("ble_adv", "New BLE device");
ESP_LOGD("ble_adv", " address: %s", x.address_str().c_str());
ESP_LOGD("ble_adv", " name: %s", x.get_name().c_str());
ESP_LOGD("ble_adv", " Advertised service UUIDs:");
for (auto uuid : x.get_service_uuids()) {
ESP_LOGD("ble_adv", " - %s", uuid.to_string().c_str());
}
ESP_LOGD("ble_adv", " Advertised service data:");
for (auto data : x.get_service_datas()) {
ESP_LOGD("ble_adv", " - %s: (length %i)", data.uuid.to_string().c_str(), data.data.size());
}
ESP_LOGD("ble_adv", " Advertised manufacturer data:");
for (auto data : x.get_manufacturer_datas()) {
ESP_LOGD("ble_adv", " - %s: (length %i)", data.uuid.to_string().c_str(), data.data.size());
if (data.data.size() == 14){
for (int i=0;i<14;i++){
ESP_LOGD("ble_adv", "-%i", data.data[i]);
}
if (data.data[8] == 255 && data.data[9] == 255){
id(meat_tempture).publish_state(99999999.00);
} else{
int temp_lsb = (data.data[8] * 256) + data.data[9];
float temperature = float(temp_lsb)/100*9.0/5.0 + 32.0;
id(meat_tempture).publish_state(temperature);
}
if (data.data[10] == 255 && data.data[11] == 255){
id(meat_taget_tempture).publish_state(99999999.00);
} else{
int temp_lsb = (data.data[10] * 256) + data.data[11];
float temperature = float(temp_lsb)/100*9.0/5.0 + 32.0;
id(meat_taget_tempture).publish_state(temperature);
}
}
}
sensor:
- platform: template
name: "Meat Tempture"
id: meat_tempture
- platform: template
name: "Meat Traget Tempture"
id: meat_taget_tempture
Did you manage to get H5179 working with ESP32 ?
Thanks so much for this! Worked for me using an H5102.
I wanted to throw in one more detail though: Under, sensor:
, you ought to have device_class: "humidity"
in order for the sensor to be shown on Homekit (per the Supported Components section).
So effectively this:
sensor:
- platform: template
name: "Master Bath Temperature"
id: govee1_temp
device_class: "temperature"
unit_of_measurement: "°C"
accuracy_decimals: 2
- platform: template
name: "Master Bath Humidity"
id: govee1_humidity
device_class: "humidity"
unit_of_measurement: '%'
accuracy_decimals: 2
- platform: template
So if anyone’s wondering why yoru humidity is not showing up in homekit, this is why . Funnily enough, the “Master Bath Temperature” section not explicitly having device_class: "temperature"
seems to show up fine on Homekit.
Is there any way to do this passively instead of active in order to save battery?
Fantastic work, John. I copied your code and it worked on the first go. I hadn’t looked at that Govee app in months, but now this temp/hygrometer unit has got a new lease on life!
I wanted to provide an update for this. I recently shifted over to using the new native bluetooth component in Home Assistant. I am using the ZEXMTE long range bluetooth dongle. The system auto identified the Govee sensors and it works very well. I have now shifting all of my automation and dashboards to the new entities and retired the EspHome solution. My sensors are in very different locations in the house but the dongle has no issue hearing “any of them” (the ESP32 also had no issues as well - very impressive performance from the ESP32 since the sensors are very far away including one on the second floor of the house)
Hi John! I realize you’re using the native components, but I’m needing to integrate the govee sensors directly into the esp32, because it’s a thermostat and I need it to function without HA.
I’ve been trying to use the original code at the top but I’m getting all wrong numbers. Any ideas?
What should I use for a Govee 5075?
My suggestion would be to use an ESPHOME BLE Gateway on the ESP32 and have that communicate with HA BLE Integration. This would allow you to use the “official” Govee BLE integration that does all of the heavy lifting (parsing) of the BLE data for you. I had started down this path of trying to get the ESPHOME BLE Gateway to talk to HA via the HACS custom BLE_Monitor integration. That Dev is merging his work with the new HA BLE support.
This would essentially allow an ESP32 to be used as a “BLE repeater” over the ESP32 Wifi into HA. I am not sure this has been fully developed yet, but I am sure someone is working on it. (I would further look into doing it except that the long range BT adapter I put on my HA box covers my entire home so I don’t have a current need)
The auto detection makes this a lot easier doesn’t it! This looks really cool, do you think USB passthrough to a VM (hyper-v) would work?