mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-07-21 22:31:16 +02:00
Mi Band 8: Toggle realtime stats (wip)
This commit is contained in:
parent
f23347c47d
commit
4ede29d1f1
|
@ -29,7 +29,7 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
|
||||||
// TODO s/HuamiExtendedActivitySample/XiaomiActivitySample/g
|
// TODO s/HuamiExtendedActivitySample/XiaomiActivitySample/g
|
||||||
public class XiaomiSampleProvider extends AbstractSampleProvider<HuamiExtendedActivitySample> {
|
public class XiaomiSampleProvider extends AbstractSampleProvider<HuamiExtendedActivitySample> {
|
||||||
protected XiaomiSampleProvider(final GBDevice device, final DaoSession session) {
|
public XiaomiSampleProvider(final GBDevice device, final DaoSession session) {
|
||||||
super(device, session);
|
super(device, session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,21 +35,13 @@ import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
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.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CallSpec;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CannedMessagesSpec;
|
||||||
|
@ -73,8 +65,6 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services.Xiao
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services.XiaomiSystemService;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services.XiaomiSystemService;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services.XiaomiWeatherService;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services.XiaomiWeatherService;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
|
||||||
|
|
||||||
public class XiaomiSupport extends AbstractBTLEDeviceSupport {
|
public class XiaomiSupport extends AbstractBTLEDeviceSupport {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(XiaomiSupport.class);
|
private static final Logger LOG = LoggerFactory.getLogger(XiaomiSupport.class);
|
||||||
|
@ -376,12 +366,12 @@ public class XiaomiSupport extends AbstractBTLEDeviceSupport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnableRealtimeHeartRateMeasurement(final boolean enable) {
|
public void onEnableRealtimeHeartRateMeasurement(final boolean enable) {
|
||||||
healthService.onEnableRealtimeHeartRateMeasurement(enable);
|
healthService.enableRealtimeStats(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnableRealtimeSteps(final boolean enable) {
|
public void onEnableRealtimeSteps(final boolean enable) {
|
||||||
healthService.onEnableRealtimeSteps(enable);
|
healthService.enableRealtimeStats(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,6 +16,10 @@
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -23,7 +27,19 @@ import java.util.Calendar;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.XiaomiSampleProvider;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.Device;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.HuamiExtendedActivitySample;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.DeviceService;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto;
|
import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiSupport;
|
||||||
|
@ -34,16 +50,29 @@ public class XiaomiHealthService extends AbstractXiaomiService {
|
||||||
public static final int COMMAND_TYPE = 8;
|
public static final int COMMAND_TYPE = 8;
|
||||||
|
|
||||||
private static final int CMD_SET_USER_INFO = 0;
|
private static final int CMD_SET_USER_INFO = 0;
|
||||||
|
private static final int CMD_REALTIME_STATS_START = 45;
|
||||||
|
private static final int CMD_REALTIME_STATS_STOP = 46;
|
||||||
|
private static final int CMD_REALTIME_STATS_EVENT = 47;
|
||||||
|
|
||||||
private static final int GENDER_MALE = 1;
|
private static final int GENDER_MALE = 1;
|
||||||
private static final int GENDER_FEMALE = 2;
|
private static final int GENDER_FEMALE = 2;
|
||||||
|
|
||||||
|
private boolean realtimeStarted = false;
|
||||||
|
private boolean realtimeOneShot = false;
|
||||||
|
private int previousSteps = -1;
|
||||||
|
|
||||||
public XiaomiHealthService(final XiaomiSupport support) {
|
public XiaomiHealthService(final XiaomiSupport support) {
|
||||||
super(support);
|
super(support);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleCommand(final XiaomiProto.Command cmd) {
|
public void handleCommand(final XiaomiProto.Command cmd) {
|
||||||
|
switch (cmd.getSubtype()) {
|
||||||
|
case CMD_REALTIME_STATS_EVENT:
|
||||||
|
handleRealtimeStats(cmd.getHealth().getRealTimeStats());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
LOG.warn("Unhandled health command");
|
LOG.warn("Unhandled health command");
|
||||||
}
|
}
|
||||||
|
@ -97,14 +126,75 @@ public class XiaomiHealthService extends AbstractXiaomiService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onHeartRateTest() {
|
public void onHeartRateTest() {
|
||||||
// TODO
|
realtimeStarted = true;
|
||||||
|
realtimeOneShot = true;
|
||||||
|
|
||||||
|
getSupport().sendCommand(
|
||||||
|
"heart rate test",
|
||||||
|
XiaomiProto.Command.newBuilder()
|
||||||
|
.setType(COMMAND_TYPE)
|
||||||
|
.setSubtype(CMD_REALTIME_STATS_START)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onEnableRealtimeHeartRateMeasurement(final boolean enable) {
|
public void enableRealtimeStats(final boolean enable) {
|
||||||
// TODO
|
if (realtimeStarted == enable) {
|
||||||
|
// same state, ignore
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
realtimeStarted = enable;
|
||||||
|
realtimeOneShot = false;
|
||||||
|
previousSteps = -1;
|
||||||
|
|
||||||
|
getSupport().sendCommand(
|
||||||
|
"realtime data",
|
||||||
|
XiaomiProto.Command.newBuilder()
|
||||||
|
.setType(COMMAND_TYPE)
|
||||||
|
.setSubtype(enable ? CMD_REALTIME_STATS_START : CMD_REALTIME_STATS_STOP)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onEnableRealtimeSteps(final boolean enable) {
|
private void handleRealtimeStats(final XiaomiProto.RealTimeStats realTimeStats) {
|
||||||
// TODO
|
if (realtimeOneShot) {
|
||||||
|
enableRealtimeStats(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (previousSteps == -1) {
|
||||||
|
previousSteps = realTimeStats.getSteps();
|
||||||
|
}
|
||||||
|
|
||||||
|
final HuamiExtendedActivitySample sample;
|
||||||
|
try (final DBHandler dbHandler = GBApplication.acquireDB()) {
|
||||||
|
final DaoSession session = dbHandler.getDaoSession();
|
||||||
|
|
||||||
|
final GBDevice gbDevice = getSupport().getDevice();
|
||||||
|
final Device device = DBHelper.getDevice(gbDevice, session);
|
||||||
|
final User user = DBHelper.getUser(session);
|
||||||
|
final int ts = (int) (System.currentTimeMillis() / 1000);
|
||||||
|
final XiaomiSampleProvider provider = new XiaomiSampleProvider(gbDevice, session);
|
||||||
|
sample = provider.createActivitySample();
|
||||||
|
|
||||||
|
sample.setDeviceId(device.getId());
|
||||||
|
sample.setUserId(user.getId());
|
||||||
|
sample.setTimestamp(ts);
|
||||||
|
sample.setHeartRate(realTimeStats.getHeartRate());
|
||||||
|
sample.setSteps(realTimeStats.getSteps() - previousSteps);
|
||||||
|
sample.setRawKind(ActivityKind.TYPE_UNKNOWN);
|
||||||
|
sample.setHeartRate(realTimeStats.getHeartRate());
|
||||||
|
sample.setRawIntensity(ActivitySample.NOT_MEASURED);
|
||||||
|
sample.setRawKind(ActivityKind.TYPE_UNKNOWN);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
LOG.error("Error creating activity sample", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
previousSteps = realTimeStats.getSteps();
|
||||||
|
|
||||||
|
final Intent intent = new Intent(DeviceService.ACTION_REALTIME_SAMPLES)
|
||||||
|
.putExtra(DeviceService.EXTRA_REALTIME_SAMPLE, sample);
|
||||||
|
LocalBroadcastManager.getInstance(getSupport().getContext()).sendBroadcast(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user