Skip to content

Latest commit

 

History

2,093 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FTW

FTW

Local-first home energy coordination.

FTW is a local-first home energy management system (EMS). It coordinates solar, batteries, grid power, EV charging and thermal assets on a Raspberry Pi or Linux host. The safety-critical runtime is one Go binary, hardware integrations are sandboxed Lua drivers, and a compiled Energyplan worker handles long-horizon planning.

The control path stays on the local network. Cloud price, weather and device integrations degrade independently; they are not required for safe local operation.

Product direction

FTW should make mixed equipment simple to live with: useful first-day planning, reliable daily charging, fast and honest live feedback, and structured access for agents. The default experience should need few choices while keeping expert controls and Lua drivers available.

VISION.md is the product direction set by Fredrik. docs/roadmap.md lists the outcomes and proof needed. These include goals that have not shipped; the capability list below is separate.

Sourceful Energy maintains FTW Community under AGPL-3.0-only with the Energyplan combination permission. Contributions are welcome, preferably starting with issues. Share a short Markdown proposal or a focused fix with relevant test evidence. See CONTRIBUTING.md. Community help is best effort; SUPPORT.md describes separate commercial services.

Join the FTW Discord for questions and community discussions.

Architecture

FTW has three explicit modules:

  • Core owns configuration, telemetry, state, safety, dispatch, API and UI.
  • Drivers translate vendor protocols and power signs in isolated Lua VMs.
  • Optimizer proposes plans over a versioned contract; core validates every result and keeps a Go fallback.

Drivers and the optimizer can evolve without moving safety authority out of Core. A new module needs a concrete reason and must reduce the complexity of the whole product. See docs/architecture.md.

Capabilities

  • self-consumption, peak shaving and explicit grid targets;
  • multi-battery allocation with fuse, SoC, slew and stale-data protection;
  • price-, weather-, PV- and load-aware planning;
  • EV charging, V2X and thermal planning;
  • local web UI, with history and configuration in SQLite;
  • Home Assistant MQTT discovery;
  • hot-reloadable, independently released Lua drivers;
  • a built-in OCPP 1.6J + 2.0.1 server, so OCPP chargers connect with no driver.

The local catalog is generated from DRIVER metadata. The public srcfl/device-drivers repo is the editable source and FTW's default signed driver channel.

This repository holds no driver source. drivers/*.lua is gitignored and fetched from that repository at the commit pinned in drivers/BUNDLED_SOURCE.json:

make drivers

The files still ship: they are the release's own drivers and what normally runs. Startup is deliberately local — a gateway boots and runs without the network, so a remote refresh must never block it — and the image, the release tarballs and the tests all read drivers/. They are simply fetched rather than committed, which is why a driver cannot be edited here at all. There is no file to open a pull request against; fix it upstream and move the pin. CI fails if one is committed.

Moving the pin is a driver release. make driver-versions-across-pin compares the drivers at the old pin against the drivers at the new one and fails when a file changed without its DRIVER version moving — the signed channel refuses to publish changed bytes under a version it already published, and a gateway offered the same version twice cannot tell them apart.

The pin needs watching in both directions. Every pull request runs --check, which catches a driver edited here. A daily job runs --behind, which catches the opposite: the pin left in place while a fix lands upstream. It opens one issue and keeps it up to date, and stays quiet unless a bundled driver actually changed.

Install on Linux

2.x and 3.x will receive no further updates. New releases use the new 0.x line. Switch now to follow the latest fixes and features; do not install 3.x beta or use it as an intermediate upgrade.

Start with Install and update FTW (Svenska). It covers old Docker images, Raspberry Pi SD-card images, 1.x/2.x/3.x, older native sites, new native and Docker installs, Home Assistant, backup, and recovery.

The new line starts at v0.131.0-beta.1; old 0.x releases up to 0.130.x are also retired. A lower version number or a saved beta channel does not tell you which install path you have. Identify it before running commands.

Old FTW on a Raspberry Pi? Use a second SD card. Keep the old card, prepare the new one and swap cards before running install commands. Follow the card-by-card steps. Do not try Docker next if the native installer refuses the old card.

Use a fresh 64-bit Raspberry Pi OS, Debian or Ubuntu host for native systemd. Docker on the same Linux host is a separate, advanced option: identify and stop old Core and its updater, and preserve any MQTT service first. The guided migration of settings and history is not ready; preserve the old data and get help if those data must move before you switch. Only one Core may control the equipment, including after reboot.

Give the FTW host a DHCP reservation in the router so device connections keep working. Open http://<host>:8080/setup after installation. The optional FTW webapp connects through an encrypted session and blind relay; relay loss does not stop local control.

Install on Home Assistant

The existing Home Assistant app is on the retired 3.x line. It does not follow new 0.x releases. Do not install that beta to get current FTW. Run new FTW on a separate Linux host and use the MQTT integration with Home Assistant.

Follow the switch guide, including backup and stopping the old app's Core, Start on boot and Watchdog. Supervisor still owns recovery of the old app; its update controls do not migrate to 0.x. Report old app or Supervisor faults in its issue tracker, and Core faults in this repository.

Local development

Requirements are Go and Node.js. Python 3 verifies release artifacts during development; no Python interpreter or service runs the planner.

git clone https://github.com/srcfl/ftw.git
cd ftw
make dev

Useful checks:

make test      # Go tests
npm test       # web
make verify    # fast test, compose, vet and build checks
make e2e       # simulator-backed full stack
make ci        # e2e, builds and browser smoke

See docs/development.md for the small set of development workflows.

Configuration

config.example.yaml and the validation types in go/internal/config are the configuration reference. Copy the example for a native development setup:

cp config.local.example.yaml config.local.yaml

Power values above a driver use one convention: positive means into the site, negative means out. Drivers alone translate vendor conventions. Read docs/site-convention.md before editing power math or writing a driver.

Drivers

Drivers are plain Lua files and need no compilation. A driver declares its catalog metadata, lifecycle and required capabilities in one file. The Go host provides capability-scoped Modbus, MQTT, serial, HTTP, WebSocket and TCP access.

Which devices are covered, and on what evidence, is published as a searchable catalog: Device driver catalog. It is generated from srcfl/device-drivers on every push to that repository's main, so the versions, tested models and per-target status it shows are the ones FTW installs. Listing is not an install claim: the page states which drivers have been confirmed against physical hardware and which have not.

Start with docs/writing-a-driver.md. Send shared driver changes to srcfl/device-drivers. That repo publishes one signed, content-addressed asset per driver and version. FTW downloads only the chosen driver, which can update or roll back without a new FTW core release. Device Support may consume the same public source later for other products or a higher support level.

EV chargers that speak OCPP are the exception: they need no driver. FTW runs an OCPP Central System (1.6J and 2.0.1), so the charger connects and registers itself. See docs/ocpp.md.

Releases

There are two channels:

  • beta receives every merged change in the next beta, aiming for one a week;
  • stable promotes the exact commit already published and tested as beta.

There is no edge channel. Beta is the shared playground: run it on a real site and report what you find as an issue naming the beta version you saw it on. An issue marked release-blocker stops that line from promoting. A beta promotes to stable after a week on the home box and at least one other real site with no open release-blocker.

Changesets produce versions and changelog entries; the native release workflow builds the checksummed Linux packages that the installer, ftw update and the Docker files use. The repository owner cuts every release. Details for operators are in docs/self-update.md; the maintainer rules are in the Releases section of AGENTS.md.

Documentation

The repository deliberately keeps prose small. Code, types, tests and driver metadata are the detailed reference.

Other files under docs/ are focused installation or external-integration guides.

Contributing

Read CONTRIBUTING.md. User-visible changes need a Changeset.

AGPL-3.0-only with the Energyplan combination permission — see LICENSE and LICENSING.md. Energyplan binaries have separate household-use terms; commercial use of those binaries needs a Sourceful agreement. Earlier versions retain their earlier licenses.

About

FTW — a local-first home energy management system (EMS) for solar, batteries, grid, and EV charging.

Topics

Resources

Contributing

Stars

20 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages