Skip to content

Diagnose and skip rogue Nightscout profile records#635

Merged
marionbarker merged 2 commits into
devfrom
feature/remote-diagnostics-warnings
May 30, 2026
Merged

Diagnose and skip rogue Nightscout profile records#635
marionbarker merged 2 commits into
devfrom
feature/remote-diagnostics-warnings

Conversation

@bjorkert
Copy link
Copy Markdown
Member

@bjorkert bjorkert commented May 4, 2026

Summary

  • Switches the Nightscout profile fetch from /profile/current to /api/v1/profiles?count=1&find[startDate][$lte]=now, so future-dated records can no longer hide the active profile. /profile/current only sorts by startDate desc and ignores whether that date is in the past or future, which makes a single rogue upload (e.g. a phone with the wrong system clock) keep winning indefinitely. The find[] filter is the same query syntax already used for treatments, sage/iage/cage, BG data, and stats.
  • Adds a "Run diagnostics" button in the Remote Settings → Debug section. It fetches up to 1000 recent profile records and surfaces three known failure modes for remote commands:
    • Profile uploaded by a different app — when Loop and Trio share a Nightscout, profile uploads overwrite each other. Detected by checking which key path carries bundleIdentifier (Loop populates loopSettings.bundleIdentifier, Trio populates the top-level field) against Storage.shared.device.value.
    • Multiple devices uploading profiles — multiple installs (spare/old phones) each push their own deviceToken, causing APNS commands to fail intermittently. Detected by compressing consecutive same-token runs and warning when a token reappears (true alternation), not when tokens simply rotate (a→b→c stays silent). The warning lists each shift with timestamp and abbreviated from→to tokens, so the user can see which devices are competing.
    • Future-dated profile record found — informational only, since the new fetch already skips them; flagged because the rogue record still corrupts what Nightscout's own dashboard considers current and signals a broken phone clock somewhere.
  • Profile records are sorted by startDate with a fallback to created_at, so uploaders that omit startDate don't cluster at the start and corrupt the bouncing-tokens compression.
  • Results auto-scroll into view when the run completes (ScrollViewReader anchored to the diagnostics block).
  • Reuses existing helpers — NightscoutUtils.executeRequest/parseDate, the find[] parameter convention, dateTimeUtils.formattedDate(from:), the orange exclamationmark.triangle warning idiom from ImportExportSettingsView. No new abstractions.

Profile fetch now uses /api/v1/profiles?count=1 with find[startDate][$lte]=now,
so future-dated records can no longer block the active profile. Adds a
"Run diagnostics" button in the Remote Settings Debug section that fetches
14 days of profile history and surfaces three failure modes:

- Bundle ID mismatch when Loop and Trio share a Nightscout
- Alternating device tokens from multiple installations
- Future-dated profile records left over from a wrong-clock uploader

The bouncing-tokens check compresses consecutive same-token runs and only
warns on actual token alternation, not normal token rotation.
@bjorkert
Copy link
Copy Markdown
Member Author

bjorkert commented May 4, 2026

Image

@bjorkert
Copy link
Copy Markdown
Member Author

bjorkert commented May 4, 2026

6DA3B5E9-4D3A-46F2-80F3-A05700E672CA

Three changes to the profile diagnostics:

- Drop the 14-day find[startDate][$gte] filter. A slow A→B→A pattern
  spread across months only registers as one transition inside a 14-day
  window, so the bouncing-tokens check would silently miss it on servers
  that honor the filter. The existing 1000-record cap now defines the
  scope, which goes back as far as upload frequency allows.
- Fall back to created_at when sorting profile records, so uploaders
  that omit startDate don't cluster at .distantPast and corrupt the
  run-length compression.
- Include the chronological list of token shifts in the bouncing-tokens
  warning. Each row shows when the shift happened and the abbreviated
  from→to tokens, so users can see at a glance which devices are
  competing instead of just "3 tokens involved across N records".
@marionbarker
Copy link
Copy Markdown
Collaborator

Test

Build this version on my test phone

Test Trio and Loop both uploading

  • Configure LoopFollow to look at my Trio test Nightscout site
  • Make sure a Trio app is actively uploading to the site
  • Configure a Loop app to upload to the same site
    • Modify therapy settings on the Loop app to force a profile update
  • on LoopFollow phone, tap on Remote Settings,
    • even though I previously selected Trio Remote Control, I needed to select it again
    • scroll to the bottom and run diagnotics
    • ✅ get Profile uploaded by a different app message

Test two versions of Loop uploading

  • Configure LoopFollow to look at my Loop test Nightscout site, change Remote to be Loop Remote Control
  • One Loop test phone was already uploading to that site
  • Configure a second Loop test phone to also upload and then modify a therapy setting
  • on LoopFollow phone, tap on Remote Settings,
    • scroll to the bottom and run diagnotics
    • ✅ get multiple devices uploading profiles warning

Test future time

I don't want to do this test because it screws up the test phone. I'll examine the code instead.

Copy link
Copy Markdown
Collaborator

@marionbarker marionbarker left a comment

Choose a reason for hiding this comment

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

Approve from code review and test.

@marionbarker marionbarker merged commit ce983de into dev May 30, 2026
1 check passed
@marionbarker marionbarker deleted the feature/remote-diagnostics-warnings branch May 30, 2026 21:51
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.

2 participants