Skip to content

Look ahead the full predictive low window - #751

Open
bjorkert wants to merge 3 commits into
devfrom
fix/predictive-lookahead-horizon
Open

bjorkert wants to merge 3 commits into
devfrom
fix/predictive-lookahead-horizon

Conversation

@bjorkert

Copy link
Copy Markdown
Member

Supersedes #732 by @JustMaier. His commit is carried over unchanged, followed by the follow-up commit proposed in his fork and a merge of current dev so the required SwiftFormat check can run. The fork is organization-owned, so GitHub cannot grant maintainer edits on the original PR branch.

Summary

The predictive low alarm looks ahead one 5-minute step less than the setting says. A 20-minute setting behaves like a 15-minute one, a 15 like a 10, and so on at every value.

The forecast series that LowBGCondition walks starts at the current glucose value. Both backends build it that way: DeviceStatusLoop stamps prediction[0] at lastLoopTime, and the OpenAPS predBGs curves all begin at the cycle's own bg. Looking predictiveMinutes ahead therefore takes ceil(predictiveMinutes / 5) + 1 points, and the alarm now examines exactly that many.

The horizon arithmetic lives in one place, LowBGCondition.forecastPoints(forMinutes:), and alarmForecastPointCap derives from it using the editor's 60-minute maximum, so the longest setting the editor offers can actually be satisfied.

For every value the UI allows, the corrected look-ahead fires on the same cycles the previous code fired on at the next setting up. Anyone who prefers their current behaviour can select one step lower and get it back exactly. Users who leave the setting alone will see more predictive alerts, and the added far-horizon alerts are less precise than the near ones. See #732 for the replay figures behind that tradeoff.

For the Trio path, lowestForecast takes the longest of the four forecast curves so one curve running short does not shorten the look-ahead.

Tests cover the boundary in both directions, a horizon longer than the published series, and the case where one of the four forecasts runs short.

JustMaier and others added 3 commits July 28, 2026 17:19
The forecast series starts at the current glucose value rather than the
first future point, so iterating ceil(predictiveMinutes / 5) entries
stopped one step short of the requested horizon. A 20-minute setting only
reached 15 minutes ahead, and a 15-minute one reached 10. At every
setting the dial behaved as though it were one notch lower.

Take one more point so the setting matches its label, and raise the alarm
forecast cap from 12 points to 13 so the 60-minute maximum is reachable
instead of capping at 55.

loopHorizonReachesRequestedMinutes is the regression test: the dip sits at
index 4, so a 20-minute look-ahead has to reach it and a 15-minute one
must not. The other added cases cover bounds safety when the horizon
exceeds the published series and pin the existing behaviour of following
the longest forecast rather than the first to run out.
LowBGCondition owns the horizon arithmetic: forecastPoints(forMinutes:)
converts a look-ahead in minutes into a point count, and
maxPredictiveMinutes is the longest look-ahead the alarm editor offers.
Both alarmForecastPointCap and the editor's Predictive stepper range
derive from these, keeping the formula, the cap, and the UI bound in
step.

trioShortForecastKeepsHorizon keeps every combined point before index 5
above the threshold, so its assertion holds only when the 25-minute
look-ahead reaches the full horizon. loopSinglePointForecast pins both
sides of the current-value convention: a lone high point stays silent
and a lone low point fires.
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