doesn’t look bad at first hand, it lacks important details when it comes to crafting the appropriate characteristics and assigning values properly to them.
On day two, we have been able to find another excellent gem.
Apart from that, MicroPython (and Python!) support for crafting specific characteristics respecting their required value codings looks rather poor these days. We’ve been able to unlock a few but are still struggling with others.
# Temperature Measurement
# UUID: 2A1C
# Format: Variable length structure
# Value Format: FLOAT (IEEE-11073 32-bit FLOAT)
# Abstract: The Temperature Measurement characteristic is a variable length structure
# containing a Flags field, a Temperature Measurement Value field and, based upon the
# contents of the Flags field, optionally a Time Stamp field and/or a Temperature Type field.
# https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.temperature_measurement.xml
After some research about 2A1C and correlating this with https://www.bluetooth.com/specifications/assigned-numbers/format-types/, we conclude that this characteristic will require appropriate value encoding to IEEE-11073 32-bit FLOAT. However, we haven’t been able to find any Python implementation for that.
def encode_ieee11073(value, precision=2):
"""
Binary representation of float value as IEEE-11073:20601 32-bit FLOAT for
implementing the BLE GATT "Temperature Measurement 2A1C" characteristic.
-- https://community.hiveeyes.org/t/convenient-ble-gatts-ess-with-micropython/2413/3
print('Adding Temperature Measurement')
payload = bytearray([0b00000000]) + float_ieee11073(42.42)
service.characteristic(uuid=0x2A1C, value=payload)
>>> ubinascii.hexlify(encode_ieee11073(42.42))
b'921000fe'
"""
# FIXME: Sanity checks dearly required.
return int(value * (10 ** precision)).to_bytes(3, 'little', True) + pack('<b', -precision)
Well, to begin with, what is a “personal health device” (PHD)? It is a type of medical apparatus that patients (and healthy persons) use without professional help, in the course of their normal lives: house, work, etc. ↩︎
def encode_temperature_2a1c(value):
"""
Temperature Measurement
UUID: 2A1C
Format: Variable length structure
Value Format: FLOAT (IEEE-11073 32-bit FLOAT)
Abstract: The Temperature Measurement characteristic is a variable length structure
containing a Flags field, a Temperature Measurement Value field and, based upon the
contents of the Flags field, optionally a Time Stamp field and/or a Temperature Type field.
https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Characteristics/org.bluetooth.characteristic.temperature_measurement.xml
IEEE-11073
==========
- https://learn.adafruit.com/introducing-the-adafruit-bluefruit-le-uart-friend/ble-gatt
- https://devzone.nordicsemi.com/f/nordic-q-a/28727/32-bit-ieee-11073-float-data-type-parser
- https://stackoverflow.com/questions/11564270/how-to-convert-ieee-11073-16-bit-sfloat-to-simple-float-in-java/14707658#14707658
- http://www.java2s.com/example/java/language-basics/reads-a-decimal-value-as-a-ieee11073-16bits-float-from-bytebuffer.html
- https://stackoverflow.com/questions/28899195/converting-two-bytes-to-an-ieee-11073-16-bit-sfloat-in-c-sharp/32950340#32950340
"""
return bytearray([0b00000000]) + encode_ieee11073(value)
Indeed, there are many of the neccesary contexts not described nor there seems to be a possibility to describe these from within the Characteristics itself.
e.g. “Temperature”: “Unit is in degrees Celsius with a resolution of 0.01 degrees Celsius” … ok, proper definition but keep in mind that would we have to disguinish between several (heights, indoor, outdoor, …)
e.g. “Humidity”: “Unit is in percent with a resolution of 0.01 percent” … I guess they mean realative humidity.
e.g. “Rainfall”: “Unit is in meters with a resolution of 1mm” … here we have a problem (besides we couldn’t integrate a water-equivalent of snow): You can’t talk about precipitation without providing a range of time. And the resolution of 1mm is roughly six times too low for a single tick of a simple rainfall-o-meter.
But interesting that there is such a infomation-snippet-data-format … could we occupy our own (more or less private) namespace within the BLE GATT ESS Characteristics? (and do a proper “import” of our and relevant $official definitions (e.g WMO/DWD) of $things-to-be-measured)
We have been working hard (on the Python level) to reach these goals. However, we have been hit by a road block where only C++ superpowers might be able to help further.