Skip to content

Release 0.7.6 - #220

Merged
this-Aditya merged 86 commits into
masterfrom
release-0.7.6
Oct 30, 2026
Merged

this-Aditya merged 86 commits into
masterfrom
release-0.7.6

Conversation

@this-Aditya

Copy link
Copy Markdown
Member

This release contains updates for the Google Health migration. It adds the new google-health-library with converters for the Google Health API data types, moves to radar-schemas 0.9.4, enables Maven Central publishing for the library, and includes security fixes. The library is published as org.radarbase:google-health-library:0.7.6.

Included PRs:

  • #200 Enable Maven Central snapshots and release publishing for oura-library and google-health-library
  • #213 Security fixes 2026-09-23
  • #199 Extract reusable Google Health code into google-health-library
  • #215 Write time fields for Google Health sleep and daily records
  • #201 Update converters as per new google health schemas
  • #206 Converters for the New Data Types: Floors, SedentaryPeriod, and ActivityLevels
  • #219 Write ECG result classification and HRV frequency powers, fix exercise speed
  • #217 Add civil times to Google Health ping intervals
  • #202 Add converters for ECG and IRN data, and update exercise data parsing

this-Aditya added 30 commits May 1, 2026 14:00

@yatharthranjan yatharthranjan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work aditya. please find some comments below. If some of these might take longer, we can proceed with the release and tackle in another PR+release.

import java.time.Instant

@JsonIgnoreProperties(ignoreUnknown = true)
data class GoogleHealthUser(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the fields are are non-null here. IIRC Upstream RestSourceUserDTO in Rest-Source-Auth declares all of them nullable.

this relies on the caller filtering on authorized=true. Make these fields nullable and filter after parsing, or perhaps just document the contract.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made it similar to how we do it for garmin, where GarminUser has all these fields non-null and it has been working fine, so I thought this would be fine too. Still, I've updated it now to handle null fields. The list is read into a new class, which has the nullable fields, and only complete users are processed, and incomplete users are skipped.
But I am keeping this class as non-null because it implements the User interface, which has a contract of non-null user fields.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok thanks

Comment thread google-health-library/build.gradle Resolved
Comment thread google-health-library/build.gradle Resolved
Comment thread gradle/libs.versions.toml Resolved
"Exercise data point has no name or dataPointName to derive a log id from " +
"for user=${user.versionedId}",
)
val activityId = idSegment.toLongOrNull()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you confirm this is always numeric? I think safer would be to just use a string here, that saves us from an error down the line if google ever changes this format (even if right now it is always numeric)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't mentioned in the docs for exercise, and they're inconsistent here. We take the id from the last part of the data point's name. I've tested it with real data and it was always numeric and fits in a long, the schema field is also already a long, should we keep it for now. If it didn't work in future we can update it by a new string field?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok sure, perhaps add a comment in code to remind us if it does ever happen

Comment on lines +87 to +94
this.beatsPerMinuteAvg = beatsPerMinuteAvg
this.samplingFrequencyHertz = frequency
this.millivoltsScalingFactor = scalingFactor
this.leadNumber = leadNumber
this.deviceModel = deviceModel
this.firmwareVersion = firmwareVersion
this.featureVersion = featureVersion
this.resultClassification = resultClassification

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a lot of these values are repeated across records. i wonder if it would be more efficient to just have a summary record and then these samples can be linked to that summary by the id ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is the better way, but if we do it now, it needs a new summary schema and topic, release, and then a new converter here. Is it okay if we do it in the next release?
ecg data also doesn't come often, only when the user explicitly takes a reading on the watch

@this-Aditya

Copy link
Copy Markdown
Member Author

Thanks yatharth, I've addressed the other points. For the ecg record and the exercise, I've noted them down and can we update them in the next release?

@yatharthranjan

Copy link
Copy Markdown
Member

ok thanks aditya. looks good. please add issues to track those.

@this-Aditya
this-Aditya merged commit 441e650 into master Oct 30, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants