private MemoryActivity ParseActivity(FitnessActivitiesPastModel healthGraphActivity) { var activityDetails = new MemoryActivity(); activityDetails.StartTime = healthGraphActivity.StartTime; activityDetails.Sport = healthGraphActivity.Type.ToFitSport(); // TODO: watch for other samples too! var numberOfTimeframes = healthGraphActivity.Path.Count; for (var i = 0; i < numberOfTimeframes; i++) { var timeFrame = new ActivityTimeFrame(); timeFrame.Timestamp = activityDetails.StartTime.AddSeconds(healthGraphActivity.Distance[i].Timestamp); timeFrame.Position = new Position((float)healthGraphActivity.Path[i].Longitude, (float)healthGraphActivity.Path[i].Latitude, (float)healthGraphActivity.Path[i].Altitude); if (healthGraphActivity.HeartRate.Count > i) { timeFrame.HeartRate = (byte)healthGraphActivity.HeartRate[i].HeartRate; } activityDetails.AddTimeFrame(timeFrame); } return(activityDetails); }
public override void Load(Stream source) { var serializer = new XmlSerializer(typeof(GpxExercise)); var exercise = serializer.Deserialize(source) as GpxExercise; if (exercise == null) { return; } foreach (var segment in exercise.Track.Segments) { foreach (var trackPoint in segment.Trackpoints) { var timeFrame = new ActivityTimeFrame(); timeFrame.Timestamp = trackPoint.Time; timeFrame.Position = new Position((float)trackPoint.Longitude, (float)trackPoint.Latitude, (float)trackPoint.Elevation); Activity.TimeFrames.Add(timeFrame); } } }
void MessageBroadcaster_RecordMesgEvent(object sender, MesgEventArgs e) { var msgRecord = e.mesg as RecordMesg; if (msgRecord == null) { return; } var timeFrame = new ActivityTimeFrame(); timeFrame.Timestamp = msgRecord.GetTimestamp().GetDateTime(); _lastTime = timeFrame.Timestamp; timeFrame.HeartRate = msgRecord.GetValidHeartRate(); timeFrame.Cadence = msgRecord.GetValidCadence(); timeFrame.Power = msgRecord.GetValidPower(); timeFrame.Timestamp = msgRecord.GetTimestamp().GetDateTime(); timeFrame.Speed = msgRecord.GetValidSpeed(); var distance = FitExtensions.GetValidDistance(msgRecord); if (distance.HasValue) { timeFrame.Distance = new Distance(distance.Value, DistanceUnit.Meter); } var alt = msgRecord.GetEnhancedAltitude(); if (msgRecord.HasPosition()) { timeFrame.Position = new SharpGeo.Position { Latitude = msgRecord.GetPositionLatInDegrees(), Longitude = msgRecord.GetPositionLongInDegrees(), Altitude = msgRecord.GetAltitude().GetValueOrDefault() }; } Activity.AddTimeFrame(timeFrame); }
public override void Load(Stream source) { var node = SmlNodeType.None; var frames = new List <ActivityTimeFrame>(); var summary = new ActivitySummary(); // SML files can be quite big (10 megabytes), so just read it sequentially instead of loading the whole file into memory using (XmlReader reader = XmlReader.Create(source)) { while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: if (reader.Name == "Header") { var xHeader = reader.ReadAsXElement(); Activity.StartTime = xHeader.GetFirstDescendantValue <DateTime>("DateTime"); var distance = xHeader.GetFirstDescendantValue <int>("Distance"); if (distance != 0) { summary.Distance = new Distance(distance, DistanceUnit.Meter); } } else if (reader.Name == "Sample") { var xSample = reader.ReadAsXElement(); DateTime utcTime = xSample.GetFirstDescendantValue <DateTime>("UTC"); var frame = frames.FirstOrDefault(frm => frm.Timestamp == utcTime); if (frame == null) { frame = new ActivityTimeFrame { Timestamp = utcTime }; frames.Add(frame); } var sampleType = xSample.GetFirstDescendantValue <string>("SampleType"); if (sampleType == "gps-tiny") { frame.Position = new Position( (float)MathEx.Rad2Deg(xSample.GetFirstDescendantValue <double>("Longitude")), (float)MathEx.Rad2Deg(xSample.GetFirstDescendantValue <double>("Latitude")) ); } else if (sampleType == "periodic") { var distance = xSample.GetFirstDescendantValue <int>("Distance"); if (distance != 0) { frame.Distance = new Distance(distance, DistanceUnit.Meter); } var speed = xSample.GetFirstDescendantValue <float>("Speed"); if (speed != 0.0f) { frame.Speed = new Speed(speed, SpeedUnit.MeterPerSecond); } var altitude = xSample.GetFirstDescendantValue <int>("Altitude"); if (altitude != 0) { frame.Altitude = new Distance(altitude, DistanceUnit.Meter); } } } else if (reader.Name == "Time") { node = SmlNodeType.Time; } else if (reader.Name == "R-R") { node = SmlNodeType.RR; } break; case XmlNodeType.Text: switch (node) { case SmlNodeType.Time: break; } break; } } // have to add timeframes in order (by timestamp) foreach (var frame in frames.OrderBy(frm => frm.Timestamp)) { Activity.AddTimeFrame(frame); } Activity.SetSummary(summary); } }
private void BeginNewFrame() { _frame = new ActivityTimeFrame(); }
public async Task <MemoryActivity> DownloadAsync(IActivitySummary activity) { if (_client == null) { return(null); } var pptActivity = activity as PPTActivitySummary; if (pptActivity == null) { return(null); } var exercise = pptActivity.Exercise; // PolarPersonalTrainerLib model GpxExercise gpsData = null; try { gpsData = await _client.GetGpsData(exercise); } catch (PPTException) { Log.Diagnostics("No GPS data found for activity {0}.", activity.Name); } return(await Task.Run <MemoryActivity>(() => { var samples = new[] { exercise.HeartRate.Values.Count, exercise.CadenceValues.Count, exercise.SpeedValues.Count }; var samplesCount = samples.Max(); // number of samples var result = new MemoryActivity(); DateTime timestamp = exercise.StartTime; // process samples for (int i = 0; i < samplesCount; i++) { var timeFrame = new ActivityTimeFrame(); timeFrame.Timestamp = timestamp; if (exercise.HeartRate.Values.Count > i) { timeFrame.HeartRate = exercise.HeartRate.Values[i]; } if (exercise.CadenceValues.Count > i) { timeFrame.Cadence = exercise.CadenceValues[i]; } if (exercise.SpeedValues.Count > i) { timeFrame.Speed = new Speed(exercise.SpeedValues[i], SpeedUnit.KilometerPerHour); } if (gpsData != null) { var trackPoint = gpsData.Track.GetTrackPoint(i); if (trackPoint != null) { timeFrame.Position = new Position(Convert.ToSingle(trackPoint.Longitude), Convert.ToSingle(trackPoint.Latitude), Convert.ToSingle(trackPoint.Elevation)); } } result.AddTimeFrame(timeFrame); timestamp = timestamp.AddSeconds(exercise.RecordingRate); // time of next sample } var summary = ActivitySummary.FromActivity(pptActivity); result.SetSummary(summary); return result; })); }
public void WriteTimeFrame(ActivityTimeFrame timeFrame) { if (_encoder == null) { return; } if (timeFrame.Type == ActivityTimeFrameType.Start) { // resumed var startMsg = new EventMesg(); startMsg.SetEventType(EventType.Start); startMsg.SetEvent(Event.OffCourse); startMsg.SetTimestamp(new Dynastream.Fit.DateTime(timeFrame.Timestamp)); _encoder.Write(startMsg); } else if (timeFrame.Type == ActivityTimeFrameType.Stop) { // stopped var stopMsg = new EventMesg(); stopMsg.SetEventType(EventType.Stop); stopMsg.SetEvent(Event.OffCourse); stopMsg.SetTimestamp(new Dynastream.Fit.DateTime(timeFrame.Timestamp)); _encoder.Write(stopMsg); } else { var recordMsg = new RecordMesg(); recordMsg.SetTimestamp(new Dynastream.Fit.DateTime(timeFrame.Timestamp)); if (timeFrame.HasPosition) { recordMsg.SetPositionLatInDegrees(timeFrame.Position.Value.Latitude); recordMsg.SetPositionLongInDegrees(timeFrame.Position.Value.Longitude); recordMsg.SetAltitude(timeFrame.Position.Value.Altitude); } if (timeFrame.HeartRate.HasValue) { recordMsg.SetHeartRate(timeFrame.HeartRate.Value); } if (timeFrame.Power.HasValue) { recordMsg.SetPower(timeFrame.Power.Value); } if (timeFrame.Cadence.HasValue) { recordMsg.SetCadence(timeFrame.Cadence.Value); } if (timeFrame.Speed.HasValue) { recordMsg.SetSpeed(timeFrame.Speed.Value.GetValueAs(SpeedUnit.MeterPerSecond)); } if (timeFrame.Distance.HasValue) { recordMsg.SetDistance(timeFrame.Distance.Value.GetValueAs(DistanceUnit.Meter)); } _encoder.Write(recordMsg); // Write R-R values if (timeFrame.HasRRValues) { var hrvMsg = new HrvMesg(); for (int i = 0; i < timeFrame.RRValues.Length; i++) { hrvMsg.SetTime(i, timeFrame.RRValues[i] / 1000.0f); } _encoder.Write(hrvMsg); } } }
public async Task <MemoryActivity> DownloadAsync(IActivitySummary activity) { var stravaActivity = activity as StravaActivitySummary; if (stravaActivity != null) // only Strava activity can be downloaded { var streams = await _client.Activities.GetActivityStreams(stravaActivity.Activity, StreamType.Time, StreamType.LatLng, StreamType.Watts, StreamType.HeartRate, StreamType.Cadence, StreamType.VelocitySmooth, StreamType.Altitude, StreamType.Moving); Debug.WriteLine("Memory allocated for downlading: " + FileHelper.GetSizeString(GC.GetTotalMemory(false))); // determine what streams we have StravaSharp.Stream timeStream = null, posStream = null, hrStream = null, speedStream = null, powerStream = null, cadenceStream = null, altitudeStream = null, movingStream = null; foreach (var stream in streams) { if (stream.Type == StreamType.Time) { timeStream = stream; } else if (stream.Type == StreamType.HeartRate) { hrStream = stream; } else if (stream.Type == StreamType.LatLng) { posStream = stream; } else if (stream.Type == StreamType.VelocitySmooth) { speedStream = stream; } else if (stream.Type == StreamType.Cadence) { cadenceStream = stream; } else if (stream.Type == StreamType.Watts) { powerStream = stream; } else if (stream.Type == StreamType.Altitude) { altitudeStream = stream; } else if (stream.Type == StreamType.Moving) { movingStream = stream; } Log.Diagnostics("{0} stream length: {1}", stream.Type, stream.Data.Length); } return(await Task.Run <MemoryActivity>(() => { // build activity from the streams' frames // pauses are not recognized this way var isMoving = false; var destActivity = new MemoryActivity { Sport = stravaActivity.Sport, Name = stravaActivity.Name }; DateTime startDate = stravaActivity.Activity.StartDate; for (int i = 0; i < streams[0].Data.Length; i++) { var timeFrame = new ActivityTimeFrame(); timeFrame.Timestamp = startDate.AddSeconds(Convert.ToInt32(timeStream.Data[i])); var moving = Convert.ToBoolean(movingStream.Data[i]); if (isMoving && !moving) { // now stops timeFrame.Type = ActivityTimeFrameType.Stop; destActivity.AddTimeFrame(timeFrame); isMoving = false; continue; } else if (!isMoving && moving) { // now starts moving again timeFrame.Type = ActivityTimeFrameType.Start; destActivity.AddTimeFrame(timeFrame); isMoving = true; } else if (!isMoving && !moving) { continue; // still standing } if (hrStream != null) { timeFrame.HeartRate = Convert.ToByte(hrStream.Data[i]); } if (posStream != null) { // position is json array var pos = posStream.Data[i] as JArray; if (pos != null) { var p = new SharpGeo.Position(); p.Latitude = pos[0].ToObject <float>(); p.Longitude = pos[1].ToObject <float>(); if (altitudeStream != null) { p.Altitude = Convert.ToSingle(altitudeStream.Data[i]); } timeFrame.Position = p; } } if (speedStream != null) { timeFrame.Speed = new Speed(Convert.ToSingle(speedStream.Data[i]), SpeedUnit.MeterPerSecond); } if (cadenceStream != null) { timeFrame.Cadence = Convert.ToByte(cadenceStream.Data[i]); } if (powerStream != null) { timeFrame.Power = Convert.ToUInt16(powerStream.Data[i]); } destActivity.AddTimeFrame(timeFrame); } var summary = new Models.ActivitySummary(); summary.ElapsedTime = stravaActivity.ElapsedTime; summary.MovingTime = stravaActivity.MovingTime; summary.Sport = stravaActivity.Sport; summary.AvgSpeed = stravaActivity.AvgSpeed; summary.MaxSpeed = stravaActivity.MaxSpeed; summary.AvgHeartRate = stravaActivity.AvgHeartRate; summary.MaxHeartRate = stravaActivity.MaxHeartRate; summary.AvgCadence = stravaActivity.AvgCadence; summary.MaxCadence = stravaActivity.MaxCadence; if (stravaActivity.HasRealPowerData) { summary.AvgPower = stravaActivity.AvgPower; summary.MaxPower = stravaActivity.MaxPower; } summary.Ascent = stravaActivity.Ascent; summary.Descent = stravaActivity.Descent; destActivity.SetSummary(summary); return destActivity; })); } return(null); }
public override void Load(System.IO.Stream source) { using (var reader = new StreamReader(source)) { string value; while (!reader.EndOfStream) { var line = reader.ReadLine(); if (GetValueOf(line, "Version", out value)) { _version = new Version(value.Insert(2, ".").Insert(1, ".")); } else if (GetValueOf(line, "Mode", out value)) { if (value[0] == '0') { _hasCadence = true; } else if (value[0] == '1') { _hasAltitude = true; } if (value[1] == '1') { _summary.Sport = Dynastream.Fit.Sport.Cycling; } else { _summary.Sport = Dynastream.Fit.Sport.Running; } if (value[2] == '0') { _unitSystem = UnitSystem.Metric; } else if (value[2] == '1') { _unitSystem = UnitSystem.American; } } else if (GetValueOf(line, "SMode", out value)) { if (value[0] == '1') { _hasSpeed = true; } if (value[1] == '1') { _hasCadence = true; } if (value[2] == '1') { _hasAltitude = true; } if (value[3] == '1') { _hasPower = true; } if (value[6] == '1') { _summary.Sport = Dynastream.Fit.Sport.Cycling; } else { _summary.Sport = Dynastream.Fit.Sport.Running; } if (value[7] == '0') { _unitSystem = UnitSystem.Metric; } else if (value[7] == '1') { _unitSystem = UnitSystem.American; } } else if (GetValueOf(line, "Date", out value)) { DateTime date; if (DateTime.TryParseExact(value, "yyyyMMdd", null, DateTimeStyles.None, out date)) { _startTime = date; } } else if (GetValueOf(line, "StartTime", out value)) { value = value.Remove(value.Length - 2); // remove the tenth second DateTime time; if (DateTime.TryParseExact(value, "HH:mm:ss", null, DateTimeStyles.None, out time)) { _startTime = _startTime.Add(time.TimeOfDay); } } else if (GetValueOf(line, "Interval", out value)) { _dataRecordingInterval = Convert.ToInt32(value); } else if (SectionBegins(line, "Trip")) { // Cycling trip data - summary for (int i = 0; i < 8; i++) { var tripData = reader.ReadLine(); if (i == 0) { _summary.Distance = GetDistance(tripData); } else if (i == 2) { _summary.ElapsedTime = Convert.ToInt32(tripData); } else if (i == 5) { _summary.AvgSpeed = GetSpeed(tripData); } else if (i == 6) { _summary.MaxSpeed = GetSpeed(tripData); } } } else if (SectionBegins(line, "HRData")) { var timestamp = _startTime; DataType[] columns = null; while (!reader.EndOfStream) { var data = reader.ReadLine(); var values = data.Split('\t'); if (columns == null) { var defaultColumns = new[] { DataType.HeartRate, DataType.Speed, DataType.Cadence, DataType.Altitude, DataType.Power }; // Parse the first line to determine the columns we have columns = new DataType[values.Length]; var idx = 0; for (int i = 0; i < defaultColumns.Length && idx < columns.Length; i++) { switch (defaultColumns[i]) { case DataType.HeartRate: columns[idx++] = DataType.HeartRate; break; case DataType.Speed: if (_hasSpeed) { columns[idx++] = DataType.Speed; } break; case DataType.Cadence: if (_hasCadence) { columns[idx++] = DataType.Cadence; } break; case DataType.Altitude: if (_hasAltitude) { columns[idx++] = DataType.Altitude; } break; case DataType.Power: if (_hasPower) { columns[idx++] = DataType.Power; } break; default: break; } } } var frame = new ActivityTimeFrame { Timestamp = timestamp, HeartRate = Convert.ToByte(values[0]) }; for (int i = 1; i < columns.Length; i++) { switch (columns[i]) { case DataType.Speed: frame.Speed = GetSpeed(values[i]); break; case DataType.Cadence: frame.Cadence = Convert.ToByte(values[i]); break; case DataType.Power: frame.Power = Convert.ToUInt16(values[i]); break; case DataType.Altitude: frame.Altitude = GetAltitude(values[i]); break; default: break; } } Activity.AddTimeFrame(frame); timestamp = timestamp.AddSeconds(_dataRecordingInterval); } } } Activity.SetSummary(_summary); } }