SenergyNets PV Production
See also
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_woutput can then be mapped to other controllers, e.g. a heat demand controller viaq_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_resultsand into the controller’s time-series result array viafinalize()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.inputswhich are via
GenericMapping(irradiance, solar elevation, etc., and possibly a rawp_w).- -For each controlled PV element:
Read the power
p_w[W].Apply basic physical constraints: - If
solar_elevation_deg < 0→p_w := 0. - Ifp_w < 0→p_w := 0. - Ifp_w > peakpower_kw * 1000→ clip to that value.
- -Store the corrected values as the controller’s results via
self.finalize().
Parameters
- prosumerobject
Prosumer container.
- -Start from the time-series inputs in
- 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
- 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:
Where:
\(\theta_\text{elev}\) is the solar elevation angle (
solar_elevation_deg).\(P_\text{peak}\) is the installed peak power in kW (
peakpowerelement field).\(p_\text{out}\) is written to the
p_woutput 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.