Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RDL52832 decoder #138

Merged
merged 9 commits into from
Jul 10, 2022

Conversation

koenvervloesem
Copy link
Member

@koenvervloesem koenvervloesem commented Jul 2, 2022

Description:

This adds a decoder for the RDL52832 sensor beacon. It's an iBeacon that also advertises temperature, humidity and accelerometer readings.

There are still some issues before this can be merged:

  • The device is only correctly detected if the decoder gets the service data for UUID 0318 (see Support service data for multiple UUIDs #137). I have a test script at the bottom of this description that does this.
  • The acceleration properties are not correctly computed. I define a .cal value three times to extract Xt, Yt and Zt (see the data format below) and use these values, but it seems the decoder is only using the latest .cal value, so accx, accy and accz are calculated based on the same extracted value (Zt). See Support multiple .cal values in decoder #139 for more information.

Data format

The data format looks like this (see https://github.com/mike-rankin/ESP32_iBeacon_Sensor/blob/main/Code/iBeacon_Test.ino):

// Data format for the RadioLand RDL52832 iBeacon
//
// service UUID 0x0318:
//    0    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15
// +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
// | Th | Tl | Hh | Hl | Xs | Xw | Xt | Xh | Ys | Yw | Yt | Yh | Zs | Zw | Zt | Zh |
// +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
// Temperature (T), stored as a 16-bit value equal to Celcius * 256
// Humidity (H), stored as a 16-bit value equal to Humidity % * 256
// Accelerometer Axes: (X,Y,Z)
//    s = sign (1=negative, 0=positive)
//    w = whole value (0 or 1)
//    t = tenths (0-9)
//    h = hundredths (0-9)

Checklist:

  • The pull request is done against the latest development branch
  • Only one feature/fix was added per PR and the code change compiles without warnings
  • I accept the DCO.

Test script

import asyncio
import json
import struct
from bleak import BleakScanner
from TheengsDecoder import decodeBLE as dble
from TheengsDecoder import getProperties, getAttribute

def detection_callback(device, advertisement_data):
    data_json = {}

    if device.name == "RDL52832":

        print(device.address, "RSSI:", device.rssi, advertisement_data)
        if advertisement_data.service_data['00000318-0000-1000-8000-00805f9b34fb']:
            dstr = '00000318-0000-1000-8000-00805f9b34fb'
            # TheengsDecoder only accepts 16 bit uuid's, this converts the 128 bit uuid to 16 bit.
            data_json['servicedatauuid'] = dstr[4:8]
            dstr = advertisement_data.service_data['00000318-0000-1000-8000-00805f9b34fb'].hex()
            data_json['servicedata'] = dstr

        if advertisement_data.manufacturer_data:
            dstr = str(struct.pack('<H', list(advertisement_data.manufacturer_data.keys())[0]).hex())
            dstr += str(list(advertisement_data.manufacturer_data.values())[0].hex())
            data_json['manufacturerdata'] = dstr

        if advertisement_data.local_name:
            data_json['name'] = advertisement_data.local_name

        if data_json:
            print("data sent to decoder: ", json.dumps(data_json))
            data_json = dble(json.dumps(data_json))
            print("TheengsDecoder found device:", data_json)

            if data_json:
                dev = json.loads(data_json)
                print(getProperties(dev['model_id']))
                brand = getAttribute(dev['model_id'], 'brand')
                model = getAttribute(dev['model_id'], 'model')
                print("brand:", brand, ", model:", model)


async def main():
    scanner = BleakScanner()
    scanner.register_detection_callback(detection_callback)
    await scanner.start()
    await asyncio.sleep(5.0)
    await scanner.stop()

    for d in scanner.discovered_devices:
        print(d)

asyncio.run(main())

@koenvervloesem koenvervloesem marked this pull request as draft July 4, 2022 15:25
@koenvervloesem koenvervloesem changed the title Add RDL52832 decoder (WIP) Add RDL52832 decoder Jul 4, 2022
@h2zero
Copy link
Member

h2zero commented Jul 9, 2022

Tests pass if you prepend an underscore to each of the .cal values after the first, just like the other items.

@DigiH
Copy link
Member

DigiH commented Jul 9, 2022

So I ordered one as well now, I just hope they send the correct one ;) @koenvervloesem, from the data sheet (only found the Chinese version so far) it seems it has exactly the same writing commands for setting its name, uuid, major, minor and txpower as my nrf51822 beacons. With seemingly a slight difference for setting the broadcast interval and an additional password setting option.

How is your experience with the above?

@DigiH
Copy link
Member

DigiH commented Jul 9, 2022

Also from my search on Aliexpress all the nrf52832 iBeacons seem to only come in one version, with the default txpower transmission, compared to the nrfnrf51822, which specifically come in two different version with either txpower or battery voltage encoded in byte 24.

Therefore I think we can safely remove the volt property to slim down the decoder at least a tiny bit.

@koenvervloesem
Copy link
Member Author

Tests pass if you prepend an underscore to each of the .cal values after the first, just like the other items.

That's a hell of an undocumented feature :-) Cool, this works indeed. I have added some extra test data with the device in various orientations.

Therefore I think we can safely remove the volt property to slim down the decoder at least a tiny bit.

I removed the property.

I think the decoder is ready now.

@koenvervloesem koenvervloesem marked this pull request as ready for review July 9, 2022 19:48
@h2zero
Copy link
Member

h2zero commented Jul 9, 2022

That's a hell of an undocumented feature :-)

Lol, yes it is. Had a look at the code this morning and thought, "well why wouldn't it work?", and so it does 😄 .

@koenvervloesem
Copy link
Member Author

How is your experience with the above?

Actually I haven't changed the default settings yet. I was more interested in the sensor readings :-)

@DigiH DigiH merged commit 37d6a3d into theengs:development Jul 10, 2022
@koenvervloesem koenvervloesem deleted the radioland_rdl52832_ibeacon branch July 10, 2022 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants