diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusConstants.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusConstants.java index 9f82d13d..70546e87 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusConstants.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusConstants.java @@ -36,6 +36,7 @@ public final class HPlusConstants { public static final byte[] CMD_SET_PREF_START = new byte[]{0x4f, 0x5a}; public static final byte[] CMD_SET_PREF_START1 = new byte[]{0x4d}; + public static final byte CMD_SET_ALARM = 0x4c; public static final byte CMD_SET_LANGUAGE = 0x22; public static final byte CMD_SET_TIMEMODE = 0x47; public static final byte CMD_SET_UNITS = 0x48; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java index 61ce6a2e..3fe16e41 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusHealthSampleProvider.java @@ -6,9 +6,6 @@ package nodomain.freeyourgadget.gadgetbridge.devices.hplus; import android.support.annotation.NonNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Collections; import java.util.Comparator; import java.util.List; @@ -30,8 +27,6 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; public class HPlusHealthSampleProvider extends AbstractSampleProvider { - private static final Logger LOG = LoggerFactory.getLogger(HPlusHealthSampleProvider.class); - private GBDevice mDevice; private DaoSession mSession; @@ -71,12 +66,12 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider getAllActivitySamples(int timestamp_from, int timestamp_to) { List samples = super.getGBActivitySamples(timestamp_from, timestamp_to, ActivityKind.TYPE_ALL); @@ -107,11 +103,11 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider overlayRecords = qb.build().list(); for (HPlusHealthActivityOverlay overlay : overlayRecords) { - insertVirtualItem(samples, overlay.getTimestampFrom(), overlay.getDeviceId(), overlay.getUserId()); - insertVirtualItem(samples, overlay.getTimestampTo() - 1, overlay.getDeviceId(), overlay.getUserId()); + insertVirtualItem(samples, Math.max(overlay.getTimestampFrom(), timestamp_from), overlay.getDeviceId(), overlay.getUserId()); + insertVirtualItem(samples, Math.min(overlay.getTimestampTo() - 1, timestamp_to - 1), overlay.getDeviceId(), overlay.getUserId()); for (HPlusHealthActivitySample sample : samples) { - if (overlay.getTimestampFrom() <= sample.getTimestamp() && sample.getTimestamp() < overlay.getTimestampTo()) { + if (sample.getTimestamp() >= overlay.getTimestampFrom() && sample.getTimestamp() < overlay.getTimestampTo()) { sample.setRawKind(overlay.getRawKind()); } } @@ -119,8 +115,6 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider() { public int compare(HPlusHealthActivitySample one, HPlusHealthActivitySample other) { return one.getTimestamp() - other.getTimestamp(); @@ -137,7 +131,7 @@ public class HPlusHealthSampleProvider extends AbstractSampleProvider getIntervals() { - List intervals = new ArrayList(); + List intervals = new ArrayList<>(); int ts = bedTimeStart + lightSleepMinutes * 60; intervals.add(new RecordInterval(bedTimeStart, ts, ActivityKind.TYPE_LIGHT_SLEEP)); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordSteps.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordSteps.java index cdc18307..33901ddd 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordSteps.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusDataRecordSteps.java @@ -5,19 +5,12 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus; */ -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Calendar; -import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; - -public class HPlusDataRecordSteps extends HPlusDataRecord{ - private static final Logger LOG = LoggerFactory.getLogger(HPlusDataRecordSteps.class); - - int steps; - int distance; +class HPlusDataRecordSteps extends HPlusDataRecord{ + public int steps; + public int distance; HPlusDataRecordSteps(byte[] data) { super(data); @@ -45,15 +38,11 @@ public class HPlusDataRecordSteps extends HPlusDataRecord{ date.set(Calendar.YEAR, year); date.set(Calendar.MONTH, month - 1); date.set(Calendar.DAY_OF_MONTH, day); - date.set(Calendar.HOUR, 23); + date.set(Calendar.HOUR_OF_DAY, 23); date.set(Calendar.MINUTE, 59); date.set(Calendar.SECOND, 59); date.set(Calendar.MILLISECOND, 999); timestamp = (int) (date.getTimeInMillis() / 1000); } - - public int getType(int ts){ - return ActivityKind.TYPE_UNKNOWN; - } } \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusHandlerThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusHandlerThread.java index a197bd4c..fe8ebffc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusHandlerThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusHandlerThread.java @@ -18,15 +18,12 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBException; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; -import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusConstants; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusHealthSampleProvider; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; -import nodomain.freeyourgadget.gadgetbridge.entities.Device; import nodomain.freeyourgadget.gadgetbridge.entities.HPlusHealthActivityOverlay; import nodomain.freeyourgadget.gadgetbridge.entities.HPlusHealthActivityOverlayDao; import nodomain.freeyourgadget.gadgetbridge.entities.HPlusHealthActivitySample; -import nodomain.freeyourgadget.gadgetbridge.entities.User; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample; @@ -34,16 +31,15 @@ import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread; -public class HPlusHandlerThread extends GBDeviceIoThread { +class HPlusHandlerThread extends GBDeviceIoThread { + private static final Logger LOG = LoggerFactory.getLogger(HPlusHandlerThread.class); private int SYNC_PERIOD = 60 * 10; private int SYNC_RETRY_PERIOD = 6; private int SLEEP_SYNC_PERIOD = 12 * 60 * 60; private int SLEEP_RETRY_PERIOD = 30; - private int HELLO_INTERVAL = 30; - - private static final Logger LOG = LoggerFactory.getLogger(HPlusHandlerThread.class); + private int HELLO_INTERVAL = 60; private boolean mQuit = false; private HPlusSupport mHPlusSupport; @@ -57,7 +53,7 @@ public class HPlusHandlerThread extends GBDeviceIoThread { private Calendar mGetDaySlotsTime = Calendar.getInstance(); private Calendar mGetSleepTime = Calendar.getInstance(); - private Object waitObject = new Object(); + private final Object waitObject = new Object(); private HPlusDataRecordRealtime prevRealTimeRecord = null; @@ -80,7 +76,6 @@ public class HPlusHandlerThread extends GBDeviceIoThread { sync(); - boolean starting = true; long waitTime = 0; while (!mQuit) { //LOG.debug("Waiting " + (waitTime)); @@ -147,25 +142,27 @@ public class HPlusHandlerThread extends GBDeviceIoThread { } } - public void sendHello() { - mHelloTime = Calendar.getInstance(); - mHelloTime.add(Calendar.SECOND, HELLO_INTERVAL); - + private void sendHello() { TransactionBuilder builder = new TransactionBuilder("hello"); builder.write(mHPlusSupport.ctrlCharacteristic, HPlusConstants.CMD_ACTION_HELLO); builder.queue(mHPlusSupport.getQueue()); + scheduleHello(); } + public void scheduleHello(){ + mHelloTime = Calendar.getInstance(); + mHelloTime.add(Calendar.SECOND, HELLO_INTERVAL); + } - public void processIncomingDaySlotData(byte[] data) { + public boolean processIncomingDaySlotData(byte[] data) { HPlusDataRecordDay record; try{ record = new HPlusDataRecordDay(data); } catch(IllegalArgumentException e){ LOG.debug((e.getMessage())); - return; + return true; } if ((record.slot == 0 && mLastSlotReceived == 0) || (record.slot == mLastSlotReceived + 1)) { @@ -181,7 +178,7 @@ public class HPlusHandlerThread extends GBDeviceIoThread { deviceId, userId, // User id record.getRawData(), // Raw Data ActivityKind.TYPE_UNKNOWN, - ActivitySample.NOT_MEASURED, // Intensity + 0, // Intensity record.steps, // Steps record.heartRate, // HR ActivitySample.NOT_MEASURED, // Distance @@ -204,11 +201,10 @@ public class HPlusHandlerThread extends GBDeviceIoThread { } } } + return true; } private void requestNextDaySlots() { - LOG.debug("Request Next Slot: Got: " + mLastSlotReceived + " Request: " + mLastSlotRequested); - //Sync Day Stats byte hour = (byte) ((mLastSlotReceived) / 6); byte nextHour = (byte) (hour + 1); @@ -240,7 +236,7 @@ public class HPlusHandlerThread extends GBDeviceIoThread { return; } - LOG.debug("Making new Request From " + hour + ":" + minute + " to " + nextHour + ":" + nextMinute); + //LOG.debug("Making new Request From " + hour + ":" + minute + " to " + nextHour + ":" + nextMinute); byte[] msg = new byte[]{39, hour, minute, nextHour, nextMinute}; //Request the entire day TransactionBuilder builder = new TransactionBuilder("getNextDaySlot"); @@ -251,16 +247,14 @@ public class HPlusHandlerThread extends GBDeviceIoThread { mGetDaySlotsTime.add(Calendar.SECOND, SYNC_RETRY_PERIOD); } - public void processIncomingSleepData(byte[] data){ - LOG.debug("Processing Sleep Data"); - + public boolean processIncomingSleepData(byte[] data){ HPlusDataRecordSleep record; try{ record = new HPlusDataRecordSleep(data); } catch(IllegalArgumentException e){ LOG.debug((e.getMessage())); - return; + return true; } mLastSleepDayReceived.setTimeInMillis(record.bedTimeStart * 1000L); @@ -288,7 +282,7 @@ public class HPlusHandlerThread extends GBDeviceIoThread { deviceId, userId, // User id record.getRawData(), // Raw Data record.activityKind, - ActivitySample.NOT_MEASURED, // Intensity + 0, // Intensity ActivitySample.NOT_MEASURED, // Steps ActivitySample.NOT_MEASURED, // HR ActivitySample.NOT_MEASURED, // Distance @@ -307,11 +301,10 @@ public class HPlusHandlerThread extends GBDeviceIoThread { mGetSleepTime = Calendar.getInstance(); mGetSleepTime.add(Calendar.SECOND, SLEEP_SYNC_PERIOD); + return true; } private void requestNextSleepData() { - LOG.debug("Request New Sleep Data"); - mGetSleepTime = Calendar.getInstance(); mGetSleepTime.add(Calendar.SECOND, SLEEP_RETRY_PERIOD); @@ -321,20 +314,18 @@ public class HPlusHandlerThread extends GBDeviceIoThread { } - public void processRealtimeStats(byte[] data) { - LOG.debug("Processing Real time Stats"); - + public boolean processRealtimeStats(byte[] data) { HPlusDataRecordRealtime record; try{ record = new HPlusDataRecordRealtime(data); } catch(IllegalArgumentException e){ LOG.debug((e.getMessage())); - return; + return true; } if(record.same(prevRealTimeRecord)) - return; + return true; prevRealTimeRecord = record; @@ -345,18 +336,14 @@ public class HPlusHandlerThread extends GBDeviceIoThread { if(record.heartRate == 255) { getDevice().setFirmwareVersion2("---"); getDevice().sendDeviceUpdateIntent(getContext()); - return; + return true; } - getDevice().setFirmwareVersion2(""+record.heartRate); + getDevice().setFirmwareVersion2("" + record.heartRate); getDevice().sendDeviceUpdateIntent(getContext()); try (DBHandler dbHandler = GBApplication.acquireDB()) { - DaoSession session = dbHandler.getDaoSession(); - HPlusHealthSampleProvider provider = new HPlusHealthSampleProvider(getDevice(), dbHandler.getDaoSession()); - HPlusHealthActivityOverlayDao overlayDao = session.getHPlusHealthActivityOverlayDao(); - Long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId(); Long deviceId = DBHelper.getDevice(getDevice(), dbHandler.getDaoSession()).getId(); @@ -365,7 +352,7 @@ public class HPlusHandlerThread extends GBDeviceIoThread { deviceId, userId, // User id record.getRawData(), // Raw Data record.activityKind, - ActivitySample.NOT_MEASURED, // Intensity + record.intensity, // Intensity ActivitySample.NOT_MEASURED, // Steps record.heartRate, // HR record.distance, // Distance @@ -375,32 +362,25 @@ public class HPlusHandlerThread extends GBDeviceIoThread { sample.setProvider(provider); provider.addGBActivitySample(sample); - if(record.activeTime > 0){ - //TODO: Register ACTIVITY Time - - //Insert the Overlays - //List overlayList = new ArrayList<>(); - //overlayList.add(new HPlusHealthActivityOverlay(record.timestamp - record.activeTime * 60, record.timestamp, ActivityKind.TYPE_ACTIVITY, deviceId, userId, null)); - //overlayDao.insertOrReplaceInTx(overlayList); - } + //TODO: Handle Active Time. With Overlay? } catch (GBException ex) { LOG.debug((ex.getMessage())); } catch (Exception ex) { LOG.debug(ex.getMessage()); } + return true; } - public void processStepStats(byte[] data) { - LOG.debug("Processing Step Stats"); + public boolean processStepStats(byte[] data) { HPlusDataRecordSteps record; try{ record = new HPlusDataRecordSteps(data); } catch(IllegalArgumentException e){ LOG.debug((e.getMessage())); - return; + return true; } try (DBHandler dbHandler = GBApplication.acquireDB()) { @@ -408,17 +388,40 @@ public class HPlusHandlerThread extends GBDeviceIoThread { Long userId = DBHelper.getUser(dbHandler.getDaoSession()).getId(); Long deviceId = DBHelper.getDevice(getDevice(), dbHandler.getDaoSession()).getId(); + + //Hugly (?) fix. + //This message returns the day summary, but the DB already has some detailed entries with steps and distance. + //However DB data is probably incomplete as some update messages could be missing + //Proposed fix: Calculate the total steps and distance and store a new sample with the remaining data + //Existing data will reflect user activity with the issue of a potencially large number of steps at midnight. + //Steps counters by day will be OK with this + + List samples = provider.getActivitySamples(record.timestamp - 3600 * 24 + 1, record.timestamp); + + int missingDistance = record.distance; + int missingSteps = record.steps; + + for(HPlusHealthActivitySample sample : samples){ + if(sample.getSteps() > 0) { + missingSteps -= sample.getSteps(); + } + if(sample.getDistance() > 0){ + missingDistance -= sample.getDistance(); + } + } + HPlusHealthActivitySample sample = new HPlusHealthActivitySample( record.timestamp, // ts deviceId, userId, // User id record.getRawData(), // Raw Data ActivityKind.TYPE_UNKNOWN, - ActivitySample.NOT_MEASURED, // Intensity - record.steps, // Steps + 0, // Intensity + Math.max( missingSteps, 0), // Steps ActivitySample.NOT_MEASURED, // HR - record.distance, // Distance + Math.max( missingDistance, 0), // Distance ActivitySample.NOT_MEASURED // Calories ); + sample.setProvider(provider); provider.addGBActivitySample(sample); } catch (GBException ex) { @@ -426,11 +429,11 @@ public class HPlusHandlerThread extends GBDeviceIoThread { } catch (Exception ex) { LOG.debug(ex.getMessage()); } + + return true; } public boolean processVersion(byte[] data) { - LOG.debug("Process Version"); - int major = data[2] & 0xFF; int minor = data[1] & 0xFF; @@ -440,14 +443,4 @@ public class HPlusHandlerThread extends GBDeviceIoThread { return true; } - - public static HPlusHealthActivitySample createActivitySample(Device device, User user, int timestampInSeconds, SampleProvider provider) { - HPlusHealthActivitySample sample = new HPlusHealthActivitySample(); - sample.setDevice(device); - sample.setUser(user); - sample.setTimestamp(timestampInSeconds); - sample.setProvider(provider); - - return sample; - } } \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java index 65350305..1deda41d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/hplus/HPlusSupport.java @@ -4,7 +4,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.hplus; * @author João Paulo Barraca <jpbarraca@gmail.com> */ -import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattCharacteristic; import android.content.BroadcastReceiver; @@ -23,7 +22,6 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.UUID; -import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusConstants; import nodomain.freeyourgadget.gadgetbridge.devices.hplus.HPlusCoordinator; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; @@ -35,10 +33,10 @@ import nodomain.freeyourgadget.gadgetbridge.model.MusicSpec; import nodomain.freeyourgadget.gadgetbridge.model.MusicStateSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.service.btle.AbstractBTLEDeviceSupport; -import nodomain.freeyourgadget.gadgetbridge.service.btle.GattCharacteristic; import nodomain.freeyourgadget.gadgetbridge.service.btle.GattService; import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetDeviceStateAction; +import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfo; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfoProfile; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -49,9 +47,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { public BluetoothGattCharacteristic ctrlCharacteristic = null; public BluetoothGattCharacteristic measureCharacteristic = null; - private int[] lastDataStats = null; - - private final GBDeviceEventVersionInfo versionCmd = new GBDeviceEventVersionInfo(); private HPlusHandlerThread syncHelper; private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @@ -82,10 +77,10 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { LOG.debug("Dispose"); LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getContext()); broadcastManager.unregisterReceiver(mReceiver); - super.dispose(); - if(syncHelper != null) - syncHelper.quit(); + close(); + + super.dispose(); } @Override @@ -112,15 +107,12 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { setInitialized(builder); - syncHelper.start(); builder.notify(getCharacteristic(HPlusConstants.UUID_CHARACTERISTIC_MEASURE), true); builder.setGattCallback(this); builder.notify(measureCharacteristic, true); - //LOG.debug("Initialization Done"); - return builder; } @@ -135,8 +127,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } private HPlusSupport syncPreferences(TransactionBuilder transaction) { - LOG.info("Attempting to sync preferences with: " + getDevice().getAddress()); - byte gender = HPlusCoordinator.getUserGender(getDevice().getAddress()); byte age = HPlusCoordinator.getUserAge(getDevice().getAddress()); byte bodyHeight = HPlusCoordinator.getUserHeight(getDevice().getAddress()); @@ -189,8 +179,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } private HPlusSupport setLanguage(TransactionBuilder transaction) { - LOG.info("Attempting to set language..."); - byte value = HPlusCoordinator.getCountry(getDevice().getAddress()); transaction.write(ctrlCharacteristic, new byte[]{ HPlusConstants.CMD_SET_LANGUAGE, @@ -201,8 +189,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { private HPlusSupport setTimeMode(TransactionBuilder transaction) { - LOG.info("Attempting to set Time Mode..."); - byte value = HPlusCoordinator.getTimeMode(getDevice().getAddress()); transaction.write(ctrlCharacteristic, new byte[]{ HPlusConstants.CMD_SET_TIMEMODE, @@ -212,9 +198,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } private HPlusSupport setUnit(TransactionBuilder transaction) { - LOG.info("Attempting to set Units..."); - - byte value = HPlusCoordinator.getUnit(getDevice().getAddress()); transaction.write(ctrlCharacteristic, new byte[]{ HPlusConstants.CMD_SET_UNITS, @@ -224,8 +207,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } private HPlusSupport setCurrentDate(TransactionBuilder transaction) { - LOG.info("Attempting to set Current Date..."); - Calendar c = Calendar.getInstance(); int year = c.get(Calendar.YEAR) - 1900; int month = c.get(Calendar.MONTH); @@ -243,8 +224,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } private HPlusSupport setCurrentTime(TransactionBuilder transaction) { - LOG.info("Attempting to set Current Time..."); - Calendar c = Calendar.getInstance(); transaction.write(ctrlCharacteristic, new byte[]{ @@ -259,8 +238,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { private HPlusSupport setDayOfWeek(TransactionBuilder transaction) { - LOG.info("Attempting to set Day Of Week..."); - Calendar c = Calendar.getInstance(); transaction.write(ctrlCharacteristic, new byte[]{ @@ -272,8 +249,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { private HPlusSupport setSIT(TransactionBuilder transaction) { - LOG.info("Attempting to set SIT..."); - int startTime = HPlusCoordinator.getSITStartTime(getDevice().getAddress()); int endTime = HPlusCoordinator.getSITEndTime(getDevice().getAddress()); @@ -291,7 +266,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { (byte) (now.get(Calendar.YEAR) % 256), (byte) (now.get(Calendar.MONTH) + 1), (byte) (now.get(Calendar.DAY_OF_MONTH)), - (byte) (now.get(Calendar.HOUR)), + (byte) (now.get(Calendar.HOUR_OF_DAY)), (byte) (now.get(Calendar.MINUTE)), (byte) (now.get(Calendar.SECOND)), 0, @@ -304,8 +279,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } private HPlusSupport setWeight(TransactionBuilder transaction) { - LOG.info("Attempting to set Weight..."); - byte value = HPlusCoordinator.getUserWeight(getDevice().getAddress()); transaction.write(ctrlCharacteristic, new byte[]{ HPlusConstants.CMD_SET_WEIGHT, @@ -316,8 +289,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } private HPlusSupport setHeight(TransactionBuilder transaction) { - LOG.info("Attempting to set Height..."); - byte value = HPlusCoordinator.getUserHeight(getDevice().getAddress()); transaction.write(ctrlCharacteristic, new byte[]{ HPlusConstants.CMD_HEIGHT, @@ -329,8 +300,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { private HPlusSupport setAge(TransactionBuilder transaction) { - LOG.info("Attempting to set Age..."); - byte value = HPlusCoordinator.getUserAge(getDevice().getAddress()); transaction.write(ctrlCharacteristic, new byte[]{ HPlusConstants.CMD_SET_AGE, @@ -341,8 +310,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } private HPlusSupport setGender(TransactionBuilder transaction) { - LOG.info("Attempting to set Gender..."); - byte value = HPlusCoordinator.getUserGender(getDevice().getAddress()); transaction.write(ctrlCharacteristic, new byte[]{ HPlusConstants.CMD_SET_GENDER, @@ -354,8 +321,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { private HPlusSupport setGoal(TransactionBuilder transaction) { - LOG.info("Attempting to set Sex..."); - int value = HPlusCoordinator.getGoal(getDevice().getAddress()); transaction.write(ctrlCharacteristic, new byte[]{ HPlusConstants.CMD_SET_GOAL, @@ -368,8 +333,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { private HPlusSupport setScreenTime(TransactionBuilder transaction) { - LOG.info("Attempting to set Screentime..."); - byte value = HPlusCoordinator.getScreenTime(getDevice().getAddress()); transaction.write(ctrlCharacteristic, new byte[]{ HPlusConstants.CMD_SET_SCREENTIME, @@ -392,28 +355,35 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } - private HPlusSupport setAlarm(TransactionBuilder transaction) { - LOG.info("Attempting to set Alarm..."); - //TODO: Find how to set alarms + private HPlusSupport setAlarm(TransactionBuilder transaction, Calendar t) { + + transaction.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_ALARM, + (byte) (t.get(Calendar.YEAR) / 256), + (byte) (t.get(Calendar.YEAR) % 256), + (byte) (t.get(Calendar.MONTH) + 1), + (byte) t.get(Calendar.HOUR_OF_DAY), + (byte) t.get(Calendar.MINUTE), + (byte) t.get(Calendar.SECOND)}); + return this; } - private HPlusSupport setBlood(TransactionBuilder transaction) { - LOG.info("Attempting to set Blood..."); - //TODO: Find what blood means for the band - return this; - } - - - private HPlusSupport setFindMe(TransactionBuilder transaction) { - LOG.info("Attempting to set Findme..."); + private HPlusSupport setFindMe(TransactionBuilder transaction, boolean state) { //TODO: Find how this works + + byte[] msg = new byte[2]; + msg[0] = HPlusConstants.CMD_SET_FINDME; + + if (state) + msg[1] = HPlusConstants.ARG_FINDME_ON; + else + msg[1] = HPlusConstants.ARG_FINDME_OFF; + + transaction.write(ctrlCharacteristic, msg); return this; } private HPlusSupport requestDeviceInfo(TransactionBuilder builder) { - LOG.debug("Requesting Device Info!"); - // HPlus devices seem to report some information in an alternative manner builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DEVICE_ID}); builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_VERSION}); @@ -433,31 +403,50 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { @Override public void pair() { + LOG.debug("Pair"); } - private void handleDeviceInfo(nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.deviceinfo.DeviceInfo info) { + private void handleDeviceInfo(DeviceInfo info) { LOG.warn("Device info: " + info); } @Override public void onNotification(NotificationSpec notificationSpec) { - LOG.debug("Got Notification"); - //TODO: Show different notifications acccording to source as Band supports this + //TODO: Show different notifications according to source as Band supports this showText(notificationSpec.title, notificationSpec.body); } - @Override public void onSetTime() { TransactionBuilder builder = new TransactionBuilder("time"); setCurrentDate(builder); setCurrentTime(builder); + + builder.queue(getQueue()); } @Override public void onSetAlarms(ArrayList alarms) { + if (alarms.size() == 0) + return; + + for (Alarm alarm : alarms) { + + if (!alarm.isEnabled()) + continue; + + if (alarm.isSmartWakeup()) //Not available + continue; + + Calendar t = alarm.getAlarmCal(); + TransactionBuilder builder = new TransactionBuilder("alarm"); + setAlarm(builder, t); + builder.queue(getQueue()); + + return; //Only first alarm + } } @@ -524,19 +513,22 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { @Override public void onFetchActivityData() { - if(syncHelper != null) + if (syncHelper != null) syncHelper.sync(); } @Override public void onReboot() { + getQueue().clear(); + + TransactionBuilder builder = new TransactionBuilder("Shutdown"); + builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SHUTDOWN, HPlusConstants.ARG_SHUTDOWN_EN}); + builder.queue(getQueue()); } @Override public void onHeartRateTest() { - LOG.debug("On HeartRateTest"); - getQueue().clear(); TransactionBuilder builder = new TransactionBuilder("HeartRateTest"); @@ -547,8 +539,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { @Override public void onEnableRealtimeHeartRateMeasurement(boolean enable) { - LOG.debug("Set Real Time HR Measurement: " + enable); - getQueue().clear(); TransactionBuilder builder = new TransactionBuilder("realTimeHeartMeasurement"); @@ -561,35 +551,24 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_ALLDAY_HRM, state}); builder.queue(getQueue()); + } @Override public void onFindDevice(boolean start) { - LOG.debug("Find Me"); - try { TransactionBuilder builder = performInitialized("findMe"); - byte[] msg = new byte[2]; - msg[0] = HPlusConstants.CMD_SET_FINDME; - - if (start) - msg[1] = HPlusConstants.ARG_FINDME_ON; - else - msg[1] = HPlusConstants.ARG_FINDME_OFF; - - builder.write(ctrlCharacteristic, msg); + setFindMe(builder, start); builder.queue(getQueue()); } catch (IOException e) { - GB.toast(getContext(), "Error toogling Find Me: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); + GB.toast(getContext(), "Error toggling Find Me: " + e.getLocalizedMessage(), Toast.LENGTH_LONG, GB.ERROR); } } @Override public void onSetConstantVibration(int intensity) { - LOG.debug("Vibration Trigger"); - getQueue().clear(); try { @@ -615,6 +594,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { @Override public void onEnableHeartRateSleepSupport(boolean enable) { + onEnableRealtimeHeartRateMeasurement(enable); } @@ -641,8 +621,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { private void showIncomingCall(String name, String number) { - LOG.debug("Show Incoming Call"); - try { TransactionBuilder builder = performInitialized("incomingCallIcon"); @@ -652,7 +630,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { //Show Call Icon builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_ACTION_INCOMING_CALL, HPlusConstants.ARG_INCOMING_CALL}); - //builder = performInitialized("incomingCallText"); builder.queue(getQueue()); //TODO: Use WaitAction @@ -714,18 +691,10 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } } - private void showText(String message) { - - showText(null, message); - } - private void showText(String title, String body) { - LOG.debug("Show Notification"); - try { TransactionBuilder builder = performInitialized("notification"); - byte[] msg = new byte[20]; for (int i = 0; i < msg.length; i++) msg[i] = ' '; @@ -790,11 +759,11 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { } } - public boolean isExpectedDevice(BluetoothDevice device) { - return true; - } - - public void close() { + private void close() { + if (syncHelper != null) { + syncHelper.quit(); + syncHelper = null; + } } @Override @@ -811,29 +780,24 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport { switch (data[0]) { case HPlusConstants.DATA_VERSION: - syncHelper.processVersion(data); - case HPlusConstants.DATA_STATS: { - syncHelper.processRealtimeStats(data); - return true; - } - case HPlusConstants.DATA_SLEEP: { - syncHelper.processIncomingSleepData(data); - return true; - } - case HPlusConstants.DATA_STEPS:{ - syncHelper.processStepStats(data); - return true; - } + return syncHelper.processVersion(data); + + case HPlusConstants.DATA_STATS: + return syncHelper.processRealtimeStats(data); + + case HPlusConstants.DATA_SLEEP: + return syncHelper.processIncomingSleepData(data); + + case HPlusConstants.DATA_STEPS: + return syncHelper.processStepStats(data); + case HPlusConstants.DATA_DAY_SUMMARY: case HPlusConstants.DATA_DAY_SUMMARY_ALT: - syncHelper.processIncomingDaySlotData(data); - return true; + return syncHelper.processIncomingDaySlotData(data); + default: - LOG.info("Unhandled characteristic changed: " + characteristicUUID); - + LOG.debug("Unhandled characteristic changed: " + characteristicUUID); + return true; } - return false; } - - }