This repository has been archived on 2024-03-27. You can view files and clone it, but cannot push or open issues/pull-requests.
encrateia/lib/models/lap.dart

366 lines
12 KiB
Dart

import 'package:encrateia/model/model.dart'
show DbLap, DbActivity, DbPowerZone, DbHeartRateZone;
import 'package:encrateia/models/power_zone.dart';
import 'package:encrateia/models/power_zone_schema.dart';
import 'package:encrateia/models/heart_rate_zone.dart';
import 'package:encrateia/models/record_list.dart';
import 'package:encrateia/models/tag.dart';
import 'package:encrateia/models/lap_tagging.dart';
import 'package:fit_parser/fit_parser.dart';
import 'package:encrateia/utils/date_time_utils.dart';
import 'package:encrateia/models/event.dart';
import 'package:encrateia/models/activity.dart';
import 'package:flutter/material.dart';
import 'package:encrateia/models/athlete.dart';
import 'package:encrateia/models/heart_rate_zone_schema.dart';
import 'bar_zone.dart';
class Lap {
Lap() {
db = DbLap();
}
Lap.fromDb(this.db);
DbLap db;
Activity activity;
int index;
List<Event> _records;
PowerZoneSchema _powerZoneSchema;
PowerZone _powerZone;
HeartRateZone _heartRateZone;
HeartRateZoneSchema _heartRateZoneSchema;
List<BarZone> powerDistributions;
List<BarZone> heartRateDistributions;
static Lap fromLap({
DataMessage dataMessage,
Activity activity,
Lap lap,
}) {
lap.db
..activitiesId = activity.db.id
..avgSpeed = dataMessage.get('avg_speed') as double
..maxSpeed = dataMessage.get('max_speed') as double
..timeStamp = dateTimeFromStrava(dataMessage.get('timestamp') as double)
..startTime = dateTimeFromStrava(dataMessage.get('start_time') as double)
..startPositionLat = dataMessage.get('start_position_lat') as double
..startPositionLong = dataMessage.get('start_position_long') as double
..endPositionLat = dataMessage.get('end_position_lat') as double
..endPositionLong = dataMessage.get('end_position_long') as double
..startPositionLat = dataMessage.get('end_position_lat') as double
..avgHeartRate = (dataMessage.get('avg_heart_rate') as double)?.round()
..maxHeartRate = (dataMessage.get('max_heart_rate') as double)?.round()
..avgRunningCadence = dataMessage.get('avg_running_cadence') as double
..event = dataMessage.get('event') as String
..eventType = dataMessage.get('event_type') as String
..eventGroup = (dataMessage.get('event_group') as double)?.round()
..sport = dataMessage.get('sport') as String
..subSport = dataMessage.get('sub_sport') as String
..avgVerticalOscillation =
dataMessage.get('avg_vertical_oscillation') as double
..totalElapsedTime =
(dataMessage.get('total_elapsed_time') as double)?.round()
..totalTimerTime =
(dataMessage.get('total_timer_time') as double)?.round()
..totalDistance = (dataMessage.get('total_distance') as double)?.round()
..totalStrides = (dataMessage.get('total_strides') as double)?.round()
..totalCalories = (dataMessage.get('total_calories') as double)?.round()
..totalAscent = (dataMessage.get('total_ascent') as double)?.round()
..totalDescent = (dataMessage.get('total_descent') as double)?.round()
..avgStanceTimePercent =
dataMessage.get('avg_stance_time_percent') as double
..avgStanceTime = dataMessage.get('avg_stance_time') as double
..maxRunningCadence =
(dataMessage.get('max_running_cadence') as double)?.round()
..intensity = dataMessage.get('intensity') as int
..lapTrigger = dataMessage.get('lap_trigger') as String
..avgTemperature = (dataMessage.get('avg_temperature') as double)?.round()
..maxTemperature = (dataMessage.get('max_temperature') as double)?.round()
..avgFractionalCadence =
dataMessage.get('avg_fractional_cadence') as double
..maxFractionalCadence =
dataMessage.get('max_fractional_cadence') as double
..totalFractionalCycles =
dataMessage.get('total_fractional_cycles') as double;
return lap;
}
Future<List<Event>> get records async {
_records ??= await Event.recordsByLap(lap: this);
return _records;
}
Future<double> get avgPower async {
if (db.avgPower == null) {
db.avgPower = RecordList<Event>(await records).calculateAveragePower();
await db.save();
}
return db.avgPower;
}
Future<double> get sdevPower async {
if (db.sdevPower == null) {
db.sdevPower = RecordList<Event>(await records).calculateSdevPower();
await db.save();
}
return db.sdevPower;
}
Future<int> get minPower async {
if (db.minPower == null) {
db.minPower = RecordList<Event>(await records).calculateMinPower();
await db.save();
}
return db.minPower;
}
Future<int> get maxPower async {
if (db.maxPower == null) {
db.maxPower = RecordList<Event>(await records).calculateMaxPower();
await db.save();
}
return db.maxPower;
}
Future<double> get avgGroundTime async {
if (db.avgGroundTime == null) {
db.avgGroundTime =
RecordList<Event>(await records).calculateAverageGroundTime();
await db.save();
}
return db.avgGroundTime;
}
Future<double> get sdevGroundTime async {
if (db.sdevGroundTime == null) {
db.sdevGroundTime =
RecordList<Event>(await records).calculateSdevGroundTime();
await db.save();
}
return db.sdevGroundTime;
}
Future<double> get avgVerticalOscillation async {
if (db.avgVerticalOscillation == null ||
db.avgVerticalOscillation == 6553.5) {
db.avgVerticalOscillation = RecordList<Event>(await records)
.calculateAverageVerticalOscillation();
await db.save();
}
return db.avgVerticalOscillation;
}
Future<double> get sdevVerticalOscillation async {
if (db.sdevVerticalOscillation == null) {
db.sdevVerticalOscillation =
RecordList<Event>(await records).calculateSdevVerticalOscillation();
await db.save();
}
return db.sdevVerticalOscillation;
}
Future<double> get avgStrydCadence async {
if (db.avgStrydCadence == null) {
db.avgStrydCadence =
RecordList<Event>(await records).calculateAverageStrydCadence();
await db.save();
}
return db.avgStrydCadence;
}
Future<double> get sdevStrydCadence async {
if (db.sdevStrydCadence == null) {
db.sdevStrydCadence =
RecordList<Event>(await records).calculateSdevStrydCadence();
await db.save();
}
return db.sdevStrydCadence;
}
Future<double> get avgLegSpringStiffness async {
if (db.avgLegSpringStiffness == null) {
db.avgLegSpringStiffness =
RecordList<Event>(await records).calculateAverageLegSpringStiffness();
await db.save();
}
return db.avgLegSpringStiffness;
}
Future<double> get sdevLegSpringStiffness async {
if (db.sdevLegSpringStiffness == null) {
db.sdevLegSpringStiffness =
RecordList<Event>(await records).calculateSdevLegSpringStiffness();
await db.save();
}
return db.sdevLegSpringStiffness;
}
Future<double> get avgFormPower async {
if (db.avgFormPower == null) {
db.avgFormPower =
RecordList<Event>(await records).calculateAverageFormPower();
await db.save();
}
return db.avgFormPower;
}
Future<double> get sdevFormPower async {
if (db.sdevFormPower == null) {
db.sdevFormPower =
RecordList<Event>(await records).calculateSdevFormPower();
await db.save();
}
return db.sdevFormPower;
}
static Future<List<Lap>> all({Activity activity}) async {
int counter = 1;
final List<DbLap> dbLapList = await activity.db.getDbLaps().toList();
final List<Lap> lapList =
dbLapList.map((DbLap dbLap) => Lap.fromDb(dbLap)).toList();
for (final Lap lap in lapList) {
lap
..activity = activity
..index = counter;
counter = counter + 1;
}
return lapList;
}
Future<PowerZoneSchema> get powerZoneSchema async {
if (_powerZoneSchema == null) {
final DbActivity dbActivity = await DbActivity().getById(db.activitiesId);
_powerZoneSchema = await PowerZoneSchema.getBy(
athletesId: dbActivity.athletesId,
date: dbActivity.timeCreated,
);
}
return _powerZoneSchema;
}
Future<HeartRateZoneSchema> get heartRateZoneSchema async {
if (_heartRateZoneSchema == null) {
final DbActivity dbActivity = await DbActivity().getById(db.activitiesId);
_heartRateZoneSchema = await HeartRateZoneSchema.getBy(
athletesId: dbActivity.athletesId,
date: dbActivity.timeCreated,
);
}
return _heartRateZoneSchema;
}
Future<void> averages() async {
final RecordList<Event> recordList = RecordList<Event>(await records);
db
..avgPower = recordList.calculateAveragePower()
..avgFormPower = recordList.calculateAverageFormPower()
..avgHeartRate = recordList.calculateAverageHeartRate()
..avgSpeed = recordList.calculateAverageSpeed()
..avgGroundTime = recordList.calculateAverageGroundTime()
..avgStrydCadence = recordList.calculateAverageStrydCadence()
..avgLegSpringStiffness = recordList.calculateAverageLegSpringStiffness()
..avgStrideRatio = recordList.calculateAverageStrideRatio()
..avgPowerRatio = recordList.calculateAverageStrideRatio()
..avgVerticalOscillation =
recordList.calculateAverageVerticalOscillation();
await db.save();
}
Future<PowerZone> get powerZone async {
if (_powerZone == null) {
final DbPowerZone dbPowerZone = await DbPowerZone()
.select()
.powerZoneSchemataId
.equals((await powerZoneSchema).id)
.and
.lowerLimit
.lessThanOrEquals(db.avgPower)
.and
.upperLimit
.greaterThanOrEquals(db.avgPower)
.toSingle();
_powerZone = PowerZone.fromDb(dbPowerZone);
}
return _powerZone;
}
Future<HeartRateZone> get heartRateZone async {
if (_heartRateZone == null) {
final DbHeartRateZone dbHeartRateZone = await DbHeartRateZone()
.select()
.heartRateZoneSchemataId
.equals((await heartRateZoneSchema).id)
.and
.lowerLimit
.lessThanOrEquals(db.avgHeartRate)
.and
.upperLimit
.greaterThanOrEquals(db.avgHeartRate)
.toSingle();
_heartRateZone = HeartRateZone.fromDb(dbHeartRateZone);
}
return _heartRateZone;
}
Future<void> autoTagger({@required Athlete athlete}) async {
final PowerZone powerZone = await this.powerZone;
if (powerZone.id != null) {
final Tag powerTag = await Tag.autoPowerTag(
athlete: athlete,
sortOrder: powerZone.lowerLimit,
color: powerZone.color,
name: powerZone.name,
);
await LapTagging.createBy(
lap: this,
tag: powerTag,
system: true,
);
}
final HeartRateZone heartRateZone = await this.heartRateZone;
if (heartRateZone.id != null) {
final Tag heartRateTag = await Tag.autoHeartRateTag(
athlete: athlete,
sortOrder: heartRateZone.lowerLimit,
color: heartRateZone.color,
name: heartRateZone.name,
);
await LapTagging.createBy(
lap: this,
tag: heartRateTag,
system: true,
);
}
}
Future<List<BarZone>> powerZoneCounts() async {
final PowerZoneSchema powerZoneSchema = await this.powerZoneSchema;
final List<Event> records = await this.records;
final List<Event> powerRecords =
records.where((Event record) => record.power != null).toList();
final List<BarZone> powerZoneCounts = await RecordList<Event>(powerRecords)
.powerZoneCounts(powerZoneSchema: powerZoneSchema);
return powerZoneCounts;
}
Future<List<BarZone>> heartRateZoneCounts() async {
final HeartRateZoneSchema heartRateZoneSchema =
await this.heartRateZoneSchema;
final List<Event> records = await this.records;
final List<Event> heartRateRecords =
records.where((Event record) => record.heartRate != null).toList();
final List<BarZone> heartRateZoneCounts =
await RecordList<Event>(heartRateRecords)
.heartRateZoneCounts(heartRateZoneSchema: heartRateZoneSchema);
return heartRateZoneCounts;
}
}