custom-components / ble_monitor

BLE monitor for passive BLE sensors
https://community.home-assistant.io/t/passive-ble-monitor-integration/
MIT License
1.9k stars 245 forks source link

govee temperature entity fails when reported temperature drops below 32f ( 0c ) #539

Closed krayj closed 2 years ago

krayj commented 2 years ago

I have 6 govee H5075 BLE climate sensing devices to test with. This repros on all of them.

[repro]

  1. have a govee H5075 BLE device successfully connected to the BLE_Monitor integration and verify it's working
  2. place a sensor in an environment that is below 0c.
  3. wait for the temperature to cross the 0c ( 32f ) boundary into negative numbers

[results]

  1. the temperature entity essentially breaks and receives no more updates via the integration.
  2. the entity history graph shows the temperature flatlined at exactly 32f ( 0c )
  3. when connecting to the device with the govee app via bluetooth, I can see that it is successfully recording much lower temperatures, so I know the device is working
  4. The humidity entity for the same device keeps updating regularly and keeps working fine, which is evidence that communication is succeeding and the device is reporting data
  5. The battery entity for the same device keeps updating regularly and keeps working fine, which is evidence that the communication is succeeding and the device is reporting data
  6. it does not matter whether I'm using the "use median" setting enabled or disabled (I have tried both)

[additional notes]

  1. I think that this device reports its actual temperature in Celsius and that when it starts reporting a negative number that it breaks something in the integration.

  2. I should also point out that I was previously using the govee-specific HACS integration without issues and only started experiencing this issue when I decommissioned my use of the govee integration and replaced it with this one... so I have high confidence there is nothing wrong with my physical sensor device and that the problem is directly related to this integration.

  3. The manufacturer of this sensor claims it's capable of accurately reporting temperatures as low as -5f (which would be -20.55c). I've personally seen it successfully report temps as low as 0f to 5f range (with the previous integration)

  4. after enabling debugging in configuration.yml, I'm seeing some pretty wild entries for this sensor:

2021-10-28 12:39:09 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'firmware': 'Govee', 'temperature': -1384.71, 'humidity': 7.9, 'battery': 63, 'rssi': -54, 'mac': 'A4C138674C11', 'type': 'H5072/H5075', 'packet': 'no packet id', 'data': True}

(connecting via the govee app is showing something in the 4.5f (-15.2c) temp range, so the value -1384.71 is not inline with what the actual sensor is reporting)

[expectation] the integration should not fail when the sensor reports data in negative numbers

Ernst79 commented 2 years ago

Temperature for your sensor is parsed with this part of the code in https://github.com/custom-components/ble_monitor/blob/master/custom_components/ble_monitor/ble_parser/govee.py

def decode_temps(packet_value: int) -> float:
    """Decode potential negative temperatures."""
    # https://github.com/Thrilleratplay/GoveeWatcher/issues/2
    if packet_value & 0x800000:
        return float((packet_value ^ 0x800000) / -100)
    return float(packet_value / 10000)

So, it seems that there is some error in this part. One possibility could be that the /100 should be /10000, but you end up with -13.8 instead of -15.2.

Could you do me a favor, and add a logger line like this, restart HA and get some of the errors from the HA log. Also report the temperature you would have expected, based on the Govee app (make sure there is not a temperature correction added in the app).

def decode_temps(packet_value: int) -> float:
    """Decode potential negative temperatures."""
    # https://github.com/Thrilleratplay/GoveeWatcher/issues/2
    _LOGGER.error("Govee temperature reading: %s", packet_value)
    if packet_value & 0x800000:
        return float((packet_value ^ 0x800000) / -100)
    return float(packet_value / 10000)
krayj commented 2 years ago

I've eliminated any in-device calibration and added the logger code and restarted HomeAssistant. Here's some of the results (keep in mind that when I see a new log entry, it might not map identically to the temperature values I'm syncing through the app - the device seems to be reporting every 30sec and I'm syncing in the govee app in realtime trying to get it as close as I can):

Measurement 1 device temperature (via govee app): -13.1c relevant log entries:

2021-10-29 10:40:53 ERROR (Thread-3) [custom_components.ble_monitor.ble_parser.govee] Govee temperature reading: 8521104
2021-10-29 10:40:53 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'firmware': 'Govee', 'temperature': -1324.96, 'humidity': 10.4, 'battery': 61, 'rssi': -46, 'mac': 'A4C138674C11', 'type': 'H5072/H5075', 'packet': 'no packet id', 'data': True}
2021-10-29 10:40:53 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'firmware': 'Govee', 'temperature': -1324.96, 'humidity': 10.4, 'battery': 61, 'rssi': -46, 'mac': 'A4C138674C11', 'type': 'H5072/H5075', 'packet': 'no packet id', 'data': True}

Measurement 2 device temperature (via govee app): -12.9c relevant log entries:

2021-10-29 10:46:55 ERROR (Thread-3) [custom_components.ble_monitor.ble_parser.govee] Govee temperature reading: 8518103
2021-10-29 10:46:55 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'firmware': 'Govee', 'temperature': -1294.95, 'humidity': 10.3, 'battery': 60, 'rssi': -46, 'mac': 'A4C138674C11', 'type': 'H5072/H5075', 'packet': 'no packet id', 'data': True}
2021-10-29 10:46:55 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'firmware': 'Govee', 'temperature': -1294.95, 'humidity': 10.3, 'battery': 60, 'rssi': -46, 'mac': 'A4C138674C11', 'type': 'H5072/H5075', 'packet': 'no packet id', 'data': True}

Measurement 3 device temperature (via govee app): -12.8c relevant log entries:

2021-10-29 10:50:25 ERROR (Thread-3) [custom_components.ble_monitor.ble_parser.govee] Govee temperature reading: 8516102
2021-10-29 10:50:25 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'firmware': 'Govee', 'temperature': -1274.94, 'humidity': 10.2, 'battery': 60, 'rssi': -46, 'mac': 'A4C138674C11', 'type': 'H5072/H5075', 'packet': 'no packet id', 'data': True}
2021-10-29 10:50:25 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'firmware': 'Govee', 'temperature': -1274.94, 'humidity': 10.2, 'battery': 60, 'rssi': -46, 'mac': 'A4C138674C11', 'type': 'H5072/H5075', 'packet': 'no packet id', 'data': True}

Measurement 4 device temperature (via govee app): -12.6c relevant log entries:

2021-10-29 10:52:35 ERROR (Thread-3) [custom_components.ble_monitor.ble_parser.govee] Govee temperature reading: 8515102
2021-10-29 10:52:35 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'firmware': 'Govee', 'temperature': -1264.94, 'humidity': 10.2, 'battery': 60, 'rssi': -46, 'mac': 'A4C138674C11', 'type': 'H5072/H5075', 'packet': 'no packet id', 'data': True}
2021-10-29 10:52:35 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'firmware': 'Govee', 'temperature': -1264.94, 'humidity': 10.2, 'battery': 60, 'rssi': -46, 'mac': 'A4C138674C11', 'type': 'H5072/H5075', 'packet': 'no packet id', 'data': True}

Please let me know if there's any additional data I can provide. I also have access to a bluetooth BLE passive sniffer and can capture raw data off the sensor if that would be helpful.

Ernst79 commented 2 years ago

Thanks, we just need to change the /100 to /10000. Will change that tomorrow. You can also do it manually in the mean time, see my previous post.

krayj commented 2 years ago

Thanks for digging in!

I don't see a /100 anywhere in that code block. I see a " / 10000 " and I see a " / -100".

Here's the original

    if packet_value & 0x800000:
        return float((packet_value ^ 0x800000) / -100)
    return float(packet_value / 10000)

I assume you mean change it to something like this?

    if packet_value & 0x800000:
        #change /-100 to /-10000
        return float((packet_value ^ 0x800000) / -10000)  
    return float(packet_value / 10000)
Ernst79 commented 2 years ago

Yes, indeed. I meant /-100

krayj commented 2 years ago

Confirmed, that fixes it! I applied the recommended modification manually and reboot and retested.

Measurement 5 (after applying the recommended modification): device temperature (via govee app): -14.8c relevant log entries:

2021-10-29 12:26:27 ERROR (Thread-3) [custom_components.ble_monitor.ble_parser.govee] Govee temperature reading: 8537101
2021-10-29 12:26:27 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'firmware': 'Govee', 'temperature': -14.8493, 'humidity': 10.1, 'battery': 60, 'rssi': -46, 'mac': 'A4C138674C11', 'type': 'H5072/H5075', 'packet': 'no packet id', 'data': True}
2021-10-29 12:26:27 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'firmware': 'Govee', 'temperature': -14.8493, 'humidity': 10.1, 'battery': 60, 'rssi': -46, 'mac': 'A4C138674C11', 'type': 'H5072/H5075', 'packet': 'no packet id', 'data': True}

Thank you for all that time and effort!

Ernst79 commented 2 years ago

No problem, 5.7.5 has been released just now with this Fix.