Computed activity fields

But I don’t want to loose al the intervals that I fixed

Ok, I’ve just saw that I can keep the existing intervals, tnx :stuck_out_tongue:

2 Likes

The fit file session field name is now a drop down that auto populates with the names of all the fields in the file session message:

4 Likes

WoW!!!

1 Like

I’ve tried a little bit to add a custom field but so far have failed. To be fair, I don’t really know how to start anyway.

I want to show the best 20min Power of the activity. And another field with best 20min Heartrate. And maybe other durations as well.

Is this possible?

Yes both of those are easy. I started with ActivityJsData from the server side data model and then looked at JsHRCurve and JsPowerCurve.

Best 20m power:

{
  icu.powerCurve.getWatts(20 * 60)
}

Best 20m HR:

{
  icu.hrCurve.getBpm(20 * 60)
}

Thanks,this works great!
That was so much better then what I was trying to do by calculating it of of the HR and Power streams myself.

1 Like

Hi!
When I use custom stream with “left_power_phase” record field, I successfully get the start angle. But this record field contains two values - start and end angle and I can’t use the second one. left_power_phase[1] give me none, preprocess fit file not helped.
Sorry for bad English.

You need to use Javascript to do that and not the record field. Tick the “Processes fit file messages” box and use a script like this:

{
  for (let m of icu.fit.record) {
    let lpp = m.left_power_phase?.value
    if (lpp) {
      let v = lpp[1] - lpp[0];
      console.log(lpp + " v = " + v);
      data.setAt(m.timestamp.value, v);
    }
  }
}

I am not sure what you want to do with the 2 degree values. Here I have just subtracted one from the other.

Thank you very much!
That’s exactly what I need. With two degree values I can calculate arc length of power phase and arc length of peack power phase in graphic view on part of the ride, not average of all the ride like Garmin.

1 Like

I love this feature, but so far have just been using it for computation at the Activity (summary) level. Is there a way to create a calculated field that appears on the charts in the Fitness tab - basically a “streaming metric” ? For example, I’d like to calculate the purple line divided by the blue line, and have the result of that calculation appear on this chart. Is that possible?

Tx. Yes, almost. You can create a custom activity field computed from your streams and plot that on the /fitness page. If you have only one activity per day that will work fine. If there is more than one activity for the day you can control how the values get merged:

1 Like

When using a computed activity field with a conversion (for example m/s to some other unit) it works as it should on activity level. But when used on the compare page it shows the “raw” value (same for fitness page). Is there any way to work around this?

See following screenshots as illustration.

I have fixed this for the compare and fitness pages. The axis ticks and marker value are now formatted correctly. Tx for the report.

I just noticed!

Great work!

1 Like

Can you also create an activity field based on an aggregation of intervals data?
I’m trying to calculate the freestyle distance and pace on my swim activities (using the IntervalSwimStroke by @raviabram at interval level)

Yes you can do that. Custom activity fields that reference the icu_intervals property on activity are evaluated twice. Once before custom interval fields and once after. So custom interval and activity fields can reference each other.

2 Likes

Thanks David, with your advice I could make it work!

1 Like

I want to capture the first value from multi-value field available in device_info.

lets say my test fit file column have multi value like these:

70
69

either using device_info.field or device_info.field[0], always gives me 69, I need to pull 70, any ideas?

thanks

You need to tick the “Processed fit file messages” box and use a script:

{
  let level
  for (let di of icu.fit.device_info) {
    if (di.manufacturer?.value !== 23 /* Suunto*/) continue
    console.log("di " + di)
    let v = di.battery_level?.value
    if (typeof v === 'number' && (!level || v < level)) level = v
  }
  level
}

In this case I have chosen the lowest value. The console log looks like this:

di timestamp(s)=1075909291,battery_voltage(V)=4.05078125,battery_level(%)=70,manufacturer=23,product=59,product_name=Suunto Vertical
di timestamp(s)=1075909479,battery_voltage(V)=4.05078125,battery_level(%)=69,manufacturer=23,product=59,product_name=Suunto Vertical
di timestamp(s)=1075912229,battery_voltage(V)=4.03125,battery_level(%)=68,manufacturer=23,product=59,product_name=Suunto Vertical
1 Like