Ejemplo n.º 1
0
    public static void MergeHeartRates(FitMessages messages)
    {
        float?   hr_anchor_event_timestamp = 0.0f;
        DateTime hr_anchor_timestamp       = new DateTime(0);
        bool     hr_anchor_set             = false;
        byte?    last_valid_hr             = 0;
        DateTime last_valid_hr_time        = new DateTime(0);

        DateTime record_range_start_time = new DateTime(messages.Records[0].GetTimestamp());
        int      hr_start_index          = 0;
        int      hr_start_sub_index      = 0;

        //
        // Update this foreach() to loop through just the Record messages
        //
        foreach (RecordMesg recordMesg in messages.Records)
        {
            long hrSum      = 0;
            long hrSumCount = 0;

            // Obtain the time for which the record message is valid
            DateTime record_range_end_time = new DateTime(recordMesg.GetTimestamp());

            // Need to determine timestamp range which applies to this record
            bool findingInRangeHrMesgs = true;

            // Start searching HR mesgs where we left off
            int hr_mesg_counter     = hr_start_index;
            int hr_sub_mesg_counter = hr_start_sub_index;

            //
            // Update this while() to loop through just the HR messages
            //
            while (findingInRangeHrMesgs && (hr_mesg_counter < messages.HeartRates.Count))
            {
                HrMesg hrMesg = new HrMesg(messages.HeartRates[hr_mesg_counter]);

                // Update HR timestamp anchor, if present
                if (hrMesg.GetTimestamp() != null && hrMesg.GetTimestamp().GetTimeStamp() != 0)
                {
                    hr_anchor_timestamp = new DateTime(hrMesg.GetTimestamp());
                    hr_anchor_set       = true;

                    if (hrMesg.GetFractionalTimestamp() != null)
                    {
                        hr_anchor_timestamp.Add((double)hrMesg.GetFractionalTimestamp());
                    }

                    if (hrMesg.GetNumEventTimestamp() == 1)
                    {
                        hr_anchor_event_timestamp = hrMesg.GetEventTimestamp(0);
                    }
                    else
                    {
                        throw new FitException("FIT HrToRecordMesgBroadcastPlugin Error: Anchor HR mesg must have 1 event_timestamp");
                    }
                }

                if (hr_anchor_set == false)
                {
                    // We cannot process any HR messages if we have not received a timestamp anchor
                    throw new FitException("FIT HrToRecordMesgBroadcastPlugin Error: No anchor timestamp received in a HR mesg before diff HR mesgs");
                }
                else if (hrMesg.GetNumEventTimestamp() != hrMesg.GetNumFilteredBpm())
                {
                    throw new FitException("FIT HrToRecordMesgBroadcastPlugin Error: HR mesg with mismatching event timestamp and filtered bpm");
                }
                for (int j = hr_sub_mesg_counter; j < hrMesg.GetNumEventTimestamp(); j++)
                {
                    // Build up timestamp for each message using the anchor and event_timestamp
                    DateTime hrMesgTime      = new DateTime(hr_anchor_timestamp);
                    float?   event_timestamp = hrMesg.GetEventTimestamp(j);

                    // Deal with roll over case
                    if (event_timestamp < hr_anchor_event_timestamp)
                    {
                        if ((hr_anchor_event_timestamp - event_timestamp) > (1 << 21))
                        {
                            event_timestamp += (1 << 22);
                        }
                        else
                        {
                            throw new FitException("FIT HrToRecordMesgBroadcastPlugin Error: Anchor event_timestamp is greater than subsequent event_timestamp. This does not allow for correct delta calculation.");
                        }
                    }
                    hrMesgTime.Add((double)(event_timestamp - hr_anchor_event_timestamp));

                    // Check if hrMesgTime is gt record start time
                    // and if hrMesgTime is lte to record end time
                    if ((hrMesgTime.CompareTo(record_range_start_time) > 0) &&
                        (hrMesgTime.CompareTo(record_range_end_time) <= 0))
                    {
                        hrSum += (long)hrMesg.GetFilteredBpm(j);
                        hrSumCount++;
                        last_valid_hr_time = new DateTime(hrMesgTime);
                    }
                    // check if hrMesgTime exceeds the record time
                    else if (hrMesgTime.CompareTo(record_range_end_time) > 0)
                    {
                        // Remember where we left off
                        hr_start_index        = hr_mesg_counter;
                        hr_start_sub_index    = j;
                        findingInRangeHrMesgs = false;

                        if (hrSumCount > 0)
                        {
                            // Update record heart rate
                            last_valid_hr = (byte?)System.Math.Round((((float)hrSum) / hrSumCount), System.MidpointRounding.AwayFromZero);
                            recordMesg.SetHeartRate(last_valid_hr);
                            messages.RecordFieldNames.Add("HeartRate");
                        }
                        // If no stored HR is available, fill in record messages with the
                        // last valid filtered hr for a maximum of 5 seconds
                        else if ((record_range_start_time.CompareTo(last_valid_hr_time) > 0) &&
                                 ((record_range_start_time.GetTimeStamp() - last_valid_hr_time.GetTimeStamp()) < 5))
                        {
                            recordMesg.SetHeartRate(last_valid_hr);
                            messages.RecordFieldNames.Add("HeartRate");
                        }

                        // Reset HR average
                        hrSum      = 0;
                        hrSumCount = 0;

                        record_range_start_time = new DateTime(record_range_end_time);

                        // Breaks out of looping within the event_timestamp array
                        break;
                    }
                }

                hr_mesg_counter++;
                hr_sub_mesg_counter = 0;
            }
        }
    }
Ejemplo n.º 2
0
        static void OnMesg(object sender, MesgEventArgs e)
        {
            Mesg msg = e.mesg;

            if (msg.Num == MesgNum.Record)
            {
                RecordMesg recordMesg = new RecordMesg(msg);
                Console.Write("Data,{0},record,", msg.LocalNum);
                if (recordMesg.GetTimestamp() != null)
                {
                    Console.Write("timestamp,{0},s,", recordMesg.GetTimestamp().GetTimeStamp());
                }
                if ((recordMesg.GetDistance() != null) && (recordMesg.GetDistance() != (uint)Fit.BaseType[Fit.UInt32].invalidValue))
                {
                    Console.Write("distance, {0:0.0}, m,", recordMesg.GetDistance());
                }
                if ((recordMesg.GetSpeed() != null) && (recordMesg.GetSpeed() != (ushort)Fit.BaseType[Fit.UInt16].invalidValue))
                {
                    Console.Write("speed,{0:0.000},m/s,", recordMesg.GetSpeed());
                }
                if ((recordMesg.GetCadence() != null) && (recordMesg.GetCadence() != (byte)Fit.BaseType[Fit.UInt8].invalidValue))
                {
                    Console.Write("cadence,{0},rpm,", recordMesg.GetCadence());
                }
                if ((recordMesg.GetEnhancedSpeed() != null) && (recordMesg.GetEnhancedSpeed() != (uint)Fit.BaseType[Fit.UInt32].invalidValue))
                {
                    Console.Write("enhanced_speed,{0:0.000},m/s,", recordMesg.GetEnhancedSpeed());
                }
                if ((recordMesg.GetHeartRate() != null) && (recordMesg.GetHeartRate() != (byte)Fit.BaseType[Fit.UInt8].invalidValue))
                {
                    Console.Write("heart_rate,{0},bpm,", recordMesg.GetHeartRate());
                }
                Console.Write("\n");
            }
            else if (msg.Num == MesgNum.Hr)
            {
                HrMesg hrMesg = new HrMesg(msg);
                Console.Write("Data,{0},hr,", msg.LocalNum);
                int count;
                if ((hrMesg.GetTimestamp() != null) && (hrMesg.GetTimestamp().GetTimeStamp() != (uint)Fit.BaseType[Fit.UInt32].invalidValue))
                {
                    Console.Write("timestamp,{0},,", hrMesg.GetTimestamp().GetTimeStamp());
                }
                if (hrMesg.GetNumFilteredBpm() > 0)
                {
                    Console.Write("filtered_bpm,");
                    count = hrMesg.GetNumFilteredBpm();
                    for (int i = 0; i < count; i++)
                    {
                        Console.Write("{0}", hrMesg.GetFilteredBpm(i));
                        if (i < count - 1)
                        {
                            Console.Write("|");
                        }
                    }
                    Console.Write(",bpm,");
                }
                if (hrMesg.GetNumEventTimestamp12() > 0)
                {
                    Console.Write("event_timestamp_12,");
                    count = hrMesg.GetNumEventTimestamp12();
                    for (int i = 0; i < count; i++)
                    {
                        Console.Write("{0}", hrMesg.GetEventTimestamp12(i));
                        if (i < count - 1)
                        {
                            Console.Write("|");
                        }
                    }
                    Console.Write(",,");
                }
                if (hrMesg.GetNumEventTimestamp() > 0)
                {
                    Console.Write("event_timestamp,");
                    count = hrMesg.GetNumEventTimestamp();
                    for (int i = 0; i < count; i++)
                    {
                        Console.Write("{0:G}", hrMesg.GetEventTimestamp(i));
                        if (i < count - 1)
                        {
                            Console.Write("|");
                        }
                    }
                    Console.Write(",s,");
                }
                if (hrMesg.GetFractionalTimestamp() != null)
                {
                    Console.Write("fractional_timestamp,{0:0.######},s,", hrMesg.GetFractionalTimestamp());
                }
                Console.Write("\n");
            }
        }