mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-02-03 21:47:32 +01:00
Read alarms from device on connect and when changed on device
TODO: - support decryption for mi band 6 - reassamble chunks for low MTU
This commit is contained in:
parent
3b95e4ea66
commit
47f7f22df4
@ -164,6 +164,8 @@ public class HuamiService {
|
|||||||
public static final byte[] COMMAND_DISABLE_DISCONNECT_NOTIFCATION = new byte[]{ENDPOINT_DISPLAY, 0x0c, 0x00, 0x00, 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_ALARMS = new byte[]{0x0d};
|
||||||
|
public static final byte[] COMMAND_REQUEST_ALARMS_WITH_TIMES = new byte[]{(byte) 0xff,0x01,0x00,0x00,0x00};
|
||||||
|
|
||||||
public static final byte[] COMMAND_REQUEST_GPS_VERSION = new byte[]{0x0e};
|
public static final byte[] COMMAND_REQUEST_GPS_VERSION = new byte[]{0x0e};
|
||||||
|
|
||||||
// The third byte controls the threshold, in minutes
|
// The third byte controls the threshold, in minutes
|
||||||
|
@ -31,5 +31,6 @@ public class HuamiDeviceEvent {
|
|||||||
public static final byte TICK_30MIN = 0x0e; // unsure
|
public static final byte TICK_30MIN = 0x0e; // unsure
|
||||||
public static final byte FIND_PHONE_STOP = 0x0f;
|
public static final byte FIND_PHONE_STOP = 0x0f;
|
||||||
public static final byte MTU_REQUEST = 0x16;
|
public static final byte MTU_REQUEST = 0x16;
|
||||||
|
public static final byte ALARM_CHANGED = 0x1a;
|
||||||
public static final byte MUSIC_CONTROL = (byte) 0xfe;
|
public static final byte MUSIC_CONTROL = (byte) 0xfe;
|
||||||
}
|
}
|
||||||
|
@ -1473,7 +1473,8 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
processDeviceEvent(HuamiDeviceEvent.START_NONWEAR);
|
processDeviceEvent(HuamiDeviceEvent.START_NONWEAR);
|
||||||
break;
|
break;
|
||||||
case HuamiDeviceEvent.ALARM_TOGGLED:
|
case HuamiDeviceEvent.ALARM_TOGGLED:
|
||||||
LOG.info("An alarm was toggled");
|
case HuamiDeviceEvent.ALARM_CHANGED:
|
||||||
|
LOG.info("An alarm was toggled or changed");
|
||||||
TransactionBuilder builder = new TransactionBuilder("requestAlarms");
|
TransactionBuilder builder = new TransactionBuilder("requestAlarms");
|
||||||
requestAlarms(builder);
|
requestAlarms(builder);
|
||||||
builder.queue(getQueue());
|
builder.queue(getQueue());
|
||||||
@ -1810,40 +1811,75 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
gbDevice.setFirmwareVersion2(gpsVersion);
|
gbDevice.setFirmwareVersion2(gpsVersion);
|
||||||
} else if (value[1] == 0x0d) {
|
} else if (value[1] == 0x0d) {
|
||||||
LOG.info("got alarms from watch");
|
LOG.info("got alarms from watch");
|
||||||
decodeAndUpdateAlarmStatus(value);
|
decodeAndUpdateAlarmStatus(value, false);
|
||||||
} else {
|
} else {
|
||||||
LOG.warn("got configuration info we do not handle yet " + GB.hexdump(value, 3, -1));
|
LOG.warn("got configuration info we do not handle yet " + GB.hexdump(value, 3, -1));
|
||||||
}
|
}
|
||||||
|
} else if (value[0] == ((byte) 0x80) && value[1] == 0x01 && value[2] == (byte) 0xc0 && value[3] == 0x00 &&
|
||||||
|
value[4] == 0x01 && value[5] == 0x00 && value[6] == 0x00 && value[7] == 0x00 && value[8] == 0x01) {
|
||||||
|
LOG.info("got full alarm configuration."); // TODO: with low mtu they come in chunks
|
||||||
|
byte[] alarmData = new byte[value.length - 9];
|
||||||
|
System.arraycopy(value, 9, alarmData, 0, alarmData.length);
|
||||||
|
decodeAndUpdateAlarmStatus(alarmData, true);
|
||||||
} else {
|
} else {
|
||||||
LOG.warn("error received from configuration request " + GB.hexdump(value, 0, -1));
|
LOG.warn("unknown response got from configuration request " + GB.hexdump(value, 0, -1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void decodeAndUpdateAlarmStatus(byte[] response) {
|
private void decodeAndUpdateAlarmStatus(byte[] response, boolean withTimes) {
|
||||||
List<nodomain.freeyourgadget.gadgetbridge.entities.Alarm> alarms = DBHelper.getAlarms(gbDevice);
|
List<nodomain.freeyourgadget.gadgetbridge.entities.Alarm> alarms = DBHelper.getAlarms(gbDevice);
|
||||||
int maxAlarms = 10;
|
int maxAlarms = 10;
|
||||||
|
|
||||||
|
//FIXME: we can rather have a full struct here probably
|
||||||
boolean[] alarmsInUse = new boolean[maxAlarms];
|
boolean[] alarmsInUse = new boolean[maxAlarms];
|
||||||
boolean[] alarmsEnabled = new boolean[maxAlarms];
|
boolean[] alarmsEnabled = new boolean[maxAlarms];
|
||||||
int nr_alarms = response[8];
|
byte[] alarmsMinute = new byte[maxAlarms];
|
||||||
|
byte[] alarmsHour = new byte[maxAlarms];
|
||||||
|
byte[] alarmsRepeat = new byte[maxAlarms];
|
||||||
|
|
||||||
|
int nr_alarms;
|
||||||
|
byte enable_flag;
|
||||||
|
if (withTimes) {
|
||||||
|
nr_alarms = response.length / 4;
|
||||||
|
enable_flag = (byte) 0x80;
|
||||||
|
} else {
|
||||||
|
nr_alarms = response[8];
|
||||||
|
enable_flag = (byte) 0x10;
|
||||||
|
}
|
||||||
for (int i = 0; i < nr_alarms; i++) {
|
for (int i = 0; i < nr_alarms; i++) {
|
||||||
byte alarm_data = response[9 + i];
|
int offset;
|
||||||
|
if (withTimes) {
|
||||||
|
offset = i * 4;
|
||||||
|
alarmsHour[i] = response[offset + 1];
|
||||||
|
alarmsMinute[i] = response[offset + 2];
|
||||||
|
alarmsRepeat[i] = response[offset + 3];
|
||||||
|
} else {
|
||||||
|
offset = 9 + i;
|
||||||
|
}
|
||||||
|
byte alarm_data = response[offset];
|
||||||
int index = alarm_data & 0xf;
|
int index = alarm_data & 0xf;
|
||||||
if (index >= maxAlarms) {
|
if (index >= maxAlarms) {
|
||||||
GB.toast("Unexpected alarm index from device, ignoring: " + index, Toast.LENGTH_SHORT, GB.ERROR);
|
GB.toast("Unexpected alarm index from device, ignoring: " + index, Toast.LENGTH_SHORT, GB.ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
alarmsInUse[index] = true;
|
alarmsInUse[index] = true;
|
||||||
boolean enabled = (alarm_data & 0x10) == 0x10;
|
boolean enabled = (alarm_data & enable_flag) == enable_flag;
|
||||||
alarmsEnabled[index] = enabled;
|
alarmsEnabled[index] = enabled;
|
||||||
LOG.info("alarm " + index + " is enabled:" + enabled);
|
LOG.info("alarm " + index + " is enabled:" + enabled);
|
||||||
}
|
}
|
||||||
for (nodomain.freeyourgadget.gadgetbridge.entities.Alarm alarm : alarms) {
|
for (nodomain.freeyourgadget.gadgetbridge.entities.Alarm alarm : alarms) {
|
||||||
boolean enabled = alarmsEnabled[alarm.getPosition()];
|
int pos = alarm.getPosition();
|
||||||
boolean unused = !alarmsInUse[alarm.getPosition()];
|
boolean enabled = alarmsEnabled[pos];
|
||||||
|
boolean unused = !alarmsInUse[pos];
|
||||||
if (alarm.getEnabled() != enabled || alarm.getUnused() != unused) {
|
if (alarm.getEnabled() != enabled || alarm.getUnused() != unused) {
|
||||||
LOG.info("updating alarm index " + alarm.getPosition() + " unused=" + unused + ", enabled=" + enabled);
|
LOG.info("updating alarm index " + pos + " unused=" + unused + ", enabled=" + enabled);
|
||||||
alarm.setEnabled(enabled);
|
alarm.setEnabled(enabled);
|
||||||
alarm.setUnused(unused);
|
alarm.setUnused(unused);
|
||||||
|
if (withTimes) {
|
||||||
|
alarm.setHour(alarmsHour[pos]);
|
||||||
|
alarm.setMinute(alarmsMinute[pos]);
|
||||||
|
alarm.setRepetition(alarmsRepeat[pos]);
|
||||||
|
}
|
||||||
DBHelper.store(alarm);
|
DBHelper.store(alarm);
|
||||||
Intent intent = new Intent(DeviceService.ACTION_SAVE_ALARMS);
|
Intent intent = new Intent(DeviceService.ACTION_SAVE_ALARMS);
|
||||||
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
|
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(intent);
|
||||||
@ -3140,7 +3176,9 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
private HuamiSupport requestAlarms(TransactionBuilder builder) {
|
private HuamiSupport requestAlarms(TransactionBuilder builder) {
|
||||||
LOG.info("Requesting alarms");
|
LOG.info("Requesting alarms");
|
||||||
writeToConfiguration(builder, HuamiService.COMMAND_REQUEST_ALARMS);
|
//FIXME: on older devices only the first one works, and on newer only the last is sufficiant
|
||||||
|
writeToConfiguration(builder, HuamiService.COMMAND_REQUEST_ALARMS);
|
||||||
|
writeToConfiguration(builder, HuamiService.COMMAND_REQUEST_ALARMS_WITH_TIMES);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user