Skip to content

Releases: srcfl/ftw

v0.130.4

Choose a tag to compare

@github-actions github-actions released this 16 Jul 20:15
1dab1dd

🛰️ Marvin

Don't Panic.

Patch Changes

  • ed59d81: Answer health probes during slow boots.

    The API port is now bound before the state DB opens, serving
    /api/health with 200 {"status":"starting"} (and 503 elsewhere) until
    the real mux takes over on the same listener. Previously a boot that ran
    a one-time VACUUM or a full integrity check on a multi-GB database left
    the port unbound for up to tens of minutes, so the Docker healthcheck
    failed and the self-update sidecar judged the deploy failed and rolled
    back in the middle of the compaction.

v0.130.3

Choose a tag to compare

@github-actions github-actions released this 16 Jul 19:14
52386a6

🛰️ Marvin

Don't Panic.

Patch Changes

  • 00a9da5: Yield between maintenance chunks so live writers are never starved.

    v0.130.2 bounded every maintenance transaction, but back-to-back chunks
    still starved the control loop during a large backlog migration: SQLite's
    busy handler retries without fairness, so the maintenance loop re-acquired
    the write lock before any waiting writer won its retry. Prune chunks,
    rolloff deletes, and diagnostics batch-deletes now pause (250/100 ms)
    between transactions, guaranteeing every waiting writer a window.

v0.130.2

Choose a tag to compare

@github-actions github-actions released this 16 Jul 18:47
54b0809

🛰️ Marvin

Don't Panic.

Patch Changes

  • 1b62749: Critical fix: bounded maintenance transactions (upgrade-lock incident).

    The first history prune after upgrading a long-running install (v0.129.0's
    Prune wiring) could hold SQLite's write lock for hours: the hot→warm
    aggregation used a correlated subquery that re-scanned the hot table once
    per 15-minute bucket, and the whole backlog ran as one transaction. Every
    control-loop write failed with SQLITE_BUSY until it finished.

    • Prune is now linear (single-pass bucket aggregation) and chunked: each
      transaction ages at most ~24 h of rows, so writers interleave. A 93-day
      backlog that previously locked the DB for 4+ hours now completes in
      seconds. Chunk and cutoff boundaries are bucket-aligned, which also fixes
      a pre-existing partial-bucket overwrite at the retention edge.
    • Prune logs its result (rows aged, chunks, duration) — maintenance is no
      longer silent.
    • Parquet rolloff deletes each day's rows right after that day's file is
      durable, in hour-sized transactions, instead of one giant end-of-run
      DELETE that could lose the race against live writers.
    • Planner-diagnostics retention in SQLite reduced 30 → 7 days (measured
      485 MB at 30 days on a real site; Parquet keeps everything), deletes are
      batched, and the table is excluded from state snapshots (snapshots shrink
      from ~470 MB to ~20 MB).

v0.130.1

Choose a tag to compare

@github-actions github-actions released this 16 Jul 18:09
f13b506

🛰️ Marvin

Don't Panic.

Patch Changes

  • d08c4cc: Automatically add and validate the independently updatable optimizer sidecar when upgrading safe existing Linux or macOS Compose installations, with rollback cleanup and fail-closed handling for operator-owned overrides.

v0.130.0

Choose a tag to compare

@github-actions github-actions released this 16 Jul 17:13
9bbcd81

🛰️ Marvin

Don't Panic.

Minor Changes

  • eba5722: Add independently updatable optimizer and Lua-driver modules with protocol negotiation, signed monorepo driver releases, content-addressed activation, selective restart, health verification, and rollback while retaining bundled and Go-DP safety fallbacks. Add explicit opt-in anonymous fleet statistics for active installations and public driver/component health.

Patch Changes

  • a4f0b33: Repair the setup wizard and pair-session component after the FTW rename, and add CI guards for browser JavaScript, release metadata, and stale Changeset package names.

v0.129.0

Choose a tag to compare

@github-actions github-actions released this 16 Jul 13:36
246c7c6

🛰️ Improbability Drive

Don't Panic.

Minor Changes

  • 8d61001: Add Sungrow PV curtail support, reset stale inverter control state when the driver loads, and surface hardware fault states such as thermal shutdowns in diagnostics.

  • af005b9: Database hardening and richer history access.

    Durability & SD-card resilience

    • Parquet rolloff now fsyncs day files (and their directory) before the atomic rename — a power cut can no longer lose a day of rolled-off samples whose SQLite rows were already deleted.
    • The rolloff streams one UTC day at a time instead of buffering the whole backlog in memory (a multi-week backlog could OOM a Pi and then never complete).
    • Planner-diagnostics day files are merged instead of overwritten — the hourly rolloff previously discarded every earlier hour of the same day from cold storage.
    • One-time VACUUM at boot when a large share of state.db is freelist (reclaims the high-water mark left by big prunes), guarded by a free-disk check.
    • Truncating WAL checkpoint after every hourly rolloff; each control-loop tick (history + metrics) is now persisted in a single transaction, halving the WAL commit rate.

    Faster history queries

    • Downsampled /api/history and /api/series queries aggregate per bucket in SQL instead of fetching every raw row into Go (a month view used to materialize >1M rows per request), and buckets carry a min/max envelope so short power spikes stay visible zoomed out.

    Richer history over REST

    • /api/series windows older than 14 days transparently include the cold Parquet tier.
    • /api/series supports comma-separated multi-metric queries, absolute since/until bounds, and format=csv export.
    • /api/series/catalog reports each metric's display unit; units from host.emit_metric are now persisted across restarts.

    Growth control

    • New state.cold_retention_days config bounds the cold Parquet tier (default 0 = keep everything).
    • Low-disk warning (log + event feed) when free space drops below 500 MB.

Patch Changes

  • af005b9: Run the wide-history retention tiers during the hourly storage rolloff so old full-resolution dashboard rows are aggregated instead of growing state.db indefinitely.

  • a4c695a: Decouple the Raspberry Pi installer image from application releases and reduce redundant CI work while retaining required validation.

  • 3e1b98a: Fail closed for direct state-changing p2pFetch API calls on public relay origins so owner ceremony and control request bodies are never raw-fetched to the relay.

    Enable short TCP keepalive on Modbus TCP driver sockets to make stale inverter sessions recover faster after network/controller interruptions.

    Use MyUplink's known-working OAuth scope set by default and expose an override for installations that can use narrower read-only auth.

    Let BatteryCoversEV take effect in passive-arbitrage PV-surplus charge slots by allowing the planned-grid cap to back off charging and cover EV import while preserving deliberate grid-charge slots.

    Resolve failed remote-home P2P attempts to the actionable sign-in/setup gate instead of leaving the page on "Reaching your home..." forever.

v0.128.1

Choose a tag to compare

@github-actions github-actions released this 16 Jul 09:28
2cd5668

🛰️ Mostly Harmless

Don't Panic.

Patch Changes

  • dcffc61: Add a one-command, rollback-safe migration from legacy Docker Compose and
    local-development images to the official Sourceful images. Include license
    and notice files in Docker build contexts so canonical main and updater images
    publish successfully.
  • 43e2d1b: Repair self-updates from legacy or developer Compose layouts by applying a
    temporary canonical image override without rewriting the host deployment, and
    preserve automatic image and state rollback on that path. Add a bilingual
    legacy-upgrade runbook and refresh migration/operator documentation,
    fresh-clone simulator defaults, driver catalog coverage, release-image
    selection, and license payloads after the Sourceful transfer.

FTW drivers (stable)

Choose a tag to compare

@github-actions github-actions released this 16 Jul 17:14
9bbcd81

Moving stable channel for independently released FTW Lua drivers. Trust manifest.json only after Ed25519 verification.

FTW Raspberry Pi installer

Pre-release

Choose a tag to compare

@github-actions github-actions released this 16 Jul 11:59

Latest FTW Raspberry Pi installer image. Built from eba5722 on 2026-07-16. Fresh installations pull the current stable FTW containers from GHCR on first boot.

FTW drivers (edge)

FTW drivers (edge) Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 16 Jul 17:09
eba5722

Moving edge channel for independently released FTW Lua drivers. Trust manifest.json only after Ed25519 verification.