Arrays and Mounting Configuration#
This page explains how collector arrays and their mounting configurations work in SunPeek, including fixed-tilt installations and single-axis tracking systems.
Overview#
In SunPeek, a collector array represents a group of solar thermal collectors that share the same orientation, collector type, and sensor connections. Arrays are the primary unit for Power Check analysis.
The mounting configuration defines how collectors are oriented relative to the sun:
Fixed mounting (
MountingFixed): Collectors have a constant tilt and azimuth angle.Single-axis tracking (
MountingSingleAxis): Collectors rotate around one axis to follow the sun.
Note
Single-axis tracking support is available in the Python API. WebUI support for configuring tracking arrays is planned for a future release.
Mounting Types#
MountingFixed#
Use MountingFixed for fixed-tilt installations where collectors maintain a constant orientation.
Parameters:
Parameter |
Description |
Unit |
Range |
|---|---|---|---|
|
Tilt angle from horizontal plane |
degree |
0-90 |
|
Compass direction the collectors face (North=0, East=90, South=180, West=270) |
degree |
0-360 |
Example:
from sunpeek.components import Array, MountingFixed
from sunpeek.common.unit_uncertainty import Q
# South-facing collectors tilted at 30 degrees
mounting = MountingFixed(
surface_tilt=Q(30, 'deg'),
surface_azimuth=Q(180, 'deg'), # South
)
array = Array(
name='Fixed array',
plant=plant,
collector=collector,
mounting=mounting,
area_gr=Q(500, 'm**2'),
sensor_map={...},
)
MountingSingleAxis#
Use MountingSingleAxis for single-axis tracking installations where collectors rotate around
a fixed axis to follow the sun. The surface orientation is calculated automatically based on
sun position using pvlib.
Configuration Parameters:
Parameter |
Description |
Unit |
Range |
|---|---|---|---|
|
Tilt angle of the rotation axis from horizontal |
degree |
0-90 |
|
Compass direction of the rotation axis (North=0, East=90, South=180, West=270) |
degree |
0-360 |
|
Maximum rotation angle from the horizontal position |
degree |
0-90 |
Common Configurations:
Horizontal N-S axis (tracks E-W):
axis_tilt=0,axis_azimuth=180Horizontal E-W axis (tracks N-S):
axis_tilt=0,axis_azimuth=90Tilted axis: Set
axis_tiltto match latitude for optimal year-round performance
Example:
from sunpeek.components import Array, MountingSingleAxis
from sunpeek.common.unit_uncertainty import Q
# Horizontal N-S axis tracker (tracks east-to-west)
mounting = MountingSingleAxis(
axis_tilt=Q(0, 'deg'), # Horizontal rotation axis
axis_azimuth=Q(180, 'deg'), # N-S orientation
max_angle=Q(60, 'deg'), # Maximum rotation from horizontal
)
array = Array(
name='Tracking array',
plant=plant,
collector=collector,
mounting=mounting,
area_gr=Q(500, 'm**2'),
sensor_map={...},
)
Virtual Sensors for Tracking Arrays#
When using MountingSingleAxis, SunPeek automatically calculates time-varying surface orientation
based on the sun position and tracker configuration. These values are available as virtual sensors:
Sensor |
Description |
Virtual |
|---|---|---|
|
Instantaneous tilt angle of collector surface |
Always calculated |
|
Instantaneous azimuth angle of collector surface |
Always calculated |
|
Optimal tracker rotation angle based on sun position |
Always calculated |
|
Actual measured rotation angle (if sensor available) |
Optional (measured) |
Accessing Virtual Sensors:
# After loading measurement data
use_csv(plant, csv_files=[...])
# Access time-varying surface orientation
tracking_array = plant.arrays[0]
# Get surface tilt as a time series (pint-pandas Series)
surface_tilt = tracking_array.mounting.surface_tilt.data
print(f"Surface tilt range: {surface_tilt.min():.1f} to {surface_tilt.max():.1f}")
# Get ideal rotation angle
ideal_rotation = tracking_array.mounting.ideal_rotation_angle.data
The virtual sensors are calculated using pvlib.tracking.singleaxis().
Array Properties#
Arrays provide convenient properties for accessing orientation, regardless of mounting type:
# For fixed mounting, tilt and azim are scalar Quantities
if array.has_orientation():
print(f"Tilt: {array.tilt}")
print(f"Azimuth: {array.azim}")
# For tracking mounting, tilt and azim are Sensor objects
# containing time-series data
if not array.has_orientation():
print("Tracking array - orientation varies with time")
print(f"Tilt data: {array.tilt.data.head()}")
# The orientation property returns tilt/azim in degrees
# Works for both fixed (scalar) and tracking (raises if time-varying)
if array.has_orientation():
orient = array.orientation
print(f"Orientation: tilt={orient['tilt']}°, azim={orient['azim']}°")
Backward Compatibility#
For backward compatibility, the legacy tilt and azim parameters on Array still work.
They are automatically converted to MountingFixed internally:
# Legacy syntax (still works)
array = Array(
name='Array',
plant=plant,
collector=collector,
tilt=Q(30, 'deg'),
azim=Q(180, 'deg'),
area_gr=Q(500, 'm**2'),
sensor_map={...},
)
# Internally creates: MountingFixed(surface_tilt=Q(30,'deg'), surface_azimuth=Q(180,'deg'))
# Recommended new syntax
array = Array(
name='Array',
plant=plant,
collector=collector,
mounting=MountingFixed(
surface_tilt=Q(30, 'deg'),
surface_azimuth=Q(180, 'deg'),
),
area_gr=Q(500, 'm**2'),
sensor_map={...},
)
Hint
While the legacy syntax is supported, we recommend using the explicit mounting parameter
for new code to make the mounting configuration clear and enable future tracking support.
Additional Array Parameters#
Beyond mounting configuration, arrays have additional parameters for shading and layout calculations:
Parameter |
Description |
Unit |
Required |
|---|---|---|---|
|
Descriptive name for the array |
— |
Yes |
|
Collector type used in this array |
— |
Yes |
|
Mounting configuration ( |
— |
Yes |
|
Total gross collector area |
m² |
Yes |
|
Distance between collector rows (for shading calculations) |
m |
No |
|
Slope of the ground beneath collectors |
degree |
No |
|
Mapping of sensor slots to sensor objects |
— |
Yes |
For details on sensor mapping, see Sensor Mapping.
See also
Collectors — Solar collector types and parameters
Fluids — Heat transfer fluid configuration
Shading — Internal shading algorithms
Advanced Topics — Advanced Python API examples including tracking arrays