Skip to content

Automations - first roundtrip for forecasts#2290

Draft
Flix6x wants to merge 12 commits into
mainfrom
feat/2288-automations-for-forecasts
Draft

Automations - first roundtrip for forecasts#2290
Flix6x wants to merge 12 commits into
mainfrom
feat/2288-automations-for-forecasts

Conversation

@Flix6x

@Flix6x Flix6x commented Jul 11, 2026

Copy link
Copy Markdown
Member

Description

First roundtrip for automations (milestone 1 of #2288): recurring tasks defined per asset — for now, computing forecasts.

  • Data model: new Automation model (id, created_at, asset_id, type, name, cronstr, active, generator_id, parameters JSONB), with an __acl__ that lets account admins and consultants update/delete, and a migration. New dependencies: croniter (cron matching/validation) and cron-descriptor (natural-language recurrence descriptions).
  • CLI: flexmeasures add automation (active by default; validates parameters with the forecast parameter schema; stores the forecaster config on a data source), flexmeasures edit automation (name, cron string, activation status) and flexmeasures delete automation. All record to the asset's audit log.
  • Running automations: flexmeasures jobs run-automations queues forecasting jobs for all automations due this minute — to be run once per minute, e.g. via cron. A Redis-based guard prevents duplicate runs within the same minute.
  • Job provenance: data generators record how their queued jobs got created (CLI, API or automation) as job meta data; the status page's jobs table shows this in a new Created Via column.
  • API: GET /assets/<id>/automations (list, without generator/parameters) and GET /assets/<id>/automations/<automation_id> (details incl. parameters, generator info and job counts per status), documented in the OpenAPI specs.
  • UI: /assets/<id>/automations page with a tabbed view (Schedules and Reports tabs prepared but deactivated), listing Name, Created At (human-readable, ISO string in title tag), Active, Recurrence (human-readable, cron string in title tag), plus per-row job counts and a Details modal loaded asynchronously. Added to the breadcrumbs dropdown; links to the status page.

Look & feel

See the new Automations page under an asset's breadcrumbs dropdown.

How to test

flexmeasures db upgrade
flexmeasures add automation --asset <id> --name "Daily PV forecasts" --cron "0 6 * * *" --sensor <sensor-id>
flexmeasures jobs run-automations  # run once per minute via cron

Tests: pytest flexmeasures/cli/tests/test_automations.py flexmeasures/api/v3_0/tests/test_automations_api.py flexmeasures/ui/tests/test_asset_crud.py

Further Improvements

Per #2288: schedules and reports as automations, CRUD for automations in the UI (POST/PATCH/DELETE endpoints).

Closes #2288

🤖 Generated with Claude Code

https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX

Flix6x and others added 7 commits July 11, 2026 15:06
Automations are recurring tasks (for now: computing forecasts) defined per
asset. The recurrence is defined by a cron string, and the work to be done
is defined by a data generator (linked through a data source) together with
the parameters to call it with.

Includes a migration for the new table, and new dependencies on croniter
(cron matching/validation) and cron-descriptor (natural-language recurrence
descriptions).

Part of #2288

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
- `flexmeasures add automation` creates an automation (active by default),
  validating the forecast parameters with the forecast parameter schema and
  storing the forecaster config on a data source.
- `flexmeasures edit automation` edits the name, recurrence (cron string)
  or activation status.
- `flexmeasures delete automation` deletes an automation.
- All three record their events in the asset's audit log.
- `flexmeasures jobs run-automations` queues jobs for all automations due
  this minute (to be run once per minute, e.g. via cron), with a Redis-based
  guard against duplicate runs within the same minute.

Part of #2288

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
Data generators can now be told how their queued jobs got triggered (via the
CLI, the API or an automation), and the train-predict pipeline stores this
on the jobs as meta data. The asset's status page shows it in a new
'Created Via' column of the jobs table.

Part of #2288

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
GET /api/v3_0/assets/<id>/automations lists the automations defined on an
asset (without generator and parameters details). GET
/api/v3_0/assets/<id>/automations/<automation_id> additionally provides the
parameters, data generator info and counts of recently created jobs per job
status. Both are documented in the OpenAPI specs.

Part of #2288

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
/assets/<id>/automations shows the asset's automations in a tabbed view
(schedules and reports tabs are prepared but deactivated), with per-row
details (parameters, data generator, job counts) loaded asynchronously into
a modal. The page is linked in the breadcrumbs dropdown and links to the
status page, where recent jobs are listed.

Part of #2288

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
Part of #2288

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
Part of #2288

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
@socket-security

socket-security Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedcron-descriptor@​2.1.0100100100100100

View full report

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
Flix6x and others added 3 commits July 11, 2026 16:09
CI runners have no locale set (POSIX), which made cron-descriptor render
'At 06:00' while dev environments with an en_US-style locale rendered
'At 06:00 AM'. Request 24-hour format explicitly so the description is
deterministic across environments.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Pxkeq64jtENY7fiWjwUsVS
- Escape automation names (and other user-controlled strings) in the
  Automations page and the status page's jobs table, closing two stored
  HTML/script injection sinks.
- Wipe parameter state on the (possibly shared) cached data generator before
  each automation run, so automations sharing a generator data source don't
  pollute each other's runs.
- Count automation job stats under the forecast target sensor(s) from the
  automation's parameters, which may belong to a different asset.
- Release the per-minute Redis guard when a run fails, so a retry within the
  same minute can still queue jobs.
- Return 404 (as documented) for nonexistent automation ids on the detail
  endpoint, and check permissions on the asset, so automation ids can no
  longer be enumerated across accounts via 403-vs-422 differences.
- Use ondelete=SET NULL for the generator FK: deleting a data source no
  longer silently deletes automations.
- Delegate Automation ACL to the asset's ACL instead of duplicating it.
- Extract the config/parameters assembly shared by `add forecasts` and
  `add automation` into a helper (which no longer drops falsy config values).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
Completes the previous commit, whose staged files were dropped by an
interrupted pre-commit run: template escaping, shared-generator state reset,
job stats under target sensors, Redis guard release on failure, 404 for
nonexistent automations, SET NULL generator FK, ACL delegation, and the
shared CLI config/parameters assembly helper.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
…essage format

PR #2303 makes click report the validation message rather than the offending
value, which changes the exact wording of this error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rbix8k1JfeUWNXEmHEZVpX
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.

Automations - first roundtrip for forecasts

1 participant