Import HRV4training data from Dropbox

I need to find a general solution to this. Likely custom wellness fields mapped to the various objects received from Garmin et al.

Any news on this? I added custom field “morning HRV” and have to manually paste rMSSD from HRV4Training.

I should probably just add a built in HRV field “HRV snapshot” and map snapshots to that.

3 posts were merged into an existing topic: Hrv4training results off by one day

Nice tips from many people about how to import data from third-party apps to intervals.

But the big picture is that these solutions are all hacks. I can’t believe it can be so complicated for hrv4training or elitehrv et al to implement one api getpoint: /hrvdata or something.

Lots of other apps and even government institutions provide api endpoints to get data. It’s more convenient that having users download these manually.

Yes I read what Altini wrote.

I’m getting my data from connect IQ apps, but the downside is that it has to create an activity. So then that inflates the number of activities by 7 each week, and also generates some clutter. Is there an API endpoint in intervals so I could maybe make a Cron job that deletes these activities after the hrv is populated?

Or is there a better solution?

I can’t even export the data from the Android version of Marco’s app. Anyone know why? It gives me an error message about not being able to write.

Sd card full?

Have you given HRV4Training the correct credentials for your Dropbox account?

1 Like

It won’t even let me get that far. Email export doesn’t work either.

Is there anyway I can plot a chart in intervals that would let me normalise the HRV against resting HR? Altini has a recent blog about when resting HR is suddenly lower due to calorie deficit you can normalize it against resting hr to get a better picture.

1 Like

Wellness metrics can’t be computed yet within Intervals.
You could get the data from the API, compute what you need in a local spreadsheet and then send it back through the API in a new custom wellness field that you can then plot on the Fitness page.
It’s similar to the result from I’mReady4, the app get’s the HRV data from the API, computes the training advice, and then sends it back to the API.

1 Like

Ah, thanks for confirming :slight_smile:

If I get an error message when attempting to export. I close the app, reopen and go straight to the export feature, then it seems to work. At least it does for me (Android 15)

1 Like

I asked them to fix this, and they dropped an update. Does it work for you now?

So far it seems to work. Thanks for raising the issue with Marco

1 Like

Absolutely :slight_smile:

@Everyday_Normal_Guy , I still seem to have the issue I mentioned above. It’s hit-and-miss if I can export the data after a measurement. In which case I need to close the app. re-open and then I can export.

Hello,
can someone help me!
I get this message and don’t know where and how I can see the data from HRV4 Training.
Thanks !!

Hi all,

I guess I had forgotten about the Dropbox functionality, so I created an R script that will merge data from the HRV4Training export into the Intervals.icu wellness export which can then be re-uploaded. The mapping is as follows.

  • HRV4Training Recovery Points → Intervals.icu Readiness
  • HRV4Training Training Motivation → Intervals.icu Motivation
  • HRV4Training Sleep Time → Intervals.icu Sleep Time
  • HRV4Training Sleep Quality → Intervals.icu Sleep Quality
  • HRV4Training Mental Energy → Intervals.icu Mood
  • HRV4Training Muscle Soreness → Intervals.icu Soreness
  • HRV4Training Fatigue → Intervals.icu Fatigue
  • HRV4Training Current Lifestyle → Intervals.icu Stress
  • HRV4Training Physical Condition → Intervals.icu Sickness

Some of the scales are reversed – either because the metrics are inversely related or because Intervals reversed the order (1-4). The HRV4Training fields also have to be converted as they are scored 1-10 and Intervals.icu uses 1-4.

I have the code set up so it only replaces empty values in the wellness file with HRV4Training data. Like many, I use HealthFit to upload a lot of metrics, and in some cases this data is superior, i.e., HRV4Training’s sleep data doesn’t include naps.

There is a “last_upload” variable at the beginning of the script that will allow you to limit how much data you send back up to Intervals. Of course, you would need to run the R script in a directory with the two csv’s (wellness.csv and hrv.csv). I’d recommend starting with recent dates to make sure it’s working for you. I just uploaded several years and it appears to have worked.

Please let me know if you find any errors. Thanks!

library(tidyverse)
library(janitor)
library(lubridate)

last_upload <- date("2025-03-23")

wellness <- read_csv("wellness.csv")
hrv <- read_csv("hrv.csv")

hrv <- hrv %>% mutate(
  new_date = date(date)
) %>% select(
  new_date,
  sleep_time,
  HR_lying,
  rMSSD_lying,
  HRV4T_Recovery_Points,
  sleep_quality,
  mental_energy,
  trainingMotivation,
  current_lifestyle,
  physical_condition,
  muscle_soreness,
  fatigue,
)

translate <- function(col) {
  col <- as.numeric(col)
}

scaled <- function(col) {
  col = case_when(
    col <= 2.5 ~ 1,
    col > 2.5 & col <= 5 ~ 2,
    col > 5 & col <= 7.5 ~ 3,
    col > 7.5 & col <= 10 ~ 4,
    .default = NA
  )
}

rev_scaled <- function(col) {
  col = case_when(
    col <= 2.5 ~ 4,
    col > 2.5 & col <= 5 ~ 3,
    col > 5 & col <= 7.5 ~ 2,
    col > 7.5 & col <= 10 ~ 1,
    .default = NA
  )
}

hrv[3:12] <- lapply(hrv[3:12],translate)
hrv[11:12] <- lapply(hrv[11:12],scaled)
hrv[6:10] <- lapply(hrv[6:10],rev_scaled)

hrv$sleep_time <- as.numeric(hms(hrv$sleep_time))
hrv$sleep_time[hrv$sleep_time == 0] <- NA
hrv$sleep_time[hrv$sleep_time > 50400] <- NA


wellness$restingHR[is.na(wellness$restingHR)] <- round(as.numeric(hrv$HR_lying[match(wellness$date, hrv$new_date)]),0)
wellness$hrv[is.na(wellness$hrv)] <- hrv$rMSSD_lying[match(wellness$date, hrv$new_date)]
wellness$readiness[is.na(wellness$readiness)] <- hrv$HRV4T_Recovery_Points[match(wellness$date, hrv$new_date)]
wellness$motivation[is.na(wellness$motivation)] <- hrv$trainingMotivation[match(wellness$date, hrv$new_date)]
wellness$sleepSecs[is.na(wellness$sleepSecs)] <- hrv$sleep_time[match(wellness$date, hrv$new_date)]
wellness$sleepQuality[is.na(wellness$sleepQuality)] <- hrv$sleep_quality[match(wellness$date, hrv$new_date)]
wellness$mood[is.na(wellness$mood)] <- hrv$mental_energy[match(wellness$date, hrv$new_date)]
wellness$soreness[is.na(wellness$soreness)] <- hrv$muscle_soreness[match(wellness$date, hrv$new_date)]
wellness$fatigue[is.na(wellness$fatigue)] <- hrv$fatigue[match(wellness$date, hrv$new_date)]
wellness$stress[is.na(wellness$stress)] <- hrv$current_lifestyle[match(wellness$date, hrv$new_date)]
wellness$Sickness[is.na(wellness$Sickness)] <- hrv$physical_condition[match(wellness$date, hrv$new_date)]

wellness <- wellness %>% filter(
  date >= last_upload & date < now()
)


write_csv(wellness,"for_intervals.csv",na="")
1 Like

Yeah, I thought they fixed it but alas no.

also, Marco never replied to me.

It works for me, when i close the app, reopen it and go straight to the export to dropbox feature