PV Production

Note

A PV Production unit consists of an element and a controller. The element defines its static / physical parameters, while the controller governs the operational logic and enforces basic physical constraints on the time series (e.g. horizon, peak power).

The create_controlled_ function creates both and connects them.

Create Controlled Function

pandaprosumer.create_controlled_pv_production(prosumer, latitude, longitude, raddatabase='PVGIS-ERA5', surface_tilt=40, surface_azimuth=0, loss=0, usehorizon=True, userhorizon=None, peakpower=1, pvtechchoice='crystSi', mountingplace='free', trackingtype=0, optimal_surface_tilt=False, optimalangles=False, outputformat='json', url='https://re.jrc.ec.europa.eu/api/v5_2/seriescalc?', map_variables=True, timeout=30, name=None, index=None, in_service=True, level=0, order=0, period=0, **kwargs)[source]

Creates a controlled PV Production component, adds it to the prosumer model, and links it to a PV production controller.

Parameters

prosumerobject

The prosumer container to which the PV production unit will be added.

latitudefloat

Latitude of the PV installation.

longitudefloat

Longitude of the PV installation.

raddatabasestr, optional

Radiation database source, by default ‘PVGIS-ERA5’.

surface_tiltfloat, optional

Tilt angle of the PV surface (degrees), by default 40.

surface_azimuthfloat, optional

Azimuth of the PV surface (degrees), by default 0.

lossfloat, optional

System losses (%), by default 0.

usehorizonbool, optional

Whether to use horizon data, by default True.

userhorizonfloat or None, optional

User-defined horizon, by default None.

peakpowerfloat, optional

Installed PV peak power (kWp), by default 1.

pvtechchoicestr, optional

PV technology type, by default ‘crystSi’.

mountingplacestr, optional

Mounting type, by default ‘free’.

trackingtypeint, optional

PV tracking type, by default 0.

optimal_surface_tiltbool, optional

Whether to use optimal surface tilt, by default False.

optimalanglesbool, optional

Whether to optimize surface angles, by default False.

outputformatstr, optional

API output format, by default ‘json’.

urlstr, optional

PVGIS API endpoint, by default given URL.

map_variablesbool, optional

Map output variables to internal names, by default True.

timeoutint, optional

API timeout (s), by default 30.

in_servicebool, optional

Whether the unit is active, by default True.

namestr, optional

Optional name of the element, by default None.

levelint, optional

Hierarchy level for controller, by default 0.

orderint, optional

Execution order of controller, by default 0.

periodint, optional

Period index for time-based operation, by default 0.

Returns

int

Controller index of the created PV production controller.

Input Static Data

Parameter

Description

Unit

name

Custom name for the PV system

N/A

in_service

Indicates if the PV system is in service

N/A

latitude

Site latitude

deg

longitude

Site longitude

deg

peakpower

Installed PV peak power

kW

loss

System losses (e.g. cables, inverter)

%

Input Time Series

The PV controller expects the following time-series inputs, typically obtained from PVGIS / pvlib or another external PV model.

Parameter

Description

Unit

p_w

Raw PV active power (before constraints)

W

poa_direct_w_m2

Plane-of-array direct irradiance

W/m²

poa_sky_diffuse_w_m2

Diffuse sky irradiance

W/m²

poa_ground_diffuse_w_m2

Diffuse ground irradiance

W/m²

solar_elevation_deg

Solar elevation angle

deg

temp_air_c

Ambient air temperature

°C

wind_speed_m_s

Wind speed at site

m/s

solar_rad_reconstr_bool

Flag indicating reconstructed irradiance

Output Time Series

The PV controller writes a corrected power output and passes through the other variables. The main difference between input and output is that p_w is guaranteed to respect physical and system constraints.

Parameter

Description

Unit

p_w

Corrected PV active power (clamped and clipped)

W

poa_direct_w_m2

Plane-of-array direct irradiance

W/m²

poa_sky_diffuse_w_m2

Diffuse sky irradiance

W/m²

poa_ground_diffuse_w_m2

Diffuse ground irradiance

W/m²

solar_elevation_deg

Solar elevation angle

deg

temp_air_c

Ambient air temperature

°C

wind_speed_m_s

Wind speed at site

m/s

solar_rad_reconstr_bool

Flag indicating reconstructed irradiance

Mapping

The PV production model can be mapped using GenericMapping.

Typical usage:

  • A ConstProfileController (or another data source) feeds the above time series into the PV controller.

  • The corrected p_w output can then be mapped to other controllers, e.g. a heat demand controller via q_received_kw (with an optional conversion from W to kW).

Model

class pandaprosumer.controller.models.pv.PvProductionController(prosumer, pv_production_object, order, level, data_source=None, in_service=True, index=None, **kwargs)[source]

Controller for PV production.

This controller represents a simple PV model that:

  • Reads static PV system parameters from the element data

  • Receives time-series inputs (irradiance, solar elevation, etc.) via the generic mapping into self.inputs.

  • Applies constraints to the active power output p_w (in W):

    • Negative power is clamped to 0 W.

    • If the solar elevation is below the horizon (solar_elevation_deg < 0), power is set to 0 W.

    • Power is limited to the installed peak power (“peakpower [kW] * 1000”).

Writes the corrected power into self.step_results and into the controller’s time-series result array via finalize()

The detailed PV production (e.g. from PVGIS / pvlib) is computed outside and provided as time series inputs, but this controller ensures that the resulting time series are only consistent with basic physical constraints and the installed system size.

control_step(prosumer)[source]

Main control logic for the PV controller.

-Start from the time-series inputs in self.inputs which are

via GenericMapping (irradiance, solar elevation, etc., and possibly a raw p_w).

-For each controlled PV element:
  • Read the power p_w [W].

  • Apply basic physical constraints: - If solar_elevation_deg < 0p_w := 0. - If p_w < 0p_w := 0. - If p_w > peakpower_kw * 1000 → clip to that value.

-Store the corrected values as the controller’s results via

self.finalize().

Parameters

prosumerobject

Prosumer container.

is_converged(container)[source]

This method calculated whether or not the controller converged. This is where any target values are being calculated and compared to the actual measurements. Returns convergence of the controller.

Parameters

container_type_

_description_

Returns

_type_

_description_

classmethod name()[source]

Name of the PV Production time series

The PV production controller does not compute detailed PV physics itself. Instead, it receives a pre-calculated active power time series and enforces basic constraints based on system size and solar geometry.

For each time step, the raw input power \(p_\text{raw}\) is transformed into a physically consistent output \(p_\text{out}\) as follows:

\begin{align*} &\text{If } \theta_\text{elev} < 0^\circ \quad \Rightarrow \quad p_\text{out} = 0 \\ &\text{Else } \\ &\quad p_\text{out} = \max(0,\; p_\text{raw}) \\ &\quad p_\text{out} = \min\left(p_\text{out},\; P_\text{peak} \cdot 1000\right) \end{align*}

Where:

  • \(\theta_\text{elev}\) is the solar elevation angle (solar_elevation_deg).

  • \(P_\text{peak}\) is the installed peak power in kW (peakpower element field).

  • \(p_\text{out}\) is written to the p_w output column.

This ensures that the PV output is always:

  • zero when the sun is below the horizon,

  • non-negative,

  • and never exceeds the installed peak capacity.