How the prognosis service works
A six-stage pipeline that turns raw IoT telemetry into anomaly events, forecasts and drift alerts. All stages run on a scheduler; every one can also be triggered manually here.
1 · Data flow
Only assets explicitly enrolled from Management → Assets flow through this pipeline. New assets default to inactive after each registry sync.
What happens per minute
- derive reads new rows from master
historyfor enrolled assets and writes 1-minute aggregates intoderived_series. The kind of aggregate depends on the series classification (smooth → median; event-driven → baseline + spike-count/peak/area; sparse → median). - score compares each new bucket against the latest forecast — score is
(actual − q50) / max(q90 − q10, 1e-9). ≥SCORE_ANOMALOUS_THRESHOLD= anomalous, ≥SCORE_SUSPICIOUS_THRESHOLD= suspicious, else normal. - If a series stays anomalous for
ANOMALY_DEBOUNCE_BUCKETSconsecutive minutes, a new event opens. Maintenance mode on the asset suppresses opening but not scoring.
What happens every 15 minutes
- forecast regenerates a 24-hour quantile (q10, q50, q90) forecast for every active series. The previous forecast is superseded so charts always show the freshest one.
What happens every 5 minutes
- drift computes rolling MAPE / coverage per series, writes
forecast_health, logs a warning when >50 % of series drift simultaneously (usually upstream — clock skew or sensor outage).
2 · Scheduler
Single-process APScheduler. Jobstore lives in the prognosis DB so the worker can be split into its own container later without code changes.
history and write 1-minute buckets into derived_series. Advances the watermark in pipeline_state..env.forecast_health; log warnings on widespread drift.Scheduler control
loading…
Live state of APScheduler. Pause/resume affects only the running
process — restarting the app brings every job back from
register_jobs.
| Job | Trigger | Next run | Status | Actions |
|---|---|---|---|---|
| loading… | ||||
4 · Live job state (manual triggers)
Auto-refreshes every 3 s while jobs are running. This is GET /api/admin/jobs.
| Job | Status | Duration | Started | Finished | Result / error |
|---|---|---|---|---|---|
| no manual jobs run yet — click Run now above. | |||||
5 · On-demand forecast
Forecasts run automatically every 15 minutes for every active series. To force one immediately — for the entire asset fleet — click the button below. To regenerate a forecast for a single series, open the Dashboard, pick the parameter, and click Run forecast now.
6 · Where to tune things
FORECAST_BACKEND— defaults totimesfm(real model, ~2 GB checkpoint). Under-warmed series (fewer thanFORECAST_MIN_CONTEXTsamples) fall back tonaiveautomatically. Set the env var tonaiveto disable TimesFM entirely.SCORE_SUSPICIOUS_THRESHOLD/SCORE_ANOMALOUS_THRESHOLD— z-score gates. Lower = more sensitive.ANOMALY_DEBOUNCE_BUCKETS— how many consecutive anomalous minutes open an event. 2–3 is sensible.MAPE_DRIFT_THRESHOLD— when a series's rolling MAPE exceeds this, the drift score climbs.- Threshold per series — manual overrides via
POST /api/threshold/...are preserved across re-profiling (auto-thresholds usesource = 'auto'inON CONFLICT).