Chreece / BTHomeV2-ESP32-example

An BTHome v2 example with encryption for ESP32
MIT License
35 stars 7 forks source link

BTHome device is not sending object ids in numerical order (from low to high object id) #15

Closed Chreece closed 1 year ago

Chreece commented 1 year ago
Logger: bthome_ble.parser
Source: components/bthome/__init__.py:44
First occurred: 13:37:51 (6 occurrences)
Last logged: 13:38:30

BTHome device is not sending object ids in numerical order (from low to high object id). This can cause issues with your BTHome receiver, payload: 05d913004a010904f28f0102ac0d
BTHome device is not sending object ids in numerical order (from low to high object id). This can cause issues with your BTHome receiver, payload: 03a00f135e0112b804100121002501

Measurements:

void loop() {
  //MEASUREMENT_MAX_LEN = 23, ENABLE_ENCRYPT will use extra 8 bytes, so each Measurement should smaller than 15

  // 1st method: just addMeasurement as much as you can, the code will split and send the adv packet automatically
  // each adv packet sending lasts for 1500ms
  bthome.resetMeasurement();
  // bthome.addMeasurement(sensorid, value) you can use the sensorids from the BTHome.h file
  bthome.addMeasurement(ID_ILLUMINANCE, 50.81f);
  bthome.addMeasurement(ID_VOLTAGE1, 230.5f);
  bthome.addMeasurement(ID_PRESSURE, 1023.86f);
  bthome.addMeasurement(ID_TEMPERATURE_PRECISE, 35.00f);
  bthome.addMeasurement(ID_HUMIDITY_PRECISE, 40.00f);
  bthome.addMeasurement(ID_TVOC, (uint64_t)350);
  bthome.addMeasurement(ID_CO2, (uint64_t)1208);
  bthome.addMeasurement_state(STATE_POWER_ON, STATE_ON);
  bthome.addMeasurement_state(STATE_MOTION, STATE_OFF);
  bthome.addMeasurement_state(STATE_PRESENCE, STATE_ON);
  bthome.sendPacket();
  bthome.stop();

  delay(10000);
}
Chreece commented 1 year ago

I did an analyze and the packet corresponds the states and object ids, can't find anything wrong but still got the errors

countrysideboy commented 1 year ago

From the bt home.io

Object ids have to be applied in numerical order (from low to high) in your advertisement. This will make sure that if you have a device (sensor) that is broadcasting a new measurement type that is added in a new (minor) BTHome update, while your BTHome receiver isn't updated yet to the same version, it will still be able to receive the older supported measurement types. A BTHome receiver will stop parsing object ids as soon as it finds an object id that isn't supported.

countrysideboy commented 1 year ago

Try adjust the addMeasurement order by the object_id?

Chreece commented 1 year ago

Now I understand what that means... Could we do that sorting in the code?

Chreece commented 1 year ago

Like: addmeasurement could collect all the data in an table, sort them, for every line in table check if it could pass in the packet then add it else chop them in to packets

countrysideboy commented 1 year ago

We may sort one m_sensorData array by the object id, but the packet chop logic now is to send packet immediately when the adv data will be overload, it cannot ensure the order of object id in different adv packet.

The simplest method currently is to adjust the order manually. The code side solution may require recording all data and sorting it, which may take up additional ram resource.

Chreece commented 1 year ago

If we add a new variable that holds an array of the individual object ids + states. Then it could be easy to sort them and chop them, or not?

countrysideboy commented 1 year ago

If we add a new variable that holds an array of the individual object ids + states. Then it could be easy to sort them and chop them, or not?

It’s so true.

Chreece commented 1 year ago

Could we have in this line a sort, checking the first byte without much resources needed?

    for (i = 0; i < this->m_sensorDataIdx; i++)
    {
      serviceData += this->m_sensorData[i]; // Add the sensor data to the Service Data
    }

(see lines 170-173 in .cpp)

*Sorry my c++ knowledge is very limited :( I just copy-paste codes...

countrysideboy commented 1 year ago

I may sort one adv packet of the sensorData array with no much ram cost, but I cannot sort it in two or more adv packet, it need additional ram to store all the data.

Chreece commented 1 year ago

I thought that the sensor data represent one element in the this->m_sensorData variable which could do the sorting easy, and tried to implement this, but each element on the array is just a byte making it difficult to distinguish every sensor data since they are not the same lenght. So now I understand why you are against of Autosort.

Still I think we must offer this option to users that probably will send 2-3 sensor data and don't care to learn how to manually sort them. Users that just want a simple method to send data to HA. Users that don't care about how effective is the code...

What do you think about it?

countrysideboy commented 1 year ago

I will try to write a fuction call sortsensorData() in this weekend to deal with the order in just one adv packet, even though every object id has different length.

countrysideboy commented 1 year ago

Finally, I use a struct to store each sensor data, sort it,and rewrite to the m_sensorData array.

The code will auto decide if sort the data or not, but I prefer to adjust the order manually.

Chreece commented 1 year ago

Finally, I use a struct to store each sensor data, sort it,and rewrite to the m_sensorData array.

The code will auto decide if sort the data or not, but I prefer to adjust the order manually.

Thank you for your hard work! From my side the project is fine as it is now... This repository may be under my name but most of the effort came from you! If you want you can send me your paypal account to add a button on the Readme for spendings for you... I'm closing this issue as resolved!

countrysideboy commented 1 year ago

Finally, I use a struct to store each sensor data, sort it,and rewrite to the m_sensorData array. The code will auto decide if sort the data or not, but I prefer to adjust the order manually.

Thank you for your hard work! From my side the project is fine as it is now... This repository may be under my name but most of the effort came from you! If you want you can send me your paypal account to add a button on the Readme for spendings for you... I'm closing this issue as resolved!

Thanks. As the bthome is an opensoure standard of ble, I think my modifications to this project should be non-profit.