-
-
Notifications
You must be signed in to change notification settings - Fork 179
Template cast (uses PR #49) #52
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
Conversation
… to get the latest remote characteristic and (optionally) it's timestamp. Getting the value and the timestamp is made unary using the semaphore to assure value and timestamp belong together. A new NimBLERemoteCharacteristic::registerForNotify() is introduced, passing only the remote characteristic and it's type (notify / indicate), since the value can now be retrieved from the remote characteristic itself. NiBLEClient::handleGapEvent() is adapted to set m_value and the new m_timestamp in the remote characteristic. Also the call to the new callback is added
…eded for returning the service data to be copied correctly. Added a timestamp for the moment a device was scanned
…ce(const NimBLEAddress &address)
…ce(const NimBLEAddress &address)
@h2zero what's your opinion about this one? I like it very much myself, because it introduces some kind of variant type for the remote data making it easy for the programmer to handle remote data with cpp data types and structs. |
I like this, nice improvement to simplify application code. Will look into it more when the other PR's are sorted. |
…nter to the data and the data size
Added the timestamp option to Set |
@h2zero Updating to latest master |
In PR #49 the value returned by reading a remote characteristic or by getting a notification for it is kept in the class instance of the
NimBLERemoteCharacteristic
. This value can be accessed as astd::string
type using thegetValue()
function.This PR adds templates to read the value in the type used by the peripheral. If e.g. the type of the value in the remote characteristic is a
uint16_t
you can do:uint16_t temperature = pCharacteristic->getValue<uint16_t>();
This is even possible if the data returned is more complex. A LYWSD03MMC temperature / humidity sensor e.g. returns both a
uint16_t temperature
and auint8_t humidity
. Since the temperature is times 100, it needs to be divided by 100.0 to get the right temperature and the decimals. Now you can do this:The same functionality is implemented for getting the manufacturer data or the service data of an advertised device, e.g. for another BLE sensor:
uint8_t firmwareVersion = dev->getManufacturerData<uint8_t>();
The advantages of the template way are:
readUInt8()
,readUInt16()
andreadUInt32()
as inNimBLERemoteCharacteristic
float
,float value = pCharacteristic->getValue<float>()
is perfectly valid, assuming that the endianness and the float data type used by the peripheral are the same as for the ESP32Normally the size of the data returned by the peripheral is checked against the size of the requested data type. This check maybe skipped by passing the optional parameter 'true'. If the returned value is smaller than the size of the requested data type a value of 0 ('zero') or returned (or more accurate: the default constructor for the type requested).
Maybe a bit beyond the scope of an explanation for a PR, but even variant like types and bit fields can be used. Two examples:
Example 1: The MJ-HT-V1 temperature / humidity sensor sends in the service data either a temperature, or a humidity or a battery level, or the combination of temperature and humidity. What service data is sent can be discriminated by checking one of the bytes,
byte[11]
, that holds0x04, 0x06, 0x0a or 0x0d
respectively. The actual data we are interested in starts at byte[14]. The length of the data varies, because battery level only is 1 byte, temperature or humidity is 2 byes and both temperature and humidity is 4 bytes. Now you can do this, using standard cpp to parse the data. Mind the 'true' passed intogetServiceData(true)
, so the length of the data is not checked. This is because thesizeof
a union is the largest size of each member, but the data sent maybe shorter.Example 2: I have a BLE sensor that sends data through the manufacturer data of an advertised device. Some data is just one bit, some data is 3 bytes, some data is 5 bits long. Now you can do this:
As said, this is more (standard) cpp functionality, not really an accomplishment of the templates added, but I am quite happy with it, and I want to share this possibility.