matthias-bs / ATC_MiThermometer

Arduino BLE Client library for receiving ATC_MiThermometer Data (as Advertising Data)
MIT License
9 stars 4 forks source link

GetName() #9

Closed kharar closed 6 months ago

kharar commented 6 months ago

Is your feature request related to a problem? Please describe. When fetchins sensor data for several devices I would also like to include the bluetooth name of the sensor in my readout. Currently all we got is the MAC and I don't want to maintain a list copy of the BTnames in code.

Describe the solution you'd like Update the struct MiThData_S and supporting code to hold the string value of the bluetooth name:

// MiThermometer data struct / type
struct MiThData_S {
        bool        valid;          //!< data valid
        int16_t     temperature;    //!< temperature x 100°C
        uint16_t    humidity;       //!< humidity x 100%
        uint16_t    batt_voltage;   //!< battery voltage [mv]
        uint8_t     batt_level;     //!< battery level   [%]
        int16_t     rssi;           //!< RSSI [dBm]
        uint8_t     count;          //!< measurement count
        std::string name;           //!< bluetooth name
        bool        reedSwitchState;
        bool        gpioTrgOutput;
        bool        controlParameters;
        bool        tempTriggerEvent;
        bool        humiTriggerEvent;
};

In such a way that we will be able to get the BT name just like any other sensor detail, for instance: std::string myName = miThDat.name; and int16_t myRssi = miThDat.rssi

Describe alternatives you've considered I have already tried modifying the supporting code myself, but I got to admit that I am in way over my head

I got as far as to insert these two lines at line 168 of ATC_MiThermometer.cpp, right next to the data[n].rssi code:

            // Received Bluetooth Name
            data[n].name = foundDevices.getDevice(i).getName().c_str();

but this is not enough to get it working

Additional context For someone who is not a complete noob, this is probably an easy fix :-)

matthias-bs commented 6 months ago

Hi,

I started looking into this right now, but most of the devices within reach to not seem to provide a name:

[182610][D][ATC_MiThermometer.cpp:99] getData(): haveName(): 0
[182616][D][ATC_MiThermometer.cpp:100] getData(): getName(): 
[182622][D][ATC_MiThermometer.cpp:106] getData(): Found: 43:07:35:f5:ef:f1  comparing to: a4:c1:38:02:8b:e0
[182631][D][ATC_MiThermometer.cpp:174] getData(): 
[182636][D][ATC_MiThermometer.cpp:106] getData(): Found: 43:07:35:f5:ef:f1  comparing to: a4:c1:38:64:8f:10
[182646][D][ATC_MiThermometer.cpp:174] getData(): 
[182650][D][ATC_MiThermometer.cpp:106] getData(): Found: 43:07:35:f5:ef:f1  comparing to: a4:c1:38:f3:c1:b4
[182660][D][ATC_MiThermometer.cpp:174] getData(): 
[182665][D][ATC_MiThermometer.cpp:99] getData(): haveName(): 1
[182670][D][ATC_MiThermometer.cpp:100] getData(): getName(): REVITIVEW5202723
[182677][D][ATC_MiThermometer.cpp:106] getData(): Found: 34:81:f4:40:62:51  comparing to: a4:c1:38:02:8b:e0
[182687][D][ATC_MiThermometer.cpp:174] getData(): 
[182692][D][ATC_MiThermometer.cpp:106] getData(): Found: 34:81:f4:40:62:51  comparing to: a4:c1:38:64:8f:10
[182701][D][ATC_MiThermometer.cpp:174] getData(): 
[182706][D][ATC_MiThermometer.cpp:106] getData(): Found: 34:81:f4:40:62:51  comparing to: a4:c1:38:f3:c1:b4

Apart from that, you already have the implementation in your request.

Regards, Matthias

matthias-bs commented 6 months ago

Added in https://github.com/matthias-bs/ATC_MiThermometer/pull/10

kharar commented 6 months ago

It is possible that only few people use it but all bluetooth devices supports advertising this information. For the LYWSD03 you can even edit the name in the Telink Flasher: Telink_flasher

To my regret the implementation I came up with is not working. I believe it has something to do with the data structure of NimBLE, unfortunately I am not code wizard enough to figure out how to pull this string from within the framework of this repository

I will take a look at #10

matthias-bs commented 6 months ago

Ah, o.k. I just added it and created a new release v0.4.1 which should be available in the Arduino library manager within an hour. Hope it works - please let me know.

kharar commented 6 months ago

Thanks, I just pulled it from here and tested the example code from the from page but unfortunately the name is not passed. My output looks like this:

Sensor 0: A4:C1:38:B2:90:45
Name: 
23.68°C
33.08%
3.938V
100%
-90dBm

I was expecting:

Name: Bathroom
kharar commented 6 months ago

I thought I'd done something wrong so I just went and pulled 0.4.1 directly from the releases page, but it's the same result, no name

kharar commented 6 months ago

As far as I figured out, if I replace

data[n].name = foundDevices.getDevice(i).getName().c_str(); with data[n].name = "Test"; //foundDevices.getDevice(i).getName().c_str(); Then the name "Test" is passed correctly, therefore I am assuming that the fault lies somewhere along the foundDevices.getDevice(i).getName().c_str() but as I mentioned before my understanding of the NimBLE integration is being challenged a lot here.

matthias-bs commented 6 months ago

I found that it works if you change to active scan mode in ATC_MiThermometer.cpp and slightly increase the scanTime:

_pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster

I don't know if this is expected behaviour or a bug - if the other data is valid, I would expect the name to be available, too.

You can set the Debug Level to "Debug" in the Arduino IDE and recompile to get more info from NimBLE and this library.

matthias-bs commented 6 months ago

See https://github.com/matthias-bs/ATC_MiThermometer/pull/11 and Release v0.4.2

kharar commented 6 months ago

With 0.4.2 I can confirm that it works as you described, also accasionally missing a name now and then, however changing scan time from 5 to 10 does not seem to affect this. It seems safe enough to assume this particular sub-problem lies within the mechanics of NimBLE or even the Bluetooth protocol itself.

Thank you so much for your effort, I am all fine with closing this issue here, unless you want to finetune the MiThData_S.valid; to encompass an optional name check

matthias-bs commented 6 months ago

I'll leave it is at is for now. I used 15 seconds when I got the name reliably. Maybe it is related to some multiple of the advertising cycle time.

matthias-bs commented 6 months ago

Here is the answer: https://development.libelium.com/ble-networking-guide/scanning-ble-devices

On the other hand, in active scanning the module will request more information once an advertisement is received, and the advertiser will answer with information like friendly name and supported profiles.

I think the reason for missing names during active scanning is that I stop scanning when I receive an advertisement with the wanted address. At that time, the response to the advertising request may not have been received yet.