Pebble: First try to receive at least steps from the Misfit pebble watchapp

here
Andreas Shimokawa 2015-10-21 23:11:16 +09:00
parent aa5749cd40
commit 44a36a5f1d
5 changed files with 151 additions and 6 deletions

View File

@ -1,10 +1,12 @@
package nodomain.freeyourgadget.gadgetbridge.devices;
public interface SampleProvider {
public static final byte PROVIDER_MIBAND = 0;
public static final byte PROVIDER_PEBBLE_MORPHEUZ = 1;
public static final byte PROVIDER_PEBBLE_GADGETBRIDGE = 2;
public static final byte PROVIDER_UNKNOWN = 100;
byte PROVIDER_MIBAND = 0;
byte PROVIDER_PEBBLE_MORPHEUZ = 1;
byte PROVIDER_PEBBLE_GADGETBRIDGE = 2;
byte PROVIDER_PEBBLE_MISFIT = 3;
byte PROVIDER_UNKNOWN = 100;
int normalizeType(byte rawType);

View File

@ -0,0 +1,30 @@
package nodomain.freeyourgadget.gadgetbridge.devices.pebble;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
public class MisfitSampleProvider implements SampleProvider {
protected float movementDivisor = 300f;
@Override
public int normalizeType(byte rawType) {
return (int) rawType;
}
@Override
public byte toRawActivityKind(int activityKind) {
return (byte) activityKind;
}
@Override
public float normalizeIntensity(short rawIntensity) {
return rawIntensity / movementDivisor;
}
@Override
public byte getID() {
return SampleProvider.PROVIDER_PEBBLE_MISFIT;
}
}

View File

@ -48,7 +48,8 @@ public class PebbleCoordinator implements DeviceCoordinator {
// FIXME: make this configurable somewhere else.
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(GBApplication.getContext());
if (sharedPrefs.getBoolean("pebble_force_untested", false)) {
return new PebbleGadgetBridgeSampleProvider();
//return new PebbleGadgetBridgeSampleProvider();
return new MisfitSampleProvider();
} else {
return new MorpheuzSampleProvider();
}

View File

@ -0,0 +1,112 @@
package nodomain.freeyourgadget.gadgetbridge.service.devices.pebble;
import android.util.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Date;
import java.util.SimpleTimeZone;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.GBException;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventSendBytes;
import nodomain.freeyourgadget.gadgetbridge.devices.SampleProvider;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class AppMessageHandlerMisfit extends AppMessageHandler {
public static final int KEY_SLEEPGOAL = 1;
public static final int KEY_STEP_ROGRESS = 2;
public static final int KEY_SLEEP_PROGRESS = 3;
public static final int KEY_VERSION = 4;
public static final int KEY_SYNC = 5;
public static final int KEY_INCOMING_DATA_BEGIN = 6;
public static final int KEY_INCOMING_DATA = 7;
public static final int KEY_INCOMING_DATA_END = 8;
public static final int KEY_SYNC_RESULT = 9;
private static final Logger LOG = LoggerFactory.getLogger(AppMessageHandlerMisfit.class);
public AppMessageHandlerMisfit(UUID uuid, PebbleProtocol pebbleProtocol) {
super(uuid, pebbleProtocol);
}
@Override
public GBDeviceEvent[] handleMessage(ArrayList<Pair<Integer, Object>> pairs) {
for (Pair<Integer, Object> pair : pairs) {
switch (pair.first) {
case KEY_INCOMING_DATA_BEGIN:
LOG.info("incoming data start");
break;
case KEY_INCOMING_DATA_END:
LOG.info("incoming data end");
break;
case KEY_INCOMING_DATA:
DBHandler db = null;
try {
db = GBApplication.acquireDB();
} catch (GBException e) {
LOG.error("Error acquiring database", e);
return null;
}
byte[] data = (byte[]) pair.second;
ByteBuffer buf = ByteBuffer.wrap(data);
buf.order(ByteOrder.LITTLE_ENDIAN);
int timestamp = buf.getInt();
int key = buf.getInt();
int samples = (data.length - 8) / 2;
if (samples <= 0) {
break;
}
if (!mPebbleProtocol.isFw3x) {
timestamp -= SimpleTimeZone.getDefault().getOffset(timestamp * 1000L) / 1000;
}
Date startDate = new Date((long) timestamp * 1000L);
Date endDate = new Date((long) (timestamp + samples * 60) * 1000L);
LOG.info("got data from " + startDate + " to " + endDate);
int steps = 0;
int totalSteps = 0;
for (int i = 0; i < samples; i++) {
short sample = buf.getShort();
if ((sample & 0x0001) == 1 && (sample & 0xff000) != 0) {
steps = (sample & 0x000e);
} else {
steps = (sample & 0x00fe);
}
totalSteps += steps;
LOG.info("got steps for sample " + i + " : " + steps + "(" + Integer.toHexString(sample & 0xffff) + ")");
byte activityKind = ActivityKind.TYPE_UNKNOWN;
if (steps > 0) {
activityKind = ActivityKind.TYPE_ACTIVITY;
}
db.addGBActivitySample(timestamp + i * 60, SampleProvider.PROVIDER_PEBBLE_MISFIT, (short) steps, (short) steps, activityKind);
}
LOG.info("total steps for above period: " + totalSteps);
if (db != null) {
db.release();
}
break;
default:
LOG.info("unhandled key: " + pair.first);
break;
}
}
// always ack
GBDeviceEventSendBytes sendBytesAck = new GBDeviceEventSendBytes();
sendBytesAck.encodedBytes = mPebbleProtocol.encodeApplicationMessageAck(mUUID, mPebbleProtocol.last_id);
return new GBDeviceEvent[]{sendBytesAck};
}
}

View File

@ -340,7 +340,7 @@ public class PebbleProtocol extends GBDeviceProtocol {
mAppMessageHandlers.put(UUID_GBPEBBLE, new AppMessageHandlerGBPebble(UUID_GBPEBBLE, PebbleProtocol.this));
mAppMessageHandlers.put(UUID_MORPHEUZ, new AppMessageHandlerMorpheuz(UUID_MORPHEUZ, PebbleProtocol.this));
mAppMessageHandlers.put(UUID_WHETHERNEAT, new AppMessageHandlerWeatherNeat(UUID_WHETHERNEAT, PebbleProtocol.this));
//mAppMessageHandlers.put(UUID_MISFIT,new AppMessageHandlerMisfit(UUID_MISFIT,PebbleProtocol.this));
mAppMessageHandlers.put(UUID_MISFIT, new AppMessageHandlerMisfit(UUID_MISFIT, PebbleProtocol.this));
}
private static byte[] encodeSimpleMessage(short endpoint, byte command) {