Files
PV_Simulator/README.md

8.3 KiB

☀️ cyberbee PV Simulator

A modular, realistic photovoltaic plant simulator written in Python.

cyberbee PV Simulator generates synthetic time-series data for an entire PV plant hierarchy — from individual panels up to the plant level — with physically grounded models, configurable fault injection, and multi-format export.


Features

Physical modelling

  • Solar position computed via pvlib (elevation, azimuth, zenith, angle of incidence)
  • Clear-sky irradiance with seasonal and daily variation (GHI, DNI, DHI, POA)
  • Module temperature model (simplified NOCT approach)
  • Temperature coefficient applied to power output
  • Annual degradation of panels
  • Sensor noise (Gaussian)

Fault simulation

  • Panel failure, soiling, and partial shading
  • Combiner box offline
  • Inverter shutdown
  • Configurable daily failure probabilities per component level
  • Fault severity and reduction factors

Weather

  • Configurable cloud factor with random variability
  • Rain events with daily probability
  • Ambient temperature (annual mean + daily swing)

Hierarchical aggregation

PV Plant
├── Inverter 1
│   ├── Combiner Box 1
│   │   ├── String 1 → Panel 1 … Panel 20
│   │   └── String 2 → Panel 1 … Panel 20
│   └── Combiner Box 2
│       └── ...
└── Inverter 2
    └── ...

Output & export

  • CSV, Parquet, JSON, SQLite
  • Per-component time series (panel, combiner, inverter, plant, weather, faults)
  • KPI and statistics: energy yield, performance ratio, availability, specific yield, clipping losses, daily/monthly aggregations, fault summaries

Project Structure

pv_simulator/
│
├── config/
│   └── plant.json          # Plant configuration
│
├── pvsim/
│   ├── __init__.py
│   ├── panel.py            # PVPanel model
│   ├── combiner.py         # CombinerBox model
│   ├── inverter.py         # Inverter model
│   ├── plant.py            # PVPlant (top-level object)
│   ├── sun.py              # Solar position model (pvlib)
│   ├── weather.py          # Meteorological model
│   ├── faults.py           # Fault manager and fault types
│   ├── simulator.py        # Simulation engine (PVSimulator)
│   ├── exporter.py         # CSV / Parquet / JSON export
│   ├── statistics.py       # KPI and statistics
│   └── utils.py            # Shared utilities
│
├── output/                 # Generated data (auto-created)
│
├── run.py                  # Entry point
├── requirements.txt
└── README.md

Installation

git clone https://github.com/your-username/pv-simulator.git
cd pv-simulator

python -m venv .venv
source .venv/bin/activate        # Linux / macOS
# .venv\Scripts\activate         # Windows

pip install -r requirements.txt

Requirements

Library Purpose
numpy Numerical computations
pandas Time-series management, CSV/Parquet export
matplotlib Production charts
scipy Statistical distributions and realistic noise
pvlib Solar position, irradiance models, PV physics
networkx Plant hierarchy representation
pyyaml YAML configuration support
tqdm Progress bar for long simulations

Configuration

The entire plant is described in pv_simulator/config/plant.json. No code changes are needed to resize or reconfigure the plant.

{
  "plant": {
    "name": "ZAK_PV_Simulator",
    "location": {
      "latitude": 45.4642,
      "longitude": 9.1900,
      "timezone": "Europe/Rome",
      "altitude": 120
    },
    "simulation": {
      "time_resolution_minutes": 5,
      "start_date": "2026-01-01 00:00:00",
      "end_date": "2026-12-31 23:55:00"
    }
  },
  "layout": {
    "inverters": [
      {
        "id": "INV_001",
        "nominal_power_kW": 100,
        "combiners": [
          {
            "id": "CB_001",
            "strings": 4,
            "panels_per_string": 20,
            "orientation": { "tilt_deg": 30, "azimuth_deg": 180 }
          }
        ]
      }
    ]
  }
}

The default configuration generates:

Component Count
Inverters 2
Combiner boxes 3
Panels 240
Nominal DC power 108 kWp

Usage

Run a full simulation

from datetime import datetime
from pvsim.simulator import PVSimulator, SimulationConfig
from pvsim.exporter import SimulationExporter
from pvsim.statistics import SimulationStatistics

config = SimulationConfig(
    start=datetime(2026, 6, 21),
    end=datetime(2026, 6, 22),
    timestep_minutes=5,
    generate_random_faults=True,
)

result = simulator.run(config)

Compute KPIs

stats = SimulationStatistics(result)
kpi = stats.plant_kpi()

print(f"Energy produced : {kpi.energy_kWh:.1f} kWh")
print(f"Peak power      : {kpi.peak_power_W:.0f} W")
print(f"Performance ratio: {kpi.performance_ratio:.2%}")
print(f"Availability    : {kpi.availability:.2%}")

Export data

exporter = SimulationExporter(output_dir="output")
exporter.export_all(result, csv=True, parquet=True, json=True, statistics=True)

Output Structure

output/
│
├── simulation.json            # Simulation summary
├── plant_kpi.json             # Plant-level KPIs
│
├── panel_kpi.csv
├── combiner_kpi.csv
├── inverter_kpi.csv
├── daily_statistics.csv
├── monthly_statistics.csv
├── fault_summary.csv
│
├── csv/
│   ├── weather.csv
│   ├── panel.csv
│   ├── combiner.csv
│   ├── inverter.csv
│   ├── plant.csv
│   └── faults.csv
│
└── parquet/
    ├── weather.parquet
    ├── panel.parquet
    ├── combiner.parquet
    ├── inverter.parquet
    ├── plant.parquet
    └── faults.parquet

Data Model

Each simulation timestep produces records at every level of the hierarchy.

Panel

Field Description
timestamp Measurement instant
irradiance_Wm2 Incident irradiance
module_temperature_C Module temperature
voltage_V Panel voltage
current_A Panel current
power_W Instantaneous power
energy_Wh Energy in timestep
soiling_factor Soiling loss factor
degradation_factor Cumulative degradation
enabled Panel operational status

Combiner Box

Field Description
dc_power_W Aggregated DC power
dc_voltage_V Bus voltage
dc_current_A Total current
active_panel_count Active panels
availability Fraction of active panels
status normal / idle / fault

Inverter

Field Description
dc_power_W DC input power
ac_power_W AC output power
efficiency Conversion efficiency
clipping_loss_W Clipping losses
temperature_C Internal temperature
status normal / idle / fault

Plant

Field Description
ac_power_W Total AC power
energy_Wh Energy in timestep
performance_ratio PR (AC / nominal)
availability Active panel fraction
fault_active Any active fault

Simulation Pipeline

pv_simulator/config/plant.json
       │
       ▼
   PVPlant (built from config)
       │
       ▼
   PVSimulator.run()
       │
       ▼
   SimulationResult
       │
       ├──────────────────┐
       ▼                  ▼
 statistics.py       exporter.py
       │                  │
       ▼                  ├── CSV
      KPI                 ├── Parquet
                          ├── JSON
                          └── SQLite (optional)

Planned Improvements

  • Single-diode model via pvlib for accurate I-V curves
  • Partial shading with bypass diode simulation
  • String-level mismatch modelling
  • Hot-spot simulation
  • Sensor drift and intermittent faults
  • Streaming / chunked export for multi-year simulations at 5-minute resolution
  • Diagnostic alarms per component
  • Interactive dashboard (Plotly / Streamlit)

License

MIT License — see LICENSE for details.


Built as part of the ZAK project — a Linux-based measurement and monitoring platform for industrial and renewable energy systems.