# Distro Energy Profiles

This directory contains 2025 solar production profiles for the middle of the Netherlands in 15-minute resolution.

The profiles are based on 2025 solar radiation data for central Netherlands and are written in the same CSV shape as the provided template:

```csv
timestamp,pv_kWh_per_15min,ptu
```

The `pv_kWh_per_15min` values are negative, matching the export convention used in the template file.

## Included files

- `standard_solar_2025_15min.csv`
- `high_yield_solar_2025_15min.csv`
- `conservative_solar_2025_15min.csv`
- `commercial_rooftop_solar_2025_15min.csv`
- `ev_workplace_2025_15min.csv`
- `ev_residential_evening_2025_15min.csv`
- `ev_mixed_daytime_rotation_2025_15min.csv`
- `ev_247_availability_2025_15min.csv`
- `heat_standard_2025_15min.csv`
- `heat_high_efficiency_2025_15min.csv`
- `heat_conservative_2025_15min.csv`
- `heat_commercial_2025_15min.csv`
- `solar_profile_viewer.html`
- `generate_solar_profiles_2025.py`
- `generate_ev_profiles_2025.py`
- `generate_heat_profiles_2025.py`
- `battery_peak_shaving_2025.py`

## Profile assumptions

These are normalized as approximate `kWh per kWp per year` style profiles:

- Standard Solar: `1000 kWh/kWp/year`
- High Yield Solar: `1100 kWh/kWp/year`
- Conservative Solar: `900 kWh/kWp/year`
- Commercial Rooftop Solar: `980 kWh/kWp/year`

The four profiles are shaped to reflect different performance assumptions:

- Standard Solar: typical residential PV
- High Yield Solar: optimized high-performance PV
- Conservative Solar: lower-output scenario with shading or installation constraints
- Commercial Rooftop Solar: stable commercial rooftop production

## How scaling works

All profiles in this folder are normalized templates. The CSV values are not tied to one fixed asset size unless stated by the normalization rule below.

Apply scaling as follows:

- Solar profiles: scale by installed PV capacity in `kWp`
- EV profiles: scale by charger power in `kW`
- Heat pump profiles: scale by annual gas-equivalent heat demand in `m³`

Examples:

- Solar: if a solar profile represents `1000 kWh/kWp/year`, then a `4.2 kWp` system uses `profile_value * 4.2`
- EV: if an EV interval value is `0.18 kWh per 15 min per kW`, then an `11 kW` charger uses `0.18 * 11 = 1.98 kWh` in that interval
- Heat pump: if a heat profile sums to `2.933 kWh per m³ gas eq`, then `1200 m³/year` maps to `2.933 * 1200 = 3519.6 kWh/year`

In all three cases, the shape stays the same and only the magnitude changes.

## Battery peak shaving

Battery behavior is modeled differently from the static solar, EV, and heat templates.

Instead of a fixed battery CSV shape, this repository includes a simulator:

```text
battery_peak_shaving_2025.py
```

It applies a simple control strategy to an existing 15-minute profile:

- discharge when net import rises above a chosen peak threshold
- optionally charge when net load is below a lower threshold
- always absorb export if the site is exporting and the battery still has room

The simulator writes:

```csv
timestamp,base_profile_kWh_per_15min,battery_power_kWh_per_15min,soc_kWh,net_load_after_battery_kWh_per_15min,ptu
```

Sign convention:

- `battery_power_kWh_per_15min > 0`: battery discharging
- `battery_power_kWh_per_15min < 0`: battery charging
- `net_load_after_battery_kWh_per_15min`: the resulting profile after battery action

Typical inputs:

- input scaling factor if the source profile is normalized
- battery capacity in `kWh`
- power limit in `kW`
- peak-shaving threshold in `kW`
- optional charge-below threshold in `kW`
- round-trip efficiency
- min, max, and initial state of charge

Example:

```bash
cd distro-energy-profiles
python3 battery_peak_shaving_2025.py \
  --input ev_workplace_2025_15min.csv \
  --output ev_workplace_with_battery_2025_15min.csv \
  --input-scale 22 \
  --capacity-kwh 120 \
  --power-kw 60 \
  --threshold-kw 35 \
  --charge-below-kw 15 \
  --allow-grid-charging
```

This will first scale the normalized EV workplace profile to a `22 kW` charger, then run the battery controller on top of it, and create a new CSV with both battery dispatch and the post-battery net load.

## DST handling

The timestamps use `Europe/Amsterdam` local time and explicitly account for daylight saving time in 2025:

- On `30/03/2025`, the `02:00` hour is skipped
- On `26/10/2025`, the `02:00` hour appears twice

That means each profile contains `35040` quarter-hour rows for the local 2025 calendar year.

## EV charging profiles

The EV profiles are normalized charging-shape profiles with the column:

```csv
timestamp,load_kWh_per_15min_per_kw,ptu
```

Interpretation:

- the value is `kWh per 15 minutes` for `1 kW` of charger power
- to scale to a charger size, multiply the value by the charger rating in `kW`
- example: `0.18 * 11 = 1.98 kWh` in that 15-minute interval for an `11 kW` charger
- annual totals scale linearly with charger power as well

Included EV patterns:

- `ev_workplace_2025_15min.csv`: daytime workplace charging pattern, mainly weekdays between 09:00 and 17:00
- `ev_residential_evening_2025_15min.csv`: residential evening and overnight charging, mainly between 18:00 and 08:00
- `ev_mixed_daytime_rotation_2025_15min.csv`: distributed daytime charging across rotating usage windows
- `ev_247_availability_2025_15min.csv`: always-available profile with a flatter spread over the day

## Heat pump profiles

The heat pump profiles are normalized weather-based electrical load profiles with the column:

```csv
timestamp,load_kWh_per_15min_per_m3_gas_eq,ptu
```

Interpretation:

- the annual sum equals the electricity needed to replace `1 m³` of annual gas-equivalent heat demand
- the reference conversion is `8.8 kWh` of useful heat per `1 m³` gas
- scale by annual gas demand in `m³`
- interval values and annual totals both scale linearly with the chosen `m³/year` demand

Example:

- if `heat_standard_2025_15min.csv` sums to about `2.933 kWh` per `1 m³`
- then a building with `1200 m³/year` gas-equivalent heat demand maps to `1200 * 2.933 = 3519.6 kWh/year` electrical heat pump demand

Included heat pump patterns:

- `heat_standard_2025_15min.csv`: typical residential operation, SCOP about `3.0`
- `heat_high_efficiency_2025_15min.csv`: optimized high-efficiency operation, SCOP about `3.8`
- `heat_conservative_2025_15min.csv`: lower-efficiency scenario, SCOP about `2.25`
- `heat_commercial_2025_15min.csv`: steadier commercial building heating load, SCOP about `3.4`

## Viewer

Open `solar_profile_viewer.html` to inspect profiles in a graph.

The page supports:

- bundled profile selection from the dropdown
- automatic graph refresh when the dropdown selection changes
- 15-minute graph viewing with range selection for full year, month, week, or day
- EV charger scaling in the viewer for `11 / 22 / 50 / 150 kW`
- generic parsing of the second CSV value column, so it can also be reused for future EV charging, heat pump, or other energy profiles

If your browser blocks loading local CSV files from the dropdown when opening the HTML directly, start a simple local server:

```bash
cd distro-energy-profiles
python3 -m http.server
```

Then open:

```text
http://localhost:8000/solar_profile_viewer.html
```

## Regenerating the CSVs

To regenerate the four solar profiles:

```bash
cd distro-energy-profiles
python3 generate_solar_profiles_2025.py
```

The script reads:

- `nasa_power_nl_mid_2025.json`

and writes the four CSV outputs again.

To regenerate the EV profiles:

```bash
cd distro-energy-profiles
python3 generate_ev_profiles_2025.py
```

To regenerate the heat pump profiles:

```bash
cd distro-energy-profiles
python3 generate_heat_profiles_2025.py
```

To simulate a battery peak-shaving strategy on any profile:

```bash
cd distro-energy-profiles
python3 battery_peak_shaving_2025.py --help
```

## Data source

Reference solar data was taken from NASA POWER hourly solar radiation data for 2025 and converted to 15-minute local Dutch timestamps.
