SenergyNets 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_senergy_nets_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 Senergy Nets 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 SenergyNets 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.SenergyNetsPvProductionController(prosumer, pv_production_object, order, level, data_source=None, in_service=True, index=None, **kwargs)[source]

Controller for SenergyNets 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.

finalize_control(container)[source]

Some controller require extended finalization. This method is being called at the end of a loadflow. It is a separate method from restore_init_state because it is possible that control finalization does not only restore the init state but also something in addition to that, that would require the results in net.

Parameters

container_type_

_description_

finalize_step(container, time)[source]

After each time step, this method is being called to clean things up or similar. The OutputWriter is a class specifically designed to store results of the loadflow. If the ControlHandler.output_writer got an instance of this class, it will be called before the finalize step.

Parameters

container_type_

_description_

time_type_

_description_

Note

This method is ONLY being called during time-series simulation!

initialize_control(container)[source]

Some controller require extended initialization in respect to the current state of the net (or their view of it). This method is being called after an initial loadflow but BEFORE any control strategies are being applied.

This method may be interesting if you are aiming for a global controller or if it has to be aware of its initial state.

Parameters

container_type_

_description_

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_

level_reset(prosumer)[source]

Resets the level for the controller.

Parameters:

container – The container object

classmethod name()[source]

Name of the PV Production time series

repair_control(container)[source]

Some controllers can cause net to not converge. In this case, they can implement a method to try and catch the load flow error by altering some values in net, for example load scaling. This method is being called in the except block in run_control. Either implement this in a controller that is likely to cause the error, or define a special “load flow police” controller for your use case.

Parameters

container_type_

_description_

restore_init_state(container)[source]

Some controllers manipulate values in net and then restore them back to initial values, e.g. DistributedSlack. This method should be used for such a purpose because it is executed in the except block of run_control to make sure that the net condition is restored even if load flow calculation doesn’t converge.

Parameters

container_type_

_description_

set_active(container, in_service)[source]

Sets the controller in or out of service.

Parameters

container_type_

_description_

in_servicebool

parameter descriving whether the chiller is in service (True, default) or not (False).

time_series_finalization(prosumer)[source]

Finalisation of the time series

Parameters

prosumerobject of type prosumer

Prosumer container

time_series_initialization(prosumer)[source]

Initialisation of the time_series

Parameters

prosumerobject of type prosumer

Prosumer container

time_step(prosumer, time)[source]

It is the first call in each time step, thus suited for things like reading profiles or prepare the controller for the next control step.

Note

This method is ONLY being called during time-series simulation!

Parameters

prosumerobject of type prosumer

Prosumer container

timefloat

current time step

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.