Data format to pass "Date Time" (0x2A08) over BLE

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
Simpler1
Posts: 16
Joined: Wed Jan 06, 2021 6:30 pm

Data format to pass "Date Time" (0x2A08) over BLE

Post by Simpler1 » Sun Jan 17, 2021 3:37 pm

I'm just getting started with setting up an ESP32-CAM as a BLE server (peripheral) and for one of the characteristics, I'd like to pass the current date/time as set on the device.

I see from the 16-bit UUID Numbers document, that UUID 0x2A08 is "Date Time", but I'm not sure what format the date/time should be when I enter it as data to the

Code: Select all

BLE().gatt_write(handle, data)
command.

I've tried the output from:

Code: Select all

utime.time()    # 664211220
machine.RTC().datetime()  # (2021, 1, 17, 6, 15, 5, 5, 986239)
nRF Connect recognizes the characteristic as a Date Time based on the UUID, but the value is not even close.

I've reviewed the documentation for bluetooth in MicroPython, but it doesn't specify.

I expect that I need to do some conversion to bytes or bytearray, but I'm not sure where I would find the documentation to describe what is expected?

Simpler1
Posts: 16
Joined: Wed Jan 06, 2021 6:30 pm

Re: Data format to pass "Date Time" (0x2A08) over BLE

Post by Simpler1 » Sun Jan 17, 2021 8:58 pm

After hours of scouring the internet, I came across these two slides:

https://speakerdeck.com/ephread/bluetoo ... y?slide=21
https://speakerdeck.com/ephread/bluetoo ... y?slide=22

So now I know the format is:

Code: Select all

             0 1  2     3   4    5      6
Description  Year Month Day Hour Minute Second
Minimum      1582 1     1   0    0      0
Maximum      9999 12    31  23   59     59
with the year being a uint16.

I can manually piece together what will produce today's date:

Code: Select all

b'\xE5\x07\x01\x11\x0F\x05\x00'
The primary question now, is how do I programmatically convert the output from machine.RTC().datetime() to this?

And the second question (not necessary for this forum) is why is this not documented somewhere on the Bluetooth website?

Simpler1
Posts: 16
Joined: Wed Jan 06, 2021 6:30 pm

Re: Data format to pass "Date Time" (0x2A08) over BLE

Post by Simpler1 » Sun Jan 17, 2021 9:26 pm

Here's what I came up with. It doesn't look pretty, but seems to work:

Code: Select all

def nowBytes():
    import machine
    rtc = machine.RTC()
    timestamp = rtc.datetime()
    time_bytes = struct.pack("<h", timestamp[0]) + struct.pack("b", timestamp[1]) + struct.pack(
        "b", timestamp[2]) + struct.pack("b", timestamp[4]) + struct.pack("b", timestamp[5]) + struct.pack("b", timestamp[6])
    return time_bytes
Is there a more efficient way to do this?

Thanks

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: Data format to pass "Date Time" (0x2A08) over BLE

Post by jimmo » Mon Jan 18, 2021 4:41 am

Simpler1 wrote:
Sun Jan 17, 2021 8:58 pm
After hours of scouring the internet, I came across these two slides:
There used to be a really useful reference for this on bluetooth.com, but there are a few places that contain the same information. For example:

https://github.com/oesmith/gatt-xml/blo ... e_time.xml

So this is telling you that the field is uint16-uint8-uint8-uint8-uint8-uint8 as you've discovered.

I would definitely recommend using struct.pack but a simpler way to use it is:

Code: Select all

time_bytes = struct.pack("<hbbbbb", timestamp[0], timestamp[1], timestamp[2], timestamp[4], timestamp[5], timestamp[6])
or even

Code: Select all

time_bytes = struct.pack("<hbbbbb", timestamp[0:3] + timestamp[4:])

Simpler1
Posts: 16
Joined: Wed Jan 06, 2021 6:30 pm

Re: Data format to pass "Date Time" (0x2A08) over BLE

Post by Simpler1 » Mon Jan 18, 2021 1:50 pm

Thanks for the link and example jimmo. Perfect.

Post Reply