Skip to content

Commit

Permalink
Migrating from epoch time to native DateTime, time related arithmetic…
Browse files Browse the repository at this point in the history
… enhancements, query corrections and development #269
  • Loading branch information
MrCsabaToth committed Mar 5, 2023
1 parent 9506e81 commit 90f2f2f
Show file tree
Hide file tree
Showing 58 changed files with 362 additions and 794 deletions.
2 changes: 1 addition & 1 deletion lib/devices/gadgets/c2_additional_status1.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class C2AdditionalStatus1 extends ComplexSensor {
}

return RecordWithSport(
timeStamp: DateTime.now().millisecondsSinceEpoch,
timeStamp: DateTime.now(),
speed: getSpeed(data),
pace: getPace(data),
cadence: data[strokeRateByteIndex],
Expand Down
2 changes: 1 addition & 1 deletion lib/devices/gadgets/c2_additional_status2.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class C2AdditionalStatus2 extends ComplexSensor {
}

return RecordWithSport(
timeStamp: DateTime.now().millisecondsSinceEpoch,
timeStamp: DateTime.now(),
calories: getCalories(data)?.toInt(),
sport: ActivityType.rowing,
);
Expand Down
2 changes: 1 addition & 1 deletion lib/devices/gadgets/c2_additional_stroke_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class C2AdditionalStrokeData extends ComplexSensor {
}

return RecordWithSport(
timeStamp: DateTime.now().millisecondsSinceEpoch,
timeStamp: DateTime.now(),
power: getPower(data)?.toInt(),
sport: ActivityType.rowing,
);
Expand Down
2 changes: 1 addition & 1 deletion lib/devices/gadgets/cadence_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ class CadenceData {

@override
String toString() {
return "($time, $revolutions, ${timeStamp.millisecondsSinceEpoch})";
return "($time, $revolutions, $timeStamp)";
}
}
2 changes: 1 addition & 1 deletion lib/devices/gadgets/cycling_power_meter_sensor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ class CyclingPowerMeterSensor extends ComplexSensor with CadenceMixin {
}

return RecordWithSport(
timeStamp: DateTime.now().millisecondsSinceEpoch,
timeStamp: DateTime.now(),
distance: distance,
calories: getCalories(data)?.toInt(),
power: getPower(data)?.toInt(),
Expand Down
2 changes: 1 addition & 1 deletion lib/devices/gadgets/cycling_speed_and_cadence_sensor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class CyclingSpeedAndCadenceSensor extends ComplexSensor with CadenceMixin {
}

return RecordWithSport(
timeStamp: DateTime.now().millisecondsSinceEpoch,
timeStamp: DateTime.now(),
distance: distance,
speed: speed,
cadence: crankCadence?.toInt(),
Expand Down
9 changes: 4 additions & 5 deletions lib/devices/gadgets/fitness_equipment.dart
Original file line number Diff line number Diff line change
Expand Up @@ -833,8 +833,8 @@ class FitnessEquipment extends DeviceBase with PowerSpeedMixin {

if (workoutState == WorkoutState.waitingForFirstMove) {
if (isNotMoving) {
if (_activity != null && _activity!.startDateTime != null) {
int elapsedMillis = now.difference(_activity!.startDateTime!).inMilliseconds;
if (_activity != null) {
int elapsedMillis = now.difference(_activity!.start).inMilliseconds;
stub.adjustTime(elapsedMillis ~/ 1000, elapsedMillis);
lastRecord.adjustTime(elapsedMillis ~/ 1000, elapsedMillis);
return pausedRecord(stub);
Expand All @@ -851,8 +851,7 @@ class FitnessEquipment extends DeviceBase with PowerSpeedMixin {

// Null activity should only happen in UX simulation mode
if (_activity != null) {
_activity!.startDateTime = now;
_activity!.start = now.millisecondsSinceEpoch;
_activity!.start = now;
if (Get.isRegistered<Isar>()) {
final database = Get.find<Isar>();
database.writeTxnSync(() async {
Expand Down Expand Up @@ -916,7 +915,7 @@ class FitnessEquipment extends DeviceBase with PowerSpeedMixin {
);
}

int elapsedMillis = now.difference(_activity?.startDateTime ?? now).inMilliseconds;
int elapsedMillis = now.difference(_activity?.start ?? now).inMilliseconds;
double elapsed = elapsedMillis / 1000.0;
// When the equipment supplied multiple data read per second but the Fitness Machine
// standard only supplies second resolution elapsed time the delta time becomes zero
Expand Down
2 changes: 1 addition & 1 deletion lib/devices/gadgets/heart_rate_monitor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class HeartRateMonitor extends ComplexSensor {
}

return RecordWithSport(
timeStamp: DateTime.now().millisecondsSinceEpoch,
timeStamp: DateTime.now(),
heartRate: getHeartRate(data),
calories: getCalories(data),
sport: ActivityType.workout,
Expand Down
2 changes: 1 addition & 1 deletion lib/devices/gadgets/running_speed_and_cadence_sensor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class RunningSpeedAndCadenceSensor extends ComplexSensor {
}

return RecordWithSport(
timeStamp: DateTime.now().millisecondsSinceEpoch,
timeStamp: DateTime.now(),
distance: getDistance(data),
speed: getSpeed(data),
cadence: getCadence(data)?.toInt(),
Expand Down
2 changes: 1 addition & 1 deletion lib/devices/gadgets/schwinn_x70_hr_sensor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class SchwinnX70HrSensor extends ComplexSensor {
}

return RecordWithSport(
timeStamp: DateTime.now().millisecondsSinceEpoch,
timeStamp: DateTime.now(),
heartRate: data[heartRateByteIndex],
sport: ActivityType.ride,
);
Expand Down
8 changes: 3 additions & 5 deletions lib/export/activity_export.dart
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ abstract class ActivityExport {
bool compress,
int exportTarget,
) async {
activity.hydrate();
final descriptor = activity.deviceDescriptor();
final track = await TrackManager().getTrack(activity.sport);
final calculator = TrackCalculator(track: track);
Expand Down Expand Up @@ -169,14 +168,13 @@ abstract class ActivityExport {
}

Map<String, dynamic> getPersistenceValues(Activity activity, bool compressed) {
final startStamp = DateTime.fromMillisecondsSinceEpoch(activity.start);
final dateString = DateFormat.yMd().format(startStamp);
final timeString = DateFormat.Hms().format(startStamp);
final dateString = DateFormat.yMd().format(activity.start);
final timeString = DateFormat.Hms().format(activity.start);
final fileName = 'Activity_${dateString}_$timeString.${fileExtension(compressed)}'
.replaceAll('/', '-')
.replaceAll(':', '-');
return {
'startStamp': startStamp,
'startStamp': activity.start,
'name': '${activity.sport} at $dateString $timeString',
'description': '${activity.sport} by ${activity.deviceName}',
'fileName': fileName,
Expand Down
7 changes: 4 additions & 3 deletions lib/export/export_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ class ExportModel {
ExportRecord lastRecord = records.last;
ExportRecord firstRecord = records.first;
if (activity.elapsed == 0 &&
(lastRecord.record.timeStamp ?? 0) > 0 &&
(firstRecord.record.timeStamp ?? 0) > 0) {
activity.elapsed = (lastRecord.record.timeStamp! - firstRecord.record.timeStamp!) ~/ 1000;
lastRecord.record.timeStamp != null &&
firstRecord.record.timeStamp != null) {
activity.elapsed =
lastRecord.record.timeStamp!.difference(firstRecord.record.timeStamp!).inSeconds;
}

if (activity.distance < eps && (lastRecord.record.distance ?? 0.0) > eps) {
Expand Down
2 changes: 1 addition & 1 deletion lib/export/export_record.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ class ExportRecord {
});

double elapsed(Activity activity) {
return ((record.timeStamp ?? 0) - activity.start) / 1000;
return (record.timeStamp ?? DateTime.now()).difference(activity.start).inMilliseconds / 1000;
}
}
2 changes: 1 addition & 1 deletion lib/export/fit/definitions/fit_activity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class FitActivity extends FitDefinitionMessage {

var dummy = FitData();
dummy.output = [localMessageType];
dummy.addLong(FitSerializable.fitDateTime(model.activity.startDateTime!));
dummy.addLong(FitSerializable.fitTimeStamp(model.activity.start));
if (exportTarget == ExportTarget.regular) {
dummy.addLong(model.activity.movingTime);
dummy.addShort(1);
Expand Down
6 changes: 2 additions & 4 deletions lib/export/fit/definitions/fit_data_record.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,8 @@ class FitDataRecord extends FitDefinitionMessage {

var data = FitData();
data.output = [localMessageType];
final dateTime = model.record.timeStamp != null
? DateTime.fromMillisecondsSinceEpoch(model.record.timeStamp!)
: DateTime.now();
data.addLong(FitSerializable.fitDateTime(dateTime));
final dateTime = model.record.timeStamp ?? DateTime.now();
data.addLong(FitSerializable.fitTimeStamp(dateTime));
if (outputGps) {
data.addGpsCoordinate(model.latitude);
data.addGpsCoordinate(model.longitude);
Expand Down
2 changes: 1 addition & 1 deletion lib/export/fit/definitions/fit_device_info.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class FitDeviceInfo extends FitDefinitionMessage {

var data = FitData();
data.output = [localMessageType];
data.addLong(FitSerializable.fitDateTime(DateTime.now()));
data.addLong(FitSerializable.fitTimeStamp(DateTime.now()));
data.addByte(FitDeviceType.fitnessEquipment);
data.addShort(model.descriptor.manufacturerFitId);
data.addByte(model.descriptor.deviceCategory == DeviceCategory.antPlusDevice
Expand Down
2 changes: 1 addition & 1 deletion lib/export/fit/definitions/fit_file_id.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class FitFileId extends FitDefinitionMessage {
data.addByte(FitFileType.activity);
data.addShort(model.descriptor.manufacturerFitId);
// data.addShort(1);
data.addLong(FitSerializable.fitDateTime(DateTime.now()));
data.addLong(FitSerializable.fitTimeStamp(DateTime.now()));
assert(productTextLength == model.descriptor.fullName.length);
data.addString(model.descriptor.fullName);
return data.output;
Expand Down
12 changes: 4 additions & 8 deletions lib/export/fit/fit_serializable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import 'fit_base_type.dart';
import 'fit_crc.dart';

abstract class FitSerializable {
static final fitEpoch = DateTime.utc(1989, 12, 31, 0, 0, 0).millisecondsSinceEpoch;
static final fitEpoch = DateTime.utc(1989, 12, 31, 0, 0, 0);
late List<int> output = [];

void addNonFloatingNumber(int? number, int length, {bool signed = false}) {
Expand Down Expand Up @@ -80,15 +80,11 @@ abstract class FitSerializable {
return output;
}

static int fitTimeStamp(int? unixMilliseconds) {
if (unixMilliseconds == null) {
static int fitTimeStamp(DateTime? dateTime) {
if (dateTime == null) {
return 0;
}

return (unixMilliseconds - fitEpoch) ~/ 1000;
}

static int fitDateTime(DateTime dateTime) {
return fitTimeStamp(dateTime.millisecondsSinceEpoch);
return dateTime.difference(fitEpoch).inSeconds;
}
}
2 changes: 1 addition & 1 deletion lib/export/json/json_export.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class JsonExport extends ActivityExport {
exportModel.averageHeartRate,
);
final jsonWorkout = JsonWorkout(
exportModel.activity.startDateTime!,
exportModel.activity.start,
exportModel.name,
jsonAggregates,
exportModel.activity.timeZone,
Expand Down
5 changes: 2 additions & 3 deletions lib/export/tcx/tcx_export.dart
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class TCXExport extends ActivityExport {
///
void addTrackPoint(ExportRecord record, ExportModel exportModel) {
_sb.writeln("<Trackpoint>");
addElement('Time', timeStampString(record.record.timeStamp));
addElement('Time', timeStampString(record.record.timeStamp ?? DateTime.now()));
if (!exportModel.rawData && exportModel.calculateGps) {
addPosition(record.latitude.toStringAsFixed(7), record.longitude.toStringAsFixed(7));
}
Expand Down Expand Up @@ -227,8 +227,7 @@ class TCXExport extends ActivityExport {
/// To get 2019-03-03T11:43:46.000Z
/// utc time
/// Need to add T in the middle
String timeStampString(int? epochTime) {
final dateTime = DateTime.fromMillisecondsSinceEpoch(epochTime ?? 0);
String timeStampString(DateTime dateTime) {
return dateTime.toUtc().toString().replaceFirst(' ', 'T');
}
}
23 changes: 13 additions & 10 deletions lib/import/csv_importer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class CSVImporter with PowerSpeedMixin {
static const timeResolutionFactor = 2;

DateTime? start;
DateTime? end;
String message = "";

List<String> _lines = [];
Expand Down Expand Up @@ -174,8 +175,6 @@ class CSVImporter with PowerSpeedMixin {
var deviceName = "";
var deviceId = mPowerImportDeviceId;
var hrmId = "";
var startTime = 0;
var endTime = 0;
var calories = 0;
var uploaded = false;
var stravaId = 0;
Expand Down Expand Up @@ -226,7 +225,7 @@ class CSVImporter with PowerSpeedMixin {
return null;
}

startTime = int.tryParse(startTimeLine[1]) ?? 0;
final startTime = int.tryParse(startTimeLine[1]) ?? 0;
if (startTime == 0) {
message = "Couldn't parse $startTimeTag";
return null;
Expand All @@ -242,7 +241,7 @@ class CSVImporter with PowerSpeedMixin {
return null;
}

endTime = int.tryParse(endTimeLine[1]) ?? 0;
final endTime = int.tryParse(endTimeLine[1]) ?? 0;
if (endTime == 0) {
message = "Couldn't parse $endTimeTag";
return null;
Expand Down Expand Up @@ -495,8 +494,7 @@ class CSVImporter with PowerSpeedMixin {
start = DateTime.now();
}

startTime = start!.millisecondsSinceEpoch;
endTime = start!.add(Duration(seconds: totalElapsed)).millisecondsSinceEpoch;
end = start!.add(Duration(seconds: totalElapsed));
}

if (movingTime == 0 && totalElapsed > 0) {
Expand Down Expand Up @@ -531,13 +529,12 @@ class CSVImporter with PowerSpeedMixin {
deviceName: deviceName,
deviceId: deviceId,
hrmId: hrmId,
start: startTime,
end: endTime,
start: start ?? DateTime.now(),
end: end,
distance: totalDistance,
elapsed: totalElapsed,
movingTime: movingTime,
calories: calories,
startDateTime: start,
uploaded: uploaded,
stravaId: stravaId,
fourCC: fourCC,
Expand Down Expand Up @@ -574,9 +571,15 @@ class CSVImporter with PowerSpeedMixin {

while (_linePointer < _lines.length) {
final values = _lines[_linePointer].split(",");
DateTime? timeStamp;
final timeStampInt = int.tryParse(values[4]);
if (timeStampInt != null) {
timeStamp = DateTime.fromMillisecondsSinceEpoch(timeStampInt);
}

final record = Record(
activityId: activity.id,
timeStamp: int.tryParse(values[4]),
timeStamp: timeStamp,
distance: double.tryParse(values[3]),
elapsed: int.tryParse(values[5]),
calories: int.tryParse(values[7]),
Expand Down
17 changes: 4 additions & 13 deletions lib/persistence/isar/activity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ class Activity {
final String deviceId;
String hrmId;
@Index()
int start; // ms since epoch
int end; // ms since epoch
DateTime start;
DateTime? end;
double distance; // m
int elapsed; // s
int movingTime; // ms
Expand All @@ -49,9 +49,6 @@ class Activity {

final records = IsarLinks<Record>();

@ignore
DateTime? startDateTime;

String get elapsedString => Duration(seconds: elapsed).toDisplay();
String get movingTimeString => Duration(milliseconds: movingTime).toDisplay();

Expand All @@ -61,7 +58,7 @@ class Activity {
required this.deviceId,
required this.hrmId,
required this.start,
this.end = 0,
this.end,
this.distance = 0.0,
this.elapsed = 0,
this.movingTime = 0,
Expand All @@ -77,7 +74,6 @@ class Activity {
this.suuntoWorkoutUrl = "",
this.trainingPeaksAthleteId = 0,
this.trainingPeaksWorkoutId = 0,
this.startDateTime,
required this.fourCC,
required this.sport,
required this.powerFactor,
Expand All @@ -89,7 +85,7 @@ class Activity {
});

void finish(double? distance, int? elapsed, int? calories, int movingTime) {
end = DateTime.now().millisecondsSinceEpoch;
end = DateTime.now();
this.distance = distance ?? 0.0;
this.elapsed = elapsed ?? 0;
this.calories = calories ?? 0;
Expand Down Expand Up @@ -172,11 +168,6 @@ class Activity {
return display.distanceByUnit(distance, si, highRes);
}

Activity hydrate() {
startDateTime = DateTime.fromMillisecondsSinceEpoch(start);
return this;
}

DeviceDescriptor deviceDescriptor() {
return allFourCC.contains(fourCC)
? DeviceFactory.getDescriptorForFourCC(fourCC)
Expand Down

0 comments on commit 90f2f2f

Please sign in to comment.