1

I am using flutter_blue plugin to discover beacons and sensors. In my case I am using Teltonika's eye sensor. The app I am making discovers sensor, and I get following data after scan

Manufacturer data.

{89A: [01, B7, 0A, 01, 2C, 0D, FA, C7, 00,  AC, 6B]}.

Service Data

{0000FEAA-0000-1000-8000-00805F9B34FB:  [00, 02, 2E, 50, 80, 6A, A3, 82, 55, AA, D9, FA, 2A, 15, 4E, 2D, 00, 55, 00, 00]}

I want to extract temperature, humidity, etc from this data, but I am not sure how to do it. I found similar question here , but I don't know how it fits in my case.

The documentations to sensor can be found here. Protocol Description section has little information about the data, but I am not sure how to use it.

Any help will be highly appreciated. Thanks

WatsMyName
  • 4,240
  • 5
  • 42
  • 73

1 Answers1

3

The Protocol Description seems to do a good job of explaining the format.

To take the example hex numbers in the Manufacturer data in the question:

[01,      // version
 B7,      // Flag value the same as documentation so it will be the same fields
 0A, 01,  // Temperature. Big endian so 2561 which needs dividing by 100 to get 25.61
 2C,      // Humidity. 2c hex is 44 decimal. So 44%
 0D, FA,  // Movement. Status is "not moving" and 3578 movement count
 C7,      // Angle. Device pitch (c7) = -57.
 00,  AC, // Angle. Device Roll (00AC) = 172
 6B]      // Battery value 3070mv

To do this with the code should be the same as the question you linked to with the exception the data is in Endian.big format which is the default setting. So for example:

import 'dart:typed_data';

var manufacturerData = Uint8List.fromList([0x01, 0xB7, 0x0A, 0x01, 0x2C, 0x0D, 0xFA, 0xC7, 0x00,  0xAC, 0x6B]);
var flags = ByteData.sublistView(manufacturerData, 1).getUint8(0);
/*
0 – Temperature value presence
1 – Humidity value presence
2 – Magnetic sensor presence
3 – Magnetic sensor state (1 magnetic field is detected/0 magnetic field is not detected) Valid value is present only if bit 2 flag is set.
4 – Movement sensor counter
5 – Movement sensor angle
6 – Low Battery indication (if set to 1 low battery voltage detected)
7 – Battery voltage value presence
 */
var flagTemperature = flags >> 0 & 1;
var flagHumidity = flags >> 1 & 1;
var flagMagPresence = flags >> 2 & 1;
var flagMagState = flags >> 3 & 1;
var flagMoveCount = flags >> 4 & 1;
var flagMoveAngle = flags >> 5 & 1;
var flagLowBatt = flags >> 6 & 1;
var flagBattery = flags >> 7 & 1;
var temperature = ByteData.sublistView(manufacturerData, 2, 4);
var humidity = ByteData.sublistView(manufacturerData, 4, 5);
var movement = ByteData.sublistView(manufacturerData, 5, 7);
var movementStatus = movement.getUint16(0) >> 15 & 1;
var movementCount = movement.getUint16(0) & 0x7fff;
var devicePitch = ByteData.sublistView(manufacturerData, 7, 8);
var deviceRoll = ByteData.sublistView(manufacturerData, 8, 10);
var battery = ByteData.sublistView(manufacturerData, 10, 11);
main() {
  print("Temperature Value presence: " + flagTemperature.toString());
  print("Humidity Value presence: " + flagHumidity.toString());
  print("Magnetic Value presence: " + flagMagPresence.toString());
  print("Magnetic State: " + flagMagState.toString());
  print("Move Sensor: " + flagMoveCount.toString());
  print("Move Angle: " + flagMoveAngle.toString());
  print("Low Battery: " + flagLowBatt.toString());
  print("Battery Value Presence: " + flagBattery.toString());
  print("Temperature: " + (temperature.getUint16(0)  / 100).toString());
  print("Humidity: " + humidity.getUint8(0).toString());
  print("Movement Status: " + movementStatus.toString());
  print("Movement count: " + movementCount.toString());
  print("Device Pitch: " + devicePitch.getInt8(0).toString());
  print("Device Roll: " + deviceRoll.getInt16(0).toString());
  print("Battery: " + (2000 + (battery.getUint8(0) * 10)).toString());
}

Which prints to the console:

Temperature Value presence: 1
Humidity Value presence: 1
Magnetic Value presence: 1
Magnetic State: 0
Move Sensor: 1
Move Angle: 1
Low Battery: 0
Battery Value Presence: 1
Temperature: 25.61
Humidity: 44
Movement Status: 0
Movement count: 3578
Device Pitch: -57
Device Roll: 172
Battery: 3070
ukBaz
  • 6,985
  • 2
  • 8
  • 31
  • Thanks a lot for a reply. What about magnetic field? – WatsMyName Mar 07 '22 at 02:51
  • And how do I know status is not moving? – WatsMyName Mar 07 '22 at 03:05
  • Updated the answer with examples of bitwise and shift operations to get status and presence values. The value of the flags reports that there is not magnetic field values included in the data. – ukBaz Mar 07 '22 at 06:58
  • On closer inspection it appears the magnetic field value is included in the flags. Example in answer updated. – ukBaz Mar 07 '22 at 07:12
  • One last question, what does `Service Data` (the one i mentioned in OP) hold? Can it be parsed to get some more information as well? – WatsMyName Mar 07 '22 at 10:31
  • The `SeviceData` is an Eddystone-UID beacon with `Namespace` and `Instance` information. More information at: https://github.com/google/eddystone/tree/master/eddystone-uid – ukBaz Mar 07 '22 at 11:02
  • Thanks, I tried to get namespace from `ServiceData` like this `var data=ByteData.sublistView(serviceData, 2, 11);`, but not sure how can i proceed further, as I am pretty much new to Dart. Also can you please give me link to tutorials where I can understand these in dart ? – WatsMyName Mar 07 '22 at 15:46
  • Take a look at: https://suragch.medium.com/working-with-bytes-in-dart-6ece83455721 – ukBaz Mar 07 '22 at 16:04
  • Thanks, I will go through it, and this may take time for me to understand this. Cn you please help me parse `serviceData` mentioned in OP and get Eddystone namespace id and instance id. Thanks in advance. – WatsMyName Mar 08 '22 at 16:02