BESS AM (BE-2262) — mando-bess-am
BESS AM = BESS Asset Management: a headless Kinesis stream processor that ingests per-second WAGO battery-telemetry events, aggregates them to 1-minute windows, and forwards the result into the mando-bess ingestion stream. A POC tracked under ticket BE-2262, authored almost exclusively by Gergely Vászon (ext, gergely.vaszon@alpiq.com).
Status — in flight, NOT merged
As of 2026-06-24 nothing BESS AM has merged to
develop. The core MR !512 is OPEN withdetailed_merge_status = requested_changes(blocked on review). All paths, crate names, schema names, and stream names below describe the proposed state on the feature branches, not what is live ondevelop. Treat as forward-looking reference until !512 merges.
For Agents
BESS AM is a newer workstream distinct from the existing flow engine. The flow-engine list (Trading / Manual Schedule / Auction / Intraday / Data Update / AFRR — see Flow Implementations) does NOT include AM. AM introduces a new
Event-typed data-point class (real-time telemetry) that is separate from the time-series flows. If asked “where does real-time SoC/SoH come from”, the answer is this pipeline, not a flow.
What it does
WAGO boxes mounted on the physical battery (the FI / Valkeakoski / Beskar asset) emit per-second telemetry — real-time State of Charge (SoC) and State of Health (SoH) — over AWS IoT Core. mando-bess-am is the headless service that consumes the raw stream, persists it, down-samples it to 1-minute aggregates, and hands it off to mando-bess.
Pipeline
WAGO Box
→ AWS IoT Core
→ Kinesis (bess-am-events) # raw per-second telemetry
→ mando-bess-am # this service: persist raw + 1-min aggregate
→ Kinesis (bess-os-events) # 1-min aggregated results
→ mando-bess # ingests into the platform
Processing steps (inside mando-bess-am)
- Consume the raw
bess-am-eventsKinesis stream. - Persist raw per-second events to the
bess_amPostgres schema (eventtable). - Aggregate to 1-minute windows, computing: Mean / Max / Min / Last / StdDev / Count / Sum.
- Close windows via a windowing + grace-period closure mechanism (a window is finalized only after its grace period elapses, to tolerate late/out-of-order per-second events).
- Forward the aggregated results to the
bess-os-eventsKinesis stream that mando-bess ingests.
Code & infrastructure fingerprints
Where to look in the
mandorepoThese are the files/modules introduced or touched by the BE-2262 work. Use them to locate the implementation when the branch is checked out.
New crate — mando-bess-am/ (mando_bess_am)
| Module | Responsibility |
|---|---|
pipeline | Stream wiring (consume → aggregate → forward) |
service/aggregation | 1-minute window aggregation (Mean/Max/Min/Last/StdDev/Count/Sum) |
service/forward | Push aggregated results to bess-os-events |
service/window_closure | Windowing + grace-period closure logic |
startup | Service bootstrap |
metrics | Service metrics |
Crate split not yet its own MR
Branch
feature/BE-2262-bess-am-poc-build-test+ commit5a739baa(“feat: separate out bess-am”) splits AM into its ownmando-bess-amcrate/image, but has NOT been raised as its own MR — it is a downstream branch of !512.
Supporting changes elsewhere in mando
| Path | Purpose |
|---|---|
mando-lib/src/adapter/kinesis/ | Kinesis adapter: consumer / producer / pipeline / checkpoint / config |
mando-core/src/model/event.rs | New Event-typed data-point model (real-time telemetry) |
mando-core/src/model/wago.rs | WAGO event model |
mando-bess/src/kinesis.rs | mando-bess side of the Kinesis wiring (ingest of bess-os-events) |
mando-bess/config/parts/battery_online.yaml | Defines the Event-typed “Online” datapoints (see below) |
container.bess-am.Dockerfile | Container image build for the AM service |
config/bess-am.yaml | AM service config |
battery_online.yaml — Event-typed datapoints
Defines Event-typed datapoints under the path Asset/FI/Valkeakoski/Beskar/Battery/.../Online, e.g.:
BATTERY_SOC_ONLINEBATTERY_SOH_ONLINE
These are keyed to Kinesis external IDs [bess-am-events, OnlineSOC/OnlineSOH]. This is the first place the new Event data-point class (vs. the existing TimeSeriesDouble / TimeSeriesDoubleMatrix / StaticData enumerated in DataPointType) shows up in config.
Database & infra
| Item | Value |
|---|---|
| Postgres schema | bess_am |
| Migrations | create_bess_am_schema, create_event_table, create_kinesis_checkpoint_table, add_event_latest_historization |
| Env prefix | BESS_AM_* |
| Kinesis streams | bess-am-events (raw in), bess-os-events (aggregated out) |
| CI job | ”Publish BESS-AM Docker Dev” (ECR tag prefix bess-am-<version>) |
Local-dev artifacts
doc/kinesis-local-setup.md— local Kinesis setup guide.- MiniStack (
ministackorg/ministack) — used to stand up local AWS-like services for development.
Related tickets
| Ticket | Relationship |
|---|---|
| BE-2262 | The BESS AM POC itself (this note). Core MR is !512. |
| BE-2341 | Generic Kinesis producer in mando-lib — the reusable producer half that AM forwarding depends on. No standalone MR; folded into the BE-2262 MR. |
| BE-2132 | Interval / Event datapoint groundwork (basic interval functionality) that AM builds on. MRs !524 (current) and !500 (superseded draft). |
Merge-request landscape (GitLab, as of 2026-06-24)
Repo
sales-and-origination/flexible-assets/bess/poc/mandoon GitLab. Main branch isdevelop.
MR !512 — THE core BESS AM MR
- Title:
feat: add kinesis consumer and event processing - Branch:
feature/BE-2262-bess-am-poc→develop - State: OPEN,
detailed_merge_status = requested_changes - Reviewers: krisztian.fekete1, gabor.nagy6, balint.budavoelgyi, andras.lederer, jozsef.nagy1
- Created: 2026-05-19 — Last updated: 2026-06-17
- Description: empty
- URL: https://gitlab.com/alpiq_cicd/sales-and-origination/flexible-assets/bess/poc/mando/-/merge_requests/512
MR !524 — interval/Event groundwork (AM-adjacent)
- Title:
feat: add basic interval functionality - Branch:
feature/BE-2132-interval-poc-2→develop - State: OPEN,
not_approved, no reviewers. Closes BE-2132.
MR !500 — superseded draft
- Title:
Draft: feat: add basic interval functionality - Branch:
feature/BE-2132-interval-poc→develop - State: OPEN / DRAFT, stale (last update 2026-05-06). Superseded by !524.
Unreleased crate-split branch
- Branch
feature/BE-2262-bess-am-poc-build-test+ commit5a739baa(“feat: separate out bess-am”) splits AM into its ownmando-bess-amcrate/image. Not raised as its own MR — downstream of !512.
Update 2026-06-24
Two things verified directly from the mando repo today.
develop merged into the MR branch (!512)
origin/develop was merged into feature/BE-2262-bess-am-poc (the !512 branch), which had drifted 46 commits behind. Result pushed as a fast-forward f9a1f81d..80a17e78 (merge commit 80a17e78).
Conflicts resolved during the merge:
| File | Resolution |
|---|---|
mando-lib/src/repo_postgres.rs | Kept both new DataSchemaPostgres trait default methods — the branch’s has_override() and develop’s latest_pk_columns(). |
py-mando/bess-csv/defaults.csv | Kept the 3 BESS AM Event rows; took develop’s newer EUR/MW/h FINGRID units. |
generated domain.rs files | Regenerated via build.rs; converged CRLF → LF to match develop’s line-ending convention (the branch had committed them as CRLF). |
Post-merge state: compiles clean (cargo check, 0 errors), 428 lib unit tests pass.
FIXED (2026-06-25) — codegen python_field casing for multi-segment Named variants
Was:
mando-codegen’sexpand_variantsmis-cased thepython_fieldfor multi-segment Named variants — e.g. aMin1/Meanvariant emittedmarket.da.price.min1.Meaninstead of the all-lowercasemarket.da.price.min1.mean(it lowercased the first path segment but not the value segment). This affected the BESS AM 1-minute aggregate datapoint names (Min1/Mean,Min1/Max,Min1/StdDev, …) — see Processing steps (inside mando-bess-am).
Fix:
mando-codegen/src/util.rs:41now lowercases the value segment —format!("{pf}.{name_lower}.{}", v.to_lowercase()).Commit:
cc4720b2“fix: lowercase value segment of variant python_field” on branchfeature/BE-2262-bess-am-poc, pushed to !512.Verified:
cargo test -p mando_codegennow 51/51 passing (was 50/1). The previously-failingutil::tests::expand_variants::named_variant_generates_datapointtest now passes.Origin (for the record): the bug came from the branch’s own
feat: separate out bess-amcommit ([[#unreleased-crate-split-branch|5a739baa]]), not the develop merge —mando-codegenwas byte-identical before and after that merge.Residual (unrelated to this fix) pre-existing rustfmt drifts remain in
mando-codegen/src/util.rsat lines ~50 and ~390 (the author's code), left untouched. Flagged by the project's nightly rustfmt; unrelated to this bug or the develop merge.Two
Update 2026-07-14: the POC’s dev migrations now bite every develop-based deploy
The May feat deploy of this branch to dev left two applied migrations in dev’s refinery_schema_history: U202605131400__create_event_table and U202605141900__create_kinesis_checkpoint_table. The files exist only on the unmerged BE-2262 branches, so any image built from develop lacks them and crash-loops at boot with MigrationError::PatchApplicationFailed (refinery validates applied migrations against the image’s filesystem). Hit and diagnosed during the Dev Deploy 2026-07-14 (error telemetry); worked around there by restoring both files byte-exact (single canonical git blob f45b6dd4 across all source commits, so refinery’s checksums pass).
Resolved 2026-07-24 (no action needed)
The two migration files landed on
origin/developwith the bess-am POC itself: commit3ebcc897“feat: add bess-am POC” (merge6fae64a5, 2026-07-23). develop’smando-bess/database/set is now byte-identical to the throwaway dev-deploy commit6bc418cd(git ls-tree diff, verified 2026-07-24), so develop-based dev deploys no longer need the restored files. Details: Dev Deploy 2026-07-14 (error telemetry); repodocs/superpowers/HANDOVER-error-handling-2026-07-24.mditem 4.
Related
- Alpiq BESS
- Agent Context
- mando-bess — ingests the
bess-os-eventsstream AM produces - mando-lib — hosts the Kinesis adapter (
adapter/kinesis/) and the newEventdata-point model - Mando
- Dev Deploy 2026-07-14 (error telemetry) - the dev crash-loop caused by this POC’s migrations in dev’s refinery history, and the byte-exact restore workaround