mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-26 02:25:50 +01:00
Huami: Set OpenTracks track category and icon
This commit is contained in:
parent
462aec6f71
commit
c36857f063
@ -19,6 +19,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public final class QHybridConstants {
|
public final class QHybridConstants {
|
||||||
public static final String HYBRIDHR_WATCHFACE_VERSION = "1.6";
|
public static final String HYBRIDHR_WATCHFACE_VERSION = "1.6";
|
||||||
public static final int HYBRID_HR_WATCHFACE_WIDGET_SIZE = 76;
|
public static final int HYBRID_HR_WATCHFACE_WIDGET_SIZE = 76;
|
||||||
@ -39,20 +41,12 @@ public final class QHybridConstants {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Map<Integer, String> WORKOUT_TYPES_TO_OPENTRACKS_CATEGORY = new HashMap<Integer, String>() {
|
public static Map<Integer, Integer> WORKOUT_TYPES_TO_ACTIVITY_KIND = new HashMap<Integer, Integer>() {
|
||||||
{
|
{
|
||||||
put(1, "running");
|
put(1, ActivityKind.TYPE_RUNNING);
|
||||||
put(2, "cycling");
|
put(2, ActivityKind.TYPE_CYCLING);
|
||||||
put(8, "walking");
|
put(8, ActivityKind.TYPE_WALKING);
|
||||||
put(12, "hiking");
|
put(12, ActivityKind.TYPE_HIKING);
|
||||||
}
|
|
||||||
};
|
|
||||||
public static Map<Integer, String> WORKOUT_TYPES_TO_OPENTRACKS_ICON = new HashMap<Integer, String>() {
|
|
||||||
{
|
|
||||||
put(1, "RUN");
|
|
||||||
put(2, "BIKE");
|
|
||||||
put(8, "WALK");
|
|
||||||
put(12, "WALK");
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ public class OpenTracksController extends Activity {
|
|||||||
private static final String ACTION_DASHBOARD = "Intent.OpenTracks-Dashboard";
|
private static final String ACTION_DASHBOARD = "Intent.OpenTracks-Dashboard";
|
||||||
private static final String ACTION_DASHBOARD_PAYLOAD = ACTION_DASHBOARD + ".Payload";
|
private static final String ACTION_DASHBOARD_PAYLOAD = ACTION_DASHBOARD + ".Payload";
|
||||||
|
|
||||||
private final Logger LOG = LoggerFactory.getLogger(OpenTracksController.class);
|
private static final Logger LOG = LoggerFactory.getLogger(OpenTracksController.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle bundle) {
|
public void onCreate(Bundle bundle) {
|
||||||
@ -111,7 +112,25 @@ public class OpenTracksController extends Activity {
|
|||||||
sendIntent(context, "de.dennisguse.opentracks.publicapi.StartRecording", null, null);
|
sendIntent(context, "de.dennisguse.opentracks.publicapi.StartRecording", null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void startRecording(Context context, String category, String icon) {
|
public static void startRecording(Context context, int activityKind) {
|
||||||
|
final String category = ActivityKind.asString(activityKind, context);
|
||||||
|
final String icon;
|
||||||
|
switch (activityKind) {
|
||||||
|
case ActivityKind.TYPE_CYCLING:
|
||||||
|
icon = "BIKE";
|
||||||
|
break;
|
||||||
|
case ActivityKind.TYPE_HIKING:
|
||||||
|
case ActivityKind.TYPE_WALKING:
|
||||||
|
icon = "WALK";
|
||||||
|
break;
|
||||||
|
case ActivityKind.TYPE_RUNNING:
|
||||||
|
icon = "RUN";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG.warn("Unmapped activity kind icon for {}", String.format("0x%X", activityKind));
|
||||||
|
icon = null;
|
||||||
|
}
|
||||||
|
|
||||||
sendIntent(context, "de.dennisguse.opentracks.publicapi.StartRecording", category, icon);
|
sendIntent(context, "de.dennisguse.opentracks.publicapi.StartRecording", category, icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +130,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.DoNotDisturb;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
||||||
@ -2027,14 +2028,18 @@ public abstract class Huami2021Support extends HuamiSupport {
|
|||||||
case WORKOUT_CMD_APP_OPEN:
|
case WORKOUT_CMD_APP_OPEN:
|
||||||
final Huami2021WorkoutTrackActivityType activityType = Huami2021WorkoutTrackActivityType.fromCode(payload[3]);
|
final Huami2021WorkoutTrackActivityType activityType = Huami2021WorkoutTrackActivityType.fromCode(payload[3]);
|
||||||
final boolean workoutNeedsGps = (payload[2] == 1);
|
final boolean workoutNeedsGps = (payload[2] == 1);
|
||||||
|
final int activityKind;
|
||||||
|
|
||||||
if (activityType == null) {
|
if (activityType == null) {
|
||||||
LOG.warn("Unknown workout activity type {}", String.format("0x%x", payload[3]));
|
LOG.warn("Unknown workout activity type {}", String.format("0x%x", payload[3]));
|
||||||
|
activityKind = ActivityKind.TYPE_UNKNOWN;
|
||||||
|
} else {
|
||||||
|
activityKind = activityType.toActivityKind();
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.info("Workout starting on band: {}, needs gps = {}", activityType, workoutNeedsGps);
|
LOG.info("Workout starting on band: {}, needs gps = {}", activityType, workoutNeedsGps);
|
||||||
|
|
||||||
onWorkoutOpen(workoutNeedsGps);
|
onWorkoutOpen(workoutNeedsGps, activityKind);
|
||||||
return;
|
return;
|
||||||
case WORKOUT_CMD_STATUS:
|
case WORKOUT_CMD_STATUS:
|
||||||
switch (payload[1]) {
|
switch (payload[1]) {
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
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.huami;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.huami;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The workout types, used to start / when workout tracking starts on the band.
|
* The workout types, used to start / when workout tracking starts on the band.
|
||||||
*/
|
*/
|
||||||
@ -38,6 +43,8 @@ public enum Huami2021WorkoutTrackActivityType {
|
|||||||
Yoga(0x3c),
|
Yoga(0x3c),
|
||||||
;
|
;
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(Huami2021WorkoutTrackActivityType.class);
|
||||||
|
|
||||||
private final byte code;
|
private final byte code;
|
||||||
|
|
||||||
Huami2021WorkoutTrackActivityType(final int code) {
|
Huami2021WorkoutTrackActivityType(final int code) {
|
||||||
@ -48,6 +55,39 @@ public enum Huami2021WorkoutTrackActivityType {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int toActivityKind() {
|
||||||
|
switch (this) {
|
||||||
|
case Badminton:
|
||||||
|
return ActivityKind.TYPE_BADMINTON;
|
||||||
|
case Elliptical:
|
||||||
|
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
|
||||||
|
case IndoorCycling:
|
||||||
|
return ActivityKind.TYPE_INDOOR_CYCLING;
|
||||||
|
case JumpRope:
|
||||||
|
return ActivityKind.TYPE_JUMP_ROPING;
|
||||||
|
case OutdoorCycling:
|
||||||
|
return ActivityKind.TYPE_CYCLING;
|
||||||
|
case OutdoorRunning:
|
||||||
|
return ActivityKind.TYPE_RUNNING;
|
||||||
|
case PoolSwimming:
|
||||||
|
return ActivityKind.TYPE_SWIMMING;
|
||||||
|
case Rowing:
|
||||||
|
return ActivityKind.TYPE_ROWING_MACHINE;
|
||||||
|
case Soccer:
|
||||||
|
return ActivityKind.TYPE_SOCCER;
|
||||||
|
case Treadmill:
|
||||||
|
return ActivityKind.TYPE_TREADMILL;
|
||||||
|
case Walking:
|
||||||
|
return ActivityKind.TYPE_WALKING;
|
||||||
|
case Yoga:
|
||||||
|
return ActivityKind.TYPE_YOGA;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.warn("Unmapped workout type {}", this);
|
||||||
|
|
||||||
|
return ActivityKind.TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
public static Huami2021WorkoutTrackActivityType fromCode(final byte code) {
|
public static Huami2021WorkoutTrackActivityType fromCode(final byte code) {
|
||||||
for (final Huami2021WorkoutTrackActivityType type : values()) {
|
for (final Huami2021WorkoutTrackActivityType type : values()) {
|
||||||
if (type.getCode() == code) {
|
if (type.getCode() == code) {
|
||||||
|
@ -110,6 +110,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.User;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.externalevents.gps.GBLocationManager;
|
import nodomain.freeyourgadget.gadgetbridge.externalevents.gps.GBLocationManager;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.externalevents.opentracks.OpenTracksController;
|
import nodomain.freeyourgadget.gadgetbridge.externalevents.opentracks.OpenTracksController;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
@ -1886,16 +1887,20 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
|||||||
break;
|
break;
|
||||||
case HuamiDeviceEvent.WORKOUT_STARTING:
|
case HuamiDeviceEvent.WORKOUT_STARTING:
|
||||||
final HuamiWorkoutTrackActivityType activityType = HuamiWorkoutTrackActivityType.fromCode(value[3]);
|
final HuamiWorkoutTrackActivityType activityType = HuamiWorkoutTrackActivityType.fromCode(value[3]);
|
||||||
|
final int activityKind;
|
||||||
|
|
||||||
if (activityType == null) {
|
if (activityType == null) {
|
||||||
LOG.warn("Unknown workout activity type {}", String.format("0x%02x", value[3]));
|
LOG.warn("Unknown workout activity type {}", String.format("0x%02x", value[3]));
|
||||||
|
activityKind = ActivityKind.TYPE_UNKNOWN;
|
||||||
|
} else {
|
||||||
|
activityKind = activityType.toActivityKind();
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean needsGps = value[2] == 1;
|
final boolean needsGps = value[2] == 1;
|
||||||
|
|
||||||
LOG.info("Workout starting on band: {}, needs gps = {}", activityType, needsGps);
|
LOG.info("Workout starting on band: {}, needs gps = {}", activityType, needsGps);
|
||||||
|
|
||||||
onWorkoutOpen(needsGps);
|
onWorkoutOpen(needsGps, activityKind);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1909,13 +1914,19 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
|||||||
*/
|
*/
|
||||||
private boolean workoutNeedsGps = false;
|
private boolean workoutNeedsGps = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Track the {@link nodomain.freeyourgadget.gadgetbridge.model.ActivityKind} that was opened, for the same reasons as {@code workoutNeedsGps}.
|
||||||
|
*/
|
||||||
|
private int workoutActivityKind = ActivityKind.TYPE_UNKNOWN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Track the last time we actually sent a gps location. We need to signal that GPS as re-acquired if the last update was too long ago.
|
* Track the last time we actually sent a gps location. We need to signal that GPS as re-acquired if the last update was too long ago.
|
||||||
*/
|
*/
|
||||||
private long lastPhoneGpsSent = 0;
|
private long lastPhoneGpsSent = 0;
|
||||||
|
|
||||||
protected void onWorkoutOpen(final boolean needsGps) {
|
protected void onWorkoutOpen(final boolean needsGps, final int activityKind) {
|
||||||
this.workoutNeedsGps = needsGps;
|
this.workoutNeedsGps = needsGps;
|
||||||
|
this.workoutActivityKind = activityKind;
|
||||||
|
|
||||||
final boolean sendGpsToBand = HuamiCoordinator.getWorkoutSendGpsToBand(getDevice().getAddress());
|
final boolean sendGpsToBand = HuamiCoordinator.getWorkoutSendGpsToBand(getDevice().getAddress());
|
||||||
|
|
||||||
@ -1936,7 +1947,7 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
|
|||||||
if (workoutNeedsGps && startOnPhone) {
|
if (workoutNeedsGps && startOnPhone) {
|
||||||
LOG.info("Starting OpenTracks recording");
|
LOG.info("Starting OpenTracks recording");
|
||||||
|
|
||||||
OpenTracksController.startRecording(getContext());
|
OpenTracksController.startRecording(getContext(), workoutActivityKind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.huami;
|
|||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The workout types, used to start / when workout tracking starts on the band.
|
* The workout types, used to start / when workout tracking starts on the band.
|
||||||
*/
|
*/
|
||||||
@ -44,6 +46,33 @@ public enum HuamiWorkoutTrackActivityType {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int toActivityKind() {
|
||||||
|
switch (this) {
|
||||||
|
case Elliptical:
|
||||||
|
return ActivityKind.TYPE_ELLIPTICAL_TRAINER;
|
||||||
|
case IndoorCycling:
|
||||||
|
return ActivityKind.TYPE_INDOOR_CYCLING;
|
||||||
|
case JumpRope:
|
||||||
|
return ActivityKind.TYPE_JUMP_ROPING;
|
||||||
|
case OutdoorCycling:
|
||||||
|
return ActivityKind.TYPE_CYCLING;
|
||||||
|
case OutdoorRunning:
|
||||||
|
return ActivityKind.TYPE_RUNNING;
|
||||||
|
case PoolSwimming:
|
||||||
|
return ActivityKind.TYPE_SWIMMING;
|
||||||
|
case RowingMachine:
|
||||||
|
return ActivityKind.TYPE_ROWING_MACHINE;
|
||||||
|
case Treadmill:
|
||||||
|
return ActivityKind.TYPE_TREADMILL;
|
||||||
|
case Walking:
|
||||||
|
return ActivityKind.TYPE_WALKING;
|
||||||
|
case Yoga:
|
||||||
|
return ActivityKind.TYPE_YOGA;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ActivityKind.TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
public static HuamiWorkoutTrackActivityType fromCode(final byte code) {
|
public static HuamiWorkoutTrackActivityType fromCode(final byte code) {
|
||||||
for (final HuamiWorkoutTrackActivityType type : values()) {
|
for (final HuamiWorkoutTrackActivityType type : values()) {
|
||||||
if (type.getCode() == code) {
|
if (type.getCode() == code) {
|
||||||
|
@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.QHybridConstants;
|
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.QHybridConstants;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.externalevents.opentracks.OpenTracksController;
|
import nodomain.freeyourgadget.gadgetbridge.externalevents.opentracks.OpenTracksController;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||||
|
|
||||||
public class WorkoutRequestHandler {
|
public class WorkoutRequestHandler {
|
||||||
public static void addStateResponse(JSONObject workoutResponse, String type, String msg) throws JSONException {
|
public static void addStateResponse(JSONObject workoutResponse, String type, String msg) throws JSONException {
|
||||||
@ -42,11 +43,15 @@ public class WorkoutRequestHandler {
|
|||||||
JSONObject workoutResponse = new JSONObject();
|
JSONObject workoutResponse = new JSONObject();
|
||||||
if (workoutRequest.optString("state").equals("started") && workoutRequest.optString("gps").equals("on")) {
|
if (workoutRequest.optString("state").equals("started") && workoutRequest.optString("gps").equals("on")) {
|
||||||
int activityType = workoutRequest.optInt("activity", -1);
|
int activityType = workoutRequest.optInt("activity", -1);
|
||||||
String activityCategory = QHybridConstants.WORKOUT_TYPES_TO_OPENTRACKS_CATEGORY.get(activityType);
|
final int activityKind;
|
||||||
String activityIcon = QHybridConstants.WORKOUT_TYPES_TO_OPENTRACKS_ICON.get(activityType);
|
if (QHybridConstants.WORKOUT_TYPES_TO_ACTIVITY_KIND.containsKey(activityType)) {
|
||||||
LOG.info("Workout started, activity type is " + activityType + "/" + activityCategory);
|
activityKind = QHybridConstants.WORKOUT_TYPES_TO_ACTIVITY_KIND.get(activityType);
|
||||||
|
} else {
|
||||||
|
activityKind = ActivityKind.TYPE_UNKNOWN;
|
||||||
|
}
|
||||||
|
LOG.info("Workout started, activity type is " + activityType + "/" + activityKind);
|
||||||
addStateResponse(workoutResponse, "success", "");
|
addStateResponse(workoutResponse, "success", "");
|
||||||
OpenTracksController.startRecording(context, activityCategory, activityIcon);
|
OpenTracksController.startRecording(context, activityKind);
|
||||||
} else if (workoutRequest.optString("type").equals("req_distance")) {
|
} else if (workoutRequest.optString("type").equals("req_distance")) {
|
||||||
long timeSecs = GBApplication.app().getOpenTracksObserver().getTimeMillisChange() / 1000;
|
long timeSecs = GBApplication.app().getOpenTracksObserver().getTimeMillisChange() / 1000;
|
||||||
float distanceCM = GBApplication.app().getOpenTracksObserver().getDistanceMeterChange() * 100;
|
float distanceCM = GBApplication.app().getOpenTracksObserver().getDistanceMeterChange() * 100;
|
||||||
|
Loading…
Reference in New Issue
Block a user