lauren_d
lauren_d

Reputation: 13

React native: read from a smartwatch (hk85)

I'm trying to receive data from a smartwatch (HK85) in react native. The connection and writing is working great. But neither notify nor read is working. And I guess that's normal since isNotifiable is set to false and read as well.

"_activePromises": {},  "_activeSubscriptions": {}, "deviceID":"8E:75:D1:20:6A:2B", "id":4, "isIndicatable":false, "isNotifiable":false, "isNotifying":false, "isReadable":false, "isWritableWithResponse":true, "isWritableWithoutResponse":true, "serviceID":3, "serviceUUID":"6e400001-b5a3-f393-e0a9-e50e24dcca9e", "uuid":"6e400002-b5a3-f393-e0a9-e50e24dcca9e"

What I don't understand is the fact that I have a SDK for Android (that comes with the watch) and basically when they want access to say the battery of the device, it writes data to it and then receives a package:

BleConnector sendData -> 0x0203_POWER, 0x10_READ
V/BaseBle: BleMessenger enqueueMessage -> WriteMessage(service='6e400001-b5a3-f393-e0a9-e50e24dcca9e', characteristic='6e400002-b5a3-f393-e0a9-e50e24dcca9e', data=0xAB, 0x01, 0x00, 0x03, 0xFC, 0xA0, 0x02, 0x03, 0x10
V/BaseBle: MessageTask -> try(1), WriteMessage(service='6e400001-b5a3-f393-e0a9-e50e24dcca9e', characteristic='6e400002-b5a3-f393-e0a9-e50e24dcca9e', data=0xAB, 0x01, 0x00, 0x03, 0xFC, 0xA0, 0x02, 0x03, 0x10
V/BaseBle: BleMessenger enqueueWritePackets -> WriteMessage(service='6e400001-b5a3-f393-e0a9-e50e24dcca9e', characteristic='6e400002-b5a3-f393-e0a9-e50e24dcca9e', data=0xAB, 0x01, 0x00, 0x03, 0xFC, 0xA0, 0x02, 0x03, 0x10
I/BaseBle: AbsBleConnector onCharacteristicWrite -> 0 SUCCESS, 6e400002-b5a3-f393-e0a9-e50e24dcca9e, 0xAB, 0x01, 0x00, 0x03, 0xFC, 0xA0, 0x02, 0x03, 0x10
V/BaseBle: BleMessenger dequeueWritePacket
I/BaseBle: AbsBleConnector onCharacteristicChanged -> 6e400003-b5a3-f393-e0a9-e50e24dcca9e, 0xAB, 0x11, 0x00, 0x04, 0x87, 0xFD, 0x02, 0x03, 0x10, 0x54
V/BaseBle: BleParser -> data length=10, received=10

So I'm a bit stuck at understanding how this works and I guess some answer reside in the onCharacteristicChanged, but how does that translate with this library?

Thank you for your time

Tried using react-native-ble-plx
Tried first response

deviceConnection.monitorCharacteristicForService(
        SERVICE_UUID,
        TX_CHARACTERISTIC,
        (error, char) => {
          console.log("Last data: " + char?.value);
        },
      );
      
      deviceConnection.writeCharacteristicWithResponseForService(
        SERVICE_UUID,
        RX_CHARACTERISTIC,
        "0xAB, 0x01, 0x00, 0x03, 0xFC, 0xA0, 0x02, 0x03, 0x10"
      ).then((data) => {
        console.log(data?.value)
      })

But the monitor never fires unless I disconnect the device and then its value is undefined. Maybe what I'm writing to it is wrong

Managed to decode data received with Android SDK

So after a long talk with chatgpt, we manage to decode the data I was receiving with my react native app after sending data with the Android SDK.

So we had to decode the base64 string to big endian array of bytes which resulted for example: Decoding qxEABK19AgMQMg== as big endian gives the following byte array:

0x32, 0x10, 0x03, 0x02, 0x7D, 0xAD, 0x04, 0x00, 0x11, 0xAB

With 0x32 being the last byte and converted in decimal giving me 50, exactly the percentage left of my smartwach.

But there is still the question as to what I should write to the device to receive it, maybe I need to convert my array of bytes to a base64 or maybe I should change how I receive and write data.

Upvotes: 0

Views: 724

Answers (1)

Michael Kotzjan
Michael Kotzjan

Reputation: 2662

The smartwatch seems to offer the Nordic UART Service for communication. Your comment including the UUIDs you received using nRF Connect shows the same UUIDs and characteristics.

The documentation I linked states that the RX characteristic can be written by either Write or Write Without Response. The TX allows notifications and will use them to give you the response to the send data.

What I don't understand is the fact that I have a SDK for Android (that comes with the watch) and basically when they want access to say the battery of the device, it writes data to it and then receives a package

The SDK also matches the UART service. To implement something similar using react-native-ble-plx you need to activate and subscribe to the notifications of the TX characteristic. See the documentation for examples.

EDIT: maybe something like this works:

device.monitorCharacteristicForService(
  SERVICE_UUID,
  TX_CHARACTERISTIC,
  (error, char) => {
    console.log("Last data: " + char?.value);
  },
);

device.writeCharacteristicWithResponseForService(
  SERVICE_UUID,
  RX_CHARACTERISTIC,
  "0xAB, 0x01, 0x00, 0x03, 0xFC, 0xA0, 0x02, 0x03, 0x10"
)

Create the listener first, then write to the characteristic.

Upvotes: 0

Related Questions