HPlus: Improve connection process (#651)

* Clean HPlus services and characteristics
* Improve connectivity
master
João Paulo Barraca 2017-04-18 10:47:28 +01:00 committed by GitHub
parent b142add631
commit 9f0d260e7a
7 changed files with 240 additions and 73 deletions

View File

@ -80,6 +80,11 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator {
return DeviceType.UNKNOWN;
}
@Override
public int getBondingStyle(GBDevice deviceCandidate){
return BONDING_STYLE_NONE;
}
@Override
public DeviceType getDeviceType() {
return DeviceType.HPLUS;

View File

@ -0,0 +1,73 @@
/* Copyright (C) 2015-2017 João Paulo Barraca
This file is part of Gadgetbridge.
Gadgetbridge is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Gadgetbridge is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.externalevents;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate;
import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService;
import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper;
/**
* Created by jpbarraca on 13/04/2017.
*/
public class BluetoothPairingRequestReceiver extends BroadcastReceiver {
private static final Logger LOG = LoggerFactory.getLogger(BluetoothConnectReceiver.class);
final DeviceCommunicationService service;
public BluetoothPairingRequestReceiver(DeviceCommunicationService service) {
this.service = service;
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (!action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
return;
}
GBDevice gbDevice = service.getGBDevice();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (gbDevice == null || device == null)
return;
DeviceCoordinator coordinator = DeviceHelper.getInstance().getCoordinator(gbDevice);
try {
if (coordinator.getBondingStyle(gbDevice) == DeviceCoordinator.BONDING_STYLE_NONE) {
LOG.info("Aborting unwanted pairing request");
abortBroadcast();
}
} catch (Exception e) {
LOG.warn("Could not abort pairing request process");
}
}
}

View File

@ -44,6 +44,7 @@ import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmClockReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.AlarmReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothConnectReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.BluetoothPairingRequestReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.MusicPlaybackReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.PebbleReceiver;
import nodomain.freeyourgadget.gadgetbridge.externalevents.PhoneCallReceiver;
@ -164,6 +165,7 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
private MusicPlaybackReceiver mMusicPlaybackReceiver = null;
private TimeChangeReceiver mTimeChangeReceiver = null;
private BluetoothConnectReceiver mBlueToothConnectReceiver = null;
private BluetoothPairingRequestReceiver mBlueToothPairingRequestReceiver = null;
private AlarmClockReceiver mAlarmClockReceiver = null;
private AlarmReceiver mAlarmReceiver = null;
@ -609,6 +611,11 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
mBlueToothConnectReceiver = new BluetoothConnectReceiver(this);
registerReceiver(mBlueToothConnectReceiver, new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED));
}
if (mBlueToothPairingRequestReceiver == null) {
mBlueToothPairingRequestReceiver = new BluetoothPairingRequestReceiver(this);
registerReceiver(mBlueToothPairingRequestReceiver, new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST));
}
if (mAlarmReceiver == null) {
mAlarmReceiver = new AlarmReceiver();
registerReceiver(mAlarmReceiver, new IntentFilter("DAILY_ALARM"));
@ -645,6 +652,12 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
unregisterReceiver(mBlueToothConnectReceiver);
mBlueToothConnectReceiver = null;
}
if (mBlueToothPairingRequestReceiver != null) {
unregisterReceiver(mBlueToothPairingRequestReceiver);
mBlueToothPairingRequestReceiver = null;
}
if (mAlarmReceiver != null) {
unregisterReceiver(mAlarmReceiver);
mAlarmReceiver = null;

View File

@ -101,6 +101,7 @@ public class BleNamesResolver {
mServices.put("00001804-0000-1000-8000-00805f9b34fb", "Tx Power");
mServices.put("0000fee0-0000-3512-2118-0009af100700", "(Propr: Xiaomi MiLi Service)");
mServices.put("00001530-0000-3512-2118-0009af100700", "(Propr: Xiaomi Weight Service)");
mServices.put("14701820-620a-3973-7c78-9cfff0876abd", "(Propr: HPLUS Service)");
mCharacteristics.put("00002a43-0000-1000-8000-00805f9b34fb", "Alert AlertCategory ID");
@ -185,6 +186,8 @@ public class BleNamesResolver {
mCharacteristics.put("00002a07-0000-1000-8000-00805f9b34fb", "Tx Power Level");
mCharacteristics.put("00002a45-0000-1000-8000-00805f9b34fb", "Unread Alert Status");
mCharacteristics.put("14702856-620a-3973-7c78-9cfff0876abd", "(Propr: HPLUS Control)");
mCharacteristics.put("14702853-620a-3973-7c78-9cfff0876abd", "(Propr: HPLUS Measurements)");
mValueFormats.put(Integer.valueOf(52), "32bit float");
mValueFormats.put(Integer.valueOf(50), "16bit float");
mValueFormats.put(Integer.valueOf(34), "16bit signed int");

View File

@ -102,4 +102,8 @@ public class HPlusDataRecordDaySlot extends HPlusDataRecord {
secondsInactive += other.secondsInactive;
}
public boolean isValid(){
return steps != 0 || secondsInactive != 0 || heartRate != -1;
}
}

View File

@ -65,6 +65,8 @@ class HPlusHandlerThread extends GBDeviceIoThread {
private int DAY_SUMMARY_SYNC_PERIOD = 24 * 60 * 60;
private int DAY_SUMMARY_SYNC_RETRY_PERIOD = 30;
private int HELLO_PERIOD = 60;
private boolean mQuit = false;
private HPlusSupport mHPlusSupport;
@ -76,6 +78,8 @@ class HPlusHandlerThread extends GBDeviceIoThread {
private Calendar mGetSleepTime = GregorianCalendar.getInstance();
private Calendar mGetDaySummaryTime = GregorianCalendar.getInstance();
private Calendar mHelloTime = GregorianCalendar.getInstance();
private boolean mSlotsInitialSync = true;
private HPlusDataRecordRealtime prevRealTimeRecord = null;
@ -88,7 +92,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
public HPlusHandlerThread(GBDevice gbDevice, Context context, HPlusSupport hplusSupport) {
super(gbDevice, context);
LOG.info("Initializing HPlus Handler Thread");
mQuit = false;
mHPlusSupport = hplusSupport;
@ -137,6 +141,10 @@ class HPlusHandlerThread extends GBDeviceIoThread {
requestDaySummaryData();
}
if(now.compareTo(mHelloTime) > 0){
sendHello();
}
now = GregorianCalendar.getInstance();
waitTime = Math.min(mGetDaySummaryTime.getTimeInMillis(), Math.min(mGetDaySlotsTime.getTimeInMillis(), mGetSleepTime.getTimeInMillis())) - now.getTimeInMillis();
}
@ -152,10 +160,14 @@ class HPlusHandlerThread extends GBDeviceIoThread {
}
public void sync() {
LOG.info("HPlus: Starting data synchronization");
mGetSleepTime.setTimeInMillis(0);
mGetDaySlotsTime.setTimeInMillis(0);
mGetDaySummaryTime.setTimeInMillis(0);
mLastSleepDayReceived.setTimeInMillis(0);
mHelloTime = GregorianCalendar.getInstance();
mHelloTime.add(Calendar.SECOND, HELLO_PERIOD);
mSlotsInitialSync = true;
mLastSlotReceived = -1;
@ -163,19 +175,41 @@ class HPlusHandlerThread extends GBDeviceIoThread {
mCurrentDaySlot = null;
mDaySlotRecords.clear();
TransactionBuilder builder = new TransactionBuilder("startSyncDayStats");
try {
if(!mHPlusSupport.isConnected())
mHPlusSupport.connect();
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DEVICE_ID});
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_VERSION});
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_CURR_DATA});
TransactionBuilder builder = new TransactionBuilder("startSyncDayStats");
builder.queue(mHPlusSupport.getQueue());
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DEVICE_ID});
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_VERSION});
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_CURR_DATA});
builder.queue(mHPlusSupport.getQueue());
}catch(Exception e){
}
synchronized (waitObject) {
waitObject.notify();
}
}
public void sendHello(){
try {
if(!mHPlusSupport.isConnected())
mHPlusSupport.connect();
TransactionBuilder builder = new TransactionBuilder("hello");
builder.write(mHPlusSupport.ctrlCharacteristic, HPlusConstants.CMD_ACTION_HELLO);
builder.queue(mHPlusSupport.getQueue());
}catch(Exception e){
}
mHelloTime = GregorianCalendar.getInstance();
mHelloTime.add(Calendar.SECOND, HELLO_PERIOD);
}
/**
* Process a message containing information regarding a day slot
* A slot summarizes 10 minutes of data
@ -190,7 +224,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
try{
record = new HPlusDataRecordDaySlot(data);
} catch(IllegalArgumentException e){
LOG.debug((e.getMessage()));
LOG.info((e.getMessage()));
return false;
}
@ -254,6 +288,11 @@ class HPlusHandlerThread extends GBDeviceIoThread {
List<HPlusHealthActivitySample> samples = new ArrayList<>();
for (HPlusDataRecordDaySlot storedRecord : mDaySlotRecords) {
//Invalid records (no data) will be ignored
if(!storedRecord.isValid())
continue;
HPlusHealthActivitySample sample = createSample(dbHandler, storedRecord.timestamp);
sample.setRawHPlusHealthData(storedRecord.getRawData());
@ -269,9 +308,9 @@ class HPlusHandlerThread extends GBDeviceIoThread {
mDaySlotRecords.clear();
} catch (GBException ex) {
LOG.debug((ex.getMessage()));
LOG.info((ex.getMessage()));
} catch (Exception ex) {
LOG.debug(ex.getMessage());
LOG.info(ex.getMessage());
}
}
@ -293,7 +332,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
try{
record = new HPlusDataRecordSleep(data);
} catch(IllegalArgumentException e){
LOG.debug((e.getMessage()));
LOG.info((e.getMessage()));
return false;
}
@ -326,7 +365,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
provider.addGBActivitySample(sample);
} catch (Exception ex) {
LOG.debug(ex.getMessage());
LOG.info(ex.getMessage());
}
mGetSleepTime = GregorianCalendar.getInstance();
@ -347,7 +386,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
try{
record = new HPlusDataRecordRealtime(data);
} catch(IllegalArgumentException e){
LOG.debug((e.getMessage()));
LOG.info((e.getMessage()));
return false;
}
@ -397,9 +436,9 @@ class HPlusHandlerThread extends GBDeviceIoThread {
//TODO: Handle Active Time. With Overlay?
} catch (GBException ex) {
LOG.debug((ex.getMessage()));
LOG.info((ex.getMessage()));
} catch (Exception ex) {
LOG.debug(ex.getMessage());
LOG.info(ex.getMessage());
}
return true;
}
@ -417,7 +456,7 @@ class HPlusHandlerThread extends GBDeviceIoThread {
try{
record = new HPlusDataRecordDaySummary(data);
} catch(IllegalArgumentException e){
LOG.debug((e.getMessage()));
LOG.info((e.getMessage()));
return false;
}
@ -437,9 +476,9 @@ class HPlusHandlerThread extends GBDeviceIoThread {
sample.setProvider(provider);
provider.addGBActivitySample(sample);
} catch (GBException ex) {
LOG.debug((ex.getMessage()));
LOG.info((ex.getMessage()));
} catch (Exception ex) {
LOG.debug(ex.getMessage());
LOG.info(ex.getMessage());
}
mGetDaySummaryTime = GregorianCalendar.getInstance();
@ -468,10 +507,16 @@ class HPlusHandlerThread extends GBDeviceIoThread {
* Issue a message requesting the next batch of sleep data
*/
private void requestNextSleepData() {
TransactionBuilder builder = new TransactionBuilder("requestSleepStats");
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_SLEEP});
builder.queue(mHPlusSupport.getQueue());
try {
if(!mHPlusSupport.isConnected())
mHPlusSupport.connect();
TransactionBuilder builder = new TransactionBuilder("requestSleepStats");
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_SLEEP});
builder.queue(mHPlusSupport.getQueue());
}catch(Exception e){
}
mGetSleepTime = GregorianCalendar.getInstance();
mGetSleepTime.add(GregorianCalendar.SECOND, SLEEP_SYNC_RETRY_PERIOD);
@ -519,19 +564,31 @@ class HPlusHandlerThread extends GBDeviceIoThread {
mLastSlotRequested = nextHour * 6 + (nextMinute / 10);
byte[] msg = new byte[]{HPlusConstants.CMD_GET_ACTIVE_DAY, hour, minute, nextHour, nextMinute};
try {
if(!mHPlusSupport.isConnected())
mHPlusSupport.connect();
TransactionBuilder builder = new TransactionBuilder("getNextDaySlot");
builder.write(mHPlusSupport.ctrlCharacteristic, msg);
builder.queue(mHPlusSupport.getQueue());
TransactionBuilder builder = new TransactionBuilder("getNextDaySlot");
builder.write(mHPlusSupport.ctrlCharacteristic, msg);
builder.queue(mHPlusSupport.getQueue());
}catch(Exception e){
}
}
/**
* Request a batch of data with the summary of the previous days
*/
public void requestDaySummaryData(){
TransactionBuilder builder = new TransactionBuilder("startSyncDaySummary");
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DAY_DATA});
builder.queue(mHPlusSupport.getQueue());
try {
if(!mHPlusSupport.isConnected())
mHPlusSupport.connect();
TransactionBuilder builder = new TransactionBuilder("startSyncDaySummary");
builder.write(mHPlusSupport.ctrlCharacteristic, new byte[]{HPlusConstants.CMD_GET_DAY_DATA});
builder.queue(mHPlusSupport.getQueue());
}catch(Exception e){
}
mGetDaySummaryTime = GregorianCalendar.getInstance();
mGetDaySummaryTime.add(Calendar.SECOND, DAY_SUMMARY_SYNC_RETRY_PERIOD);
}

View File

@ -94,8 +94,6 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
deviceType = type;
addSupportedService(GattService.UUID_SERVICE_GENERIC_ACCESS);
addSupportedService(GattService.UUID_SERVICE_GENERIC_ATTRIBUTE);
addSupportedService(HPlusConstants.UUID_SERVICE_HP);
LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getContext());
@ -106,7 +104,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
@Override
public void dispose() {
LOG.debug("Dispose");
LOG.info("Dispose");
LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getContext());
broadcastManager.unregisterReceiver(mReceiver);
@ -117,7 +115,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
@Override
protected TransactionBuilder initializeDevice(TransactionBuilder builder) {
LOG.debug("Initializing");
LOG.info("Initializing");
builder.add(new SetDeviceStateAction(getDevice(), GBDevice.State.INITIALIZING, getContext()));
@ -424,7 +422,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
@Override
public void onNotification(NotificationSpec notificationSpec) {
//TODO: Show different notifications according to source as Band supports this
//LOG.debug("OnNotification: Title: "+notificationSpec.title+" Body: "+notificationSpec.body+" Source: "+notificationSpec.sourceName+" Sender: "+notificationSpec.sender+" Subject: "+notificationSpec.subject);
//LOG.info("OnNotification: Title: "+notificationSpec.title+" Body: "+notificationSpec.body+" Source: "+notificationSpec.sourceName+" Sender: "+notificationSpec.sender+" Subject: "+notificationSpec.subject);
showText(notificationSpec.title, notificationSpec.body);
}
@ -435,40 +433,46 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
@Override
public void onSetTime() {
TransactionBuilder builder = new TransactionBuilder("time");
try {
TransactionBuilder builder = performInitialized("time");
setCurrentDate(builder);
setCurrentTime(builder);
setCurrentDate(builder);
setCurrentTime(builder);
builder.queue(getQueue());
builder.queue(getQueue());
}catch(IOException e){
}
}
@Override
public void onSetAlarms(ArrayList<? extends Alarm> alarms) {
try {
TransactionBuilder builder = performInitialized("alarm");
TransactionBuilder builder = new TransactionBuilder("alarm");
for (Alarm alarm : alarms) {
for (Alarm alarm : alarms) {
if (!alarm.isEnabled())
continue;
if (!alarm.isEnabled())
continue;
if (alarm.isSmartWakeup()) //Not available
continue;
if (alarm.isSmartWakeup()) //Not available
continue;
Calendar t = alarm.getAlarmCal();
setAlarm(builder, t);
builder.queue(getQueue());
Calendar t = alarm.getAlarmCal();
setAlarm(builder, t);
GB.toast(getContext(), getContext().getString(R.string.user_feedback_miband_set_alarms_ok), Toast.LENGTH_SHORT, GB.INFO);
return; //Only first alarm
}
setAlarm(builder, null);
builder.queue(getQueue());
GB.toast(getContext(), getContext().getString(R.string.user_feedback_miband_set_alarms_ok), Toast.LENGTH_SHORT, GB.INFO);
GB.toast(getContext(), getContext().getString(R.string.user_feedback_all_alarms_disabled), Toast.LENGTH_SHORT, GB.INFO);
}catch(Exception e){}
return; //Only first alarm
}
setAlarm(builder, null);
builder.queue(getQueue());
GB.toast(getContext(), getContext().getString(R.string.user_feedback_all_alarms_disabled), Toast.LENGTH_SHORT, GB.INFO);
}
@ -485,7 +489,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
@Override
public void onSetCannedMessages(CannedMessagesSpec cannedMessagesSpec) {
LOG.debug("Canned Messages: " + cannedMessagesSpec);
LOG.info("Canned Messages: " + cannedMessagesSpec);
}
@Override
@ -541,39 +545,47 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
@Override
public void onReboot() {
getQueue().clear();
try {
getQueue().clear();
TransactionBuilder builder = new TransactionBuilder("Shutdown");
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SHUTDOWN, HPlusConstants.ARG_SHUTDOWN_EN});
builder.queue(getQueue());
TransactionBuilder builder = performInitialized("Shutdown");
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SHUTDOWN, HPlusConstants.ARG_SHUTDOWN_EN});
builder.queue(getQueue());
}catch(Exception e){
}
}
@Override
public void onHeartRateTest() {
getQueue().clear();
try{
TransactionBuilder builder = performInitialized("HeartRateTest");
TransactionBuilder builder = new TransactionBuilder("HeartRateTest");
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_HEARTRATE_STATE, HPlusConstants.ARG_HEARTRATE_MEASURE_ON}); //Set Real Time... ?
builder.queue(getQueue());
}catch(Exception e){
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_HEARTRATE_STATE, HPlusConstants.ARG_HEARTRATE_MEASURE_ON}); //Set Real Time... ?
builder.queue(getQueue());
}
}
@Override
public void onEnableRealtimeHeartRateMeasurement(boolean enable) {
getQueue().clear();
try {
TransactionBuilder builder = performInitialized("realTimeHeartMeasurement");
byte state;
TransactionBuilder builder = new TransactionBuilder("realTimeHeartMeasurement");
byte state;
if (enable)
state = HPlusConstants.ARG_HEARTRATE_ALLDAY_ON;
else
state = HPlusConstants.ARG_HEARTRATE_ALLDAY_OFF;
if (enable)
state = HPlusConstants.ARG_HEARTRATE_ALLDAY_ON;
else
state = HPlusConstants.ARG_HEARTRATE_ALLDAY_OFF;
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_ALLDAY_HRM, state});
builder.queue(getQueue());
builder.write(ctrlCharacteristic, new byte[]{HPlusConstants.CMD_SET_ALLDAY_HRM, state});
builder.queue(getQueue());
}catch(Exception e){
}
}
@Override
@ -632,13 +644,13 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
@Override
public void onSendConfiguration(String config) {
LOG.debug("Send Configuration: " + config);
LOG.info("Send Configuration: " + config);
}
@Override
public void onTestNewFunction() {
LOG.debug("Test New Function");
LOG.info("Test New Function");
}
@Override
@ -706,7 +718,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
}
private void showText(String title, String body) {
LOG.debug("Show Notification: " + title + " --> " + body);
try {
TransactionBuilder builder = performInitialized("notification");
@ -844,7 +856,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
return syncHelper.processIncomingDaySlotData(data);
default:
LOG.debug("Unhandled characteristic changed: " + characteristicUUID);
LOG.info("Unhandled characteristic change: " + characteristicUUID + " code: " + data[0]);
return true;
}
}
@ -878,7 +890,7 @@ public class HPlusSupport extends AbstractBTLEDeviceSupport {
getDevice().addDeviceInfo(new GenericItem("", info));
}
} catch (IllegalArgumentException e) {
LOG.debug((e.getMessage()));
LOG.info((e.getMessage()));
}
}