micropython / micropython-lib

Core Python libraries ported to MicroPython
Other
2.38k stars 993 forks source link

Can Characteristics have data types? #766

Open adrianblakey opened 10 months ago

adrianblakey commented 10 months ago

Is there an api (and does BT allow it) to assign a data type to a Characteristic?

I am creating my own service and characteristics using 128bit UUID's. I'd like to in effect say "this characteristic is an integer" - is that possible?

dlech commented 10 months ago

You can add a "Characteristic presentation format" descriptor to the characteristic for for that.

adrianblakey commented 10 months ago

Please could you point me to the api?

adrianblakey commented 10 months ago

It looks like it's another 16 bit uuid hex string - does it get appended to the characteristic uuid?

dlech commented 10 months ago

I haven't used the MicroPython Bluetooth API, I just know BLE in general.

I assume it would just be part of https://docs.micropython.org/en/latest/library/bluetooth.html#bluetooth.BLE.gatts_register_services

which says:

Each characteristic is a two-or-three-element tuple containing a UUID, a flags value, and optionally a list of descriptors.

Each descriptor is a two-element tuple containing a UUID and a flags value.

And you would need to look up the Bluetooth specs to figure out the UUID and the required flags for the "Characteristic presentation format" descriptor to know what values to fill in.

jimmo commented 10 months ago

@dlech You are correct but I think this might be different to what @adrianblakey is asking.

I get the impression that what you want is to be able to say that e.g. this characteristic is a temperature, and therefore (e.g. the temp characteristic on the standard environmental service) should be interpreted as a sint16 deci-degrees. i.e. if I read() it, it should return back a float "degrees" (even though internally it's the sint16).

There's currently no support for this... I haven't given it a lot of thought yet but I think it would be very useful. Maybe having a library of standard converters, and being able to pass it to the Characteristic constructor (on the server, some other mechanism on the client).

Carglglz commented 10 months ago

@dlech is right, and here are the specs: (see also https://bitbucket.org/bluetooth-SIG/public/src/main/assigned_numbers/uuids/)

Descriptor Metadata:
Descriptor: Characteristic Presentation Format

    - NAME: Characteristic Presentation Format
    - ABSTRACT: The Characteristic Presentation Format descriptor defines the format of the Characteristic Value.
    - SUMMARY: One or more Characteristic Presentation Format descriptors may be present. If multiple of these descriptors are present, then a
                   Aggregate Formate descriptor is present. This descriptor is read only and does not require authentication or authorization to
                   read. This descriptor is composed of five parts: format, exponent, unit, name space and description. The Format field determines
                   how a single value contained in the Characteristic Value is formatted. The Exponent field is used with integer data types to
                   determine how the Characteristic Value is further formatted. The actual value = Characteristic Value * 10^Exponent.
    - UUID: 2904
    - INFO TEXT: None
    - Format:
        - Requirement: Mandatory
        - Format: 8bit
        - Ctype: B
        - Minimum: 0
        - Maximum: 27
        - Enumerations:
            - 0: Reserved For Future Use
            - 1: Boolean
            - 2: unsigned 2-bit integer
            - 3: unsigned 4-bit integer
            - 4: unsigned 8-bit integer
            - 5: unsigned 12-bit integer
            - 6: unsigned 16-bit integer
            - 7: unsigned 24-bit integer
            - 8: unsigned 32-bit integer
            - 9: unsigned 48-bit integer
            - 10: unsigned 64-bit integer
            - 11: unsigned 128-bit integer
            - 12: signed 8-bit integer
            - 13: signed 12-bit integer
            - 14: signed 16-bit integer
            - 15: signed 24-bit integer
            - 16: signed 32-bit integer
            - 17: signed 48-bit integer
            - 18: signed 64-bit integer
            - 19: signed 128-bit integer
            - 20: IEEE-754 32-bit floating point
            - 21: IEEE-754 64-bit floating point
            - 22: IEEE-11073 16-bit SFLOAT
            - 23: IEEE-11073 32-bit FLOAT
            - 24: IEEE-20601 format
            - 25: UTF-8 string
            - 26: UTF-16 string
            - 27: Opaque Structure
    - Exponent:
        - Requirement: Mandatory
        - Format: sint8
        - Ctype: b
    - Unit:
        - InformativeText: The Unit is a UUID.
        - Requirement: Mandatory
        - Format: uint16
        - Ctype: H
    - Namespace:
        - InformativeText: The Name Space field is used to identify the organization that is responsible for defining the enumerations for the
         description field.
        - Requirement: Mandatory
        - Format: 8bit
        - Ctype: B
        - Minimum: 0
        - Maximum: 1
        - Enumerations:
            - 1: Bluetooth SIG Assigned Numbers
    - Description:
        - InformativeText: The Description is an enumerated value from the organization identified by the Name Space field.
        - Requirement: Mandatory
        - Format: 16bit
        - Ctype: h

@adrianblakey you need to create the characteristic with this descriptor (2904) and then write (using the value handle of this descriptor) the appropriate values in those fields

FORMAT EXPONENT UNIT NAMESPACE DESCRIPTION
B (8bit) b (sint8) H (uint16) B(8bit) h(16bit)

e.g in binary

#                               FORMAT    EXPONENT    UNIT         NAMESPACE    DESCRIPTION
BLE.gatts_write(value_handle, 0b00000110_00000000_0010011100100110_00000000_0000000000000000)