diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/NativeFITMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/NativeFITMessage.java index 4e8615323b..7dfda10935 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/NativeFITMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/NativeFITMessage.java @@ -356,7 +356,7 @@ public class NativeFITMessage { new FieldDefinitionPrimitive(69, BaseType.UINT32, "avg_lap_time", 1000, 0), // s new FieldDefinitionPrimitive(70, BaseType.UINT16, "best_lap_index"), new FieldDefinitionPrimitive(71, BaseType.UINT16, "min_altitude", 5, 500), // m - new FieldDefinitionPrimitive(78, BaseType.UINT32, "work_time"), // ms + new FieldDefinitionPrimitive(78, BaseType.UINT32, "active_time", 1000, 0), // s new FieldDefinitionPrimitive(79, BaseType.UINT16, "avg_swim_cadence", 10, 0), // rpm new FieldDefinitionPrimitive(80, BaseType.UINT16, "avg_swolf"), new FieldDefinitionPrimitive(82, BaseType.UINT16, "player_score"), @@ -536,6 +536,7 @@ public class NativeFITMessage { new FieldDefinitionPrimitive(61, BaseType.UINT16, "repetition_num"), new FieldDefinitionPrimitive(62, BaseType.UINT16, "min_altitude", 5, 500), // m new FieldDefinitionPrimitive(63, BaseType.UINT8, "min_heart_rate"), + new FieldDefinitionPrimitive(70, BaseType.UINT32, "active_time", 1000, 0), // s new FieldDefinitionPrimitive(71, BaseType.UINT16, "wkt_step_index"), new FieldDefinitionPrimitive(73, BaseType.UINT16, "avg_swolf"), new FieldDefinitionPrimitive(74, BaseType.UINT16, "opponent_score"), @@ -951,13 +952,13 @@ public class NativeFITMessage { new FieldDefinitionPrimitive(1, BaseType.UINT16, "calories"), // kcal new FieldDefinitionPrimitive(2, BaseType.UINT32, "distance"), new FieldDefinitionPrimitive(3, BaseType.UINT32, "cycles"), - new FieldDefinitionPrimitive(4, BaseType.UINT32, "active_time"), + new FieldDefinitionPrimitive(4, BaseType.UINT32, "active_time", 1000, 0), // s new FieldDefinitionPrimitive(5, BaseType.ENUM, "activity_type"), new FieldDefinitionPrimitive(6, BaseType.ENUM, "activity_subtype"), new FieldDefinitionPrimitive(7, BaseType.ENUM, "activity_level"), new FieldDefinitionPrimitive(8, BaseType.UINT16, "distance_16"), new FieldDefinitionPrimitive(9, BaseType.UINT16, "cycles_16"), - new FieldDefinitionPrimitive(10, BaseType.UINT16, "active_time_16"), + new FieldDefinitionPrimitive(10, BaseType.UINT16, "active_time_16"), // s new FieldDefinitionPrimitive(11, BaseType.UINT32, "local_timestamp"), new FieldDefinitionPrimitive(12, BaseType.SINT16, "temperature", 100, 0), // °C new FieldDefinitionPrimitive(14, BaseType.SINT16, "temperature_min", 100, 0), // °C @@ -1065,6 +1066,12 @@ public class NativeFITMessage { new FieldDefinitionPrimitive(4, BaseType.UINT8, "device_index") )); + public static final NativeFITMessage OPEN_WATER_EVENT = new NativeFITMessage(89, "OPEN_WATER_EVENT", Arrays.asList( + new FieldDefinitionPrimitive(0, BaseType.ENUM, "event_type"), + new FieldDefinitionPrimitive(5, BaseType.UINT32, "swim_stroke"), + new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP) + )); + public static final NativeFITMessage LENGTH = new NativeFITMessage(101, "LENGTH", Arrays.asList( new FieldDefinitionPrimitive(0, BaseType.ENUM, "event"), new FieldDefinitionPrimitive(1, BaseType.ENUM, "event_type"), @@ -1566,6 +1573,60 @@ public class NativeFITMessage { new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP) )); + public static final NativeFITMessage GOLF_COURSE = new NativeFITMessage(190, "GOLF_COURSE", Arrays.asList( + new FieldDefinitionPrimitive(0, BaseType.UINT32, "course_id"), + new FieldDefinitionPrimitive(1, BaseType.STRING, "name"), + new FieldDefinitionPrimitive(2, BaseType.UINT32, "local_time"), + new FieldDefinitionPrimitive(3, BaseType.UINT32, "start_time", FieldDefinitionFactory.FIELD.TIMESTAMP), + new FieldDefinitionPrimitive(4, BaseType.UINT32, "end_time", FieldDefinitionFactory.FIELD.TIMESTAMP), + new FieldDefinitionPrimitive(8, BaseType.UINT8, "out"), + new FieldDefinitionPrimitive(9, BaseType.UINT8, "in"), + new FieldDefinitionPrimitive(10, BaseType.UINT8, "total"), + new FieldDefinitionPrimitive(11, BaseType.STRING, "tee"), + new FieldDefinitionPrimitive(12, BaseType.UINT8, "slope"), + new FieldDefinitionPrimitive(21, BaseType.FLOAT32, "rating"), + new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP) + )); + + public static final NativeFITMessage GOLF_STATS = new NativeFITMessage(191, "GOLF_STATS", Arrays.asList( + new FieldDefinitionPrimitive(0, BaseType.STRING, "name"), + new FieldDefinitionPrimitive(2, BaseType.UINT8, "out"), + new FieldDefinitionPrimitive(3, BaseType.UINT8, "in"), + new FieldDefinitionPrimitive(4, BaseType.UINT16, "total"), + new FieldDefinitionPrimitive(7, BaseType.UINT8, "fairway_hit"), + new FieldDefinitionPrimitive(8, BaseType.UINT8, "gir"), + new FieldDefinitionPrimitive(9, BaseType.UINT8, "putts"), + new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP) + )); + + public static final NativeFITMessage SCORE = new NativeFITMessage(192, "SCORE", Arrays.asList( + new FieldDefinitionPrimitive(1, BaseType.UINT8, "hole_number"), + new FieldDefinitionPrimitive(2, BaseType.SINT8, "score"), + new FieldDefinitionPrimitive(5, BaseType.SINT8, "putts"), + new FieldDefinitionPrimitive(6, BaseType.ENUM, "fairway"), // 0=left, 1=right, 2=hit + new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP) + )); + + public static final NativeFITMessage HOLE = new NativeFITMessage(193, "HOLE", Arrays.asList( + new FieldDefinitionPrimitive(0, BaseType.UINT8, "hole_number"), + new FieldDefinitionPrimitive(1, BaseType.UINT32, "distance", 100, 0), // m + new FieldDefinitionPrimitive(2, BaseType.UINT8, "par"), + new FieldDefinitionPrimitive(3, BaseType.UINT8, "handicap"), + new FieldDefinitionPrimitive(4, BaseType.SINT32, "position_lat", FieldDefinitionFactory.FIELD.COORDINATE), + new FieldDefinitionPrimitive(5, BaseType.SINT32, "position_long", FieldDefinitionFactory.FIELD.COORDINATE), + new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP) + )); + + public static final NativeFITMessage SHOT = new NativeFITMessage(194, "SHOT", Arrays.asList( + new FieldDefinitionPrimitive(1, BaseType.UINT8, "hole_number"), + new FieldDefinitionPrimitive(2, BaseType.SINT32, "start_position_lat", FieldDefinitionFactory.FIELD.COORDINATE), + new FieldDefinitionPrimitive(3, BaseType.SINT32, "start_position_long", FieldDefinitionFactory.FIELD.COORDINATE), + new FieldDefinitionPrimitive(4, BaseType.SINT32, "end_position_lat", FieldDefinitionFactory.FIELD.COORDINATE), + new FieldDefinitionPrimitive(5, BaseType.SINT32, "end_position_long", FieldDefinitionFactory.FIELD.COORDINATE), + new FieldDefinitionPrimitive(7, BaseType.UINT32, "club_type"), + new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP) + )); + public static final NativeFITMessage EXD_SCREEN_CONFIGURATION = new NativeFITMessage(200, "EXD_SCREEN_CONFIGURATION", Arrays.asList( new FieldDefinitionPrimitive(0, BaseType.UINT8, "screen_index"), new FieldDefinitionPrimitive(1, BaseType.UINT8, "field_count"), @@ -1964,6 +2025,7 @@ public class NativeFITMessage { new FieldDefinitionPrimitive(27, BaseType.UINT32, "end_time"), new FieldDefinitionPrimitive(28, BaseType.UINT32, "total_calories"), // kcal new FieldDefinitionPrimitive(74, BaseType.UINT32, "start_elevation", 5, 500), // meter + new FieldDefinitionPrimitive(78, BaseType.UINT32, "active_time", 1000, 0), // s new FieldDefinitionPrimitive(110, BaseType.UINT32, "total_moving_time", 1000, 0), // seconds new FieldDefinitionPrimitive(254, BaseType.UINT16, "message_index") )); @@ -1981,6 +2043,7 @@ public class NativeFITMessage { new FieldDefinitionPrimitive(11, BaseType.UINT8, "max_heart_rate"), // bpm new FieldDefinitionPrimitive(12, BaseType.SINT32, "avg_vert_speed", 1000, 0), // m/s new FieldDefinitionPrimitive(13, BaseType.UINT32, "total_calories"), // kcal + new FieldDefinitionPrimitive(65, BaseType.UINT32, "active_time", 1000, 0), // s new FieldDefinitionPrimitive(77, BaseType.UINT32, "total_moving_time", 1000, 0), // s new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP), new FieldDefinitionPrimitive(254, BaseType.UINT16, "message_index") @@ -2302,10 +2365,11 @@ public class NativeFITMessage { new FieldDefinitionPrimitive(1, BaseType.SINT16, "start_tz_offset"), // min new FieldDefinitionPrimitive(2, BaseType.UINT32, "end_timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP), new FieldDefinitionPrimitive(3, BaseType.SINT16, "end_tz_offset"), // min - new FieldDefinitionPrimitive(4, BaseType.ENUM, "unknown_4"), // 8 - new FieldDefinitionPrimitive(6, BaseType.ENUM, "unknown_6"), // 0 - new FieldDefinitionPrimitive(7, BaseType.UINT32, "timestamp_7", FieldDefinitionFactory.FIELD.TIMESTAMP), - new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP) + new FieldDefinitionPrimitive(4, BaseType.ENUM, "feedback"), // 8 = good timing + long duration + low need + new FieldDefinitionPrimitive(6, BaseType.ENUM, "deleted", FieldDefinitionFactory.FIELD.BOOLEAN), + new FieldDefinitionPrimitive(7, BaseType.UINT32, "updated_timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP), + new FieldDefinitionPrimitive(253, BaseType.UINT32, "timestamp", FieldDefinitionFactory.FIELD.TIMESTAMP), + new FieldDefinitionPrimitive(254, BaseType.UINT16, "message_index") )); public static final NativeFITMessage WORKOUT_SCHEDULE = new NativeFITMessage(428, "WORKOUT_SCHEDULE", Arrays.asList( @@ -2377,6 +2441,7 @@ public class NativeFITMessage { put(80, ANT_RX); put(81, ANT_TX); put(82, ANT_CHANNEL_ID); + put(89, OPEN_WATER_EVENT); put(101, LENGTH); put(103, MONITORING_INFO); put(104, DEVICE_STATUS); @@ -2418,6 +2483,11 @@ public class NativeFITMessage { put(186, VIDEO_DESCRIPTION); put(187, VIDEO_CLIP); put(188, OHR_SETTINGS); + put(190, GOLF_COURSE); + put(191, GOLF_STATS); + put(192, SCORE); + put(193, HOLE); + put(194, SHOT); put(200, EXD_SCREEN_CONFIGURATION); put(201, EXD_DATA_FIELD_CONFIGURATION); put(202, EXD_DATA_CONCEPT_CONFIGURATION); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitGolfCourse.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitGolfCourse.java new file mode 100644 index 0000000000..4a547b3a49 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitGolfCourse.java @@ -0,0 +1,180 @@ +/* Copyright (C) 2026 Freeyourgadget + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages; + +import androidx.annotation.Nullable; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FitRecordDataBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordData; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordDefinition; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordHeader; + +/** + * WARNING: This class was auto-generated, please avoid modifying it directly. + * See {@link nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.codegen.FitCodeGen} + * + * @noinspection unused + */ +public class FitGolfCourse extends RecordData { + public FitGolfCourse(final RecordDefinition recordDefinition, final RecordHeader recordHeader) { + super(recordDefinition, recordHeader); + + final int nativeNumber = recordDefinition.getNativeFITMessage().getNumber(); + if (nativeNumber != 190) { + throw new IllegalArgumentException("FitGolfCourse expects native messages of " + 190 + ", got " + nativeNumber); + } + } + + @Nullable + public Long getCourseId() { + return getFieldByNumber(0, Long.class); + } + + @Nullable + public String getName() { + return getFieldByNumber(1, String.class); + } + + @Nullable + public Long getLocalTime() { + return getFieldByNumber(2, Long.class); + } + + @Nullable + public Long getStartTime() { + return getFieldByNumber(3, Long.class); + } + + @Nullable + public Long getEndTime() { + return getFieldByNumber(4, Long.class); + } + + @Nullable + public Integer getOut() { + return getFieldByNumber(8, Integer.class); + } + + @Nullable + public Integer getIn() { + return getFieldByNumber(9, Integer.class); + } + + @Nullable + public Integer getTotal() { + return getFieldByNumber(10, Integer.class); + } + + @Nullable + public String getTee() { + return getFieldByNumber(11, String.class); + } + + @Nullable + public Integer getSlope() { + return getFieldByNumber(12, Integer.class); + } + + @Nullable + public Float getRating() { + return getFieldByNumber(21, Float.class); + } + + @Nullable + public Long getTimestamp() { + return getFieldByNumber(253, Long.class); + } + + /** + * @noinspection unused + */ + public static class Builder extends FitRecordDataBuilder { + public Builder() { + super(190); + } + + public Builder setCourseId(final Long value) { + setFieldByNumber(0, value); + return this; + } + + public Builder setName(final String value) { + setFieldByNumber(1, value); + return this; + } + + public Builder setLocalTime(final Long value) { + setFieldByNumber(2, value); + return this; + } + + public Builder setStartTime(final Long value) { + setFieldByNumber(3, value); + return this; + } + + public Builder setEndTime(final Long value) { + setFieldByNumber(4, value); + return this; + } + + public Builder setOut(final Integer value) { + setFieldByNumber(8, value); + return this; + } + + public Builder setIn(final Integer value) { + setFieldByNumber(9, value); + return this; + } + + public Builder setTotal(final Integer value) { + setFieldByNumber(10, value); + return this; + } + + public Builder setTee(final String value) { + setFieldByNumber(11, value); + return this; + } + + public Builder setSlope(final Integer value) { + setFieldByNumber(12, value); + return this; + } + + public Builder setRating(final Float value) { + setFieldByNumber(21, value); + return this; + } + + public Builder setTimestamp(final Long value) { + setFieldByNumber(253, value); + return this; + } + + @Override + public FitGolfCourse build() { + return (FitGolfCourse) super.build(); + } + + @Override + public FitGolfCourse build(final int localMessageType) { + return (FitGolfCourse) super.build(localMessageType); + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitGolfStats.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitGolfStats.java new file mode 100644 index 0000000000..4b53ae9061 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitGolfStats.java @@ -0,0 +1,140 @@ +/* Copyright (C) 2026 Freeyourgadget + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages; + +import androidx.annotation.Nullable; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FitRecordDataBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordData; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordDefinition; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordHeader; + +/** + * WARNING: This class was auto-generated, please avoid modifying it directly. + * See {@link nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.codegen.FitCodeGen} + * + * @noinspection unused + */ +public class FitGolfStats extends RecordData { + public FitGolfStats(final RecordDefinition recordDefinition, final RecordHeader recordHeader) { + super(recordDefinition, recordHeader); + + final int nativeNumber = recordDefinition.getNativeFITMessage().getNumber(); + if (nativeNumber != 191) { + throw new IllegalArgumentException("FitGolfStats expects native messages of " + 191 + ", got " + nativeNumber); + } + } + + @Nullable + public String getName() { + return getFieldByNumber(0, String.class); + } + + @Nullable + public Integer getOut() { + return getFieldByNumber(2, Integer.class); + } + + @Nullable + public Integer getIn() { + return getFieldByNumber(3, Integer.class); + } + + @Nullable + public Integer getTotal() { + return getFieldByNumber(4, Integer.class); + } + + @Nullable + public Integer getFairwayHit() { + return getFieldByNumber(7, Integer.class); + } + + @Nullable + public Integer getGir() { + return getFieldByNumber(8, Integer.class); + } + + @Nullable + public Integer getPutts() { + return getFieldByNumber(9, Integer.class); + } + + @Nullable + public Long getTimestamp() { + return getFieldByNumber(253, Long.class); + } + + /** + * @noinspection unused + */ + public static class Builder extends FitRecordDataBuilder { + public Builder() { + super(191); + } + + public Builder setName(final String value) { + setFieldByNumber(0, value); + return this; + } + + public Builder setOut(final Integer value) { + setFieldByNumber(2, value); + return this; + } + + public Builder setIn(final Integer value) { + setFieldByNumber(3, value); + return this; + } + + public Builder setTotal(final Integer value) { + setFieldByNumber(4, value); + return this; + } + + public Builder setFairwayHit(final Integer value) { + setFieldByNumber(7, value); + return this; + } + + public Builder setGir(final Integer value) { + setFieldByNumber(8, value); + return this; + } + + public Builder setPutts(final Integer value) { + setFieldByNumber(9, value); + return this; + } + + public Builder setTimestamp(final Long value) { + setFieldByNumber(253, value); + return this; + } + + @Override + public FitGolfStats build() { + return (FitGolfStats) super.build(); + } + + @Override + public FitGolfStats build(final int localMessageType) { + return (FitGolfStats) super.build(localMessageType); + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitHole.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitHole.java new file mode 100644 index 0000000000..5704d813a1 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitHole.java @@ -0,0 +1,130 @@ +/* Copyright (C) 2026 Freeyourgadget + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages; + +import androidx.annotation.Nullable; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FitRecordDataBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordData; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordDefinition; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordHeader; + +/** + * WARNING: This class was auto-generated, please avoid modifying it directly. + * See {@link nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.codegen.FitCodeGen} + * + * @noinspection unused + */ +public class FitHole extends RecordData { + public FitHole(final RecordDefinition recordDefinition, final RecordHeader recordHeader) { + super(recordDefinition, recordHeader); + + final int nativeNumber = recordDefinition.getNativeFITMessage().getNumber(); + if (nativeNumber != 193) { + throw new IllegalArgumentException("FitHole expects native messages of " + 193 + ", got " + nativeNumber); + } + } + + @Nullable + public Integer getHoleNumber() { + return getFieldByNumber(0, Integer.class); + } + + @Nullable + public Double getDistance() { + return getFieldByNumber(1, Double.class); + } + + @Nullable + public Integer getPar() { + return getFieldByNumber(2, Integer.class); + } + + @Nullable + public Integer getHandicap() { + return getFieldByNumber(3, Integer.class); + } + + @Nullable + public Double getPositionLat() { + return getFieldByNumber(4, Double.class); + } + + @Nullable + public Double getPositionLong() { + return getFieldByNumber(5, Double.class); + } + + @Nullable + public Long getTimestamp() { + return getFieldByNumber(253, Long.class); + } + + /** + * @noinspection unused + */ + public static class Builder extends FitRecordDataBuilder { + public Builder() { + super(193); + } + + public Builder setHoleNumber(final Integer value) { + setFieldByNumber(0, value); + return this; + } + + public Builder setDistance(final Double value) { + setFieldByNumber(1, value); + return this; + } + + public Builder setPar(final Integer value) { + setFieldByNumber(2, value); + return this; + } + + public Builder setHandicap(final Integer value) { + setFieldByNumber(3, value); + return this; + } + + public Builder setPositionLat(final Double value) { + setFieldByNumber(4, value); + return this; + } + + public Builder setPositionLong(final Double value) { + setFieldByNumber(5, value); + return this; + } + + public Builder setTimestamp(final Long value) { + setFieldByNumber(253, value); + return this; + } + + @Override + public FitHole build() { + return (FitHole) super.build(); + } + + @Override + public FitHole build(final int localMessageType) { + return (FitHole) super.build(localMessageType); + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitLap.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitLap.java index 64be1b4f58..aa589e0515 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitLap.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitLap.java @@ -350,6 +350,11 @@ public class FitLap extends RecordData { return getFieldByNumber(63, Integer.class); } + @Nullable + public Double getActiveTime() { + return getFieldByNumber(70, Double.class); + } + @Nullable public Integer getWktStepIndex() { return getFieldByNumber(71, Integer.class); @@ -1043,6 +1048,11 @@ public class FitLap extends RecordData { return this; } + public Builder setActiveTime(final Double value) { + setFieldByNumber(70, value); + return this; + } + public Builder setWktStepIndex(final Integer value) { setFieldByNumber(71, value); return this; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitMonitoring.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitMonitoring.java index c7006bb4fb..23e1929553 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitMonitoring.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitMonitoring.java @@ -63,8 +63,8 @@ public class FitMonitoring extends RecordData { } @Nullable - public Long getActiveTime() { - return getFieldByNumber(4, Long.class); + public Double getActiveTime() { + return getFieldByNumber(4, Double.class); } @Nullable @@ -225,7 +225,7 @@ public class FitMonitoring extends RecordData { return this; } - public Builder setActiveTime(final Long value) { + public Builder setActiveTime(final Double value) { setFieldByNumber(4, value); return this; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitNap.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitNap.java index 783b2273d2..87ffc95615 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitNap.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitNap.java @@ -60,17 +60,17 @@ public class FitNap extends RecordData { } @Nullable - public Integer getUnknown4() { + public Integer getFeedback() { return getFieldByNumber(4, Integer.class); } @Nullable - public Integer getUnknown6() { - return getFieldByNumber(6, Integer.class); + public Boolean getDeleted() { + return getFieldByNumber(6, Boolean.class); } @Nullable - public Long getTimestamp7() { + public Long getUpdatedTimestamp() { return getFieldByNumber(7, Long.class); } @@ -79,6 +79,11 @@ public class FitNap extends RecordData { return getFieldByNumber(253, Long.class); } + @Nullable + public Integer getMessageIndex() { + return getFieldByNumber(254, Integer.class); + } + /** * @noinspection unused */ @@ -107,17 +112,17 @@ public class FitNap extends RecordData { return this; } - public Builder setUnknown4(final Integer value) { + public Builder setFeedback(final Integer value) { setFieldByNumber(4, value); return this; } - public Builder setUnknown6(final Integer value) { + public Builder setDeleted(final Boolean value) { setFieldByNumber(6, value); return this; } - public Builder setTimestamp7(final Long value) { + public Builder setUpdatedTimestamp(final Long value) { setFieldByNumber(7, value); return this; } @@ -127,6 +132,11 @@ public class FitNap extends RecordData { return this; } + public Builder setMessageIndex(final Integer value) { + setFieldByNumber(254, value); + return this; + } + @Override public FitNap build() { return (FitNap) super.build(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitOpenWaterEvent.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitOpenWaterEvent.java new file mode 100644 index 0000000000..67c934a5cf --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitOpenWaterEvent.java @@ -0,0 +1,90 @@ +/* Copyright (C) 2026 Freeyourgadget + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages; + +import androidx.annotation.Nullable; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FitRecordDataBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordData; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordDefinition; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordHeader; + +/** + * WARNING: This class was auto-generated, please avoid modifying it directly. + * See {@link nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.codegen.FitCodeGen} + * + * @noinspection unused + */ +public class FitOpenWaterEvent extends RecordData { + public FitOpenWaterEvent(final RecordDefinition recordDefinition, final RecordHeader recordHeader) { + super(recordDefinition, recordHeader); + + final int nativeNumber = recordDefinition.getNativeFITMessage().getNumber(); + if (nativeNumber != 89) { + throw new IllegalArgumentException("FitOpenWaterEvent expects native messages of " + 89 + ", got " + nativeNumber); + } + } + + @Nullable + public Integer getEventType() { + return getFieldByNumber(0, Integer.class); + } + + @Nullable + public Long getSwimStroke() { + return getFieldByNumber(5, Long.class); + } + + @Nullable + public Long getTimestamp() { + return getFieldByNumber(253, Long.class); + } + + /** + * @noinspection unused + */ + public static class Builder extends FitRecordDataBuilder { + public Builder() { + super(89); + } + + public Builder setEventType(final Integer value) { + setFieldByNumber(0, value); + return this; + } + + public Builder setSwimStroke(final Long value) { + setFieldByNumber(5, value); + return this; + } + + public Builder setTimestamp(final Long value) { + setFieldByNumber(253, value); + return this; + } + + @Override + public FitOpenWaterEvent build() { + return (FitOpenWaterEvent) super.build(); + } + + @Override + public FitOpenWaterEvent build(final int localMessageType) { + return (FitOpenWaterEvent) super.build(localMessageType); + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitRecordDataFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitRecordDataFactory.java index 961834c1b1..ebf281b696 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitRecordDataFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitRecordDataFactory.java @@ -79,6 +79,7 @@ public class FitRecordDataFactory { case 80 -> new FitAntRx(recordDefinition, recordHeader); case 81 -> new FitAntTx(recordDefinition, recordHeader); case 82 -> new FitAntChannelId(recordDefinition, recordHeader); + case 89 -> new FitOpenWaterEvent(recordDefinition, recordHeader); case 101 -> new FitLength(recordDefinition, recordHeader); case 103 -> new FitMonitoringInfo(recordDefinition, recordHeader); case 104 -> new FitDeviceStatus(recordDefinition, recordHeader); @@ -120,6 +121,11 @@ public class FitRecordDataFactory { case 186 -> new FitVideoDescription(recordDefinition, recordHeader); case 187 -> new FitVideoClip(recordDefinition, recordHeader); case 188 -> new FitOhrSettings(recordDefinition, recordHeader); + case 190 -> new FitGolfCourse(recordDefinition, recordHeader); + case 191 -> new FitGolfStats(recordDefinition, recordHeader); + case 192 -> new FitScore(recordDefinition, recordHeader); + case 193 -> new FitHole(recordDefinition, recordHeader); + case 194 -> new FitShot(recordDefinition, recordHeader); case 200 -> new FitExdScreenConfiguration(recordDefinition, recordHeader); case 201 -> new FitExdDataFieldConfiguration(recordDefinition, recordHeader); case 202 -> new FitExdDataConceptConfiguration(recordDefinition, recordHeader); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitScore.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitScore.java new file mode 100644 index 0000000000..9603f29935 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitScore.java @@ -0,0 +1,110 @@ +/* Copyright (C) 2026 Freeyourgadget + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages; + +import androidx.annotation.Nullable; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FitRecordDataBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordData; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordDefinition; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordHeader; + +/** + * WARNING: This class was auto-generated, please avoid modifying it directly. + * See {@link nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.codegen.FitCodeGen} + * + * @noinspection unused + */ +public class FitScore extends RecordData { + public FitScore(final RecordDefinition recordDefinition, final RecordHeader recordHeader) { + super(recordDefinition, recordHeader); + + final int nativeNumber = recordDefinition.getNativeFITMessage().getNumber(); + if (nativeNumber != 192) { + throw new IllegalArgumentException("FitScore expects native messages of " + 192 + ", got " + nativeNumber); + } + } + + @Nullable + public Integer getHoleNumber() { + return getFieldByNumber(1, Integer.class); + } + + @Nullable + public Integer getScore() { + return getFieldByNumber(2, Integer.class); + } + + @Nullable + public Integer getPutts() { + return getFieldByNumber(5, Integer.class); + } + + @Nullable + public Integer getFairway() { + return getFieldByNumber(6, Integer.class); + } + + @Nullable + public Long getTimestamp() { + return getFieldByNumber(253, Long.class); + } + + /** + * @noinspection unused + */ + public static class Builder extends FitRecordDataBuilder { + public Builder() { + super(192); + } + + public Builder setHoleNumber(final Integer value) { + setFieldByNumber(1, value); + return this; + } + + public Builder setScore(final Integer value) { + setFieldByNumber(2, value); + return this; + } + + public Builder setPutts(final Integer value) { + setFieldByNumber(5, value); + return this; + } + + public Builder setFairway(final Integer value) { + setFieldByNumber(6, value); + return this; + } + + public Builder setTimestamp(final Long value) { + setFieldByNumber(253, value); + return this; + } + + @Override + public FitScore build() { + return (FitScore) super.build(); + } + + @Override + public FitScore build(final int localMessageType) { + return (FitScore) super.build(localMessageType); + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitSession.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitSession.java index 0fa5bd5a94..475f766645 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitSession.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitSession.java @@ -396,8 +396,8 @@ public class FitSession extends RecordData { } @Nullable - public Long getWorkTime() { - return getFieldByNumber(78, Long.class); + public Double getActiveTime() { + return getFieldByNumber(78, Double.class); } @Nullable @@ -1328,7 +1328,7 @@ public class FitSession extends RecordData { return this; } - public Builder setWorkTime(final Long value) { + public Builder setActiveTime(final Double value) { setFieldByNumber(78, value); return this; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitShot.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitShot.java new file mode 100644 index 0000000000..87d2ed560d --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitShot.java @@ -0,0 +1,130 @@ +/* Copyright (C) 2026 Freeyourgadget + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.messages; + +import androidx.annotation.Nullable; + +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.FitRecordDataBuilder; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordData; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordDefinition; +import nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.RecordHeader; + +/** + * WARNING: This class was auto-generated, please avoid modifying it directly. + * See {@link nodomain.freeyourgadget.gadgetbridge.service.devices.garmin.fit.codegen.FitCodeGen} + * + * @noinspection unused + */ +public class FitShot extends RecordData { + public FitShot(final RecordDefinition recordDefinition, final RecordHeader recordHeader) { + super(recordDefinition, recordHeader); + + final int nativeNumber = recordDefinition.getNativeFITMessage().getNumber(); + if (nativeNumber != 194) { + throw new IllegalArgumentException("FitShot expects native messages of " + 194 + ", got " + nativeNumber); + } + } + + @Nullable + public Integer getHoleNumber() { + return getFieldByNumber(1, Integer.class); + } + + @Nullable + public Double getStartPositionLat() { + return getFieldByNumber(2, Double.class); + } + + @Nullable + public Double getStartPositionLong() { + return getFieldByNumber(3, Double.class); + } + + @Nullable + public Double getEndPositionLat() { + return getFieldByNumber(4, Double.class); + } + + @Nullable + public Double getEndPositionLong() { + return getFieldByNumber(5, Double.class); + } + + @Nullable + public Long getClubType() { + return getFieldByNumber(7, Long.class); + } + + @Nullable + public Long getTimestamp() { + return getFieldByNumber(253, Long.class); + } + + /** + * @noinspection unused + */ + public static class Builder extends FitRecordDataBuilder { + public Builder() { + super(194); + } + + public Builder setHoleNumber(final Integer value) { + setFieldByNumber(1, value); + return this; + } + + public Builder setStartPositionLat(final Double value) { + setFieldByNumber(2, value); + return this; + } + + public Builder setStartPositionLong(final Double value) { + setFieldByNumber(3, value); + return this; + } + + public Builder setEndPositionLat(final Double value) { + setFieldByNumber(4, value); + return this; + } + + public Builder setEndPositionLong(final Double value) { + setFieldByNumber(5, value); + return this; + } + + public Builder setClubType(final Long value) { + setFieldByNumber(7, value); + return this; + } + + public Builder setTimestamp(final Long value) { + setFieldByNumber(253, value); + return this; + } + + @Override + public FitShot build() { + return (FitShot) super.build(); + } + + @Override + public FitShot build(final int localMessageType) { + return (FitShot) super.build(localMessageType); + } + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitSplit.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitSplit.java index 2c616843d4..0872e9a9a9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitSplit.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitSplit.java @@ -124,6 +124,11 @@ public class FitSplit extends RecordData { return getFieldByNumber(74, Double.class); } + @Nullable + public Double getActiveTime() { + return getFieldByNumber(78, Double.class); + } + @Nullable public Double getTotalMovingTime() { return getFieldByNumber(110, Double.class); @@ -227,6 +232,11 @@ public class FitSplit extends RecordData { return this; } + public Builder setActiveTime(final Double value) { + setFieldByNumber(78, value); + return this; + } + public Builder setTotalMovingTime(final Double value) { setFieldByNumber(110, value); return this; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitSplitSummary.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitSplitSummary.java index 62048a689c..518fa8619f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitSplitSummary.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/garmin/fit/messages/FitSplitSummary.java @@ -99,6 +99,11 @@ public class FitSplitSummary extends RecordData { return getFieldByNumber(13, Long.class); } + @Nullable + public Double getActiveTime() { + return getFieldByNumber(65, Double.class); + } + @Nullable public Double getTotalMovingTime() { return getFieldByNumber(77, Double.class); @@ -182,6 +187,11 @@ public class FitSplitSummary extends RecordData { return this; } + public Builder setActiveTime(final Double value) { + setFieldByNumber(65, value); + return this; + } + public Builder setTotalMovingTime(final Double value) { setFieldByNumber(77, value); return this; diff --git a/app/src/test/resources/TestFitMessageTypeParsing.txt b/app/src/test/resources/TestFitMessageTypeParsing.txt index 7f0b02829f..49e2dadb9e 100644 --- a/app/src/test/resources/TestFitMessageTypeParsing.txt +++ b/app/src/test/resources/TestFitMessageTypeParsing.txt @@ -32,7 +32,7 @@ FitFieldCapabilities{2025-09-21 23:59:59.000, file=2, mesg_num=1, field_num=1, c FitFileCreator{2025-09-21 23:59:59.000, software_version=1, hardware_version=1}, FitBloodPressure{2025-09-21 23:59:59.000, systolic_pressure=1, diastolic_pressure=1, mean_arterial_pressure=1, map_3_sample_mean=1, map_morning_values=1, map_evening_values=1, heart_rate=1, heart_rate_type=1, status=1, user_profile_index=1, timestamp=1758499199}, FitSpeedZone{2025-09-21 23:59:59.000, high_value=1.0, name=a, message_index=1}, -FitMonitoring{2025-09-21 23:59:59.000, device_index=1, calories=1, distance=100, cycles=2, active_time=1000, activity_type=1, activity_subtype=1, activity_level=1, distance_16=1, cycles_16=1, active_time_16=1, local_timestamp=1, temperature=1.0, temperature_min=1.0, temperature_max=1.0, activity_time=[1,,65534], active_calories=1, current_activity_type_intensity=1, timestamp_min_8=1, timestamp_16=1, heart_rate=1, intensity=1.0, duration_min=1, duration=1, ascent=1.0, descent=1.0, moderate_activity_minutes=1, vigorous_activity_minutes=1, timestamp=1758499199}, +FitMonitoring{2025-09-21 23:59:59.000, device_index=1, calories=1, distance=100, cycles=2, active_time=1.0, activity_type=1, activity_subtype=1, activity_level=1, distance_16=1, cycles_16=1, active_time_16=1, local_timestamp=1, temperature=1.0, temperature_min=1.0, temperature_max=1.0, activity_time=[1,,65534], active_calories=1, current_activity_type_intensity=1, timestamp_min_8=1, timestamp_16=1, heart_rate=1, intensity=1.0, duration_min=1, duration=1, ascent=1.0, descent=1.0, moderate_activity_minutes=1, vigorous_activity_minutes=1, timestamp=1758499199}, FitTrainingFile{2025-09-21 23:59:59.000, type=2, manufacturer=1, product=1, serial_number=1, time_created=1127433599, timestamp=1758499199}, FitHrv{2025-09-21 23:59:59.000, time=[1000,,4200]}, FitAntRx{2025-09-21 23:59:59.000, fractional_timestamp=1.0, mesg_id=1, mesg_data=[1,,254], channel_number=1, data=[1,,254], timestamp=1758499199},