Skip to content

NimBLE_Client + Beacon BLE #215

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
lucasromeiro opened this issue Apr 1, 2021 · 57 comments
Closed

NimBLE_Client + Beacon BLE #215

lucasromeiro opened this issue Apr 1, 2021 · 57 comments

Comments

@lucasromeiro
Copy link

Hello, first I would like to congratulate you for the excellent work!

I have a small challenge:

I always used esp8266.
Now I need to connect an esp32 to a temperature and humidity (BLE) sensor.

I'm going to send a picture of him here.

I used your Scan example and it worked, found the equipment!

But, I am not able to connect to the BLE beacon to receive the temperature and humidity.
I tried to use the example NimBLE_Client.ino but was unsuccessful.

Would you help me? I didn't find many instructions and I really liked the example because it is very organized, I would like to make it work.

As there are no instructions in the example, I did not change anything.

I don't know what to do to change and read the Beacon variables (temperature and humidity)

Thank you so much for helping us all!

https://sc04.alicdn.com/kf/H4188ed456d95460a96dcffc01e015e6fl.jpg

Advertised Device found: Name: ThermoBeacon, Address: 70:f7:00:00:11:1a, manufacturer data: 100000001a110000f770830cef01be04c4300000, serviceUUID: 0xfff0, txPower: 0

@h2zero
Copy link
Owner

h2zero commented Apr 1, 2021

Hi @lucasromeiro I am unable to see the picture in the link.

I can say that if you have saved the pointer to the advertised device or the address of it you should be able to connect to it. Maybe you could provide a log output and/or code example?

@lucasromeiro
Copy link
Author

Hello, I used the CLIENT example. I didn't change anything. How can I change this information?

Advertised Device found: Name: ThermoBeacon, Address: 70:f7:00:00:11:1a, manufacturer data: 100000001a110000f770830cef01be04c4300000, serviceUUID: 0xfff0, txPower: 0

image

@h2zero
Copy link
Owner

h2zero commented Apr 2, 2021

Ok, the easiest thing to change is this line to the service UUID of your device (FFF0).

So change that to if(advertisedDevice->isAdvertisingService(NimBLEUUID("FFF0")))

That should get you connected to it, after that you will need to get the services and characteristics from it and read/write to them. I don't know what the UUID's are except for the one you mentioned but you can use NimBLEClient::discoverAttributes() after connecting to get the database from the device. After that you could loop through each service/characteristic and print the UUID's.

We can go over that process once you get connected to the device, let me know.

@lucasromeiro
Copy link
Author

lucasromeiro commented Apr 2, 2021

NICE!!!
The result of FFF0:

image

THANKS!!!!

Can you explain better how to do the loop to discover the services and features?

image

After I discover these services, how do I use them?

One last important question, I have another BLE device, but it does not return this code 000F that worked on this one, how do I do it in these cases? Would I put the name? the MAC? Do you have these options?

Thank you very much for all your help, it will solve a problem of mine !!!

Other beacon scan:

Found another manufacturers beacon!
strManufacturerData: 29 [6][0][1][9][20][2][EA][31][EB][8A][7A][7A][7F][22][6E][EB][C2][7E][D5][57][C8][43][24][54][D6][D3][18][2F][11]
Device name: T201

@h2zero
Copy link
Owner

h2zero commented Apr 2, 2021

You will have quite a bit of work to do here but I will try to explain the work flow as best I can.

  • After connection you can call NimBLEClient::discoverAttributes(); which will get the attribute database from the device.
  • Next you want to do something with those attributes, probably read their UUID's/values. To do that you could use something like this:
 auto pServices = pClient->getServices();
 for (auto pService : *pServices)  {
      Serial.printf("Found service: %s\n", pService->getUUID()->toString.c_str());
      auto pCharacteristics = pService->getCharacteristics();
      for (auto pCharacteristic : *pCharacteristics) {
          Serial.printf("Found characteristic: %s  ", pCharacteristic->getUUID()->toString.c_str());
          Serial.printf("Value: %s\n", pCharacteristic->readValue().c_str())
      }
  }

To connect to the other device I suggest comparing the name instead of the UUID since it does not advertise it.

@lucasromeiro
Copy link
Author

Hello, I managed to adapt to make it work!
Look how it looks:

image

The code I modified some things that had silly errors and put in this place. is correct?

I did not find the codes for temperature and humidity. =(

image

https://btprodspecificationrefs.blob.core.windows.net/assigned-values/16-bit%20UUID%20Numbers%20Document.pdf

Here is a table of all the codes, none of them are for temperature and humidity.
What do you suggest I do?

as for your suggestion to put the name of the sensor, I think it will be better to put MAC, so I will be able to differentiate both, Would it be possible to work like this?

if(advertisedDevice->isAdvertisingService(NimBLEUUID("MAC HERE!!!!")))

@lucasromeiro
Copy link
Author

I was able to find it at MAC!

But I still don't know how to put a command to read temperature and humidity. ☹

image

@h2zero
Copy link
Owner

h2zero commented Apr 2, 2021

Glad you got that sorted.

You will need to change the service/characteristic get() calls to use the UUID's the device has for those values. Looks like it's the service UUID ffe0 and characteristic UUID's fff5 and fff3. When you read the values from those you will want to convert the string to an integer value like this : int temperature = pChar->readValue<int>() and uint16_t humidity = pChar->readValue<uint16_t>()

@lucasromeiro
Copy link
Author

Hello, I tried the combinations that passed me and I didn't get any results.
Look how it looks:

Did I do something wrong?

image

image

@h2zero
Copy link
Owner

h2zero commented Apr 2, 2021

Sorry, I didn't look well enough at the service UUID's. The service you want is 180a and the characteristics appear to be 2a2a and 2a50. You will have to play around with them all to find the data you're looking for or use a phone and nRFConnect app to be more precise.

@lucasromeiro
Copy link
Author

Hi!

I did the tests, look at the prints below.

I get paid but I still can't see the temperature and humidity.
I read somewhere that the 2 bytes received that have either changed LITTLE ENDIAN) Something like that.
I'm a novice, I may be confusing.

What can I do?

For 180a (2a2a):

image

For 180a (2a50):

image

image

what is this(tasty)?

image

@h2zero
Copy link
Owner

h2zero commented Apr 2, 2021

what is this(tasty)?

lol that's just silly code that is for demonstration, you should remove all of that as you don't need it.

I don't know what the values are that you are getting, the device doesn't seem to be using the standard temp/humidity characteristics. Maybe search google for information on that device, probably someone has figured it out already.

One thing you can try also is changing the temperature read to this: int16_t temperature = pChar->readValue<int16_t>()

@lucasromeiro
Copy link
Author

Got it, how do you suggest that I search?
As I am not a profound connoisseur of the area, I am not sure how to look.
What words / phrases do I search for?

Wouldn't this data that I received and show above be correct and out of order? Perhaps it is correct and just needs to be interpreted correctly. What do you think?

TEST: int16_t temperature = pChar->readValue<int16_t>():

For 180a (2a50):

image

For 180a (2a2a):

image

These codes according to the table say something else. Are we not looking at the wrong data?

2a2a:
image

2a50:
image

FONT: https://btprodspecificationrefs.blob.core.windows.net/assigned-values/16-bit%20UUID%20Numbers%20Document.pdf

@h2zero
Copy link
Owner

h2zero commented Apr 2, 2021

Yes those do look to be the wrong data, however I do not see the standard temp / humidity characteristics available so I guessed that they used those instead for some reason. The temperature should be UUID 2a6e and humidity 2a6f but I do not see them in the list. Perhaps it only advertises those values?

@lucasromeiro
Copy link
Author

Thanks for the tip, I looked at the nRFConnect app.

Look at the result:

it helps?
Was that what you wanted?

image

image

image

image

image

image

@h2zero
Copy link
Owner

h2zero commented Apr 2, 2021

Thanks, I think I see what it's doing now, it will only send the data over notifications. To do that you will have to subscribe to UUID FFF3 and possibly FFF5.

So you can remove all the readvalue code and just change it to get those UUID's and call pChr->subscribe(true, notifyCB). You'll probably need to change the code in the notifyCB to properly print the float values.

@lucasromeiro
Copy link
Author

lucasromeiro commented Apr 2, 2021

Hello, what would notifications be, what is the difference for the method we were doing?

I like to understand how it works. That's why I ask questions. (Thank you for your help)

I didn't quite understand what I should do now to make these notifications work.
I'm confused.
Can you explain better?

Can I simulate this by the application I downloaded on my cell phone and validate that it will work?

If we can validate the reading using the application I think it is easier to qchar the correro command. not? but I don't know how to translate these results. to find out if it is correct.

App result:

A2A2:
0xFE-00-65-78-70-65-72-69-6D-65-6E-74-61-6C

2A50:
0x01-04-05-00-00-10-01

How I can see it?

@h2zero
Copy link
Owner

h2zero commented Apr 3, 2021

Yes this is a different operation, there is no reading or writing of characteristics that need to be done for this device.
When you subscribe for notifications the device will send you updated values that you will receive in the notifyCB function that you can see in the example code. Simply, you can use the code in my previous post to replace all the read/write stuff in the example then wait to see the notification callback and watch the values come from the device.

You can also do this on your phone when you click on the enable notifications button in the screen pic you posted earlier. When you do this you should see the characteristic value being updated once in a while. The basic concept is connect->subscribe to the characteristic notifications->wait for data, nothing more to do.

I think you would benefit more from a little more study of BLE concepts so you'll understand more of what you're doing.
Here is a link with tutorials to help you with the concepts https://www.novelbits.io/.

@lucasromeiro
Copy link
Author

I'll try to do what you told me! I'll let you know tomorrow morning.
Thanks for the tip of the site! I will access to learn !!

I decided to do it on the app as you told me. but nothing happened. Did I do something wrong?

506331D1-6402-4E2D-82D6-B3A0F513C605

@h2zero
Copy link
Owner

h2zero commented Apr 3, 2021

I think this is a difficult device to work with as it is using non-standard characteristics.
From conversations in the past about such devices it may be that you need to write a value to the UUID FFF5 first before it will send notifications (this is probably the dumbest thing I ever heard of, sorry for the rant, but it is what it is).

Anyway, with notifications enabled as you show above, you should see the value being updated every so often, if not, try writing a value 1 to the characteristic FFF5 and see what happens.

You're doing fine, keep up the work, this is just a particularly difficult device to work with.

@lucasromeiro
Copy link
Author

It seems very difficult to even work with these devices. Your tips are helping me a lot! I don't know anyone else who can help me with this. As it is a device that does not follow a standard, it will be difficult to solve it yourself. (thanks for all the help!) I tried to do what you told me to do, but by signing the notification by clicking on the 3 down arrows that are circled, no photo, I didn't get anything. no variables have been updated. nothing kept updating itself. :( I tried to do what you asked and I wrote 1. I tried to write bit, utf8, etc. I tried to write other values, I also wrote in the other data sending fields. The only time something changed was when I sent bit 1 on FFF5. this appears the value that is circled in red in the photo. that value has not changed anymore.

F60A6A67-54B6-4966-B8A7-504D74EB3E5C

@h2zero
Copy link
Owner

h2zero commented Apr 3, 2021

That looks like you've got it solved, writing 1 to fff5 caused a notification to be sent for the fff3 characteristic, the value was updated to 0x0105. Now you'll need to translate that into the value you expect to see, assuming little endian format that would make it 0x0501 = 1281 or 12.81 depending on format, or big endian 0x0105 = 261 or 26.1, whatever makes sense in your conditions will determine the conversion.

@lucasromeiro
Copy link
Author

Hello, is that what I should do in the code?
I tried to put now the part you asked for and take the readings: pChr->subscribe(true, notifyCB)

I'm not quite sure what to do now.

Modify notifyCB? how?

image

image

Regarding the change in fff5 that caused a notification in fff3, it doesn't seem like anything I'm expecting. It cannot be temperature or humidity in any shape. I investigated and found no relationship.
This value does not change much, even if I change the room temperature or humidity.
I believe that we are capturing some other internal variable of control of the equipment that we will not be able to understand.

There must be some other code to be sent and get the correct variables (I imagine).

@h2zero
Copy link
Owner

h2zero commented Apr 3, 2021

In that code you have subscribed to fff5 which is incorrect, you want fff3 there, then write a value to fff5. As for what the data is, I don't know, you might need to disconnect and reconnect to get updated values or something, you'll have to try some things with your phone to see if you can figure it out. Do you know the name/model of this device?

@lucasromeiro
Copy link
Author

Now is correct?

` /** Now we can read/write/subscribe the charateristics of the services we are interested in /
NimBLERemoteService
pSvc = nullptr;
NimBLERemoteCharacteristic* pChr = nullptr;
NimBLERemoteDescriptor* pDsc = nullptr;

pSvc = pClient->getService("ffe0");//DEAD//ffe0//180a


if(pSvc) {     /** make sure it's not null */


  pChr = pSvc->getCharacteristic("fff5");//BEEF//fff5/fff3
  pChr->subscribe(true, notifyCB);
  
  if(pChr->writeValue(true)) {//tasty
      Serial.print("Wrote new value to: ");
      Serial.println(pChr->getUUID().toString().c_str());
  }
  else {
      /** Disconnect if write failed */
      pClient->disconnect();
      return false;
  }

  delay(500);
            
    pChr = pSvc->getCharacteristic("fff3");
    
    Serial.print("(int): ");
    int temperature = pChr->readValue<int>();

    //int16_t temperature = pChr->readValue<int16_t>();
    Serial.println(temperature);
    
    Serial.print("(uint16_t): ");
    uint16_t humidity = pChr->readValue<uint16_t>();
    Serial.println(humidity);

`
Result:

image

The device is "WS02": https://www.aliexpress.com/item/1005001626596814.html?spm=a2g0s.9042311.0.0.27424c4d3lFjTo

image

@h2zero
Copy link
Owner

h2zero commented Apr 3, 2021

if(pSvc) {     /** make sure it's not null */


  pChr = pSvc->getCharacteristic("fff5");//BEEF//fff5/fff3
  pChr->subscribe(true, notifyCB);
  
  if(pChr->writeValue(true)) {//tasty
      Serial.print("Wrote new value to: ");
      Serial.println(pChr->getUUID().toString().c_str());
  }

That's not quite correct, try:

if(pSvc) {     /** make sure it's not null */

  // subscribe to fff3
  pChr = pSvc->getCharacteristic("fff3");
  pChr->subscribe(true, notifyCB);

  // write value to fff5 to trigger notification?
  pChr = pSvc->getCharacteristic("fff5");
  
  if(pChr->writeValue(true)) {
      Serial.print("Wrote new value to: ");
      Serial.println(pChr->getUUID().toString().c_str());
  }

Try that, let me know what happens.

@h2zero
Copy link
Owner

h2zero commented Apr 3, 2021

I tried looking up some info on this and couldn't find much. Perhaps @1technophile has seen this type of thing before?

@lucasromeiro
Copy link
Author

The code:

`

pSvc = pClient->getService("ffe0");//DEAD//ffe0//180a


if(pSvc) {     /** make sure it's not null */


  // subscribe to fff3
  pChr = pSvc->getCharacteristic("fff3");
  pChr->subscribe(true, notifyCB);

  // write value to fff5 to trigger notification?
  pChr = pSvc->getCharacteristic("fff5");
  
  if(pChr->writeValue(true)) {
      Serial.print("Wrote new value to: ");
      Serial.println(pChr->getUUID().toString().c_str());
  }

  delay(5000);
            
    pChr = pSvc->getCharacteristic("fff3");
    
    Serial.print("(int): ");
    int temperature = pChr->readValue<int>();

    //int16_t temperature = pChr->readValue<int16_t>();
    Serial.println(temperature);
    
    Serial.print("(uint16_t): ");
    uint16_t humidity = pChr->readValue<uint16_t>();
    Serial.println(humidity);

`

Result:

image

@1technophile
Copy link

1technophile commented Apr 3, 2021

Maybe a different approach could be to check if the device advertises temperature and humidity, this way you would avoid the BLE connection and save its battery life.
If true you just need a scan and to convert the data.

So as to check this, you scan the device several times, take notes of the manufacturer data and service data read, record the temperature from the app and see if there is a correlation.

If you want to go this track, post here, the scan results and what you see in the app after the scan. I think 5-10 scans data are necessary.

@lucasromeiro
Copy link
Author

This world is too small!

I was looking at @1technophile work because I have a LYWSD03MMC sensor here with me!
It also provides temperature and humidity. It seems to be easier to use.
I was thinking of using LYWSD03MMC also in my project.

I'm looking to talk to @1technophile see if he can help me with this. I saw his GITHUB code. It is very extensive and professional. Some things I don't understand.
I wanted his help to make a simple .ino, just to read the data from the LYWSD03MMC sensor and show it in the serial, then I'll put it on the LCD of my M5 STICKC.

I was VERY happy that you guys know each other!

@lucasromeiro
Copy link
Author

For reference:

image

@1technophile
Copy link

Here is what we need for at least 5 scans, would be better with big amplitudes of temp and hum, so as to get relevant measurement value, I suggest that you find the app corresponding to the beacon and check the temp and hum on it.

Manufacturerdata temp hum
100000001a110000f7705d0c0302170413010000
100000001a110000f770b80b0002cc0404000000

@lucasromeiro
Copy link
Author

lucasromeiro commented Apr 3, 2021

Here is what we need for at least 5 scans, would be better with big amplitudes of temp and hum, so as to get relevant measurement value, I suggest that you find the app corresponding to the beacon and check the temp and hum on it.

Manufacturerdata temp hum
100000001a110000f7705d0c0302170413010000
100000001a110000f770b80b0002cc0404000000

I believe this is what you asked for:

manufacturer data TEMP HUM
100000001a110000f770580cf5016c0443090000 31.31 70.8
100000001a110000f7701302ac000000f4017f080000 31.31 71.1
100000001a110000f770580cf501580452090000 31.31 69.9
100000001a110000f770570cf5015f0459090000 31.31 69.6
100000001a110000f7701302ac000000f4017f080000 31.31 70.2
100000001a110000f770580cf501640467090000 31.31 69.9
100000001a110000f770580cf5015a046e090000 31.31 69.6
100000001a110000f7701302ac000000f4017f080000 31.31 71.8
100000001a110000f7701302ac000000f4017f080000 31.31 70.8

@1technophile
Copy link

It is strange that your temp doesn't change. Could you try to add lines with different temperatures by changing the sensor location.

@1technophile
Copy link

1technophile commented Apr 3, 2021

A track to follow for the humidity (got help from this):
10 00 00 00 1a 11 00 00 f7 70 58 0c f5 01 6c 04 43 09 00 00 31.31 70.8
04 6c to dec = 1132
1132/16 = 70.75

10 00 00 00 1a 11 00 00 f7 70 58 0c f5 01 5a 04 6e 09 00 00 31.31 69.6
04 5a to dec = 1114
1114/16 = 69.625

@1technophile
Copy link

For the temp:
10 00 00 00 1a 11 00 00 f7 70 58 0c f5 01 6c 04 43 09 00 00 31.31 70.8
01 f5 to dec = 501
501/16 = 31.3125

10 00 00 00 1a 11 00 00 f7 70 58 0c f5 01 5a 04 6e 09 00 00 31.31 69.6
01 f5 to dec = 501
501/16 = 31.3125

For the battery
10 00 00 00 1a 11 00 00 f7 70 58 0c f5 01 6c 04 43 09 00 00 31.31 70.8
0c 58 to dec = 3160mV

@lucasromeiro
Copy link
Author

For the temp:
10 00 00 00 1a 11 00 00 f7 70 58 0c f5 01 6c 04 43 09 00 00 31.31 70.8
01 f5 to dec = 501
501/16 = 31.3125

10 00 00 00 1a 11 00 00 f7 70 58 0c f5 01 5a 04 6e 09 00 00 31.31 69.6
01 f5 to dec = 501
501/16 = 31.3125

For the battery
10 00 00 00 1a 11 00 00 f7 70 58 0c f5 01 6c 04 43 09 00 00 31.31 70.8
0c 58 to dec = 3160mV

image

Much simpler than I imagined.
What good news!!

Can we get some more useful information out of that string?

@1technophile
Copy link

1technophile commented Apr 3, 2021

If you don't mind I'm going to add it to OpenMQTTGateway :-)
Here is a code prototype extracted from the project (not tested) that you can tweak:

JsonObject& process_ws02(JsonObject& BLEdata) {
  const char* manufacturerdata = BLEdata["manufacturerdata "].as<const char*>();

  double temperature = (double)value_from_hex_data(manufacturerdata , 20, 4, true) / 16;
  double humidity = (double)value_from_hex_data(manufacturerdata , 24, 4, true) / 16;
  double voltage = (double)value_from_hex_data(manufacturerdata , 16, 4, true) / 1000;

  //Set Json values
  BLEdata.set("tempc", (double)temperature);
  BLEdata.set("tempf", (double)convertTemp_CtoF(temperature));
  BLEdata.set("hum", (double)humidity);
  BLEdata.set("volt", (double)voltage);

  return BLEdata;
}

/** 
 * Retrieve an unsigned long value from a char array extract representing hexadecimal data, reversed or not,
 * This value can represent a negative value if canBeNegative is set to true
 */
long value_from_hex_data(const char* service_data, int offset, int data_length, bool reverse, bool canBeNegative = true) {
  char data[data_length + 1];
  memcpy(data, &service_data[offset], data_length);
  data[data_length] = '\0';
  long value;
  if (reverse) {
    // reverse data order
    char rev_data[data_length + 1];
    revert_hex_data(data, rev_data, data_length + 1);
    value = strtol(rev_data, NULL, 16);
  } else {
    value = strtol(data, NULL, 16);
  }
  if (value > 65000 && data_length <= 4 && canBeNegative)
    value = value - 65535;
  Log.trace(F("value %D" CR), value);
  return value;
}

@lucasromeiro
Copy link
Author

If you don't mind I'm going to add it to OpenMQTTGateway :-)
Here is a code prototype extracted from the project (not tested) that you can tweak:

I don't care, you can use it however you want. You are the one who discovered it. (brilliant idea)
If it helps you, I have another BLE temperature and humidity devices here with me. I bought it because they are the best known.
I can pass on the information to add to your project.
If that will help you.

image

@1technophile
Copy link

I can pass on the information to add to your project.
If that will help you.

Could be nice!

Can you share the links where you bought them, please?

@1technophile
Copy link

I think the issue can be closed, you can open a thread into OpenMQTTGateway forum so as to discuss the others.

@h2zero
Copy link
Owner

h2zero commented Apr 3, 2021

Ha, nice work here, thanks @1technophile. More things to add to your gateway 😄

@lucasromeiro
Copy link
Author

I think the issue can be closed, you can open a thread into OpenMQTTGateway forum so as to discuss the others.

Yes! Thanks guys!!

@lucasromeiro
Copy link
Author

lucasromeiro commented Apr 3, 2021

JsonObject& process

@1technophile

Your code is well advanced for me.
I'm still trying to make it work.
Do you have any tips?
I never used that kind of statement:
JsonObject & process_ws02 (JsonObject & BLEdata) {

Can you help me simplify so that I understand?
I really need something very simple.
Thank you for your help

My code:

#include <NimBLEDevice.h>


long value_from_hex_data(const char* service_data, int offset, int data_length, bool reverse, bool canBeNegative = true) {
  char data[data_length + 1];
  memcpy(data, &service_data[offset], data_length);
  data[data_length] = '\0';
  long value;
  if (reverse) {
    // reverse data order
    char rev_data[data_length + 1];
    revert_hex_data(data, rev_data, data_length + 1);
    value = strtol(rev_data, NULL, 16);
  } else {
    value = strtol(data, NULL, 16);
  }
  if (value > 65000 && data_length <= 4 && canBeNegative)
    value = value - 65535;
  //Log.trace(F("value %D" CR), value);
  return value;
}

void revert_hex_data(const char* in, char* out, int l) {
  //reverting array 2 by 2 to get the data in good order
  int i = l - 2, j = 0;
  while (i != -2) {
    if (i % 2 == 0)
      out[j] = in[i + 1];
    else
      out[j] = in[i - 1];
    j++;
    i--;
  }
  out[l - 1] = '\0';
}

JsonObject& process_ws02(JsonObject& BLEdata) {
  const char* manufacturerdata = BLEdata["manufacturerdata "].as<const char*>();

  double temperature = (double)value_from_hex_data(manufacturerdata , 20, 4, true) / 16;
  double humidity = (double)value_from_hex_data(manufacturerdata , 24, 4, true) / 16;
  double voltage = (double)value_from_hex_data(manufacturerdata , 16, 4, true) / 1000;

  //Set Json values
  BLEdata.set("tempc", (double)temperature);
  BLEdata.set("tempf", (double)convertTemp_CtoF(temperature));
  BLEdata.set("hum", (double)humidity);
  BLEdata.set("volt", (double)voltage);

  return BLEdata;
}
void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
  Serial.println("Scanning...");

}

void loop() {

  char* manufacturerdata = BLEUtils::buildHexData(NULL, (uint8_t*)advertisedDevice->getManufacturerData().data(), advertisedDevice->getManufacturerData().length());
  BLEdata.set("manufacturerdata", manufacturerdata);
  process_ws02(BLEdata);
  delay(1000);
  

}

@1technophile
Copy link

1technophile commented Apr 3, 2021

long value_from_hex_data(const char* service_data, int offset, int data_length, bool reverse, bool canBeNegative = true) {
  char data[data_length + 1];
  memcpy(data, &service_data[offset], data_length);
  data[data_length] = '\0';
  long value;
  if (reverse) {
    // reverse data order
    char rev_data[data_length + 1];
    revert_hex_data(data, rev_data, data_length + 1);
    value = strtol(rev_data, NULL, 16);
  } else {
    value = strtol(data, NULL, 16);
  }
  if (value > 65000 && data_length <= 4 && canBeNegative)
    value = value - 65535;
  //Log.trace(F("value %D" CR), value);
  return value;
}

void revert_hex_data(const char* in, char* out, int l) {
  //reverting array 2 by 2 to get the data in good order
  int i = l - 2, j = 0;
  while (i != -2) {
    if (i % 2 == 0)
      out[j] = in[i + 1];
    else
      out[j] = in[i - 1];
    j++;
    i--;
  }
  out[l - 1] = '\0';
}

void process_ws02( char* manufacturerdata) {
  Serial.print("Temperature:");
  Serial.println(value_from_hex_data(manufacturerdata , 20, 4, true) / 16);
  Serial.print("Humidity:");
  Serial.println(value_from_hex_data(manufacturerdata , 24, 4, true) / 16);
  Serial.print("Voltage:");
  Serial.println(value_from_hex_data(manufacturerdata , 16, 4, true) / 1000);
}

Begin with BLE scan example

And add the function call process_ws02(manufacturerdata); into the callback BLEAdvertisedDeviceCallbacks

After having extracted the manufacturer data with:
char* manufacturerdata = BLEUtils::buildHexData(NULL, (uint8_t*)advertisedDevice->getManufacturerData().data(), advertisedDevice->getManufacturerData().length());

@lucasromeiro
Copy link
Author

lucasromeiro commented Apr 3, 2021

@1technophile Nice! Thanks!!!

How do you suggest that I post about the other models on your forum?

@1technophile
Copy link

@lucasromeiro could you test this branch and see if it works please:
1technophile/OpenMQTTGateway#932

How do you suggest that I post about the other models on your forum?

Ideally if you could post one topic for each sensor with the scanned data it would be great.

1technophile added a commit to 1technophile/OpenMQTTGateway that referenced this issue Apr 27, 2021
1technophile added a commit to 1technophile/OpenMQTTGateway that referenced this issue May 8, 2021
@h2zero h2zero closed this as completed Jan 19, 2022
@Frank22m
Copy link

Frank22m commented May 1, 2022

hi everyone I bought this thermobeacon. I understood that the thermobeacon sends the temperature and humidity data to the sensor blue app on the smartphone via adv_packet. He wants to know if anyone knows how to change these temperature and humidity values. Let me explain ... my goal is to have the wrong humidity and temperature data displayed on the phone app (eg temperature 20 ° I would like to inject a temperature of 40 °. Please someone help me! Thanks.

link thermobeacon: https://www.amazon.de/ORIA-Kabelloses-Thermometer-Thermo-Hygrometer-Export-funktion-2-x-bluetooth/dp/B08DL5NN58

@h2zero
Copy link
Owner

h2zero commented May 1, 2022

LOL, playing tricks on people? As much fun as that would be it isn't really possible to do unless you can access and reflash the device or create your own imitation device that the phone will detect as legitimate.

@Frank22m
Copy link

Frank22m commented May 1, 2022

@h2zero Hi, thanks for answering me. I sniffed the packets between thermobeacon and smartphone (with ubertooth) and captured the connection. How can I make the imitation device that the phone will detect how to transfer?

@h2zero
Copy link
Owner

h2zero commented May 1, 2022

Just create a server with the same services/characteristics/descriptors as the original and copy the advertisement format/data. This may take a bit of time on your part but if you can sniff the data and it's not encrypted you should be able to do it.

@Frank22m
Copy link

Frank22m commented May 1, 2022

@h2zero can I clone it with nRF Connect for example?

@h2zero
Copy link
Owner

h2zero commented May 1, 2022

You can clone the device services etc.. with nRFConnect but not the advertisements I don't think.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants