Skip to content

Add a CarPlay widget with Now, Alerts and 3 h pages - #830

Draft
MtlPhil wants to merge 2 commits into
loopandlearn:devfrom
achkars-org:pr/carplay-widgets
Draft

MtlPhil wants to merge 2 commits into
loopandlearn:devfrom
achkars-org:pr/carplay-widgets

Conversation

@MtlPhil

@MtlPhil MtlPhil commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

This builds on #829 and should be merged after it. The branch contains #829's commit (1e17855d, stale cue and status line) followed by the widget commit (d83620c6). Please review only d83620c6 here: the first commit is reviewed in #829. Once #829 is merged, this PR will show only the widget commit.

The widget reuses what #829 adds to GlucoseSnapshot: the override details (insulin needs and range) and the stale check.

A small widget for the CarPlay Widgets screen, also usable on the Home Screen (iOS 26 and later). A button in the corner steps through its pages:

  • Now: the reading, delta and the time of the reading, the loop values, and any running override as insulin needs, target range (the override's own, else the loop's current range) and end time, or ∞ with no end.
  • Alerts: only in the cycle while there is something to report.
  • 3 h: the last three hours against the target range.

Alerts

  • Alerts come from LoopFollow's alarms. Each alarm has a "Show in CarPlay" toggle, off by default, and is listed with LoopFollow's icon and wording.
  • Alarms about a state stay listed while it holds, including carbs on board and recommended bolus above their threshold. Alarms about an event stay listed for 15 minutes after they fire.

Clock times

  • Times on the widget and on the CarPlay Live Activity are clock times rather than ages or countdowns, so the text stays still while driving.

Refreshing

  • The app writes the widget's state after each alarm check and Live Activity refresh, and asks for a reload only when something shown has changed.
  • The system holds back reloads from an app in the background, so the app also sends a WidgetKit push, coalescing changes within 10 seconds into one.
  • Reload requests and pushes are logged at debug level under a new CarPlay log category.

Builders

  • The Live Activity extension now needs the Push Notifications capability and entitlement. The Fastfile adds it to the extension's identifier, so existing builders need to run "2. Add Identifiers" and "3. Create Certificates" again before building.

Tests cover which alarms are listed and for how long.

A Live Activity only redraws when an update reaches it, so with no network
or a stopped app it cannot show that its data is old. staleDate is now 12
minutes after the reading and is sent in update pushes, so iOS can flag the
activity without the app. Renewal relies only on laRenewBy and
laRenewalFailed, so stale data no longer replaces the activity when the app
opens; an activity with no stored deadline is still replaced, since it
could never renew.

The small family, shown on CarPlay and in the Watch Smart Stack:

- A stale reading is struck out in red, with the BG and arrow grey.
- A status line, on by default, shows the update time, IOB and COB (or Not
  Looping in their place) and any active override with its insulin needs,
  range and time left. While it is on, IOB, COB and Override are not
  offered for the right slot; a stored choice of one of them comes back
  when the line is turned off. Turning it off also restores the original
  font sizes.
- A Tight CarPlay Layout switch, off by default, replaces the right slot
  with projected BG, IOB, COB and basal, and centres the bottom row. No API
  tells CarPlay from the Watch, so it also needs a width of at least 205
  points: the 240-wide CarPlay layouts, not the 170-wide one.

Both switches explain themselves in an info button.
A small widget for the CarPlay Widgets screen, also usable on the Home
Screen (iOS 26 and later). A button in the corner steps through its pages:

- Now: the reading, delta and the time of the reading, the loop values,
  and any running override as insulin needs, target range (the override's
  own, else the loop's current range) and end time, or ∞ with no end.
- Alerts: only in the cycle while there is something to report.
- 3 h: the last three hours against the target range.

Alerts come from LoopFollow's alarms. Each alarm has a "Show in CarPlay"
toggle, off by default, and is listed with LoopFollow's icon and wording.
Alarms about a state stay listed while it holds, including carbs on board
and recommended bolus above their threshold; alarms about an event stay
listed for 15 minutes after they fire.

Times on the widget and on the CarPlay Live Activity are clock times rather
than ages or countdowns, so the text stays still while driving.

The app writes the widget's state after each alarm check and Live Activity
refresh and asks for a reload only when something shown has changed. As the
system holds back reloads from an app in the background, the app then also
sends a WidgetKit push, coalescing changes within 10 seconds into one. The
Live Activity extension gets the Push Notifications capability and
entitlement for this. Reload requests and pushes are logged at debug level
under a new CarPlay log category.
@MtlPhil
MtlPhil marked this pull request as draft November 10, 2026 13:16
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.

1 participant