1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-09-26 16:26:52 +02:00

Huami: get alarms at connect and save changes to database, react to on-device changes immediatly when device is connected

This commit is contained in:
Andreas Shimokawa 2019-12-27 22:19:17 +01:00
parent f958f3a54d
commit 3bf72f957a
4 changed files with 69 additions and 48 deletions

View File

@ -59,6 +59,7 @@ public class HuamiService {
public static final int ALERT_LEVEL_PHONE_CALL = 2;
public static final int ALERT_LEVEL_VIBRATE_ONLY = 3;
// set metric distance
// set 12 hour time mode
@ -158,6 +159,9 @@ public class HuamiService {
public static final byte[] COMMAND_ENABLE_DISCONNECT_NOTIFCATION = new byte[]{ENDPOINT_DISPLAY, 0x0c, 0x00, 0x01, 0, 0, 0, 0};
public static final byte[] COMMAND_DISABLE_DISCONNECT_NOTIFCATION = new byte[]{ENDPOINT_DISPLAY, 0x0c, 0x00, 0x00, 0, 0, 0, 0};
public static final byte[] COMMAND_REQUEST_ALARMS = new byte[]{0x0d};
public static final byte[] COMMAND_REQUEST_GPS_VERSION = new byte[]{0x0e};
// The third byte controls the threshold, in minutes
// The last 8 bytes represent 2 separate time intervals for the inactivity warnings
// If there is no do not disturb interval, the last 4 bytes (the second interval) are 0

View File

@ -26,9 +26,6 @@ import static nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService.EN
public class AmazfitBipService {
public static final UUID UUID_CHARACTERISTIC_WEATHER = UUID.fromString("0000000e-0000-3512-2118-0009af100700");
// goes to UUID_CHARACTERISTIC_3_CONFIGURATION, TODO: validate this for Mi Band 2, it maybe triggers more than only GPS version...
public static final byte[] COMMAND_REQUEST_GPS_VERSION = new byte[]{0x0e};
public static final byte COMMAND_ACTIVITY_DATA_TYPE_DEBUGLOGS = 0x07;
public static final byte[] COMMAND_SET_LANGUAGE_SIMPLIFIED_CHINESE = new byte[]{ENDPOINT_DISPLAY, 0x13, 0x00, 0x00};

View File

@ -1152,6 +1152,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
break;
case HuamiDeviceEvent.ALARM_TOGGLED:
LOG.info("An alarm was toggled");
TransactionBuilder builder = new TransactionBuilder("requestAlarms");
requestAlarms(builder);
builder.queue(getQueue());
break;
case HuamiDeviceEvent.FELL_ASLEEP:
LOG.info("Fell asleep");
@ -1325,6 +1328,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
} else if (HuamiService.UUID_CHARACTERISTIC_7_REALTIME_STEPS.equals(characteristicUUID)) {
handleRealtimeSteps(characteristic.getValue());
return true;
} else if (HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION.equals(characteristicUUID)) {
handleConfigurationInfo(characteristic.getValue());
return true;
} else {
LOG.info("Unhandled characteristic changed: " + characteristicUUID);
logMessageContent(characteristic.getValue());
@ -1419,6 +1425,51 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
}
}
private void handleConfigurationInfo(byte[] value) {
if (value == null || value.length < 4) {
return;
}
if (value[0] == 0x10 && value[2] == 0x01) {
if (value[1] == 0x0e) {
String gpsVersion = new String(value, 3, value.length - 3);
LOG.info("got gps version = " + gpsVersion);
gbDevice.setFirmwareVersion2(gpsVersion);
} else if (value[1] == 0x0d) {
LOG.info("got alarms from watch");
decodeAndUpdateAlarmStatus(value);
} else {
LOG.warn("got configuration info we do not handle yet " + GB.hexdump(value, 3, -1));
}
} else {
LOG.warn("error received from configuration request " + GB.hexdump(value, 0, -1));
}
}
private void decodeAndUpdateAlarmStatus(byte[] response) {
List<nodomain.freeyourgadget.gadgetbridge.entities.Alarm> alarms = DBHelper.getAlarms(gbDevice);
boolean[] alarmsInUse = new boolean[10];
boolean[] alarmsEnabled = new boolean[10];
int nr_alarms = response[8];
for (int i = 0; i < nr_alarms; i++) {
byte alarm_data = response[9 + i];
int index = alarm_data & 0xf;
alarmsInUse[index] = true;
boolean enabled = (alarm_data & 0x10) == 0x10;
alarmsEnabled[index] = enabled;
LOG.info("alarm " + index + " is enabled:" + enabled);
}
for (nodomain.freeyourgadget.gadgetbridge.entities.Alarm alarm : alarms) {
boolean enabled = alarmsEnabled[alarm.getPosition()];
boolean unused = !alarmsInUse[alarm.getPosition()];
if (alarm.getEnabled() != enabled || alarm.getUnused() != unused) {
LOG.info("updating alarm index " + alarm.getPosition() + " unused=" + unused + ", enabled=" + enabled);
alarm.setEnabled(enabled);
alarm.setUnused(unused);
DBHelper.store(alarm);
}
}
}
private void enableRealtimeSamplesTimer(boolean enable) {
if (enable) {
getRealtimeSamplesSupport().start();
@ -2227,6 +2278,19 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
}
}
protected HuamiSupport requestGPSVersion(TransactionBuilder builder) {
LOG.info("Requesting GPS version");
builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_REQUEST_GPS_VERSION);
return this;
}
private HuamiSupport requestAlarms(TransactionBuilder builder) {
LOG.info("Requesting alarms");
builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), HuamiService.COMMAND_REQUEST_ALARMS);
return this;
}
@Override
public String customStringFilter(String inputString) {
if (HuamiCoordinator.getUseCustomFont(gbDevice.getAddress())) {
@ -2287,6 +2351,7 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
setDisconnectNotification(builder);
setExposeHRThridParty(builder);
setHeartrateMeasurementInterval(builder, getHeartRateMeasurementInterval());
requestAlarms(builder);
}
private int getHeartRateMeasurementInterval() {

View File

@ -17,11 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami.amazfitbip;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import org.slf4j.Logger;
@ -29,7 +25,6 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Set;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiFWHelper;
@ -37,21 +32,14 @@ import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiService;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipFWHelper;
import nodomain.freeyourgadget.gadgetbridge.devices.huami.amazfitbip.AmazfitBipService;
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
import nodomain.freeyourgadget.gadgetbridge.model.DeviceType;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
import nodomain.freeyourgadget.gadgetbridge.model.RecordedDataTypes;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertCategory;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.AlertNotificationProfile;
import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.alertnotification.NewAlert;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiIcon;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.HuamiSupport;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchActivityOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.FetchSportsSummaryOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.huami.operations.HuamiFetchDebugLogsOperation;
import nodomain.freeyourgadget.gadgetbridge.service.devices.miband.NotificationStrategy;
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
public class AmazfitBipSupport extends HuamiSupport {
@ -162,39 +150,6 @@ public class AmazfitBipSupport extends HuamiSupport {
}
}
@Override
public boolean onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
boolean handled = super.onCharacteristicChanged(gatt, characteristic);
if (!handled) {
UUID characteristicUUID = characteristic.getUuid();
if (HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION.equals(characteristicUUID)) {
return handleConfigurationInfo(characteristic.getValue());
}
}
return false;
}
private boolean handleConfigurationInfo(byte[] value) {
if (value == null || value.length < 4) {
return false;
}
if (value[0] == 0x10 && value[1] == 0x0e && value[2] == 0x01) {
String gpsVersion = new String(value, 3, value.length - 3);
LOG.info("got gps version = " + gpsVersion);
gbDevice.setFirmwareVersion2(gpsVersion);
return true;
}
return false;
}
// this probably does more than only getting the GPS version...
private AmazfitBipSupport requestGPSVersion(TransactionBuilder builder) {
LOG.info("Requesting GPS version");
builder.write(getCharacteristic(HuamiService.UUID_CHARACTERISTIC_3_CONFIGURATION), AmazfitBipService.COMMAND_REQUEST_GPS_VERSION);
return this;
}
@Override
public void phase2Initialize(TransactionBuilder builder) {
super.phase2Initialize(builder);