# rudy-smith/gb-bess-dispatch architecture

> Architecture diagram of the GitHub repository rudy-smith/gb-bess-dispatch, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/rudy-smith/gb-bess-dispatch
- Repository: https://github.com/rudy-smith/gb-bess-dispatch

## Overview

This repository is a GB grid-scale battery arbitrage research and dispatch optimiser. Its main workflow obtains Elexon market prices, maps them to GB settlement periods, cleans and gates data, solves daily battery dispatch, independently replays schedules, and compares performance with a threshold baseline. The README also documents degradation and duration/efficiency studies and a NESO forecast-data client. Script-level orchestration is inferred from documented capabilities and filenames; unsampled source limits certainty about exact wiring.

Main entry points: [`scripts/build_dataset.py`](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/build_dataset.py) (Build dataset), [`src/model/milp.py`](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/model/milp.py) (MILP optimiser), [`scripts/solve_day.py`](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/solve_day.py) (Daily solve), [`scripts/run_benchmark.py`](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/run_benchmark.py) (Benchmark run)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_market_data["Market data"]
  node_fetch_prices["Fetch prices<br/>[fetch_prices.py]"]
  node_elexon_client["Elexon client<br/>[elexon.py]"]
  node_raw_data[("Raw price cache")]
  node_neso_client["NESO client<br/>[neso.py]"]
end

subgraph group_preparation["Data preparation"]
  node_build_dataset["Build dataset<br/>[build_dataset.py]"]
  node_calendar["GB calendar<br/>[calendar_gb.py]"]
  node_cleaner["Price cleaning<br/>[clean.py]"]
  node_processed_data[("Processed data")]
end

subgraph group_dispatch["Dispatch and validation"]
  node_solve_day["Daily solve<br/>[solve_day.py]"]
  node_benchmark["Benchmark run<br/>[run_benchmark.py]"]
  node_battery["Battery model<br/>[battery.py]"]
  node_milp["MILP optimiser<br/>[milp.py]"]
  node_replay["Independent replay<br/>[battery.py]"]
end

subgraph group_analysis["Strategy analysis"]
  node_baseline["Threshold baseline<br/>[baselines.py]"]
  node_baseline_run["Baseline run<br/>[run_baseline.py]"]
  node_degradation["Degradation sweep"]
  node_sensitivity["Sensitivity analysis<br/>[run_sensitivity.py]"]
  node_results[("Results")]
end

node_operator(("Analyst"))
node_elexon_api["Elexon API"]
node_neso_api["NESO portal"]

node_operator -->|"requests data"| node_fetch_prices
node_fetch_prices -->|"fetches prices"| node_elexon_client
node_elexon_client -->|"queries API"| node_elexon_api
node_elexon_client -->|"caches rows"| node_raw_data
node_operator -->|"builds dataset"| node_build_dataset
node_build_dataset -->|"reads prices"| node_raw_data
node_build_dataset -->|"maps periods"| node_calendar
node_build_dataset -->|"cleans data"| node_cleaner
node_build_dataset -->|"writes dataset"| node_processed_data
node_operator -->|"solves day"| node_solve_day
node_solve_day -->|"reads prices"| node_processed_data
node_solve_day -->|"uses specification"| node_battery
node_solve_day -->|"solves dispatch"| node_milp
node_milp -->|"audits schedule"| node_replay
node_operator -->|"runs benchmark"| node_benchmark
node_benchmark -->|"reads prices"| node_processed_data
node_benchmark -->|"optimises days"| node_milp
node_benchmark -->|"writes results"| node_results
node_operator -->|"runs comparison"| node_baseline_run
node_baseline_run -->|"reads prices"| node_processed_data
node_baseline_run -->|"runs rule"| node_baseline
node_baseline_run -->|"writes results"| node_results
node_operator -->|"runs sweep"| node_degradation
node_degradation -->|"varies wear cost"| node_milp
node_degradation -->|"writes results"| node_results
node_operator -->|"runs scenarios"| node_sensitivity
node_sensitivity -->|"varies parameters"| node_milp
node_sensitivity -->|"writes results"| node_results
node_neso_client -.->|"queries forecasts"| node_neso_api

click node_fetch_prices "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/fetch_prices.py"
click node_elexon_client "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/fetch/elexon.py"
click node_raw_data "https://github.com/rudy-smith/gb-bess-dispatch/tree/main/data/raw"
click node_neso_client "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/fetch/neso.py"
click node_build_dataset "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/build_dataset.py"
click node_calendar "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/prep/calendar_gb.py"
click node_cleaner "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/prep/clean.py"
click node_processed_data "https://github.com/rudy-smith/gb-bess-dispatch/tree/main/data/processed"
click node_solve_day "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/solve_day.py"
click node_benchmark "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/run_benchmark.py"
click node_battery "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/model/battery.py"
click node_milp "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/model/milp.py"
click node_replay "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/model/battery.py"
click node_baseline "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/model/baselines.py"
click node_baseline_run "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/run_baseline.py"
click node_degradation "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/run_degradation_sweep.py"
click node_sensitivity "https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/run_sensitivity.py"
click node_results "https://github.com/rudy-smith/gb-bess-dispatch/tree/main/data/processed"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_fetch_prices,node_elexon_client,node_raw_data,node_neso_client toneBlue
class node_build_dataset,node_calendar,node_cleaner,node_processed_data toneAmber
class node_solve_day,node_benchmark,node_battery,node_milp,node_replay,node_elexon_api toneMint
class node_baseline,node_baseline_run,node_degradation,node_sensitivity,node_results toneRose
class node_operator,node_neso_api toneIndigo
```

## Components

### Market data

- [Fetch prices](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/fetch_prices.py): `scripts/fetch_prices.py`
- [Elexon client](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/fetch/elexon.py): `src/fetch/elexon.py`
- [Raw price cache](https://github.com/rudy-smith/gb-bess-dispatch/tree/main/data/raw): `data/raw`
- [NESO client](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/fetch/neso.py): `src/fetch/neso.py`

### Data preparation

- [Build dataset](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/build_dataset.py): `scripts/build_dataset.py`
- [GB calendar](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/prep/calendar_gb.py): `src/prep/calendar_gb.py`
- [Price cleaning](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/prep/clean.py): `src/prep/clean.py`
- [Processed data](https://github.com/rudy-smith/gb-bess-dispatch/tree/main/data/processed): `data/processed`

### Dispatch and validation

- [Daily solve](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/solve_day.py): `scripts/solve_day.py`
- [Benchmark run](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/run_benchmark.py): `scripts/run_benchmark.py`
- [Battery model](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/model/battery.py): `src/model/battery.py`
- [MILP optimiser](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/model/milp.py): `src/model/milp.py`
- [Independent replay](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/model/battery.py): `src/model/battery.py`

### Strategy analysis

- [Threshold baseline](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/src/model/baselines.py): `src/model/baselines.py`
- [Baseline run](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/run_baseline.py): `scripts/run_baseline.py`
- [Degradation sweep](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/run_degradation_sweep.py): `scripts/run_degradation_sweep.py`
- [Sensitivity analysis](https://github.com/rudy-smith/gb-bess-dispatch/blob/main/scripts/run_sensitivity.py): `scripts/run_sensitivity.py`
- [Results](https://github.com/rudy-smith/gb-bess-dispatch/tree/main/data/processed): `data/processed`

### Other components

- **Analyst**
- **Elexon API**
- **NESO portal**

## Connections

- Analyst → Fetch prices: requests data
- Fetch prices → Elexon client: fetches prices
- Elexon client → Elexon API: queries API
- Elexon client → Raw price cache: caches rows
- Analyst → Build dataset: builds dataset
- Build dataset → Raw price cache: reads prices
- Build dataset → GB calendar: maps periods
- Build dataset → Price cleaning: cleans data
- Build dataset → Processed data: writes dataset
- Analyst → Daily solve: solves day
- Daily solve → Processed data: reads prices
- Daily solve → Battery model: uses specification
- Daily solve → MILP optimiser: solves dispatch
- MILP optimiser → Independent replay: audits schedule
- Analyst → Benchmark run: runs benchmark
- Benchmark run → Processed data: reads prices
- Benchmark run → MILP optimiser: optimises days
- Benchmark run → Results: writes results
- Analyst → Baseline run: runs comparison
- Baseline run → Processed data: reads prices
- Baseline run → Threshold baseline: runs rule
- Baseline run → Results: writes results
- Analyst → Degradation sweep: runs sweep
- Degradation sweep → MILP optimiser: varies wear cost
- Degradation sweep → Results: writes results
- Analyst → Sensitivity analysis: runs scenarios
- Sensitivity analysis → MILP optimiser: varies parameters
- Sensitivity analysis → Results: writes results
- NESO client → NESO portal: queries forecasts
