REST API

All endpoints return JSON. Base URL: http://<host>:5000

GET /api/summary

System snapshot: all units (live + virtual), energy prices, cost tracking.

{
  "timestamp": 1713250000,
  "units": {
    "Stream Ultra": {
      "soc_percent": 78.2,
      "state": "CHARGING",
      "power_w": 1200,
      "solar_w": 340,
      "capacity_kwh": 3.84,
      "is_virtual": false
    }
  },
  "grid": { "house_demand_w": 320, "grid_import_w": 0, "agile_price_p": 12.5 },
  "total_soc_percent": 62.5,
  "savings_p": 147.3,
  "energy_prices": {
    "current_import_p_kwh": 18.23,
    "current_export_p_kwh": 7.50,
    "region": "J",
    "agile_today": { "min_p_kwh": -2.0, "max_p_kwh": 35.0, "avg_p_kwh": 21.4 }
  }
}

GET /api/history/soc

Historical SoC readings per unit (rolling 24h window).

{
  "Stream Ultra": [
    {"timestamp": 1713250000, "soc_percent": 78.2, "state": "CHARGING", "power_w": 1200, "solar_w": 340}
  ]
}

GET /api/history/power

Historical power flow + grid data for charting.

{
  "grid": [{"timestamp": 1713250000, "house_demand_w": 320, "grid_import_w": 0, "solar_generation_w": 450}],
  "units": { "Stream Ultra": [...] }
}

POST /api/simulation/run

Run a cost simulation with virtual units. Accepts JSON body:

{
  "duration_hours": 24,
  "grid_profile": "agile",
  "solar_profile": "summer",
  "initial_soc": { "Unit B (Ultra X)": 50.0 }
}

Response includes daily costs (pence and GBP), per-unit cycles, final SoC, and charge/discharge event lists.

{
  "daily_cost_with_battery_gbp": 4.20,
  "daily_cost_without_battery_gbp": 7.35,
  "savings_gbp": 3.15,
  "cycles": { "Unit B (Ultra X)": 1.2 },
  "final_soc": { "Unit B (Ultra X)": 45.0 },
  "charge_events": [...],
  "discharge_events": [...]
}

PUT /api/mock-soc/<unit_id>

Set mock SoC for a virtual unit. Accepts JSON body:

{ "mock_soc": 65.0 }

Returns 400 for physical units. Use this to set up what-if scenarios before running simulations.

GET /api/settings

All app settings (secrets masked). Returns array of objects with key, value, is_secret, etc.

PUT /api/settings/<key>

Set a single setting. JSON body: {"value": "..."}

GET /stream

SSE (Server-Sent Events) endpoint. Emits /api/summary data every 5 seconds. Connect with EventSource('/stream').

Home Assistant — MQTT Auto-Discovery

Create sensors that auto-populate from this app's MQTT data. Add to configuration.yaml:

# sensors.yaml or configuration.yaml
mqtt:
  sensor:
    - name: "EcoFlow SoC"
      state_topic: "/open/api/v1/device/quota/get/STREAM_ULTRA_SN"
      value_template: "{{ value_json.data.batSoc | float }}"
      unit_of_measurement: "%"
      device_class: battery
      unique_id: "ecoflow_stream_ultra_soc"

    - name: "EcoFlow Power"
      state_topic: "/open/api/v1/device/quota/get/STREAM_ULTRA_SN"
      value_template: "{{ value_json.data.watts | float }}"
      unit_of_measurement: "W"
      device_class: power
      unique_id: "ecoflow_stream_ultra_power"

    - name: "EcoFlow Solar Input"
      state_topic: "/open/api/v1/device/quota/get/STREAM_ULTRA_SN"
      value_template: "{{ value_json.data.solarInputWatts | float }}"
      unit_of_measurement: "W"
      device_class: power
      unique_id: "ecoflow_stream_ultra_solar"

Replace STREAM_ULTRA_SN with your device serial number. Topic structure and field names come from the EcoFlow Developer API.

Home Assistant — REST Sensor

Poll this app's REST API from Home Assistant (no MQTT broker needed):

# configuration.yaml
sensor:
  - platform: rest
    name: "EcoFlow Summary"
    resource: http://ECOFLOW_HOST:5000/api/summary
    scan_interval: 60
    json_attributes:
      - units
      - energy_prices
      - grid
    value_template: "{{ value_json.total_soc_percent }}"

  - platform: template
    sensors:
      ecoflow_total_soc:
        value_template: "{{ state_attr('sensor.ecoflow_summary', 'total_soc_percent') }}"
        unit_of_measurement: "%"
        device_class: battery
      ecoflow_import_price:
        value_template: "{{ state_attr('sensor.ecoflow_summary', 'energy_prices').current_import_p_kwh }}"
        unit_of_measurement: "p/kWh"
      ecoflow_savings:
        value_template: "{{ state_attr('sensor.ecoflow_summary', 'savings_p') }}"
        unit_of_measurement: "p"

Octopus Energy API

This app uses the Octopus Energy API for tariff pricing.

Public Endpoints (No API Key)

Tariff rates are publicly accessible — no authentication required:

# Agile import rates (Region J — South East England)
GET https://api.octopus.energy/v1/products/AGILE-24-10-01/
    electricity-tariffs/E-1R-AGILE-24-10-01-J/standard-unit-rates/

# Response: array of half-hourly rates
{
  "results": [
    {
      "valid_from": "2025-01-15T16:30:00Z",
      "valid_to": "2025-01-15T17:00:00Z",
      "value_exc_vat": 28.51,
      "value_inc_vat": 29.94
    }
  ]
}

Authenticated Endpoints

For account-specific data (consumption, meter readings), provide your API key via the Settings page. The key is stored locally in the app database and never sent to third parties.

# Account consumption (requires API key)
GET https://api.octopus.energy/v1/electricity-meter-points/MPAN/meters/SERIAL/consumption/
Authorization: Basic BASE64(API_KEY:)

Product codes used:

  • AGILE-24-10-01 — Octopus Agile Import
  • AGILE-OUTGOING-19-05-13 — Agile Outgoing (export)
  • GO-FIX-12M-26-03-23 — Octopus Go

Region: J (UK Power Networks — South East England)

EcoFlow MQTT Broker

Direct connection to EcoFlow's MQTT broker for device telemetry.

Connection Details

Hostmqtt.ecoflow.com
Port8883 (TLS)
AuthDeveloper API Access Key + HMAC-SHA256 signature
CredentialsGet from EcoFlow Developer Portal

Topic Structure

# Subscribe to device telemetry
/open/api/v1/device/quota/get/{DEVICE_SN}

# Send commands (e.g. set backup reserve)
/open/api/v1/device/quota/set/{DEVICE_SN}

Telemetry Payload

{
  "data": {
    "batSoc": 78,
    "watts": 1200,
    "solarInputWatts": 340,
    "inputWatts": 1540,
    "outputWatts": 200
  }
}

Field names may vary by firmware version. Common alternatives: soc for batSoc, power for watts, solarWatts for solarInputWatts.

Setup

  1. Register at developer-eu.ecoflow.com
  2. Get Access Key and Secret Key
  3. Enter credentials in ⚙️ Settings
  4. App connects automatically — check connection status on the Settings page