{"id":39674454,"url":"https://github.com/bmesuere/optivolt","last_synced_at":"2026-01-18T09:43:50.463Z","repository":{"id":319899604,"uuid":"1079177335","full_name":"bmesuere/optivolt","owner":"bmesuere","description":"Optivolt is a linear and mixed-integer optimizer for home energy systems.","archived":false,"fork":false,"pushed_at":"2025-12-11T19:33:07.000Z","size":551,"stargazers_count":4,"open_issues_count":9,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-12-12T14:52:50.783Z","etag":null,"topics":["dess","ems","victron","victronenergy","vrm"],"latest_commit_sha":null,"homepage":"https://optivolt.bartm.be/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bmesuere.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-10-19T09:20:15.000Z","updated_at":"2025-12-11T12:39:46.000Z","dependencies_parsed_at":"2025-10-20T21:08:18.392Z","dependency_job_id":"2d3a690d-63d9-4913-968e-1cb6fe9a7ce1","html_url":"https://github.com/bmesuere/optivolt","commit_stats":null,"previous_names":["bmesuere/optivolt"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bmesuere/optivolt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmesuere%2Foptivolt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmesuere%2Foptivolt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmesuere%2Foptivolt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmesuere%2Foptivolt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bmesuere","download_url":"https://codeload.github.com/bmesuere/optivolt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmesuere%2Foptivolt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28534175,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dess","ems","victron","victronenergy","vrm"],"created_at":"2026-01-18T09:43:49.685Z","updated_at":"2026-01-18T09:43:50.441Z","avatar_url":"https://github.com/bmesuere.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OptiVolt 🔋\n\nPlan and control a home energy system with forecasts, dynamic tariffs, and a day-ahead optimization pipeline. OptiVolt builds a linear program over 15-minute slots to decide how your **battery**, **PV**, **EV**, **heat pump**, and the **grid** should interact to minimize cost.\n\n- **Primary focus:** Victron Energy ESS systems via the **Victron VRM API** and MQTT Dynamic ESS schedule writing.\n- **How to run:** as a **Home Assistant add-on** (recommended) _or_ as a **standalone Node.js server** that serves the web UI and API from the same port.\n\n## Features\n\n- Day-ahead cost minimization over 15-minute slots using HiGHS (WASM)\n- Server-side VRM integration for forecasts/prices and system limits\n- Optional Dynamic ESS schedule pushes over MQTT (first 4 slots)\n- Static, build-free web UI served by the same Express process\n- Persistent settings + time-series data under a configurable data directory\n\n## Architecture\n\n- The **UI** (in `app/`) is static and calls the **Express API** on the same origin.\n- The **API** (in `api/`) exposes:\n  - `POST /calculate` — builds \u0026 solves the LP with **HiGHS** and returns per-slot flows, SoC, and DESS mappings. The request body can ask the server to refresh VRM data first and/or push the first slots to Victron via MQTT.\n  - `GET/POST /settings` — read/write persisted system + algorithm settings in `DATA_DIR/settings.json` (defaulting to `api/defaults/default-settings.json`).\n  - `POST /vrm/refresh-settings` — fetch latest Dynamic ESS limits/settings from VRM and persist.\n- Data (forecasts, prices, SoC) are server-owned: VRM refreshes write to `DATA_DIR/data.json` (defaulting to `api/defaults/default-data.json`) and the solver always reads from this persisted snapshot.\n- Shared logic lives in **`lib/`** (LP builder/parser, DESS mapping, VRM + MQTT clients).\n\n```text\napp/                 # Static web UI (index.html, main.js, app/scr/**)\napi/                 # Express server (routes + services)\nlib/                 # Core logic: LP builder, parser, DESS mapper, VRM + MQTT clients\naddon/               # Home Assistant add-on wrapper (s6, run scripts)\ntranslations/        # i18n strings for the HA add-on settings\nDockerfile           # Image for HA add-on / container use\nconfig.yaml          # Home Assistant add-on manifest\n```\n\n### Running the server locally\n\n```bash\nnpm install\nnpm run api       # or: npm run dev  (loads .env.local via dotenv-cli + nodemon)\n```\n\nBy default the server listens on `http://localhost:3000`.\n\n**Environment variables:**\n\n- `HOST` (default `0.0.0.0`), `PORT` (default `3000`)\n- `DATA_DIR` (default `\u003crepo\u003e/data`); stores `settings.json` and `data.json`\n- `VRM_INSTALLATION_ID`, `VRM_TOKEN` (enable VRM refresh routes)\n- `MQTT_HOST`, `MQTT_PORT`, `MQTT_USERNAME`, `MQTT_PASSWORD` (optional; required to push Dynamic ESS schedules)\n\nCreate a `.env.local` file in the project root to set these variables for local development.\n\n## Installing Optivolt in Home Assistant\n\nThis section explains how to install and wire up the Optivolt add-on in Home Assistant.\n\n### 1. Expose the add-on directory over Samba\n\n1. Install the **Samba share** add-on in Home Assistant.\n2. Configure it so that the `/addons` (or `addons/`) directory is available as a network share.\n3. From your laptop/desktop, mount that share. In this example, it is mounted as `/Volumes/addons`.\n\n### 2. Copy the Optivolt files into Home Assistant\n\nOn your development machine, copy the contents of your local Optivolt repository into the mounted `addons` share.\n\nExample (macOS / Linux):\n\n```bash\nrsync -av --delete \\\n  --exclude 'node_modules' \\\n  --exclude '.git' \\\n  --exclude '.DS_Store' \\\n  ~/Code/optivolt/ /Volumes/addons/optivolt/\n```\n\nThis will sync your local `~/Code/optivolt` directory into the `optivolt` add-on directory on Home Assistant, while skipping development artefacts.\n\n### 3. Install the Optivolt add-on in Home Assistant\n\n1. Go to **Settings → Add-ons → Add-on Store**.\n2. Use the menu to **reload** local add-ons if necessary.\n3. Find the **Optivolt** add-on in the list and click **Install**.\n\n### 4. Configure VRM and Victron connection settings\n\nOpen the Optivolt add-on configuration panel and enter:\n\n- Your **Victron VRM** credentials / installation ID.\n- The **Victron IP address** on your local network.\n\nSave the configuration.\n\n### 5. Start the add-on and verify data\n\n1. Start the Optivolt add-on.\n2. Open the Optivolt UI (from the add-on page).\n3. Verify that data is being fetched correctly (time series, prices, SoC, etc.). If data does not load, check the logs of the add-on.\n\n### 6. Trigger Optivolt every 15 minutes from Home Assistant\n\nOptivolt exposes a `/calculate/` HTTP endpoint that you can call periodically from Home Assistant.\n\nFirst, define a `rest_command` in your Home Assistant configuration:\n\n```yaml\nrest_command:\n  optivolt_calculate:\n    url: \"http://localhost:3070/calculate/\"\n    method: POST\n    content_type: \"application/json\"\n    payload: \u003e-\n      {\n        \"updateData\": true,\n        \"writeToVictron\": true\n      }\n```\n\nThen, create an automation that calls this command every 15 minutes, a few seconds after each quarter hour (to align with the quarter-hour slots):\n\n```yaml\nautomation:\n  - alias: \"Trigger Optivolt calculate every quarter hour\"\n    trigger:\n      - platform: time_pattern\n        minutes: \"/15\"\n        seconds: 5\n    action:\n      - service: rest_command.optivolt_calculate\n```\n\nAdjust the trigger as needed if you want a specific offset (e.g. 00:00:05, 00:15:05, ...).\n\n### 7. Put DESS into Node-RED mode\n\nTo prevent Victron DESS from overwriting the settings that Optivolt writes, set DESS to **Node-RED** mode.\n\nI used the Home Assistant **Victron MQTT extension** to switch DESS into Node-RED mode.\n\n### 8. Work around the Victron price API bug\n\nThere is a bug in the Victron API: the **price data is not available** when DESS is *not* in the default mode. To work around this:\n\n- Create a Home Assistant automation that temporarily sets DESS to **default** mode between **13:00 and 14:00** every day.\n- During that window, price data is available and can be fetched; outside of it, DESS can be left in Node-RED mode so Optivolt fully controls the schedule.\n\nOnce all these steps are in place, Optivolt should run as an add-on, keep its data and schedules up to date, and continuously steer your Victron system using the optimized plan.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbmesuere%2Foptivolt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbmesuere%2Foptivolt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbmesuere%2Foptivolt/lists"}