atc1441 / ATC_MiThermometer

Custom firmware for the Xiaomi Thermometer LYWSD03MMC and Telink Flasher via USB to Serial converter
2.86k stars 480 forks source link

implausible data get from LYWSD03MMC #127

Open ercoleg opened 3 years ago

ercoleg commented 3 years ago

Hello, I'm currently using the following toolchain:

I usually get good measurements from both sensors on my DB but sometimes, from the farther, I get some implausible information (see image).

I have some questions:

Thank you for your help

G

image

atc1441 commented 3 years ago

thank you for the issue

This behavior is new to me, good question on what it could be.

The communication should already have crc on BLE level so i would think of the sensor reading itself is maybe wrong.

What is the battery state ?

ercoleg commented 3 years ago

In this moment, the one that has inplausible data is the one with battery 82% image

satmandu commented 3 years ago

I'm actually having a similar issue on one of my devices too, which I have outside mywindow (so exposed to ~ 32F weather.)

Bluetooth device 0 is already enabled
Enable LE scan
scan params: interval=1280.000ms window=1280.000ms own_bdaddr=public whitelist=no
socket filter set to ptype=HCI_EVENT_PKT event=LE_META_EVENT
Listening ...
2020-12-27 00:19:49 - Device:  A4:C1:AA:BB:CC:DD Temp: 11825.2°F Humidity: 52% Batt: 42%
2020-12-27 00:19:53 - Device:  A4:C1:AA:BB:CC:DD Temp: 11825.2°F Humidity: 52% Batt: 42%
2020-12-27 00:19:57 - Device:  A4:C1:AA:BB:CC:DD Temp: 11825.2°F Humidity: 52% Batt: 42%

(The temperature on the device display seems appropriate.)

This is the script I use:

#!/usr/bin/env python3
import sys
from datetime import datetime
import bluetooth._bluetooth as bluez

from bluetooth_utils import (toggle_device, enable_le_scan,
                             parse_le_advertising_events,
                             disable_le_scan, raw_packet_to_str)

# Use 0 for hci0
dev_id = 0
toggle_device(dev_id, True)

try:
    sock = bluez.hci_open_dev(dev_id)
except:
    print("Cannot open bluetooth device %i" % dev_id)
    raise

# Set filter to "True" to see only one packet per device
enable_le_scan(sock, filter_duplicates=False)

try:
    def le_advertise_packet_handler(mac, adv_type, data, rssi):
        data_str = raw_packet_to_str(data)
        # Check for ATC preamble
        if data_str[6:10] == '1a18':
            tempC = int(data_str[22:26], 16) / 10
            tempCst = ("%0.1f°C" % tempC)
            tempF = (9/5)*tempC + 32
            tempFst = ("%0.1f°F" % tempF)
            hum = int(data_str[26:28], 16)
            batt = int(data_str[28:30], 16)
            print("%s - Device: %s Temp: %s Humidity: %s%% Batt: %s%%" % \
                 (datetime.now().strftime("%Y-%m-%d %H:%M:%S"), mac, tempFst, hum, batt))

    # Called on new LE packet
    parse_le_advertising_events(sock,
                                handler=le_advertise_packet_handler,
                                debug=False)
# Scan until Ctrl-C
except KeyboardInterrupt:
    disable_le_scan(sock)

(This script requires https://github.com/colin-guyon/py-bluetooth-utils/blob/master/bluetooth_utils.py to be in the same folder.)

satmandu commented 3 years ago

(all of my devices are LYWSD03MMC equipped with ATC FW)

yeshuawatso commented 3 years ago

(all of my devices are LYWSD03MMC equipped with ATC FW)

Your script doesn't conform to the advertisements from the stock ATC FW. You need to bitshift your value in this line:

tempC = int(data_str[22:26], 16) / 10

before you divide, maybe something like:

tempC = (int(data_str[22:26], 16)<<8)/10

See https://github.com/atc1441/ATC_MiThermometer/blob/a72a5ca20162bc168d27900b6fe15b1847b0f666/ATC_Thermometer/ble.c#L205

satmandu commented 3 years ago

Thanks!