1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-06-20 12:00:51 +02:00

Mi Band 8: Fix system service

This commit is contained in:
José Rebelo 2023-10-03 23:18:03 +01:00
parent 7af155281c
commit 290383627e
3 changed files with 111 additions and 105 deletions

View File

@ -40,16 +40,10 @@ public class XiaomiConstants {
public static final UUID UUID_CHARACTERISTIC_XIAOMI_UNKNOWN_0003 = UUID.fromString((String.format(BASE_UUID, "0003")));
public static final int CMD_TYPE_AUTH = 1;
public static final int CMD_TYPE_SYSTEM = 2;
public static final int CMD_AUTH_NONCE = 26;
public static final int CMD_AUTH_AUTH = 27;
public static final int CMD_SYSTEM_BATTERY = 1;
public static final int CMD_SYSTEM_DEVICE_INFO = 2;
public static final int CMD_SYSTEM_CLOCK = 3;
public static final int CMD_SYSTEM_CHARGER = 79;
// TODO not like this
public static final byte[] PAYLOAD_ACK = new byte[]{0, 0, 3, 0};
public static final byte[] PAYLOAD_HEADER_AUTH = new byte[]{0, 0, 2, 2};

View File

@ -236,58 +236,14 @@ public class XiaomiSupport extends AbstractBTLEDeviceSupport {
LOG.error("Failed to initialize transaction builder", e);
return;
}
setCurrentTime(builder);
systemService.setCurrentTime(builder);
builder.queue(getQueue());
}
public void setCurrentTime(final TransactionBuilder builder) {
final Calendar now = GregorianCalendar.getInstance();
final TimeZone tz = TimeZone.getDefault();
final GBPrefs gbPrefs = new GBPrefs(new Prefs(GBApplication.getDeviceSpecificSharedPrefs(gbDevice.getAddress())));
final String timeFormat = gbPrefs.getTimeFormat();
final boolean is24hour = DeviceSettingsPreferenceConst.PREF_TIMEFORMAT_24H.equals(timeFormat);
final XiaomiProto.Clock clock = XiaomiProto.Clock.newBuilder()
.setTime(XiaomiProto.Time.newBuilder()
.setHour(now.get(Calendar.HOUR_OF_DAY))
.setMinute(now.get(Calendar.MINUTE))
.setSecond(now.get(Calendar.SECOND))
.setMillisecond(now.get(Calendar.MILLISECOND))
.build())
.setDate(XiaomiProto.Date.newBuilder()
.setYear(now.get(Calendar.YEAR))
.setMonth(now.get(Calendar.MONTH) + 1)
.setDay(now.get(Calendar.DATE))
.build())
.setTimezone(XiaomiProto.TimeZone.newBuilder()
.setZoneOffset(((now.get(Calendar.ZONE_OFFSET) / 1000) / 60) / 15)
.setDstOffset(((now.get(Calendar.DST_OFFSET) / 1000) / 60) / 15)
.setName(tz.getID())
.build())
.setIsNot24Hour(!is24hour)
.build();
sendCommand(
builder,
XiaomiProto.Command.newBuilder()
.setType(CMD_TYPE_SYSTEM)
.setSubtype(CMD_SYSTEM_CLOCK)
.setSystem(XiaomiProto.System.newBuilder().setClock(clock).build())
.build()
);
}
@Override
public void onTestNewFunction() {
final TransactionBuilder builder = createTransactionBuilder("test new function");
sendCommand(
builder,
XiaomiProto.Command.newBuilder()
.setType(CMD_TYPE_SYSTEM)
.setSubtype(CMD_SYSTEM_DEVICE_INFO)
.build()
);
builder.queue(getQueue());
}
@ -466,18 +422,12 @@ public class XiaomiSupport extends AbstractBTLEDeviceSupport {
encryptedIndex = 1; // TODO not here
if (GBApplication.getPrefs().getBoolean("datetime_synconconnect", true)) {
setCurrentTime(builder);
systemService.setCurrentTime(builder);
}
for (final AbstractXiaomiService service : mServiceMap.values()) {
service.initialize(builder);
}
// request device info
sendCommand(builder, CMD_TYPE_SYSTEM, CMD_SYSTEM_DEVICE_INFO);
// request battery status
sendCommand(builder, CMD_TYPE_SYSTEM, CMD_SYSTEM_BATTERY);
}
private void sendAck(final BluetoothGattCharacteristic characteristic) {
@ -486,52 +436,6 @@ public class XiaomiSupport extends AbstractBTLEDeviceSupport {
builder.queue(getQueue());
}
protected void handleConfigCommand(final XiaomiProto.Command cmd) {
switch (cmd.getSubtype()) {
case CMD_SYSTEM_DEVICE_INFO:
final XiaomiProto.DeviceInfo deviceInfo = cmd.getSystem().getDeviceInfo();
final GBDeviceEventVersionInfo gbDeviceEventVersionInfo = new GBDeviceEventVersionInfo();
gbDeviceEventVersionInfo.fwVersion = deviceInfo.getFirmware();
//gbDeviceEventVersionInfo.fwVersion2 = "N/A";
gbDeviceEventVersionInfo.hwVersion = deviceInfo.getModel();
final GBDeviceEventUpdateDeviceInfo gbDeviceEventUpdateDeviceInfo = new GBDeviceEventUpdateDeviceInfo("SERIAL: ", deviceInfo.getSerialNumber());
evaluateGBDeviceEvent(gbDeviceEventVersionInfo);
evaluateGBDeviceEvent(gbDeviceEventUpdateDeviceInfo);
return;
case CMD_SYSTEM_BATTERY:
final XiaomiProto.Battery battery = cmd.getSystem().getPower().getBattery();
final GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
batteryInfo.batteryIndex = 0;
batteryInfo.level = battery.getLevel();
switch (battery.getState()) {
case 1:
batteryInfo.state = BatteryState.BATTERY_CHARGING;
break;
case 2:
batteryInfo.state = BatteryState.BATTERY_NORMAL;
break;
default:
batteryInfo.state = BatteryState.UNKNOWN;
LOG.warn("Unknown battery state {}", battery.getState());
}
evaluateGBDeviceEvent(batteryInfo);
return;
case CMD_SYSTEM_CHARGER:
// charger event, request battery state
sendCommand(
"request battery state",
XiaomiProto.Command.newBuilder()
.setType(CMD_TYPE_SYSTEM)
.setSubtype(CMD_SYSTEM_BATTERY)
.build()
);
return;
default:
LOG.warn("Unknown config command {}", cmd.getSubtype());
}
}
private short encryptedIndex = 0;
public void sendCommand(final String taskName, final XiaomiProto.Command command) {

View File

@ -19,20 +19,128 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdateDeviceInfo;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto;
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiSupport;
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
public class XiaomiSystemService extends AbstractXiaomiService {
private static final Logger LOG = LoggerFactory.getLogger(XiaomiSystemService.class);
public static final int COMMAND_TYPE = 2;
public static final int CMD_BATTERY = 1;
public static final int CMD_DEVICE_INFO = 2;
public static final int CMD_CLOCK = 3;
public static final int CMD_CHARGER = 79;
public XiaomiSystemService(final XiaomiSupport support) {
super(support);
}
@Override
public void initialize(final TransactionBuilder builder) {
// request device info
getSupport().sendCommand(builder, COMMAND_TYPE, CMD_DEVICE_INFO);
// request battery status
getSupport().sendCommand(builder, COMMAND_TYPE, CMD_BATTERY);
}
@Override
public void handleCommand(final XiaomiProto.Command cmd) {
// TODO
switch (cmd.getSubtype()) {
case CMD_DEVICE_INFO:
final XiaomiProto.DeviceInfo deviceInfo = cmd.getSystem().getDeviceInfo();
final GBDeviceEventVersionInfo gbDeviceEventVersionInfo = new GBDeviceEventVersionInfo();
gbDeviceEventVersionInfo.fwVersion = deviceInfo.getFirmware();
//gbDeviceEventVersionInfo.fwVersion2 = "N/A";
gbDeviceEventVersionInfo.hwVersion = deviceInfo.getModel();
final GBDeviceEventUpdateDeviceInfo gbDeviceEventUpdateDeviceInfo = new GBDeviceEventUpdateDeviceInfo("SERIAL: ", deviceInfo.getSerialNumber());
getSupport().evaluateGBDeviceEvent(gbDeviceEventVersionInfo);
getSupport().evaluateGBDeviceEvent(gbDeviceEventUpdateDeviceInfo);
return;
case CMD_BATTERY:
final XiaomiProto.Battery battery = cmd.getSystem().getPower().getBattery();
final GBDeviceEventBatteryInfo batteryInfo = new GBDeviceEventBatteryInfo();
batteryInfo.batteryIndex = 0;
batteryInfo.level = battery.getLevel();
switch (battery.getState()) {
case 1:
batteryInfo.state = BatteryState.BATTERY_CHARGING;
break;
case 2:
batteryInfo.state = BatteryState.BATTERY_NORMAL;
break;
default:
batteryInfo.state = BatteryState.UNKNOWN;
LOG.warn("Unknown battery state {}", battery.getState());
}
getSupport().evaluateGBDeviceEvent(batteryInfo);
return;
case CMD_CHARGER:
// charger event, request battery state
getSupport().sendCommand(
"request battery state",
XiaomiProto.Command.newBuilder()
.setType(COMMAND_TYPE)
.setSubtype(CMD_BATTERY)
.build()
);
return;
default:
LOG.warn("Unknown config command {}", cmd.getSubtype());
}
}
public void setCurrentTime(final TransactionBuilder builder) {
final Calendar now = GregorianCalendar.getInstance();
final TimeZone tz = TimeZone.getDefault();
final GBPrefs gbPrefs = new GBPrefs(new Prefs(GBApplication.getDeviceSpecificSharedPrefs(getSupport().getDevice().getAddress())));
final String timeFormat = gbPrefs.getTimeFormat();
final boolean is24hour = DeviceSettingsPreferenceConst.PREF_TIMEFORMAT_24H.equals(timeFormat);
final XiaomiProto.Clock clock = XiaomiProto.Clock.newBuilder()
.setTime(XiaomiProto.Time.newBuilder()
.setHour(now.get(Calendar.HOUR_OF_DAY))
.setMinute(now.get(Calendar.MINUTE))
.setSecond(now.get(Calendar.SECOND))
.setMillisecond(now.get(Calendar.MILLISECOND))
.build())
.setDate(XiaomiProto.Date.newBuilder()
.setYear(now.get(Calendar.YEAR))
.setMonth(now.get(Calendar.MONTH) + 1)
.setDay(now.get(Calendar.DATE))
.build())
.setTimezone(XiaomiProto.TimeZone.newBuilder()
.setZoneOffset(((now.get(Calendar.ZONE_OFFSET) / 1000) / 60) / 15)
.setDstOffset(((now.get(Calendar.DST_OFFSET) / 1000) / 60) / 15)
.setName(tz.getID())
.build())
.setIsNot24Hour(!is24hour)
.build();
getSupport().sendCommand(
builder,
XiaomiProto.Command.newBuilder()
.setType(COMMAND_TYPE)
.setSubtype(CMD_CLOCK)
.setSystem(XiaomiProto.System.newBuilder().setClock(clock).build())
.build()
);
}
}