How to implement the BLE Current Time Service

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

How to implement the BLE Current Time Service

Post by Simpler1 » Sun Apr 18, 2021 1:47 am

I want to implement the BLE Current Time Service on an ESP32-CAM so that I can read, write, and notify the values from a peripheral.

I can see that the Current Time Service has the following:

Code: Select all

name="Current Time Service"
type="org.bluetooth.service.current_time"
uuid="1805"
...
  <Characteristics>
    <Characteristic 
    name="Current Time"
    type="org.bluetooth.characteristic.current_time">
      <Requirement>Mandatory</Requirement>
The mandatory characteristic of Current Time has a the following:

Code: Select all

name="Current Time"
type="org.bluetooth.characteristic.current_time" 
uuid="2A2B">
...
  <Value>
    <Field name="Exact Time 256">
      <Requirement>Mandatory</Requirement>
      <Reference>org.bluetooth.characteristic.exact_time_256</Reference>
The Value -> Field -> Reference of Exact Time 256 has the following:

Code: Select all

name="Exact Time 256"
type="org.bluetooth.characteristic.exact_time_256" 
uuid="2A0C">
...
  <Value>
    <Field name="Day Date Time">
      <InformativeText>Reference the Time Characteristic</InformativeText>
      <Requirement>Mandatory</Requirement>
      <Reference>org.bluetooth.characteristic.day_date_time</Reference>
The Value -> Field -> Reference of Day Date Time has the following:

Code: Select all

name="Day Date Time"
type="org.bluetooth.characteristic.day_date_time" 
uuid="2A0A">
...
  <Value>
    <Field name="Date Time">
      <Requirement>Mandatory</Requirement>
      <Reference>org.bluetooth.characteristic.date_time</Reference>
The Value -> Fields of Date Time have the following:

Code: Select all

name="Date Time"
type="org.bluetooth.characteristic.date_time" 
uuid="2A08">
...
  <Value>
    <Field name="Year">
      <InformativeText>Year as defined by the Gregorian calendar.</InformativeText>
      <Requirement>Mandatory</Requirement>
      <Format>uint16</Format>
      <Unit>org.bluetooth.unit.time.year</Unit>
      <Minimum>1582</Minimum>
      <Maximum>9999</Maximum>
      <AdditionalValues>
        <Enumeration key="0" value="Year is not known" />
      </AdditionalValues>
    </Field>
    <Field name="Month">
      <InformativeText>Month of the year as defined by the Gregorian calendar.</InformativeText>
      <Requirement>Mandatory</Requirement>
      <Format>uint8</Format>
      <Unit>org.bluetooth.unit.time.month</Unit>
      <Minimum>0</Minimum>
      <Maximum>12</Maximum>
      <Enumerations>
        <Enumeration key="0" value="Month is not known" />
        <Enumeration key="1" value="January" />
        <Enumeration key="2" value="February" />
        <Enumeration key="3" value="March" />
        <Enumeration key="4" value="April" />
        <Enumeration key="5" value="May" />
        <Enumeration key="6" value="June" />
        <Enumeration key="7" value="July" />
        <Enumeration key="8" value="August" />
        <Enumeration key="9" value="September" />
        <Enumeration key="10" value="October" />
        <Enumeration key="11" value="November" />
        <Enumeration key="12" value="December" />
      </Enumerations>
    </Field>
    <Field name="Day">
      <InformativeText>Day of the month as defined by the Gregorian calendar.</InformativeText>
      <Requirement>Mandatory</Requirement>
      <Format>uint8</Format>
      <Unit>org.bluetooth.unit.time.day</Unit>
      <Minimum>1</Minimum>
      <Maximum>31</Maximum>
      <AdditionalValues>
        <Enumeration key="0" value="Day of Month is not known" />
      </AdditionalValues>
    </Field>
    <Field name="Hours">
      <InformativeText>Number of hours past midnight.</InformativeText>
      <Requirement>Mandatory</Requirement>
      <Format>uint8</Format>
      <Unit>org.bluetooth.unit.time.hour</Unit>
      <Minimum>0</Minimum>
      <Maximum>23</Maximum>
    </Field>
    <Field name="Minutes">
      <InformativeText>Number of minutes since the start of the hour.</InformativeText>
      <Requirement>Mandatory</Requirement>
      <Format>uint8</Format>
      <Unit>org.bluetooth.unit.time.minute</Unit>
      <Minimum>0</Minimum>
      <Maximum>59</Maximum>
    </Field>
    <Field name="Seconds">
      <InformativeText>Number of seconds since the start of the minute.</InformativeText>
      <Requirement>Mandatory</Requirement>
      <Format>uint8</Format>
      <Unit>org.bluetooth.unit.time.second</Unit>
      <Minimum>0</Minimum>
      <Maximum>59</Maximum>
    </Field>
  </Value>
My question is how do I implement this service so that I can access all of these values?

I have the following so far, but this only gets me as far as the Current Time Characteristic:

Code: Select all

_CURRENT_TIME_UUID = bluetooth.UUID(0x1805)
_CURRENT_TIME_CHAR = (
    bluetooth.UUID(0x2A2B),
    bluetooth.FLAG_NOTIFY | bluetooth.FLAG_WRITE,
)
_CURRENT_TIME_SERVICE = (
    _CURRENT_TIME_UUID,
    (_CURRENT_TIME_CHAR,),
)

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

Re: How to implement the BLE Current Time Service

Post by Simpler1 » Sun Apr 18, 2021 4:34 pm

I figured it out. All of of the values are just strung together in a single bytes object from top to bottom (left to right).

Exact Time 256 + Adjust Reason(uint8)
Exact Time 256 = Day Date Time + Fractions256(uint8)

Day Date Time = Date Time + Day of Week
Date Time = Year(uint16) + Month(uint8) + Day(uint8) + Hours(uint8) + Minutes(uint8) + Seconds(uint8)
Day of Week = Day of Week(uint8) [0=unknown, 1=Monday, etc.]

Octet Meaning (left to right)
----- -------
0 Year
1 Year
2 Month
3 Day
4 Hours
5 Minutes
6 Seconds
7 Day of Week (0 = unknown)
8 Fractions256 (0 = uknown)
9 Adjust Reason (0x03 = Manual Update => External Reference => No Time Zone Change => No DST Change)

Post Reply