Skip to content

Feat: automations page improvements - #2554

Open
BelhsanHmida wants to merge 25 commits into
mainfrom
feat/automations-page-improvements
Open

BelhsanHmida wants to merge 25 commits into
mainfrom
feat/automations-page-improvements

Conversation

@BelhsanHmida

@BelhsanHmida BelhsanHmida commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Description

  • Say how far off each next run is (in 6 minutes, in 4 hours, tomorrow), with the exact clock time, its timezone and its recurrence on hover — addressing the review comment on CRUD for automations in the API and UI #2294.
  • Phrase future moments as in 6 minutes rather than 6 minutes from now, matching how the shared helper already phrases tomorrow and in 4 days. Every other caller renders a past moment, so only this column changes wording.
  • Read Created At on the automation's own clock too, so a row mixes no timezones.
  • List the automations of sub-assets by default, naming the owning asset in a column that links to its own page, with a switch to narrow the listing that is remembered per session.
  • Take include-child-assets=false on [GET] /assets/(id)/automations, and on [GET] /assets/(id)/jobs likewise, to list only what belongs to the asset itself.
  • List the automations and jobs of only those assets below which the user may read: a child asset can belong to another organisation than its parent.
  • Move the endpoints that store a user's choices in the UI in their session out of the official v3 API, into /api/dev/session/..., with kebab-case paths and fields. That includes the two that already existed (default_asset_view, keep_legends_below_graphs) and the status page's two.
  • Address every per-automation request at the asset that owns the automation, so Info, Run now, Edit, Activate/Deactivate and Delete work on a sub-asset's row.
  • Keep the listing up to date about once a minute, without a manual reload, holding off while the tab is in the background or a panel is open.
  • Rename the per-row Details button to Info, and lay its panel out left-aligned with a scrolling configuration block.
  • Report the data generator's configuration as config on the automation's source, and show it in the Info panel under the data source it describes.
  • Let a new forecast or report automation be given its generator and that generator's configuration on creation, which the API and CLI already accepted but the form did not send.
  • Drop (UTC) from the Info panel's cursor heading, which CRUD for automations in the API and UI #2294 began rendering in the automation's own timezone.
  • Added changelog item in documentation/changelog.rst

Look & Feel

The listing, reaching below the asset

toy-building has no automations of its own; all seven belong to toy-solar below it. The Asset column links to each owning asset, Next run says how far off each run is, and Updated just now says how current the listing is.

01-listing-with-sub-assets

The same page, narrowed to the asset itself

The switch is remembered for the next visit, and the Asset column goes away with it.

02-listing-narrowed

Hovering a Next run or Created At cell gives the precise moment on the automation's own clock, together with the recurrence that produced it:

Europe/Amsterdam: 17 Sept 2026, 05:00 GMT+2 (0 5 * * *)

The Info panel, with the data source's configuration

The configuration sits under the data source it describes, because it is what separates this source from another of the same model. This automation forecasts with a future regressor on day-ahead prices and a past regressor on the battery, so it records under a data source of its own, and Reads from lists both regressors.

03-info-panel-with-config

Creating a forecast automation with a configuration

04-create-form-forecasting

The same form, for a schedule automation

A schedule automation's generator follows from the asset and its flex config, so it is not offered one.

05-create-form-scheduling

The row's Actions menu

06-actions-menu

A read-only viewer, on an unowned asset

No Actions menu and no New automation button, but the Info panel still opens.

07-read-only-view

How to test

uv run pytest flexmeasures/ui/tests/ flexmeasures/api/v3_0/tests/

Results: flexmeasures/ui/tests/ 146 passed, flexmeasures/api/v3_0/tests/ 514 passed.

New tests:

  • flexmeasures/api/v3_0/tests/test_automations_api.py — a sub-asset's automation is listed and names its asset, include_child_assets=false narrows the listing, and the data source reports the configuration it was created with.
  • flexmeasures/api/v3_0/tests/test_assets_api.py — posting the page's scope records it in the session, next to the same test for the status page's job scope.
  • flexmeasures/ui/tests/js/test_automation_actions.py — the page's row builder, run against the real shared time helper: the six-minute case, the tooltip, the fallback beyond a week, that sorting still runs on the moment rather than on the words, the Created At clock, and the Asset cell.
  • flexmeasures/ui/tests/test_asset_crud.py — the rendered page's columns, scope parameter, refresh timer, Info button and configuration fields.

Each new test was confirmed to fail with the behaviour it covers removed.

Manual verification used a local instance whose toy-buildingtoy-solar tree carries automations across Europe/Amsterdam, UTC, Asia/Seoul and Pacific/Auckland, including DST gap and fold cases:

  • The relative phrasings and their tooltips, and the fallback to the schedule's clock beyond a week.
  • The scope switch, its effect on the columns, and its persistence across a reload.
  • The Info panel on a sub-asset's automation, which is what surfaced the 404s.
  • A refresh picking up both a rename made directly in the database and a newly queued job, while holding the sort the user had chosen.
  • Creating a forecast automation with regressors through the form, and confirming it records under a data source of its own.
  • A read-only viewer on an unowned asset.

Further Improvements

  • A configuration cannot be edited after creation, matching the API. Changing it would repoint the automation at a different data source, split its output history across two sources, and need the creator's sensor permissions checked afresh — the same reasoning that keeps parameters frozen. A Duplicate with changes action would serve the same need without any of that.
  • Refreshing costs the same requests a manual reload always has, one per automation for the job counts. A bulk endpoint for those counts would cut it, if a large asset ever makes it felt.
  • Let plugins define automation types backed by data generators #2530 also changes this create form, limiting it to built-in types. The fields added here serve forecasting and reporting, both built-in, so the two should compose; whoever merges second should check.

Related Items

Follows up on #2294.


Sign-off

  • I agree to contribute to the project under Apache 2 License.
  • To the best of my knowledge, the proposed patch is not based on code under GPL or other license that is incompatible with FlexMeasures

…me on hover

Context:
- Review of #2294: the next run time can be displayed in more human form,
  like "in 6 minutes", "in 4 hours" or "tomorrow", as other pages already do.
  The precise date and time is still needed, but belongs on hover.

Change:
- Render the next run with getHumanFriendlyDeltaOrTimeStr, the helper the Created At
  column and the status and user pages already use.
- Move the precise time to the tooltip, on the automation's own clock, next to the
  timezone and the cron recurrence that produced it.
- Phrase future moments as "in 6 minutes" rather than "6 minutes from now", matching
  how the same helper already phrases "tomorrow" and "in 4 days". Every other caller
  renders a past moment, so only this column changes wording.
- Give the helper an options.fallback, and pass the schedule-clock time: beyond a week
  there is no useful relative phrasing left, and the old fallback dated the run by the
  viewer's clock rather than by the clock the automation keeps.
- Drop "(local)" from the column heading, which no longer describes what the cell shows.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- The Created At cell showed a friendly delta, but hovering it produced the raw stored
  timestamp in UTC, which is neither precise-looking nor the clock the rest of the row keeps.

Change:
- Spell the creation moment out in the automation's timezone on hover, as the next run
  already does, so a row mixes no clocks.
- Fall back to the same schedule-clock wording once the automation is older than a week,
  rather than dating it by the viewer's own timezone.
- Keep the stored timestamp as the tooltip when the timezone cannot be resolved.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- "Details" reads like a second Actions menu next to it, while the button only ever opens
  a read-only panel about one automation.

Change:
- Label the button Info, and rename the class, modal ids, row key and loader that name it,
  so the code reads the same as the page.
- Note that DataTables' own info option is its record count, not this column.
- Say "Could not load this automation's info" when that panel fails, matching the button.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- The automation endpoint named the data source but said nothing about how its data generator
  was set up, so the forecaster's model, training period and regressors were invisible
  to anyone reading an automation.

Change:
- Include the data generator's stored config with the source it belongs to.
  The config is what separates one data source from another of the same model,
  so it is reported alongside the source rather than as a field of its own.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- The Info panel named the data source but not the settings it was created with,
  so a reader could not tell which model an automation forecasts with, or over what training period.

Change:
- Read the configuration under the data source it describes, since it is what separates
  this source from another one of the same model.
- Say so plainly when a source records no configuration, rather than showing an empty block.
- Rename the heading from "Data generator" to "Data source", the term the rest of the panel uses.
- Left-align preformatted blocks, which the centred modal text left hanging in mid-air.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- Automations are usually defined on a sub-asset, so a site asset's automations endpoint
  reported nothing, even while plenty ran below it.
- The status page already solved the same problem for jobs, in #2500.

Change:
- Include the automations of the asset's descendants by default, and let
  include_child_assets=false narrow the listing to the asset itself, as [GET] /assets/(id)/jobs does.
  Whoever may read an asset may read its descendants, too, as a child asset belongs to the same account.
- Name the owning asset in each entry, so a listing spanning several assets stays readable.
- Add an endpoint that remembers the user's choice of scope in their session,
  next to the one the status page uses for its own toggle.
- Regenerate the OpenAPI spec.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- Automations tend to be defined on a sub-asset, so the page of a site asset looked empty
  even while plenty ran beneath it, and there was nowhere to see it all at once.

Change:
- List the automations of sub-assets by default, and name the owning asset in a column
  that links to its own automations page. The column appears only while the listing spans
  more than one asset.
- Offer the scope as a switch, but only on an asset that has children, and remember the choice
  for the next visit. This mirrors the status page's "Include jobs of sub-assets".
- Address every per-automation request at the asset that owns the automation, not at the page's
  asset. Info, Run now, Edit, the activation toggle and Delete all answered 404 on a sub-asset's
  automation otherwise, since those endpoints check that the automation belongs to the asset named.
- Rebuild rather than redraw the table when the scope changes, as the columns change with it,
  and order by where Created At actually sits, now that a column can precede it.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- Runs happen, and jobs change state, while the page sits open. Until now the only way
  to see any of it was to reload by hand, and nothing on screen said how old it was.

Change:
- Fetch the listing again about once a minute, and put the fresh rows into the tables that
  already stand, so the sort the user chose and the place they scrolled to both survive.
- Hold off while the tab is in the background, and catch up as soon as it comes back.
- Hold off while a panel or menu is open, so a refresh never shuts something being read,
  and never let two refreshes overlap.
- Say when the listing last came from the server, re-wording that stamp between refreshes,
  since "2 minutes ago" goes stale with no new data.
- A refresh costs the same requests a manual reload always has, one per automation for the
  job counts. A bulk endpoint for those counts would be the way to cut it, if a large asset
  ever makes it felt.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- The automations endpoint learned to report what runs below an asset, and to describe
  the data source's configuration, and the automations page learned to remember its scope.

Change:
- Check that a sub-asset's automation is listed and names its own asset, that
  include_child_assets=false narrows the listing back to the asset itself,
  and that the data source reports the configuration it was created with.
- Check that posting the page's scope records it in the session, next to the same
  test for the status page's job scope.
- Each was confirmed to fail with the behaviour it covers removed.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
… a row is

Context:
- The next run is now phrased as a delta with the clock time on hover, Created At is read
  on the automation's own clock, and a row can belong to a sub-asset.

Change:
- Exercise the page's row builder against the real shared time helper, loaded the way the
  page loads it, rather than against a stand-in that could drift from it.
- Check the six-minute case the review asked for, the hover that carries the precise time,
  timezone and recurrence, the fallback to the schedule's clock beyond a week,
  and that sorting still runs on the moment rather than on the words.
- Check that Created At is read on the automation's timezone, using a moment that falls on
  a different date there than in UTC.
- Check that a row names and links the asset its automation is defined on.
- Fail the script helper loudly on an unrendered Jinja value: the two added for the scope
  reached the browser as a syntax error, which reads as every check failing at once.
- Each was confirmed to fail with the behaviour it covers removed.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- The page reaches below the asset, tells the time in relative terms, keeps itself current,
  and reports the data source's configuration.

Change:
- Describe the sub-asset scope and the query parameter that narrows it.
- Describe the relative next run, what hovering gives, and the clock both time columns read on.
- Mention that the page refreshes itself, and when it holds off.
- Rename "details" to the Info panel, and say it carries the data source's configuration.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- The page follows up on #2294 with relative run times, a scope reaching below the asset,
  a self-refreshing listing, and a renamed Info panel that carries the data source's config.

Change:
- Add a bullet to the automations detail list in the main changelog, beside the #2294 entry.
- Open v3.0-38 in the API change log, for the new query parameter, the config on an
  automation's source, and the endpoint that remembers the page's scope.
- The PR number is not known yet, so the main changelog entry links to PR #XXXX.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- test_asset_page pins the page's rendered script, and still expected the "Next run (local)"
  column heading and the precise time in the cell.

Change:
- Expect the renamed column, and the delta the cell now renders.
- Also pin the scope parameter, the refresh timer, the Info button and the data source's
  configuration, so this test keeps covering what the page grew.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
…he cursor UTC

Context:
- Every automation's modal is part of its row, so it sits inside the centred Info cell and
  inherited that centring: headings, values and JSON all sat in the middle of a wide panel.
  Left-aligning only the preformatted blocks had made the mismatch plainer, not better.
- The panel still labelled the cursor UTC, though #2294 began rendering it in the automation's
  own timezone. The value on screen read "+02:00" under a heading saying UTC.

Change:
- Left-align the panel, and set each heading as a small caption above the value it labels.
- Give preformatted blocks a quiet background and a height to scroll within, so a long
  forecaster config no longer pushes the sensors and parameters out of view.
- Drop "(UTC)" from the cursor heading, and say on hover which clock it is read on.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- The panel labelled the cursor UTC while rendering it in the automation's own timezone,
  and this test pinned the wrong label.

Change:
- Expect the heading without "(UTC)", and guard against the old label coming back.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
…created

Context:
- The API and `flexmeasures add automation` both accept a forecaster `config` and a
  `data-generator`, but the New automation form sent neither, so a forecast automation made
  in the UI always got the default forecaster: CustomLGBM over P30D, with no regressors.
- The Info panel now shows that configuration, which made the gap plainer: you could read a
  training period you had no way to set.

Change:
- Offer a Data generator field and a Configuration (JSON) field, and send each only when filled,
  so leaving them empty still means the API's own defaults.
- Show both only for a forecast automation: a schedule automation's generator follows from the
  asset and its flex config rather than being chosen.
- Say in the field's help that these settings decide which data source the results record under,
  and that they cannot be changed afterwards.
- Report malformed JSON with the field's name and the parser's message, for the configuration
  as well as the parameters, rather than the bare "not valid JSON" the parameters gave.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- The form now offers a data generator and a forecaster configuration, for forecast automations only.

Change:
- Pin the fields, the payload lines that send them, and the toggle that hides them for a
  schedule automation. Pinning only the parsing passed with the sending removed, so the
  assertions name the payload.
- Confirmed to fail with the configuration left out of the request.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- Eight commits landed on main since this branch was cut, several of them on the very page
  and endpoints it changes.

Change:
- Take main's rename of the Recurrence timezone column, and this branch's renamed Next run.
- Keep the extracted column list, which the scope needs, rather than main's inline one.
- Keep loadAutomations over main's inline fetch, and pull the type list into AUTOMATION_TYPES,
  so that reporting, which #2297 added, is listed on both the success and the error path.
  Two separate literals is how it came to be missing from one of them.
- Keep one set of the data generator and configuration fields. Main added its own while this
  branch added a second, and neither conflicted textually, so the merge had kept both: duplicate
  element ids, and duplicate keys in the create request.
- Offer those fields for reporting as well as forecasting, since a report automation also runs a
  generator the creator configures; only a schedule automation derives its own.
- Read the request's generator from the gated value, so a schedule automation no longer sends
  whatever a hidden field was left holding by an earlier choice of type.
- Keep both sides' changelog entries, and main's console.error on a failed listing.

The branch's own diff against main is unchanged but for those resolutions:
the same eleven files, with asset_automations.html and test_asset_crud.py accounting for the rest.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Context:
- The entry was written before the pull request existed, so it linked to a placeholder,
  and it predated the configuration fields on the New automation form.

Change:
- Link to PR #2554.
- Say that a new forecast or report automation can be given its generator's configuration
  from the form, not only through the API and the CLI.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
@BelhsanHmida
BelhsanHmida marked this pull request as ready for review September 17, 2026 01:31
@Flix6x Flix6x linked an issue Sep 17, 2026 that may be closed by this pull request
@Flix6x Flix6x added this to the 1.1.0 milestone Sep 17, 2026
@Flix6x
Flix6x self-requested a review September 17, 2026 08:55

@Flix6x Flix6x left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll do a pass at this with Claude now.

Comment thread documentation/api/change_log.rst Outdated
Comment thread documentation/api/change_log.rst Outdated
""""""""""""""""""""""""""""
- ``GET /api/v3_0/assets/<id>/automations`` now lists the automations of the asset's child assets as well, so that a site asset reports everything that runs below it, and each entry names the asset it is defined on in ``asset`` and ``asset-name``. Pass ``include_child_assets=false`` to list only the automations defined on the asset itself. Whoever may read an asset may read its descendants, too, as a child asset belongs to the same account as its parent.
- ``GET /api/v3_0/assets/<id>/automations/<automation_id>`` now reports the data generator's stored configuration as ``config`` on the automation's ``source``, such as the model a forecaster trains and the period it trains over. The configuration is what separates one data source from another of the same model.
- Added ``POST /api/v3_0/assets/automations_page_child_assets``, which records in the session whether the automations page should list the automations of child assets, next to the endpoint the status page uses for its own job scope.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think these API endpoints should be part of the public v3 API. I feel it just clutters up our Swagger docs.

I suggest moving it to an API blueprint dedicated to internal FM UI support. This API changelog might need to get a dedicated section for this new blueprint (I suggest the bottom of the page) with a disclaimer that these endpoints are not part of the official API and can have (externally) breaking changes with any FM version.

Two more such endpoint are /api/v3_0/assets/keep_legends_below_graphs and /api/v3_0/assets/default_asset_view and I suggest moving those to this blueprint, too.

next to the endpoint the status page uses for its own job scope.

I didn't understand the comment.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Moved, together with the two you named and the status page's two, since all five do the same job: storing a choice made in the UI in the user's session. They're now a SessionAPI view in the dev blueprint, under /api/dev/session/..., as in your second comment. That blueprint's endpoints were already outside the Swagger docs and outside the official API. Their paths and fields are kebab-case now, since their URLs change anyway. The API changelog has a section at the bottom listing them, with the disclaimer. 26b630c, f5cd73b

About "next to the endpoint the status page uses for its own job scope": that meant status_page_child_jobs, which stores the status page's own Include jobs of sub-assets switch. The sentence is gone.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A clarification on "That blueprint's endpoints were already outside the Swagger docs": the generator doesn't exclude them by blueprint. It adds a path entry to openapi-specs.json for every route under /api/, /api/dev/... included. The dev endpoints' docstrings have no OpenAPI section, though, so those entries are empty ({}), and Swagger UI renders no operations for them.

So the session endpoints stay out of the rendered Swagger docs because their docstrings don't describe them in OpenAPI, not because of their /api/dev prefix. A future OpenAPI docstring would bring them back, wherever they live. In Sphinx, dev.rst documents only the modules it names, and the new session module isn't among them.

Comment thread documentation/features/automations.rst Outdated
Comment thread documentation/features/automations.rst Outdated
The page shows the next scheduled run for each automation (excluding any pending catch-up run).
An automation's details show the sensors it reads from and writes to, linking to each sensor's page.
Automations are usually defined on a sub-asset, so the page lists what runs anywhere below the asset as well, naming the asset each automation belongs to.
Turn *Include automations of sub-assets* off to see only the automations defined on the asset itself; the choice is remembered for your next visit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Continuing my thoughts on grouping these UI settings under a dedicated API blueprint:

  • The two previously existing endpoints (default_asset_view and keep_legends_below) mention they are changing a preference for the current user. So far it hasn't been stated explicitly whether that's also true for this endpoint. "the choice is remembered for your next visit" fulfills that role here.
  • Alternative to a new blueprint, repurpose the dev blueprint as a UI blueprint. It contains chart endpoints under the class SensorAPI(FlaskView) . There, we could add a new FlaskView subclass for endpoints that set session variables (note this in its docstring).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I went with repurposing the dev blueprint: a SessionAPI(FlaskView) next to the chart endpoints. Its docstring says these endpoints store the current user's choices in their session, and that they aren't part of the official API. The blueprint's module docstring now says it covers UI support as well as endpoints under development. 26b630c

Comment thread flexmeasures/api/v3_0/assets.py Outdated
Comment thread flexmeasures/api/v3_0/assets.py Outdated
Comment thread flexmeasures/api/v3_0/assets.py Outdated
Comment thread flexmeasures/api/v3_0/assets.py Outdated
Comment thread flexmeasures/api/v3_0/assets.py Outdated
Flix6x and others added 2 commits September 17, 2026 12:55
…er may read

The automations listing, and the jobs listing it followed (#2500), included
every asset below the requested one, on the grounds that whoever may read
an asset may read what is below it, as a child asset belongs to the same
account as its parent. That does not hold: a child asset can belong to
another account, so one organisation could list the automations and jobs
on another's assets simply by holding a parent above them. Each asset below
is now checked for read access on its own (get_readable_offspring).

The test calling build_asset_jobs_data directly now does so as the user who
owns the assets, as an anonymous caller may read none of them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0129WrXeJ5gia2pctFH93BqC
Signed-off-by: F.N. Claessen <claessen@seita.nl>
The endpoints that store a user's choices in the FlexMeasures UI in their
session are not API a client should build on, and filled the Swagger docs.
All five move to a SessionAPI view in the dev blueprint, whose endpoints
are not part of the official API either:

  /api/v3_0/assets/default_asset_view            -> /api/dev/session/default-asset-view
  /api/v3_0/assets/keep_legends_below_graphs     -> /api/dev/session/keep-legends-below-graphs
  /api/v3_0/assets/status_page_tab               -> /api/dev/session/status-page-tab
  /api/v3_0/assets/status_page_child_jobs        -> /api/dev/session/status-page-child-jobs
  /api/v3_0/assets/automations_page_child_assets -> /api/dev/session/automations-page-child-assets

As their URLs change anyway, their paths and fields are kebab-case, and so
is the include-child-assets query parameter of the automations and jobs
listings. include-child-assets is no longer required by the two page
endpoints, and defaults to false, as listing the assets below as well asks
more of the server. They store what they are sent in the session directly,
rather than copying it into request.values for set_session_variables, and
their 400 responses, which the schemas' 422s made unreachable, are gone
with their Swagger docs. The session keys the templates read are unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0129WrXeJ5gia2pctFH93BqC
Signed-off-by: F.N. Claessen <claessen@seita.nl>
… and trim the changelog entry

The API changelog's entry for v3.0-38 names include-child-assets, covers
the jobs listing too, and says only readable assets below are included,
where it claimed readers of an asset may read what is below it. The page
endpoint no longer appears there: a section at the bottom lists the
endpoints supporting the FlexMeasures UI, with a note that they are not
part of the official API and may change in any version. The automations
docs say the page refreshes once a minute, which it does, and the main
changelog entry keeps to what changed for users.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0129WrXeJ5gia2pctFH93BqC
Signed-off-by: F.N. Claessen <claessen@seita.nl>
@nhoening

Copy link
Copy Markdown
Member

What is the reason to move endpoints to the dev API? They have been in production, so at least the naming is confusing.

…ssets below

Listing the assets below as well asks more of the server, so the
automations and jobs listings, and the automations and status pages, now
list only what belongs to the asset itself by default. The API takes
include-child-assets=true, and each page's switch stores the choice in
the session as before, now starting off. build_asset_jobs_data defaults
to leaving the assets below out, too.

The docs, the API changelog and the changelog entries for this PR and
for #2500, which introduced the status page's switch, say so.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0129WrXeJ5gia2pctFH93BqC
Signed-off-by: F.N. Claessen <claessen@seita.nl>
@Flix6x

Flix6x commented Sep 17, 2026

Copy link
Copy Markdown
Member

What is the reason to move endpoints to the dev API? They have been in production, so at least the naming is confusing.

See these comment threads for how I derived there:

I see your point about not moving endpoints from a production blueprint to a dev blueprint. A related discrepancy is with the existing chart-support endpoints in that dev blueprint: at some point they were published under the v3 documentation.

I don't have a complete picture of the end state and transition I have in mind yet, but I suggest for now at least:

  • Not introducing any new session-variable-setting endpoints under v3.
  • Moving the 4 previously existing session-variable-setting endpoints out of v3 (two of which actually already seemed to be hidden from Sphinx and Swagger). As far as I'm concerned they were never supposed to be in there. I don't consider them being in use by API users. Feel free to push back on this point.
  • Optionally, renaming the dev blueprint to a ui-support blueprint1 (I don't think this has implications for the Swagger docs and likely the Sphinx docs are only affected in the code auto-summary section, but I'll be sure to check).
  • I also want to make clear that I am not suggesting to remove the chart-support endpoints out of the v3 docs. I consider these may be actively in use by API users.

Alternatively, I can imagine we move/keep everything to/in v3 and just make the decision to exclude all session-variable-setting endpoints from Sphinx and Swagger. I'll consider these options now, and feel free to weigh in.

Footnotes

  1. Not sure about the name or right scope yet. At least I would not reuse the term "internal API" since our relationship with that idea has soured.

This reverts 095f631, which had the automations and jobs listings, and
the automations and status pages, leave the assets below out unless asked.
#2447 asked for a site asset to show what happened anywhere below it by
default, as it is often unclear at which level a schedule was triggered,
so the listings and both pages include the assets below again, with
include-child-assets=false or the page's switch to narrow them down.

The session endpoints that store a page's switch now also treat a missing
include-child-assets as true, in line with the pages.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0129WrXeJ5gia2pctFH93BqC
Signed-off-by: F.N. Claessen <claessen@seita.nl>
@Flix6x

Flix6x commented Sep 17, 2026

Copy link
Copy Markdown
Member

Opinion from Claude (the coding assistant Felix works with on this PR), posted at Felix's request.

On where the session-preference endpoints should live, following up on @nhoening's question and @Flix6x's options. First, three facts that shape the choice:

  • Swagger exclusion is decided by the docstring, not the blueprint. The spec generator adds an entry for every route under /api/, but a route whose docstring has no OpenAPI section gets an empty entry, which Swagger UI doesn't render. That's why the /api/dev endpoints are absent from Swagger, and a v3 endpoint could be absent the same way.
  • Sphinx documents modules explicitly: v3_0.rst includes flexmeasures.api.v3_0.assets, and dev.rst names its modules, with a "use at your own risk" warning.
  • Only FlexMeasures' own UI calls these endpoints, and it deploys together with the server. Two of them (default_asset_view, keep_legends_below_graphs) are released; the status page's two and the automations one are not.

How I'd weigh the options:

  1. Keep them in v3, but undocumented. Least churn, but a versioned prefix would host endpoints we don't treat as API, which invites someone to document them one day and so promise stability nobody intends.
  2. /api/dev, as in this PR now. It works, but @nhoening is right that "dev" reads as "under development", while these are production UI plumbing.
  3. Rename the dev blueprint to one dedicated to UI support. In my view, this is the best fit. The chart endpoints there serve the UI too, so everything the UI needs from the server outside the official API has one clearly named home, with the disclaimer the API changelog section already carries. The chart endpoints Swagger shows are the v3_0 asset chart routes, which a rename wouldn't touch; the dev ones are documented only in Sphinx, as use-at-your-own-risk. To remove any doubt, the old URLs, the two released v3 session endpoints and the /api/dev routes, could stay as undocumented aliases for one release.
  4. Move them out of /api, into the UI package. This fits the session endpoints themselves, as they only write session keys the templates read. But it would split UI support across two places, while option 3 keeps it in one.

So I'd go with option 3, with aliases for one release if we want zero risk for anyone calling the old URLs.

Separately: following #2447, both listings and both pages include the assets below by default again (7a3fe4e).

@Flix6x

Flix6x commented Sep 17, 2026

Copy link
Copy Markdown
Member

From Claude (the coding assistant Felix works with on this PR), posted at Felix's request, to untangle a mix-up in Felix's earlier comment and correct it where needed.

There are two sets of chart routes, with the same three names:

Routes Code Called by Documented
/api/v3_0/assets/<id>/chart, /chart_data, /chart_annotations api/v3_0/assets.py, since #449 (July 2022) the asset page's graphs Swagger and the v3 Sphinx pages
/api/dev/sensor/<id>/chart, /chart_data, /chart_annotations api/dev/sensors.py the sensor page's graphs only the Sphinx Developer API page ("still under development and subject to change")

They are separate endpoints with separate implementations. No dev endpoint shares an endpoint name with a v3 one, so the Swagger generator doesn't mix them up either. The chart endpoints Swagger shows are all the v3_0 asset routes. With identical names, and with /api/dev/asset itself having moved to v3_0 in #392 (March 2022), it's easy to take them for the dev blueprint's own.

Corrections to Felix's comment above:

  • "the existing chart-support endpoints in that dev blueprint: at some point they were published under the v3 documentation" — The chart endpoints published under v3 are the asset routes above, which were written for v3_0 from the start. The dev blueprint's sensor chart routes have never been in the v3 docs or in Swagger. Their spec entries are empty, as their docstrings have no OpenAPI section.
  • "two of which actually already seemed to be hidden from Sphinx and Swagger" — Nothing was hidden. That observation came from a server running v1.1.0rc1, which only has default_asset_view and keep_legends_below_graphs. status_page_tab and status_page_child_jobs arrived after that release candidate, with Status page: split sensor data and jobs into tabs #2470 and Status page: include the jobs of sub-assets (optional) #2500.
  • "I am not suggesting to remove the chart-support endpoints out of the v3 docs" — This holds for the v3_0 asset chart routes, and renaming the dev blueprint wouldn't touch them. It would move the sensor chart routes, which are documented only as under development.

Are /api/dev/sensor/<id> and /api/dev/asset/<id> UI endpoints too? In my view, yes.

  • Chart-specific data: they return a subset of attributes chosen for the charts: name, timezone, and the time range of the data (timerange for a sensor, timerange_of_sensors_to_show for an asset). Their docstrings say "for use in charts", and the class docstrings already say they "support the FlexMeasures UI".
  • One caller: the graphs template, which uses them to warn about a timezone difference and to bound the selectable period.
  • No public counterpart role: the public representations of sensors and assets are GET /api/v3_0/sensors/<id> and GET /api/v3_0/assets/<id>, which don't expose those time ranges. The dev endpoints are chart helpers, not resources.

So they belong with the session endpoints in a UI-support blueprint. The one judgement call left is the three sensor chart routes: their asset counterparts are public v3 API, so they could instead be promoted to v3 for symmetry. Until someone asks for that, grouping them with the other UI support seems right to me.

A small aside: dev.rst still lists flexmeasures.api.dev.assets, a module that no longer exists since #392. The dev AssetAPI lives in api/dev/sensors.py, so it is documented anyway.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0129WrXeJ5gia2pctFH93BqC
Signed-off-by: F.N. Claessen <claessen@seita.nl>
BelhsanHmida added a commit that referenced this pull request Sep 17, 2026
…t fault

Context:
- PR #2563 changes which key an automation's validation errors are reported under,
  which an API client reads.

Change:
- Added an entry to the "Automations, in detail" section of the main changelog,
  rather than to Bugfixes, since automations have not shipped in a release yet.
- Added a v3.0-39 section to the API change log, saying explicitly that this is not
  a breaking change, as the automation endpoints are not part of a release.
- Numbered v3.0-39 against PR #2554's v3.0-38, which merges first.

Signed-off-by: Mohamed Belhsan Hmida <mohamedbelhsanhmida@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Automations page UX touches

3 participants