From d68a4211b6ce29c5cc2f2c8c442eec7b3d0f2dd9 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Thu, 2 Jul 2015 10:26:32 +0200 Subject: [PATCH] First attempt at parsing the live sensor data, see issue #63 - Live sensor data reading is toggled using the "Set music info" in the debug activity. - The readings are ONLY logged at the moment - The miband increments a "counter" (two bytes) at every reading, but it may be that more readings are sent with the same counter value. This is already addressed. - The name of the axes is general (axis1, 2 and 3) because we still don't know which is which - It could be that the axes depend on the wear location (especially wearing as a necklace means that the miband rests in a vertical position, while wearing on the wrist means it rests in a horizontal position). NB: It could be that we get RAW data, hence not dependent on the wear location. - Since the miband may be inserted in two directions in its strap, I guess this also has to be taken into account - the battery impact of reading this data in unknown --- .../gadgetbridge/miband/MiBandService.java | 5 +-- .../gadgetbridge/miband/MiBandSupport.java | 41 ++++++++++++++++++- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandService.java index e9500f36..20fc9d12 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandService.java @@ -137,14 +137,13 @@ public class MiBandService { public static final byte COMMAND_SET_TIMER = 0x4; + public static final byte COMMAND_GET_SENSOR_DATA = 0x12; + /* public static final byte COMMAND_FACTORY_RESET = 0x9t; - - public static final byte COMMAND_GET_SENSOR_DATA = 0x12t - public static final byte COMMAND_SEND_FIRMWARE_INFO = 0x7t public static final int COMMAND_SET_COLOR_THEME = et; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java index 12597601..017d2e32 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/miband/MiBandSupport.java @@ -73,7 +73,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { private GregorianCalendar activityDataTimestampToAck = null; private volatile boolean telephoneRinging; private volatile boolean isLocatingDevice; - + private volatile boolean isReadingSensorData; public MiBandSupport() { addSupportedService(MiBandService.UUID_SERVICE_MIBAND_SERVICE); @@ -206,6 +206,8 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { private static final byte[] startVibrate = new byte[]{MiBandService.COMMAND_SEND_NOTIFICATION, 1}; private static final byte[] stopVibrate = new byte[]{MiBandService.COMMAND_STOP_MOTOR_VIBRATE}; private static final byte[] reboot = new byte[]{MiBandService.COMMAND_REBOOT}; + private static final byte[] sensorRead = new byte[]{MiBandService.COMMAND_GET_SENSOR_DATA, 1}; + private static final byte[] sensorStop = new byte[]{MiBandService.COMMAND_GET_SENSOR_DATA, 0}; private static final byte[] fetch = new byte[]{MiBandService.COMMAND_FETCH_DATA}; private byte[] getNotification(long vibrateDuration, int vibrateTimes, int flashTimes, int flashColour, int originalColour, long flashDuration) { @@ -422,7 +424,19 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { @Override public void onSetMusicInfo(String artist, String album, String track) { - // not supported + try { + TransactionBuilder builder = performInitialized("Toggle sensor reading"); + if (isReadingSensorData){ + builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT), sensorStop); + isReadingSensorData = false; + }else { + builder.write(getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT), sensorRead); + isReadingSensorData = true; + } + builder.queue(getQueue()); + } catch (IOException ex) { + LOG.error("Unable to toggle sensor reading MI", ex); + } } @Override @@ -527,6 +541,8 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { handleBatteryInfo(characteristic.getValue(), BluetoothGatt.GATT_SUCCESS); } else if (MiBandService.UUID_CHARACTERISTIC_NOTIFICATION.equals(characteristicUUID)) { // device somehow changed, should we update e.g. battery level? + } else if (MiBandService.UUID_CHARACTERISTIC_SENSOR_DATA.equals(characteristicUUID)) { + handleSensorData(characteristic.getValue()); } } @@ -647,6 +663,27 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { } } + private void handleSensorData(byte[] value) { + int counter=0, step=0, axis1=0, axis2=0, axis3 =0; + if((value.length - 2) % 6 != 0) { + LOG.warn("GOT UNEXPECTED SENSOR DATA WITH LENGTH: " + value.length); + for (byte b : value) { + LOG.warn("DATA: " + String.format("0x%4x", b)); + } + } + else { + counter = (value[0] & 0xff) | ((value[1] & 0xff) << 8); + for (int idx = 0; idx < ((value.length - 2) / 6); idx++) { + step = idx * 6; + axis1 = (value[step+2] & 0xff) | ((value[step+3] & 0xff) << 8); + axis2 = (value[step+4] & 0xff) | ((value[step+5] & 0xff) << 8); + axis3 = (value[step+6] & 0xff) | ((value[step+7] & 0xff) << 8); + } + LOG.info("READ SENSOR DATA VALUES: counter:"+counter+" step:"+step+" axis1:"+axis1+" axis2:"+axis2+" axis3:"+axis3+";"); + } + } + + private void flushActivityDataHolder() { GregorianCalendar timestamp = this.activityDataTimestampProgress; byte category, intensity, steps;