Repository navigation
Sync upstream Trio dev (902be75e8, 1.0.2.66) into Tai dev - #43
Merged
Merged
Conversation
Fix temp target percentages being truncated instead of rounded.
TidepoolService's uploadDoseData annotates doses through its remoteDataServiceDelegate and throws TidepoolServiceError.configuration when none is set. Trio never set one, so every dose upload failed on the pinned TidepoolService. BaseTidepoolManager now conforms to RemoteDataServiceDelegate and attaches itself whenever the service is created or restored. - getBasalHistory returns [] on purpose: with a non-empty history, TidepoolService hits a preconditionFailure for temp basals with unit .units, which is how Trio builds them. Empty leaves doses as Trio built them, including their scheduledBasalRate. - automationHistory applies the current dosing mode to the whole range (Trio sets `automatic` on every dose, so the overlay skips them). - fetchDeviceLogs returns []. Upload-only; dosing is unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SuGCnzpk8tfJPiA2Y6FRrX
Drop explanations that said Trio lacks device logs and dosing mode history, which it has. Keep one line on why getBasalHistory returns an empty array. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…elegate Fix Tidepool dose uploads failing with "configuration"
Fix basal rate editor saving the lowest rate on 0.01 U/h pumps
Fix percent rounding and unify percent formatting
Redact signed-out Dexcom Share accounts in export
Fix Medtrum crash loop and device delete races
# Conflicts: # Trio.xcodeproj/project.pbxproj # Trio/Sources/Modules/Adjustments/View/Overrides/AdjustmentsRootView+Overrides.swift # Trio/Sources/Modules/Adjustments/View/TempTargets/AdjustmentsRootView+TempTargets.swift
Fix duration translations and unify duration formatting
Wait for first unlock before opening Core Data
# Conflicts: # Trio/Sources/Helpers/TimeAgoFormatter.swift # Trio/Sources/Modules/Adjustments/View/Overrides/AddOverrideForm.swift # Trio/Sources/Modules/Adjustments/View/TempTargets/EditTempTargetForm.swift # Trio/Sources/Modules/BasalProfileEditor/BasalProfileEditorProvider.swift # Trio/Sources/Modules/BasalProfileEditor/BasalProfileEditorStateModel.swift # Trio/Sources/Modules/History/View/HistoryRootView+Treatments.swift # Trio/Sources/Modules/Home/View/Header/CurrentGlucoseView.swift # Trio/Sources/Modules/Home/View/HomeRootView+BottomControls.swift # Trio/Sources/Views/SettingInputSection.swift
The basal editor mapped the picker's value back to a rate index with a fixed-scale floor (rounded(scale: 3)). The picker round-trips through Double, so on a U10 grid with a 0.025 pump step 0.0425 came back as 0.0424999..., truncated to 0.042 and was floored to 0.04 - a silent ~6 % under-delivery that was then saved. Move roundBasal's nearest-rate rule (ties upward, zero seed) into Decimal.nearestSupportedBasalRate(in:), have roundBasal call it, and use it in updateFromTherapyItems so the editor resolves rates the way the algorithm does. Tests: a "Basal editor picker rate selection" suite in RoundBasalTests covering the U10 0.0425 regression, U10/U50 four-decimal rates, a round-trip sweep over 0.01/0.025/0.05/0.1 steps x four concentrations, and parity with roundBasal.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Sync upstream Trio dev (902be75, 1.0.2.66) into Tai dev
Brings Tai
devup to upstreamnightscout/Triodevat902be75e8— 32 upstream commits since the last sync base23bb3be36(1.0.2.59), reported upstream as 54 files, +709 / −500, plus three submodule pins. Merge commit on this branch:742f7a8d9(7f7642d8e+902be75e8).What changed
Device deletion is tracked asynchronously, and pump alerts stay on the delegate queue
LibreLoopdbe4f9cddandSyaiKitef0aed342both tear down on the main actor inside an asyncdelete(), andMedtrumKiteee17b0fcreports alert pump events on the delegate queue. On the Trio side,Trio/Sources/APS/DeviceDataManager.swiftsetspumpManager.delegateQueuebefore assigningpumpManagerDelegate, so no delegate callback can land on the default main queue while a device is being replaced or deleted.Medtrum: crash loop, alert queue and device delete races
Upstream fix (PR #1757) carried by the
MedtrumKitpin above: a device that fails while being deleted no longer re-enters the crash loop, alert pump events no longer race the deletion, and deleting a device mid-alert drains the queue instead of leaving orphaned callbacks.Dexcom Share account redacted in log exports
Trio/Sources/Logger/Export/SensitiveValues.swiftgainedadd(deviceLogMessage:): G7 logsSigned in to Dexcom Share as <account> (<server>)at sign-in, and after a sign-out that line is the only remaining record of the account.LogExportnow feeds every device log message through it, so the username is replaced with.accountin exported logs (upstream PR #1756).One formatter family for durations, time-ago and percentages
Trio/Sources/Helpers/Formatters.swiftreplaces the deletedTimeAgoFormatter.swift:Duration.formattedTimeSpan(_:locale:)with theSpanStylecases.exact(1d 1h 30m),.largestTwoUnits(2d 16h) and.minutes(90m), plusformattedSpokenTimeSpanfor VoiceOver (1 hour, 30 minutes). Spans round down and show< 1munder a minute.Date.formattedTimeAgo()reads the visible span (2d 16h, not64h) while stored override/temp-target durations keep their minutes —Duration(minutes: Decimal)clamps, because those values come from Core Data and Nightscout unchecked.FormatStylehelpers (wholePercent,oneDecimalPercent,upToOneDecimalPercent,upToTwoDecimalPercent, forDoubleandDecimal), so 0.8 renders80%with the locale's percent style instead of a hand-built string. They replace the ad-hoc percent formatting in the Home header, Stats charts, Adjustments, Autosens settings and settings export.%@%% Insulin→%@ Insulin, plus new keys for the spoken forms), so translators get whole phrases instead of span +ago.formatHrMin/formatHoursAndMinuteshelpers and theCGMSensorDisplayStatecountdown state are gone;AdaptProfileRootView(a Tai-only file) moved toformattedTimeSpan(.largestTwoUnits)in the same change.Basal rate editor rounding on 0.01 U/h pumps
Upstream PR #1674:
BasalProfileEditorProviderrounds the rate sent to the pump to three places after dividing by insulin concentration, andBasalProfileEditorStateModel.updateFromTherapyItemspicks the index vialastIndex(where: { $0 <= value.rounded(scale: 3) }). Previously a 0.01 U/h pump could silently save the profile's lowest rate.SMB/UAM minute labels and a translated override "Off"
The override and adjustment rows now render max SMB/UAM limits through
formattedTimeSpan(.minutes)(SMB 30m,UAM 60m) instead of a hand-concatenated\(minutes) min, with matching spoken labels, andSMBs Offgoes throughString(localized:)so the override row is translated (PRs #1743 follow-up + translation fix).Tidepool delegate and dose upload fixes
BaseTidepoolManagernow implementsRemoteDataServiceDelegate(remoteDataServiceDelegate = selfin thetidepoolServicesetter, upstream PR #1742): device logs are not uploaded, basal history returns empty on purpose — a non-empty history makesDoseEntry.annotated(with:)hit apreconditionFailurefor the.unitstemp basals Trio builds — and automation history reports the dosing mode. With the delegate in place, dose uploads stop failing with "configuration" (upstream #1740).Core Data waits for the first unlock
Model/CoreDataStack.swiftdistinguishes a protected-data failure (SQLITE_AUTH/ 23) from an ordinary lock and waits forprotectedDataDidBecomeAvailableNotificationinstead of burning its retry budget on 1-second sleeps. After a restart, a background launch before the first unlock no longer leaves the store uninitialized.Tests
Five upstream test files came along:
CoreDataProtectedDataTests,DurationFormattingTests,PercentFormattingTests,TidepoolTherapySettingsTestsand an extendedLogExportTests(redaction case).Sync mechanics
nightscout/Triodevat 902be75 (CI: Bump APP_DEV_VERSION to 1.0.2.66), 32 commits since merge base 23bb3be.7f7642d8e(Taidev, PR Sync upstream Trio dev (23bb3be36, 1.0.2.59) into Tai dev #42 merge) and902be75e8.LibreLoop0c90cd9a0→dbe4f9cdd,MedtrumKit1e761ef6a→eee17b0fc,SyaiKitd46674c54→ef0aed342. All 16 gitlink entries match upstream902be75e8;.gitmodulesis byte-identical to upstream (16 stanzas, noLoopAlgorithm).Config.xcconfig:APP_DEV_VERSION1.0.2.59 → 1.0.2.66 (Tai'sBUNDLE_IDENTIFIERunchanged).TimeAgoFormatter.swift— deleted (upstream removal).HistoryRootView+Treatments.swift— stays deleted (Tai had already consolidated History).AddOverrideForm— Tai'sstride(DecimalPickerSettings.overridePercentageMin…Max)+ upstream.formatted(.percent).EditTempTargetForm—(percentage/100).formatted(.wholePercent)slider labels,Duration(minutes:).formattedTimeSpan(), deadformatter/formattedPercentagehelpers removed.BasalProfileEditorProvider— combined.roundedDouble(toPlaces: 3).BasalProfileEditorStateModel— Tai'ssubscribe()(sortedRates.lastIndex(where:)) + upstream.rounded(scale: 3)inupdateFromTherapyItems.CurrentGlucoseView— Tai's header +formattedTimeAgo()/formattedSpokenTimeAgo(); spoken path usesformattedSpokenTimeSpan(.largestTwoUnits)because it feeds only the VoiceOver label.HomeRootView+BottomControls— Tai's multi-use panel with upstream's formatting internals (.wholePercent,.formattedTimeSpan(.largestTwoUnits), SMB/UAM.minutes,upToOneDecimalPercent), keeping upstream's(text:spoken:)tuples so the spoken accessibility labels survive.SettingInputSection— upstream.formatted(.wholePercent)with Tai's.factor/.factorRaw/.pickerSetting(for:)delegation.Tai-specific behaviour preserved
AutoISF*,Determination+AutoISF,OpenAPScolumns, autoISF settings/history modules — untouched by this range (OpenAPS.swiftchange is upstream's percent formatting only).GarminManager,GarminCommandRouter, WatchConfig views and tests) — untouched.taiCyan/taiOrange/taiTealcolours, Tai app icons,BuildDetails.plist.Testflight/: kept, see the checklist below.AdaptProfileRootView.swiftis the only Tai-exclusive file in the diff, and only itsformatHrMincall moved to the new span formatter.Not included
HistoryRootView.Verification
Independent review on card t_94d346f3 — verdict PASS at head
742f7a8d9, working tree clean:7f7642d8eis upstream's file set plus Tai'sAdaptProfileRootViewcleanup, with only the two upstream-deleted files (TimeAgoFormatter.swift,CGMSensorDisplayState.swift) removed.formattedSpokenTimeSpan, C8(text:spoken:)tuples) are documented, justified and test-green.project.pbxprojobject graph 2737 objects, 0 unresolved refs, 0 duplicate IDs; new test targets registered;LoopQuantitydelivery-limits port andnumberFormatterchart-axis formatters intact; no dangling references to the deleted helpers.xcodebuild build-for-testing -scheme "Trio Tests"— SUCCEEDED;test-without-building— TEST EXECUTE SUCCEEDED: 1213 tests / 152 suites passed (21.3 s, iOS 27.0 simulator,-parallel-testing-enabled NO).swift test --package-path AlgorithmPackagefails atxcstringstool generate-symbols— verified identically on baseline7f7642d8ein a fresh worktree, i.e. pre-existing Xcode 27.0 strictness on the localization catalog (12 duplicate-symbol keys + one%-ispecifier), not a merge regression. Tracked as separate cleanup work.git submodule statusclean, no+/-/Umarkers; pins match upstream902be75e8.Checklist before merge
Testflight/WhatToTest.en-CA.txtstill readsbased on Trio dev 1.0.0.5. It is not touched by this sync (kept as-is on purpose) — Robert bumps it to the1.0.2.66line when preparing the build.Algorithm Package (swift test)+Run Unit Tests).Screenshots
Not applicable — no Tai-side UI change is introduced by this sync; the UI changes listed above are upstream's own and are visible in the upstream PRs (#1743, #1756, #1757, #1672, #1674, #1742).