This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Unable to read battery level from battery characteristic on Thingy:52 using bluetoothctl on linux

Below is the output from a 'bluetoothctl' session for one of my thingy:52's 

This is running on a raspberry pi 4 using Ubuntu Mate 20.xx

The output below is using command line 'bluetoothctl'. (Clearly the actual Mac adrs you see has been altered for this post)

The Thingy can be connected to and all characteristics can be read ( those identified as 'Read' in the spec)

Using 'bluetoothctl: notify on' for other notification capable characteristics will produce updates. 

Regarding reading the battery level/value, the nRF Connect app for iOS can read the battery level. 

The bluetoothctl session below shows that I can connect to the thingy:52, drill into the battery characteristic, set it to notify, 

but no notification is received. This is even after sufficient time has elapsed for the battery state to change. 

Yes, I am aware that the documentation shows no battery notification is sent unless the state of the battery (read that as level of charge) changes. 

However, the iOS nRFConnect app is able to do a one-shot read of the battery level/value if one taps on the 'single down arrow' icon.

The FW version 2.2.0 (which is running on my Thingy:52) shows the battery level type to be both Read/Notify. 

I would not argue since the iOS app allows a single-shot read. 

From the 'bluetoothctl' session below, the service '000a' and char '000b' is the battery service as found by the 'bluetoothctl' command

[bluetooth]# list-attributes xx:18:81:32:yy:B0 

// I identified this as the Battery Service, the 0001801 was my clue.


[NEW] Primary Service (Handle 0xb000)
/org/bluez/hci0/dev_xx_18_81_32_yy_B0/service000a
00001801-0000-1000-8000-00805f9b34fb
Generic Attribute Profile
[NEW] Characteristic (Handle 0xd6b0)
/org/bluez/hci0/dev_xx_18_81_32_yy_B0/service000a/char000b
00002a05-0000-1000-8000-00805f9b34fb
Service Changed
[NEW] Descriptor (Handle 0x4680)
/org/bluez/hci0/dev_xx_18_81_32_yy_B0/service000a/char000b/desc000d
00002902-0000-1000-8000-00805f9b34fb
Client Characteristic Configuration

Can anyone tell me what is needed in order to do at least a one shot read of the battery value? 

Note if I do a ' read' I do get an error, the same error as when I try to read a notification only attribute. 

Any help is appreciated... 

Regards... 

Bluetoothctl session begin:

[bluetooth]connect xx:18:81:32:yy:B0

[Thingy2]# menu gatt

[Thingy2]# select-attribute /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service000a/char000b

[Thingy2:/service000a/char000b]# attribute-info /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service000a/char000b

Characteristic - Service Changed

UUID: 00002a05-0000-1000-8000-00805f9b34fb

Service: /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service000a

Notifying: no //<---

Flags: indicate

[Thingy2:/service000a/char000b]# notify on

[CHG] Attribute /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service000a/char000b Notifying: yes

Notify started //<---

[Thingy2:/service000a/char000b]# attribute-info /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service000a/char000b

Characteristic - Service Changed

UUID: 00002a05-0000-1000-8000-00805f9b34fb

Service: /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service000a

Notifying: yes //<---

Flags: indicate

[Thingy2:/service000a/char000b]# 

  • Thank you again for the quick response.

    The link you provided is one that I have used.(At least the command order)

    If there is a specific memory offset from 0000fe59-... would you let me know what the offset is?

    Or, is it necessary to pair with the thingy in order to even see the battery service?

    I have connected to the thingy many times with

    [bluetoothctl]# connect <mac adrs here>

    Each time as included above, I get a list of services with their tiered characteristics and descriptions (partially included here)

    Primary Service (Handle 0xacdc)
    /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service0066
    0000fe59-0000-1000-8000-00805f9b34fb
    Nordic Semiconductor ASA
    Characteristic (Handle 0x0240)
    /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service0066/char0067
    8ec90003-f315-4f60-9fb8-838830daea50
    Vendor specific
    Descriptor (Handle 0x0000)
    /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service0066/char0067/desc0069
    00002902-0000-1000-8000-00805f9b34fb

    ...

    However, the one that is never shown is the battery service.

    Using the [bluetoothctl]# list (after having connected to the thingy, not paired)

    I get a list which includes the UUID for the battery service as shown above and repeated here for clarity:

    ...

    UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb)
    UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
    UUID: Battery Service (0000180f-0000-1000-8000-00805f9b34fb)
      // <------

    ...

    The Bluetooth spec lists the battery service as type GSS. 

    However, on completion of the above 'connect' command under bluetoothctl, the device/service/characteristic path is not found and does not exist for the battery service.

    This says that the battery service is not enumerated under bluetoothctl?

    So, are there specific offsets from the 0000fe59 location that I missed in the documentation?

    The benefit (supposed) to using bluetoothctl is that it is 'standardized' with Bluez under linux.

    This means that much of the software stack that would have to be handwritten/cut-pasted/ etc is already done and optimized for the linux kernel.

    There are older tools which have bee deprecated hcitool and gatttool and those were rolled into bluetoothctl.

    If anyone in your group has insights as to how to get at this ever-elusive battery service under bluetoothctl please let me know.

    Thank you again...


  • Some additional findings:

    Using btmon (A bluetooth monitor)
    I launched btmon from one terminal session (#1)
    I launched bluetoothctl from another terminal session (#2)

    From (#2) issue 

    [bluetoothctl]# connect xx:18:81:32:yy:B0

    [Thingy2]# 

    To read the attribute info, one must first go into the GATT submenu 

    [Thingy2]# menu gatt

    On connection executed by (#2), the following is reported by #1 (condensed version)

    #23 [hci0] 526.473447
    LE Advertising Report (0x02)
    Num reports: 1
    Event type: Connectable undirected - ADV_IND (0x00)
    Address type: Random (0x01)
    Address: xx:18:81:32:yy:B0 (Static)
    Data length: 30
    Flags: 0x06
    LE General Discoverable Mode
    BR/EDR Not Supported
    128-bit Service UUIDs (partial): 1 entry
    Vendor specific (ef680100-9b35-4933-9b10-52ffa9740042)
    Name (complete): Thingy2
    RSSI: -42 dBm (0xd6)
    < HCI Command: LE Set Scan Enable (0x08|0x000c) plen 2

    #43 [hci0] 527.519266
    ATT: Read By Group Type Response (0x11) len 13
    Attribute data length: 6
    Attribute group list: 2 entries
    Handle range: 0x0001-0x0009
    UUID: Generic Access Profile (0x1800)
    Handle range: 0x000a-0x000d
    UUID: Generic Attribute Profile (0x1801)
    < ACL Data TX: Handle 64 flags 0x00 dlen 9

    #51 [hci0] 527.812983
    ATT: Read By Group Type Response (0x11) len 101
    Attribute data length: 20
    Attribute group list: 5 entries
    Handle range: 0x000e-0x001e
    UUID: Vendor specific (ef680100-9b35-4933-9b10-52ffa9740042)
    Handle range: 0x001f-0x0030
    UUID: Vendor specific (ef680200-9b35-4933-9b10-52ffa9740042)
    Handle range: 0x0031-0x004e
    UUID: Vendor specific (ef680400-9b35-4933-9b10-52ffa9740042)
    Handle range: 0x004f-0x0056
    UUID: Vendor specific (ef680300-9b35-4933-9b10-52ffa9740042)
    Handle range: 0x0057-0x0061
    UUID: Vendor specific (ef680500-9b35-4933-9b10-52ffa9740042)
    < ACL Data TX: Handle 64 flags 0x00 dlen 11

    #58 [hci0] 527.910473
    ATT: Read By Group Type Response (0x11) len 13
    Attribute data length: 6
    Attribute group list: 2 entries
    Handle range: 0x0062-0x0065
    UUID: Battery Service (0x180f)
    Handle range: 0x0066-0xffff
    UUID: Nordic Semiconductor ASA (0xfe59)
    < ACL Data TX: Handle 64 flags 0x00 dlen 9

    Now we try to correlate the btmon 'Handle range:' with the service../char.. values

    // bluetoothctl list report (#2):
    [NEW] Primary Service (Handle 0xf000)
    /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service001f
    ef680200-9b35-4933-9b10-52ffa9740042
    Vendor specific

    [NEW] Characteristic (Handle 0xaf90)
    /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service001f/char002f
    ef680206-9b35-4933-9b10-52ffa9740042
    Vendor specific

    // btmon report:
    Handle range: 0x001f-0x0030
    UUID: Vendor specific (ef680200-9b35-4933-9b10-52ffa9740042)

    // Another one...

    // bluetoothctl list report (#2):
    [NEW] Primary Service (Handle 0xf000)
    /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service0031
    ef680400-9b35-4933-9b10-52ffa9740042
    [NEW] Characteristic (Handle 0xaf90)
    /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service0031/char0032
    ef680401-9b35-4933-9b10-52ffa9740042
    ...
    [NEW] Characteristic (Handle 0xaf90)
    /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service0031/char004c
    ef68040a-9b35-4933-9b10-52ffa9740042
    Vendor specific
    [NEW] Descriptor (Handle 0x4a70)
    /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service0031/char004c/desc004e
    00002902-0000-1000-8000-00805f9b34fb
    Client Characteristic Configuration

    // btmon report:
    Handle range: 0x0031-0x004e
    UUID: Vendor specific (ef680400-9b35-4933-9b10-52ffa9740042)


    // The clues:
    1.1 The above suggests that btmon shows the vendor specific service for the
    200 series service with a range of 0x001f-0x0030

    The [bluetoothctl]# list report corresponds with:

    service001f //<-- The offset
    service001f/char002f //<-- The last characteristic offset

    And the next service listed has
    HandleRange: 0x0031 to 0x004e

    The [bluetoothctl]# list report corresponds with:

    /service0031 //<-- The offset
    and the last charactersitic's description at
    /service0031/char004c/desc004e //<-- The last characteristic offset

    1.2 Maybe the battery can be found at:

    Handle range: 0x0062-0x0065
    UUID: Battery Service (0x180f)
    service0062/


    [Thingy2:/service0066/char0067]# select-attribute /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service0066/char0067/desc0069

    Notice the prompt changes only when the attribute is valid:


    [Thingy2:/service0066/char0067/desc0069]# read

    A Legitimate read operation producers results:


    Attempting to read /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service0066/char0067/desc0069
    [CHG] Attribute /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service0066/char0067/desc0069 Value:
    00 00 ..
    00 00

    Notice the attempt to read what should be the battery offset:

    And notice that the prompt does not change indicating attribute is not valid:

    [Thingy2:/service0066/char0067/desc0069]# select-attribute /org/bluez/hci0/dev_xx_18_81_32_yy_B0/service0062/char0063

    [Thingy2:/service0066/char0067/desc0069]#

    Again no joy. So, battery service is present and has an offset but is not a GATT service and therefore cannot be found under the GATT menu. 

  • Well?

    From the last post, it is clear that the Battery is a GSS (Standard service) and not a GATT service.

    So, can anyone in the Nordic Dev Group look into a solution?

    How does one read the value for the Battery Service without writing a full C program?

    How does one take advantage of the basic tools built into linux in order to work with the bluetooth stack graciously provided by Nordic?

    Thank you again.

  • SOLUTION AT LAST!

    (Since it appears that this thread has been relegated to the dust bin....)

    // 1. After a determined effort, here is what I was able to do with the Thingy:52

    // Make sure you have gatttool installed via apt or pip if you are on the Pi. 

    // 2. IMPORTANT to enable this first...
    pisys1@piSys1:~$ sudo btmgmt le on

    pisys1@piSys1:~$ sudo gatttool -t random -b yo:ur:ma:c:ad:rs -I
    [yo:ur:ma:c:ad:rs][LE]> connect
    Attempting to connect to yo:ur:ma:c:ad:rs
    Connection successful

    [yo:ur:ma:c:ad:rs][LE]>

    // 3. Display all the characteristics of the Thingy52...
    [yo:ur:ma:c:ad:rs][LE]> characteristics
    handle: 0x0002, char properties: 0x02, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
    handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
    handle: 0x0006, char properties: 0x02, char value handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb
    handle: 0x0008, char properties: 0x02, char value handle: 0x0009, uuid: 00002aa6-0000-1000-8000-00805f9b34fb
    handle: 0x000b, char properties: 0x20, char value handle: 0x000c, uuid: 00002a05-0000-1000-8000-00805f9b34fb
    handle: 0x000f, char properties: 0x0a, char value handle: 0x0010, uuid: ef680101-9b35-4933-9b10-52ffa9740042
    handle: 0x0011, char properties: 0x0a, char value handle: 0x0012, uuid: ef680102-9b35-4933-9b10-52ffa9740042
    handle: 0x0013, char properties: 0x0a, char value handle: 0x0014, uuid: ef680104-9b35-4933-9b10-52ffa9740042
    handle: 0x0015, char properties: 0x0a, char value handle: 0x0016, uuid: ef680105-9b35-4933-9b10-52ffa9740042
    handle: 0x0017, char properties: 0x0a, char value handle: 0x0018, uuid: ef680106-9b35-4933-9b10-52ffa9740042
    handle: 0x0019, char properties: 0x02, char value handle: 0x001a, uuid: ef680107-9b35-4933-9b10-52ffa9740042
    handle: 0x001b, char properties: 0x0a, char value handle: 0x001c, uuid: ef680108-9b35-4933-9b10-52ffa9740042
    handle: 0x001d, char properties: 0x0a, char value handle: 0x001e, uuid: ef680109-9b35-4933-9b10-52ffa9740042
    handle: 0x0020, char properties: 0x10, char value handle: 0x0021, uuid: ef680201-9b35-4933-9b10-52ffa9740042
    handle: 0x0023, char properties: 0x10, char value handle: 0x0024, uuid: ef680202-9b35-4933-9b10-52ffa9740042
    handle: 0x0026, char properties: 0x10, char value handle: 0x0027, uuid: ef680203-9b35-4933-9b10-52ffa9740042
    handle: 0x0029, char properties: 0x10, char value handle: 0x002a, uuid: ef680204-9b35-4933-9b10-52ffa9740042
    handle: 0x002c, char properties: 0x10, char value handle: 0x002d, uuid: ef680205-9b35-4933-9b10-52ffa9740042
    handle: 0x002f, char properties: 0x0a, char value handle: 0x0030, uuid: ef680206-9b35-4933-9b10-52ffa9740042
    handle: 0x0032, char properties: 0x0a, char value handle: 0x0033, uuid: ef680401-9b35-4933-9b10-52ffa9740042
    handle: 0x0034, char properties: 0x10, char value handle: 0x0035, uuid: ef680402-9b35-4933-9b10-52ffa9740042
    handle: 0x0037, char properties: 0x10, char value handle: 0x0038, uuid: ef680403-9b35-4933-9b10-52ffa9740042
    handle: 0x003a, char properties: 0x10, char value handle: 0x003b, uuid: ef680404-9b35-4933-9b10-52ffa9740042
    handle: 0x003d, char properties: 0x10, char value handle: 0x003e, uuid: ef680405-9b35-4933-9b10-52ffa9740042
    handle: 0x0040, char properties: 0x10, char value handle: 0x0041, uuid: ef680406-9b35-4933-9b10-52ffa9740042
    handle: 0x0043, char properties: 0x10, char value handle: 0x0044, uuid: ef680407-9b35-4933-9b10-52ffa9740042
    handle: 0x0046, char properties: 0x10, char value handle: 0x0047, uuid: ef680408-9b35-4933-9b10-52ffa9740042
    handle: 0x0049, char properties: 0x10, char value handle: 0x004a, uuid: ef680409-9b35-4933-9b10-52ffa9740042
    handle: 0x004c, char properties: 0x10, char value handle: 0x004d, uuid: ef68040a-9b35-4933-9b10-52ffa9740042
    handle: 0x0050, char properties: 0x10, char value handle: 0x0051, uuid: ef680302-9b35-4933-9b10-52ffa9740042
    handle: 0x0053, char properties: 0x0a, char value handle: 0x0054, uuid: ef680301-9b35-4933-9b10-52ffa9740042
    handle: 0x0055, char properties: 0x0a, char value handle: 0x0056, uuid: ef680303-9b35-4933-9b10-52ffa9740042
    handle: 0x0058, char properties: 0x0a, char value handle: 0x0059, uuid: ef680501-9b35-4933-9b10-52ffa9740042
    handle: 0x005a, char properties: 0x04, char value handle: 0x005b, uuid: ef680502-9b35-4933-9b10-52ffa9740042
    handle: 0x005c, char properties: 0x10, char value handle: 0x005d, uuid: ef680503-9b35-4933-9b10-52ffa9740042
    handle: 0x005f, char properties: 0x10, char value handle: 0x0060, uuid: ef680504-9b35-4933-9b10-52ffa9740042
    handle: 0x0063, char properties: 0x12, char value handle: 0x0064, uuid: 00002a19-0000-1000-8000-00805f9b34fb
    handle: 0x0067, char properties: 0x28, char value handle: 0x0068, uuid: 8ec90003-f315-4f60-9fb8-838830daea50
    [yo:ur:ma:c:ad:rs][LE]>

    // Notice all of the offsets shown and specifically  'handle: 0x0063 and handle 0x0064' for the
    // characteristic 00002a19, e.g. The Battery Characteristic. 
    // Note that for the battery service, the characteristic is displayed as a full UUID,
    // NOT the service 0x180F as a full UUID.

    // Read the battery service characteristic value
    [yo:ur:ma:c:ad:rs][LE]> char-read-uuid 00002a19-0000-1000-8000-00805f9b34fb 0x0063 0x0066
    handle: 0x0064 value: 60 // <-- Expected 1 byte

    // Lo and behold, the elusive battery value has finally been read!

    // Enable notify on Temperature value
    [yo:ur:ma:c:ad:rs][LE]> char-write-req 0x0022 0100
    Characteristic value was written successfully
    Notification handle = 0x0021 value: 17 18 // <-- Expected 2 bytes
    Notification handle = 0x0021 value: 17 0f
    Notification handle = 0x0021 value: 17 16
    Notification handle = 0x0021 value: 17 1c
    Notification handle = 0x0021 value: 17 0f
    Notification handle = 0x0021 value: 17 21
    Notification handle = 0x0021 value: 17 25

    // Disable notify on Temperature value
    [yo:ur:ma:c:ad:rs][LE]> char-write-req 0x0022 0000
    Characteristic value was written successfully

    // Read the name value
    [yo:ur:ma:c:ad:rs][LE]> char-read-uuid ef680101-9b35-4933-9b10-52ffa9740042 0x000f 0x0010
    handle: 0x0010 value: 54 68 69 6e 67 79 32 // <-- Expected 5 bytes(Thingy2)

    So... if this helps anyone, pls comment. Maybe a bit obsessive, but I knew that one should be able to get at all these characteristics using low level linux tools.

Related