1
0
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:
José Rebelo 2022-09-18 11:04:50 +01:00 committed by Gitea
parent 462aec6f71
commit c36857f063
7 changed files with 126 additions and 23 deletions

View File

@ -19,6 +19,8 @@ package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid;
import java.util.HashMap;
import java.util.Map;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public final class QHybridConstants {
public static final String HYBRIDHR_WATCHFACE_VERSION = "1.6";
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(2, "cycling");
put(8, "walking");
put(12, "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");
put(1, ActivityKind.TYPE_RUNNING);
put(2, ActivityKind.TYPE_CYCLING);
put(8, ActivityKind.TYPE_WALKING);
put(12, ActivityKind.TYPE_HIKING);
}
};
}

View File

@ -30,6 +30,7 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.util.GB;
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_PAYLOAD = ACTION_DASHBOARD + ".Payload";
private final Logger LOG = LoggerFactory.getLogger(OpenTracksController.class);
private static final Logger LOG = LoggerFactory.getLogger(OpenTracksController.class);
@Override
public void onCreate(Bundle bundle) {
@ -111,7 +112,25 @@ public class OpenTracksController extends Activity {
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);
}

View File

@ -130,6 +130,7 @@ import nodomain.freeyourgadget.gadgetbridge.devices.miband.DoNotDisturb;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator;
import nodomain.freeyourgadget.gadgetbridge.devices.miband.VibrationProfile;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
@ -2027,14 +2028,18 @@ public abstract class Huami2021Support extends HuamiSupport {
case WORKOUT_CMD_APP_OPEN:
final Huami2021WorkoutTrackActivityType activityType = Huami2021WorkoutTrackActivityType.fromCode(payload[3]);
final boolean workoutNeedsGps = (payload[2] == 1);
final int activityKind;
if (activityType == null) {
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);
onWorkoutOpen(workoutNeedsGps);
onWorkoutOpen(workoutNeedsGps, activityKind);
return;
case WORKOUT_CMD_STATUS:
switch (payload[1]) {

View File

@ -16,6 +16,11 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
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.
*/
@ -38,6 +43,8 @@ public enum Huami2021WorkoutTrackActivityType {
Yoga(0x3c),
;
private static final Logger LOG = LoggerFactory.getLogger(Huami2021WorkoutTrackActivityType.class);
private final byte code;
Huami2021WorkoutTrackActivityType(final int code) {
@ -48,6 +55,39 @@ public enum Huami2021WorkoutTrackActivityType {
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) {
for (final Huami2021WorkoutTrackActivityType type : values()) {
if (type.getCode() == code) {

View File

@ -110,6 +110,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.User;
import nodomain.freeyourgadget.gadgetbridge.externalevents.gps.GBLocationManager;
import nodomain.freeyourgadget.gadgetbridge.externalevents.opentracks.OpenTracksController;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice.State;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
@ -1886,16 +1887,20 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
break;
case HuamiDeviceEvent.WORKOUT_STARTING:
final HuamiWorkoutTrackActivityType activityType = HuamiWorkoutTrackActivityType.fromCode(value[3]);
final int activityKind;
if (activityType == null) {
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;
LOG.info("Workout starting on band: {}, needs gps = {}", activityType, needsGps);
onWorkoutOpen(needsGps);
onWorkoutOpen(needsGps, activityKind);
break;
default:
@ -1909,13 +1914,19 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
*/
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.
*/
private long lastPhoneGpsSent = 0;
protected void onWorkoutOpen(final boolean needsGps) {
protected void onWorkoutOpen(final boolean needsGps, final int activityKind) {
this.workoutNeedsGps = needsGps;
this.workoutActivityKind = activityKind;
final boolean sendGpsToBand = HuamiCoordinator.getWorkoutSendGpsToBand(getDevice().getAddress());
@ -1936,7 +1947,7 @@ public abstract class HuamiSupport extends AbstractBTLEDeviceSupport implements
if (workoutNeedsGps && startOnPhone) {
LOG.info("Starting OpenTracks recording");
OpenTracksController.startRecording(getContext());
OpenTracksController.startRecording(getContext(), workoutActivityKind);
}
}

View File

@ -18,6 +18,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.huami;
import java.util.Locale;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
/**
* The workout types, used to start / when workout tracking starts on the band.
*/
@ -44,6 +46,33 @@ public enum HuamiWorkoutTrackActivityType {
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) {
for (final HuamiWorkoutTrackActivityType type : values()) {
if (type.getCode() == code) {

View File

@ -27,6 +27,7 @@ import org.slf4j.LoggerFactory;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.devices.qhybrid.QHybridConstants;
import nodomain.freeyourgadget.gadgetbridge.externalevents.opentracks.OpenTracksController;
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
public class WorkoutRequestHandler {
public static void addStateResponse(JSONObject workoutResponse, String type, String msg) throws JSONException {
@ -42,11 +43,15 @@ public class WorkoutRequestHandler {
JSONObject workoutResponse = new JSONObject();
if (workoutRequest.optString("state").equals("started") && workoutRequest.optString("gps").equals("on")) {
int activityType = workoutRequest.optInt("activity", -1);
String activityCategory = QHybridConstants.WORKOUT_TYPES_TO_OPENTRACKS_CATEGORY.get(activityType);
String activityIcon = QHybridConstants.WORKOUT_TYPES_TO_OPENTRACKS_ICON.get(activityType);
LOG.info("Workout started, activity type is " + activityType + "/" + activityCategory);
final int activityKind;
if (QHybridConstants.WORKOUT_TYPES_TO_ACTIVITY_KIND.containsKey(activityType)) {
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", "");
OpenTracksController.startRecording(context, activityCategory, activityIcon);
OpenTracksController.startRecording(context, activityKind);
} else if (workoutRequest.optString("type").equals("req_distance")) {
long timeSecs = GBApplication.app().getOpenTracksObserver().getTimeMillisChange() / 1000;
float distanceCM = GBApplication.app().getOpenTracksObserver().getDistanceMeterChange() * 100;