JsBergbau/MiTemperature2

Investigating on values

rusq opened this issue · 32 comments

rusq commented

Hey, great job with getting this working!

For your reference, gattool output for my sensor is

Notification handle = 0x0036 value: eb 08 36 c0 0b 
[A4:C1:38:E9:2A:F3][LE]>

The unknown values for my sensor are c0 0b.
After a while it read e5 0b.

The other one

Notification handle = 0x0036 value: f9 07 3d 78 0c
[A4:C1:38:1F:50:35][LE]>

On my sensor the last value is also 0b
Currently it is e5 0b. last time I checked it was 9f 0b
Current readings are

Temperature: 22.75
Humidity: 53

Hi there,

Thanks a lot for your work.

Here are my values for my 4 sensors :

Notification handle = 0x0036 value: d6 07 33 c9 0c
Notification handle = 0x0036 value: c8 07 30 fd 0b
Notification handle = 0x0036 value: 2a 09 2b dc 0c
Notification handle = 0x0036 value: 58 09 2b b9 0c

rusq commented

if that's a 16-bit word, looks like this parameter is in range 0x0Bxx - 0x0Cxx and doesn't change very often.

Hey, great job with getting this working!

For your reference, gattool output for my sensor is

Notification handle = 0x0036 value: eb 08 36 c0 0b 
[A4:C1:38:E9:2A:F3][LE]>

The unknown values for my sensor are c0 0b.
After a while it read e5 0b.

The other one

Notification handle = 0x0036 value: f9 07 3d 78 0c
[A4:C1:38:1F:50:35][LE]>

I think it is the value of the battery voltage in mV. This is: 0BC0 hex = 3008 mV= 3.008 V
The sensor updates the battery level every hour or so
The operating range is 2v to 3v. This is 0 to 100% battery
On the other hand, in my case, it seems that the following UUIDs associated with the battery status do not work, and never change the value of 0x64 = 100% or 0x63 = 99%:
UUID 0x189F -> 0x2A19
UUID ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6 -> ebe0ccc4-7a0a-4b0c-8a1a-6ff2997da3a6
Could anyone confirm it?

Thanks for the info. I saw this post with supposed voltage somewhere else a few days ago and wanted to make some tests. Didn't manage yet.

Yeah it seems that the battery value of 99 % never changes.

I had to change the battery in a Aqara because the device went off when placed vertically. Just lying on the table it worked without problems. Battery value read out was still 99 %. The Aqara sensors have a battery indicator which shortly was displayed before this particular device was going off.

I have a voltage meter and a low battery now, so I'll report back in a few days.

Someone may be interested to know that the LYWSD03MMC sensor has an internal operating RTC. With the advantage of having battery support.

Although the sensor does not present it on the LCD screen, in the UUID ebe0ccb0 -... / ebe0ccb7 -... maintains the date and time in UnixTime format (seconds since Jan 01 1970. (UTC) - https: // www.unixtimestamp.com/index.php).

This UUID allows Read and Write.
The structure of the bytes is as follows:
Raw reading -> B3-B2-B1-B0 (endian littel format)
Decoded reading -> B0 B1 B2 B3 (total seconds since 01-01-1970)

To initialize the UUID, you must write the desired Date / Time with the bytes in the raw format (endian littel format).

Of course, you have to take into account the time zone

I can confirm now last to bytes are the battery voltage. Note: When measuring the battery outside the device battery level is about 0,15 V higher than displayed on the last 2 bytes. To measure "the real" voltage when Aqara sensor is sending data, I put a wire under the contact for the minus pole. On my measurement the voltage bounced about 0,05 V. Thats very strange since Bluetooth low energy consumes very little power. I think the batteries included in the Aqara are from low quality. Out of 8 sensors I now have two with empty batteries. But not the ones I'm using the longest time. I suspect bad battery quality for the second delivery.
I'll rewrite the script to read out the battery voltage. My first Aqara which is now running since first or second week of January now has 2554 mV.
A brand new Aqara which now was just lying around for about 2 weeks without any connection had 2885 mV measured outside. Another 3014 mV and another 2089 mV.

Hi JsBergbau, when you say Aqara (product name WSDCGQ11LM) is that the same as LYWSD03MMC?
Sorry I do not understand, I thought that Aqara are Zigbee protocol equipment, right?
Is there a BLE version of Aqara sensors?

JsBergbau: " My first Aqara which is now running since first or second week of January now has 2554 mV. "
Those sensors seem to spend a lot of battery. In six / seven weeks the sensor has spent 50% of battery, or as you say, the batteries are from low quality.
In my tests, I have verified that when the voltage reaches 2.1 V, the empty battery icon is activated, and it is imminent that LYWSD03MMC sensor turns off.

rusq commented

I was running with a constant connection for about a month (I got 7 of those sensors, out of which 4 was polled for the home assistant), in two of them battery died - those which were not polled have 3.06V on the battery and in two discharged ones the voltmeter shows 2.6V, so I guess having a constant connection isn't very good idea. It's notable as both of them discharged with the difference of several ours.

rusq commented

Oh, and for the record, the battery level that was retrieved via polling was always 99%, even minutes before they shut down, so the battery percentage is not reliable. @jaggil, great finding! @JsBergbau awesome idea on having these as a battery level.

For the reference - 2.75V can be considered as 0%, as that's the voltage on a completely dead sensor. When plugged in into back the sensor, it doesn't turn on. It's the same battery that was showing ~2.6 before, I guess the voltage drops over the time and restores up to a certain point, I'm no batterologist.

In my battery tests I have used an adjustable power supply, and the summary is as follows:
1.- The operating range is between 2.1v to 3v.
2.- When 2.1 v is reached, the empty battery icon is activated on the LCD screen.
Also, the "UUID ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6 -> ebe0ccc4-7a0a-4b0c-8a1a-6ff2997da3a6" changes value from 0x64 to 0x0A (I guess it is 100% to 10%). This change may take an hour or so.
I guess it's a binary indicator of battery status.
Of course, in this voltage the brightness of the screen is minimal, and it is difficult to see the data.
3.- When it reaches 2.09v, the sensor turns off.
My conclusion is that the 0 to 100% battery range corresponds to 2.1v to 3v
@rusq Thank you/Gracias

OK friends,
Now that we know the battery's operating range, I think it is necessary to reopen issue # 10 to determine the best way to communicate with the sensor, in order for the battery to last the maximum time.
I don't know if it is better to have a permanent connection and receive the data every 6 seconds, or make connections every 5 minutes (or the time that each project needs) and once the data is received, make a disconnection.

Hi JsBergbau, when you say Aqara (product name WSDCGQ11LM) is that the same as LYWSD03MMC?
Sorry I do not understand, I thought that Aqara are Zigbee protocol equipment, right?
Is there a BLE version of Aqara sensors?

Where did you read that WSDCGQ11LM and LYWSD03MMC are the same? I even don't know WSDCGQ11LM sensor....
The LYWSD03MMC are Bluetooth Low Energy sensors.

Hi JsBergbau, when you say Aqara (product name WSDCGQ11LM) is that the same as LYWSD03MMC?
Sorry I do not understand, I thought that Aqara are Zigbee protocol equipment, right?
Is there a BLE version of Aqara sensors?

Where did you read that WSDCGQ11LM and LYWSD03MMC are the same? I even don't know WSDCGQ11LM sensor....
The LYWSD03MMC are Bluetooth Low Energy sensors.

As I understand it, we have two different products:
Aqara (product name WSDCGQ11LM with Zigbee protocol)
Xiaomi MiTemperature2 (LYWSD03MMC with BLE)

But you make many references to the Aqara sensor and that confuses me if you mean one or the other.

Oh, and for the record, the battery level that was retrieved via polling was always 99%, even minutes before they shut down, so the battery percentage is not reliable.

I can confim that.

For the reference - 2.75V can be considered as 0%, as that's the voltage on a completely dead sensor. When plugged in into back the sensor, it doesn't turn on. It's the same battery that was showing ~2.6 before,

Currently my sensor with the lowest batterylevel is running at 2.29 V. The voltage even recovers a bit, it now was 2.32 V.

I guess the voltage drops over the time and restores up to a certain point, I'm no batterologist.
If you pull the battery out and hold it in your hands, it gets warmer and thus recovers a few mV, so that the sensor could turn on again.

I've implemented now reading out the voltage and will impemtent the -b option to give an estimated percent value. For compatbility reasons you can still specifiy a number after b but it will be ignored.

Script is now updated to read battery voltage and get an estimated battery level based on the battery voltage.

Now the second battery is empty. The replaced battery seemed to be low quality. Nevertheless, interesting voltage values
grafik
A rapid drop below 2.36V, then voltage rises above 2.39 V and then device goes off with a higher voltage than it recovered from.

Would be interesting to see some comparison between subscribing to notifications and polling (e.g. every 5 or 10 minutes) now with the voltage data. Has anybody done that yet?

MiTemperature2 extensions

Hello, I have continued investigating all the parameters that are accessible by communications and I have found / decoded the meaning of the following points:

1.- Command to stop / resume T / H / Batt notifications but keeping the connection active. This would be an alternative to disconnect completely and reconnect after the desired reconnection time.

2.- Command to change the units of the temperature of the LCD screen in degrees Fahrenheit. This only affects the screen, notifications remain in degrees Celsius

3.- Setting the time, date and time, internal clock (UnixTime format).

4.- By default the sensor stores records every hour of the maximum / minimum temperature / humidity and with date and time stamp. They can be read by notifications

5.- Command to read the amount of stored records.

6.- Command to delete all records.

7.- Command to read by notifications, from a specific record.

8.- Command to read the last stored record (in the last hour)

9.- Command to initialize maximum and minimum temperature and maximum and minimum comfort humidity. It is supposed to affect the face icon that appears on the LCD screen, it is still unclear.

If anyone is interested in using any of them, you can let me know here, and I will post the details of how to do it.

rusq commented

MiTemperature2 extensions

Hello, I have continued investigating all the parameters that are accessible by communications and I have found / decoded the meaning of the following points:

1.- Command to stop / resume T / H / Batt notifications but keeping the connection active. This would be an alternative to disconnect completely and reconnect after the desired reconnection time.

2.- Command to change the units of the temperature of the LCD screen in degrees Fahrenheit. This only affects the screen, notifications remain in degrees Celsius

3.- Setting the time, date and time, internal clock (UnixTime format).

4.- By default the sensor stores records every hour of the maximum / minimum temperature / humidity and with date and time stamp. They can be read by notifications

5.- Command to read the amount of stored records.

6.- Command to delete all records.

7.- Command to read by notifications, from a specific record.

8.- Command to read the last stored record (in the last hour)

9.- Command to initialize maximum and minimum temperature and maximum and minimum comfort humidity. It is supposed to affect the face icon that appears on the LCD screen, it is still unclear.

If anyone is interested in using any of them, you can let me know here, and I will post the details of how to do it.

Yeah please share.
With your findings I think I can update the script to connect for example every five minutes, receiving current data. But also I could fetch maximum and minium data within that 5 minutes. That gives a much better accuracy because you don't miss any short changes.

BTW: How did you manage to find out these parameters?

To whom it May concern, (Part 1)

First of all I want to apologize for my level of English.
I have a survival level in English. My best English friend is the "Google Translator" :-) 😃

I also want to say that I have done the research with two android apps, namely:
https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp
https://play.google.com/store/apps/details?id=no.nordicsemi.android.log

The second is a support to see the messages (logs).
With this app you can check messages (read / write) without programming.

Until these days I didn't know anything about BLE, so I had to read some documents, this is one of the ones I've used and that can help to understand BLE a bit (sorry, it's a PDF in Spanish):
https://www.google.com/url?sa=t&source=web&rct=j&url=https://upcommons.upc.edu/bitstream/handle/2117/82702/memoria.pdf&ved=2ahUKEwi9n__XheTnAhUI3IUKHdOFAuwQFjAeusgwkJavOJoVoJoVJoVJoVJoVJoVJoVJoVoJoVJoVJoVJoVJoVJoVGJoVJoVJoVGJoVGJoVJJVKJVKVKJVKVKVJVKVKVJVKVKWJVKWKWJWWWWWWWWWWWWWWWWWWWWWWWWWWWWWsCYDsWAHWAVKAWRKWAH

Without going into deep analysis, the summary that I have been able to understand is the following:
1.- After turning it on, the sensor device is in "advertising" mode, this is "without being connected to anyone".
Every certain time interval the sensor sends to the world a package that includes data of its address, name, and basic general characteristics (GAP-Generic Access Profile).
With the nRF app I have deduced that the package has 33 bytes.
Do these packages involve a lot of energy consumption? I suppose not, and with this consumption the manufacturer says that the battery will last 1 year or so.
2.- When the central device (ie smartphone, Raspberry Pi, ESP32, etc.) is in scan mode, it receives the above-mentioned "advertising" packages and decodes data.
3.- If the central device wishes to obtain the T / H / Batt data, it must ask the sensor to initiate a change to a "connected" state, and after a negotiation, the two ends will be in that mode, and in the LCD screen shows the connected icon.
In this "connected" state, there are features that can be received with a specific read command, but others need a command that activates the "Notifications". This is the case of the T / H / Batt values.
If no notification is activated, nor is any parameter read, the sensor remains connected, but the minimum packets continue to be exchanged to keep the connection alive. This is often called Empty Link Layer PD.
In this state, the sensor device consume more energy than the state of "advertising" ?, I do not know, the best way to know will be doing real tests that last a few weeks / months.

Well, after this introduction, let's get to the point.

 In order not to write too much, I will simplify the references to the UUIDs as follows:
PRIMARY SERVICE = "ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6"
I simplify it by writing "ebe0ccb0-"
and the different "CHARACTERISTIC" that are included in "ebe0ccb0-", such as "ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6", I simplify this by writing "ebe0ccc1-".

1.- Then, when both devices are connected, and the central device has activated the reading by "Notifications" the "characteristic ebe0ccc1-" is received every six seconds until a command to stop the "Notifications" is sent or proceed to disconnect completely and the sensor device will return to the "Advertising" state.
In the log of the nRF app we can see the two commands, which are:

gatt.setCharacteristicNotification(ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6, true)
gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x0100)

gatt.setCharacteristicNotification(ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6, false)
gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x0000)

Comandos de Notificaciones

Both commands are activated in the nRF app by clicking on the three arrows icon

Before continuing with the following points, please tell me if this part is understood and I am able to explain myself.
Thank you

@JsBergbau : But also I could fetch maximum and minium data within that 5 minutes. That gives a much better accuracy because you don't miss any short changes.

If you're thinking of using the device's local storage to do that, I'm afraid it doesn't work, since the record you make is "per hour" and only stores a maximum / minimum temperature value and a humidity value. maximum / minimum, but within that hour not within its 5 minute connection period.

@jaggil: Yeah thanks a lot. I understand so far. Please go on in explaining.

@jaggil:

I'm afraid it doesn't work, since the record you make is "per hour" and only stores a maximum / minimum temperature value and a humidity value. maximum / minimum, but within that hour not within its 5 minute connection period.

Yeah I know that, but we have:

5.- Command to read the amount of stored records.

6.- Command to delete all records.

So get min and max from the last hour. Delete all records, get current value. Disconnect. Connect again in 5 minutes and do the same again. I think that will work and you won't lose short spikes within that 5 minutes.

I did some measurements and when connected the sensor used 25 times more power than on advertising mode, more details see here #10 (comment)

I'm looking forward to get the UUIDs/characeteristics @jaggil found out, to implement a connection interval every 5 minutes with maintaining sudden changes within that interval.

For power draw and battery related stuff I've created a new issue. Please discuss there #18
We're now on a good way to stay connected and lose only about 25 % battery lifetime compared to unconnected state. Currently we have with this script a 25 times lower battery lifetime compared to unconnected.

To whom it may concern (Part 2)

2.- To change the temperature units on the LCD screen, we have to use the following commands:
ºF -> gatt.writeCharacteristic (ebe0ccbe-7a0a-4b0c-8a1a-6ff2997da3a6, value = 0x01)
ºC -> gatt.writeCharacteristic (ebe0ccbe-7a0a-4b0c-8a1a-6ff2997da3a6, value = 0x00)

TempUnit

Of course, we can also read the current value with the command
gatt.readCharacteristic (ebe0ccbe-7a0a-4b0c-8a1a-6ff2997da3a6)

The data is a single byte.
As I mentioned in a previous post, the reading of T by notifications (ebe0ccc1-) is still in degrees celsius.

3.- To set the internal clock, we must know that it is in the following location and that the data is in UnixTime (little-endian) format.

Time

The read command is:
gatt.readCharacteristic (ebe0ccb7-7a0a-4b0c-8a1a-6ff2997da3a6)
Read Response received from ebe0ccb7-7a0a-4b0c-8a1a-6ff2997da3a6, value: (0x) 65-FC-54-5E

Converting the data into decimal we have:
UnixTime = 5E54FC65 Hex = 1582627945 seconds (from 1-1-1970)
Or what is the same = Tuesday, 25-Feb-20 10:52:25 UTC
Conversion made at https://www.unixtimestamp.com/index.php

The command to set the clock is:
gatt.writeCharacteristic (ebe0ccb7-7a0a-4b0c-8a1a-6ff2997da3a6, value = 0x65FC545E)

If the nRF app is used, the "BYTE ARRAY" data type must be selected in the menu that appears when the write icon is pressed (up arrow)
The clock setting is important if we want to see that the hourly records are recorded with the correct time.

4.- Hourly records of max / min values.
In the following location we have the reading by notifications of the max / min data of T / H, which by default the sensor device stores.

Data record

Each register occupies 14 bytes. All data has the little-endian format (except its has a single size byte).
The first group of 4 bytes (marked "Ind") is the general index of the register.
Index = 00000149 Hex = 329 decimal
With those 4 bytes you can address a lot of records, but I suppose the device will have a smaller capacity according to the size of its internal memory.

The next 4 bytes are the date / time in UnixTime format.
Time = 5E550C40 Hex = 1582632 000 dec = Tuesday, 25-Feb-20 16:23:16 UTC

The next two bytes are the maximum temperature.
That is: Tmax = 00DD hex = 221 ° C (x 10). Actual value is 22.1 ° C
The next byte is maximum humidity.
This is: Hmax = 43 Hex = 67%
And the same concept for minimum values.
Tmin = 00D5 hex = 213 ° C (x10). Actual value 21.3 ºC
Hmin = 3C Hex = 60%

The following command activate the reading by notifications:
Enabling notifications for ebe0ccbc-7a0a-4b0c-8a1a-6ff2997da3a6
gatt.setCharacteristicNotification (ebe0ccbc-7a0a-4b0c-8a1a-6ff2997da3a6, true)
gatt.writeDescriptor (00002902-0000-1000-8000-00805f9b34fb, value = 0x0100)

Disabling notifications for ebe0ccbc-7a0a-4b0c-8a1a-6ff2997da3a6
gatt.setCharacteristicNotification (ebe0ccbc-7a0a-4b0c-8a1a-6ff2997da3a6, false)
gatt.writeDescriptor (00002902-0000-1000-8000-00805f9b34fb, value = 0x0000)
Data written to describ. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 00-00

When notifications are activated for the first time after a new connection, the sensor device sends all the records starting with the oldest one.
When the device sends the last one, the notifications are stopped, and even if they are deactivated and activated again in the nRF app, the sensor does not send them again.
To make the device send them again, without making a complete disconnection, it is necessary to initialize the sending index, we see this in point 7.

I will finish this part here so as not to make very extensive publications.
I made some small updates in part 1
I will post part 3 later

To whom it may concern (Part 3)

5 and 6.- Command to read the amount of stored records and deleted.
This information can be read in the following location

Cantidad de registros

What I have been able to understand, we have a record index and total records, that is:
Index of the last record = 0000014A hex = 330 dec
Total records = 000000A7 hex = 167 dec

Why don't they match? Because on this device I have already done some deletion of records.
With these two data, we can calculate the index of the oldest record, that is:
Oldest index = 0x0000014A -0x000000A7 + 0x01 = 0x000000A4 = 164 dec
We add 1 because the index starts at 0x00000000.
The reading comado is:
gatt.readCharacteristic (ebe0ccb9-7a0a-4b0c-8a1a-6ff2997da3a6)
Read Response received from ebe0ccb9-7a0a-4b0c-8a1a-6ff2997da3a6, value: (0x) 4A-01-00-00-A7-01-00-00

The delete command is located at:

Borrar registros

And in the nRF app log we have:
gatt.writeCharacteristic (ebe0ccd1-7a0a-4b0c-8a1a-6ff2997da3a6, value = 0x01)
Data written to ebe0ccd1-7a0a-4b0c-8a1a-6ff2997da3a6, value: (0x) 01
"(0x) 01" sent

If we now read in "ebe0ccb9-" we find that the total number of records is 0x00000000, but the first index is the last one that had been registered.
gatt.readCharacteristic (ebe0ccb9-7a0a-4b0c-8a1a-6ff2997da3a6)
Read Response received from ebe0ccb9-7a0a-4b0c-8a1a-6ff2997da3a6, value: (0x) 4A-01-00-00-00-00-00-00

My opinion is that the delete command only affects the storage of Max / Min records, but not the evaluation that the device is currently doing with the temperature / humidity and that it will register when the 1 hour cycle is completed .

What we don't know is when will the index restart?
When the internal memory becomes full?
When it reaches its maximum value of 0xFFFFFFFF?
Answer pending.

7.- Command to read by notifications, from a specific record.
As I have understood, this command initializes the first index that must be transmitted when the records are read by notifications.
It is located in:

Set indice

The range of the value we can write will be what we determine when we have read "ebe0ccb9-" and we will have the oldest and last value.
We can choose not to send us all the records, but from a number we want.
In the nRF log we can see the command:
gatt.writeCharacteristic (ebe0ccba-7a0a-4b0c-8a1a-6ff2997da3a6, value = 0x014D0000)
Data written to ebe0ccba-7a0a-4b0c-8a1a-6ff2997da3a6, value: (0x) 01-4D-00-00
"(0x) 01-4D-00-00" sent

8.- Command to read the last stored record (in the last hour)
If we are only interested in reading the last record, the command is located at:

Último registro

The data is decoded in the same way as in point 4

9.- Command to initialize comfort values for the face icon
In the small manual in Chinese language, we find the following table:

tabla confort_300

It is understood that the "happy face" located in the center is where the temperature and humidity limits provide the best comfort

Well, the default T / H limits are found in:

Limites confort

Where the limits are:
TempMax = 0x0A8C = 2700 => 27 ºC
TempMin = 0x076C = 1900 => 19 ºC
HumMax = 0x55 = 85%
HumMin = 0x14 = 20%

The commands to read and write are the following:
Reading characteristic ebe0ccd7-7a0a-4b0c-8a1a-6ff2997da3a6
gatt.readCharacteristic (ebe0ccd7-7a0a-4b0c-8a1a-6ff2997da3a6)
Read Response received from ebe0ccd7-7a0a-4b0c-8a1a-6ff2997da3a6, value: (0x) 8C-0A-6C-07-55-14
"(0x) 8C-0A-6C-07-55-14" received

Writing request to characteristic ebe0ccd7-7a0a-4b0c-8a1a-6ff2997da3a6
gatt.writeCharacteristic (ebe0ccd7-7a0a-4b0c-8a1a-6ff2997da3a6, value = 0x8C0A6C075514)
Data written to ebe0ccd7-7a0a-4b0c-8a1a-6ff2997da3a6, value: (0x) 8C-0A-6C-07-55-14
"(0x) 8C-0A-6C-07-55-14" sent


Well, here is all that I have been able to decode.
The following characteristics are pending
Set conn interval
Desconectar

Luck and thanks


Updated 2020/02/27
After @JsBergbau has investigated the communications interval in #18 (comment), I have thought about reflecting it in this post, so that all the GATT codes that are decoded meet in the same place.

We are talking about the following characteristic:
Set conn interval_00

With this characteristic you can configure the communications interval, once the connection has been established, between the sensor device and the central device:

When the two devices negotiate the connection parameters, they agree on parameters to transmit data very quickly, as we can see in the log with the nRF app:
I 13: 17: 45.337 Connected to A4: C1: 38: 89: 78: 1C
V 13: 17: 45.339 Requesting new MTU ...
D 13: 17: 45,339 gatt.requestMtu (517)
I 13: 17: 45.623 Connection parameters updated (interval: 7.5ms, latency: 0, timeout: 5000ms)
I 13: 17: 46.797 MTU changed to: 23
V 13: 17: 46,820 Discovering services ...
D 13: 17: 46.820 gatt.discoverServices ()
I 13: 17: 46.836 Connection parameters updated (interval: 30.0ms, latency: 0, timeout: 900ms)
D 13: 17: 46.856 [Callback] Services discovered with status: 0

As you can see, the final interval is 30.0 ms

But the problem is that this interval discharges the battery very quickly.

To change it we can use the command:
V 13: 40: 07.676 Writing request to characteristic ebe0ccd8-7a0a-4b0c-8a1a-6ff2997da3a6
D 13: 40: 07.676 gatt.writeCharacteristic (ebe0ccd8-7a0a-4b0c-8a1a-6ff2997da3a6, value = 0xF401)
I 13: 40: 07.855 Data written to ebe0ccd8-7a0a-4b0c-8a1a-6ff2997da3a6, value: (0x) F4-01
At 13: 40: 07.855 "(0x) F4-01" sent
I 13: 40: 08.118 Connection parameters updated (interval: 500.0ms, latency: 0, timeout: 6000ms).

Now the interval is 500ms and the battery consumption will be much lower, but communications are slower, although for T / H parameters it is not critical.

I have read that the official BLE protocol includes intervals from 7.5 ms to 4 seconds, but the LYWSD03MMC device supports a maximum of 500 ms.
https://www.novelbits.io/ble-connection-intervals/

Thank you very much for investing your time in investigating and your detailed report for the community. I've linked to this issue in the readme that also other users can find it easily.

Hi all,

I would like to use an slightly modified version of this script to receive notifications from this new xiaomi bluetooth door/window sensor:

image

The first thing is to find out the way to connect to this sensor. I have started following @jaggil instructions, but I've had no success.

I have connected to the device using NRF android app, and I have enabled all notifications, but I still do not receive any notification.

image

If I do the same with a LYWSD03MMC, I periodically receive notifications.

I don't know what to test next. Any suggestion?

Thanks for your help.

Hello @pulgarzito , without having a device like yours, we cannot do tests to help you effectively..
Anyway, I would try to find a "CHARACTERISTIC" that contains the word NOTIFY, just like the LYWSD03MMC device has.

image

It is also possible that there is a "CHARACTERISTIC" (a bit hidden) that blocks notifications in a general way.
It is a matter of trying and trying. I spent a long time finding the meaning of almost all the features of the LYWSD03MMC.
Good luck.

@jaggil, @JsBergbau I did some measurements on LYWSD02MMC - the last 2 bytes of characteristic ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6 are not battery millivolts (mV) or the measurement is extremely imprecise when the battery is low (sometimes value of these 2 bytes increase when the real voltage has decreased).
Also when the battery is low the difference between this value and the actual battery millivolts is very high (up to 355 mV according to my measurements).
When the battery is full this value looks like battery millivolts - then the measured difference (between the value and actual voltage) was less than 50 mV (I did a single measurement and didn't write down the details).

The following measurements were made by connecting a single almost empty CR2032 battery in parallel with 3300 μF capacitor and 2 multimeters (manufactured by Extech and Aneng) to LYWSD02MMC.

Value of the characteristic Last 2 bytes as little-endian integer Extech reading Aneng reading Comment
B8-08-2D-7F-09 2431 2240 mV Not yet connected
B7-08-2D-92-09 2450 2225 mV Not yet connected Value in characteristic increases while actual voltage decreases
B9-08-2D-1C-09 2332 2173 mV 2178 mV
B5-08-2D-99-09 2457 2169 mV 2173 mV Value in characteristic increases while actual voltage decreases
B1-08-2D-7A-09 2426 2157 mV 2162 mV
B2-08-2D-31-09 2353 2144 mV 2148 mV
B0-08-2D-5D-09 2397 2128 mV 2133 mV Value in characteristic increases while actual voltage decreases
B2-08-2D-5D-09 2397 2126 mV 2131 mV
B1-08-2D-5D-09 2397 2124 mV 2128 mV
B0-08-2D-BA-09 2490 2122 mV 2126 mV Value in characteristic increases while actual voltage decreases; measurement done around 22 seconds after previous measurement