Welcome
Welcome to Proximal Energy's documentation website. This website is intended to provide a comprehensive guide to the various aspects of Proximal Energy's software. The website is divided into several sections, each of which is designed to provide a detailed explanation of a specific aspect of each of the main functionalities of the platform.
Hints
- The entire documentation set can be exported as PDF by clicking on the printer icon in the top right hand corner of the page.
- You can press the left and right arrow keys on your keyboard to navigate to the previous and next page respectively.
Commissioning Overview
This document describes all of the things necessary to commission a project in Proximal. It can be used as a checklist for each project you would like to bring online.
System and SCADA Definition
Required Documents
Your contact at Proximal will provide you a Google Sheet to fill out for your specific project. This google sheet mirrors a combiner shedule diagram in your IFC or as-built construction documents and will be used by our team to set up your project in our database.
Performance Modeling
Required Documents
- PAN file: Used for module modeling
- OND file: Used for inverter modeling
- Transformer Spec Sheet
Events Overview
An Event is a time-bounded, addressable period of project or component underperformance. The Events pipeline turns operational telemetry into Event records, assigns the most defensible device and failure mode, calculates energetic or financial impact where possible, and keeps the set of active Events shown in the platform up to date.
An Event is not simply an alarm. It is the pipeline's reconciled interpretation of several kinds of evidence:
- measured power relative to a device's expected participation;
- decoded equipment status and alarm bits;
- BESS charge and discharge availability;
- PV irradiance and expected operating conditions;
- tracker position relative to an ideal tracking profile;
- curtailment setpoints and related controls;
- the plant's device hierarchy; and
- previously detected Events that overlap the current analysis window.
The pipeline is deliberately heuristic. It favors operationally useful, addressable Events over emitting every anomalous sample. In particular, it suppresses short glitches, retains uncertainty when telemetry is missing, consolidates simultaneous child failures at an actionable ancestor, and reconciles every new detection with existing Event history.
Documentation map
- Events Pipeline follows an Event from analysis through persistence, losses, and the active-Event list shown in the platform.
- Event Detection Methods explains PV detection and the two independent BESS detection paths: status-based and status-less.
- Event Ancestral Hierarchy explains ancestor suppression, descendant rollup, singleton correction, imputed parents, and the effects of hierarchy on Event continuity.
How an Event is represented
Each Event is attached to one device and uses a half-open time interval: it includes the start time and excludes the end time.
The start time is the first anomalous sample. The end time is the timestamp of the first recovered sample, so that recovered sample is not part of the Event. A missing end time means the Event is still open.
This interval convention matters for loss accounting and reconciliation. The first healthy five-minute sample is not charged as loss, and two Events that merely abut at the same timestamp do not overlap.
Event state is consistent with that interval:
- Closed — the Event has an end time.
- Active — the Event is open and current evidence is still anomalous, or current evidence is indeterminate.
- Pending close — a BESS Event is being held open by slow-close hysteresis even though direct evidence has recovered.
Every Event with an end time is closed. An open Event whose state is missing or invalid is treated as active.
What the pipeline currently covers
The pipeline currently detects or supports:
- project and device offline Events;
- PV inverter, inverter-module, combiner, meter, and related hierarchy Events;
- BESS PCS, PCS module group, PCS module, bank, string, collector, transformer, meter, and project Events, depending on available metadata;
- tracker-row and tracker-zone underperformance Events; and
- curtailment Events.
Soiling and some broader underperformance classifications remain separate or under continued development. The exact supported device set depends on the project's metadata, available telemetry, and failure-mode configuration rather than on this list alone.
Design principles
Unknown is not healthy
Most detection flags have three possible values:
Truemeans positive anomalous evidence.Falsemeans positive nominal or recovered evidence.NAmeans that the method cannot determine state from the available data.
The distinction is essential. A communications gap must not automatically close an Event, but missing data must not automatically open one either.
Detection and attribution are separate
Detection answers whether and when a device appears unavailable or underperforming. Hierarchy processing answers where the condition should be represented. Failure-mode assignment answers what immediately observable condition best describes it. Root cause is a separate operational conclusion and may require inspection or maintenance evidence.
Reanalysis is expected
The pipeline repeatedly revisits recent history. Backfilled telemetry and revised evidence can extend, close, merge, or supersede an Event. Event IDs and existing metadata are preserved where intervals overlap, while redundant unclaimed records may be removed.
The Event device should be actionable
When every comparable child under a parent is anomalous at the same time, the hierarchy can roll the condition up to the parent. When an ancestor is already anomalous, descendant flags are made indeterminate so the platform does not present dependent symptoms as independent work items. See Event Ancestral Hierarchy for the precise rules and exceptions.
Events Pipeline
This page describes how Events are produced and kept current. PV and BESS processing follow asset-specific paths, then converge on saving Events, aggregating losses, and refreshing the active-Event list shown in the platform.
1. Project selection
PV projects run PV detection, BESS projects run BESS detection, and hybrid PV-plus-storage projects run both. A failure in one does not prevent the other, or later steps such as loss aggregation, from being attempted.
Only projects with Event integration enabled are processed.
2. Analysis-window selection
All window selection uses the project's local time zone. Events are reanalyzed on a regular cadence:
- At local midnight, the preceding three days are analyzed in one-day chunks.
- At each other six-hour boundary, the period from local midnight through the current five-minute boundary is reanalyzed.
- At other five-minute boundaries, the preceding hour is analyzed.
- When a specific range is reprocessed, ranges longer than one day are divided into one-day chunks.
Reanalysis is not just a recovery mechanism. It is part of normal correctness: delayed telemetry can change flags, recent open Events need to be extended or closed, and overlapping records must be reconciled.
The logical window convention is half-open: it includes the start and excludes the end. Samples are generally represented at five-minute resolution.
3. Metadata and existing Event retrieval
For each project and window, the pipeline loads the device and tag metadata needed for detection. It also retrieves existing Events that intersect the window.
Existing Events serve four purposes:
- seed the initial state of a device so an Event can continue across window boundaries;
- preserve the original Event ID, detection time, failure mode, root cause, and other durable metadata when intervals overlap;
- close open Events for which no detection evidence remains; and
- protect claim-linked Event records from deletion during overlap cleanup.
Before new detection, overlapping existing Events on the same device are consolidated. The retained Event covers the union of the overlapping intervals. The earliest Event is normally retained, but a claim-referenced Event takes precedence over an unclaimed Event. If more than one overlapping Event is claim-referenced, those records are kept rather than deleting a claim dependency.
4. Building detection flags
Both PV and BESS detection reduce heterogeneous telemetry to a flag for each device at each timestamp. Each flag is True, False, or NA:
True: anomalous evidence is present.False: nominal or recovered evidence is present.NA: the method has insufficient evidence.
PV primarily uses power under an irradiance gate, with separate tracker and curtailment paths. BESS creates two independent evidence sets: one from decoded statuses and another from power or availability telemetry. Those results are merged so that True wins, but False combined with NA remains NA rather than being treated as healthy.
The exact detection logic is covered in Event Detection Methods.
5. Hierarchy transformation
The raw device flags are transformed before they become Events:
- an active ancestor masks its descendants;
- simultaneous flags from every sibling of the same device type can roll up to their parent;
- rollup repeats until no higher-level change occurs; and
- BESS applies singleton and imputed-parent corrections for particular hierarchy shapes.
The result is not a simple aggregation. NA is used intentionally to express dependence and prevent a masked child from becoming a separate Event. The detailed algorithm and edge cases are in Event Ancestral Hierarchy.
6. Temporal cleanup and Event intervals
The pipeline removes isolated anomalous samples before creating Event intervals. The PV and BESS paths then apply slightly different temporal rules.
PV
PV joins True–NA–True across an interior telemetry gap, but leading or trailing NA does not start or extend a new Event. Consecutive True samples become one interval. A new non-curtailment Event must normally contain at least 15 minutes of POA-qualified anomalous duration. Existing Events and explicitly exempt devices are not discarded by this new-Event duration filter.
BESS
BESS converts consecutive True samples into intervals after removing isolated True samples. A newly detected interval must normally be at least 10 minutes long. BESS additionally applies a six-hour recovery grace period: a recovery gap shorter than six hours is treated as continuous, preventing short nominal periods from prematurely closing an Event.
The BESS Event state still records the distinction between evidence and hysteresis. If an Event is open only because of the grace period, it is pending close. If direct evidence remains anomalous, or is indeterminate, it remains active.
7. Reconciliation with existing Events
New intervals are reconciled with existing intervals per device using half-open overlap semantics. Overlapping intervals are unioned:
- the earliest start time is retained;
- if either interval is open, the merged interval remains open;
- otherwise the latest end time is retained; and
- existing durable metadata and Event IDs are preferred.
Two intervals where one ends exactly when the other begins are not merged.
Open Events not represented by the current detection results are treated as orphans. They are closed at the analysis start unless they are protected by an asset-specific exception, such as tracker handling, or are already represented by a merged Event. BESS slow-close history is analyzed before this point so short recoveries are not mistaken for orphans.
If interval consolidation makes an existing unclaimed Event redundant, it may be removed. Claim-referenced Events are protected from deletion.
8. Failure-mode assignment
Failure mode describes the first observable cause supported by telemetry; it is not necessarily the physical root cause.
For status-based BESS detection, an abnormal status bit can carry a configured failure mode directly into the Event. When several bits are abnormal, their configured failure modes are retained as candidates and the Event window is used to infer the most representative value. If no specific status-derived mode survives, BESS assigns a device-type fallback such as PCS offline, bank offline, string offline, module-group offline, or module offline; unsupported types receive unknown.
PV assigns failure modes after interval reconciliation. Curtailment is stamped separately so that a generic failure-mode lookup does not overwrite a supported curtailment classification. Tracker stow and other PV modes use their corresponding telemetry and device context.
Root cause remains distinct. It can be populated through later operational analysis, claims, or field findings.
9. Saving Events
The pipeline checks Event state before saving. New Events are created, existing Events are updated, and redundant unclaimed overlapping Events may be removed. Any closed Event whose state is not closed is corrected.
Loss records are stored separately and keyed by Event and timestamp. They are updated in place so repeated analysis can revise recent loss estimates.
10. Loss calculation
PV energetic loss compares expected and actual production, with device- and hierarchy-aware allocation. The calculation prevents overlapping ancestor and descendant Events from double counting the same shortfall and caps allocated loss by the available meter-level shortfall. Curtailment loss uses the curtailment setpoint and is bounded by both expected shortfall and actual shortfall.
BESS currently uses a capacity-based financial proxy. For each five-minute sample in the Event interval, it applies a flat daily value of $0.357/kW/day to the Event device's AC capacity. It also emits a capacity loss record. Project-level BESS Events use POI capacity.
After all per-window processing, recent loss records are coalesced onto the Event:
- financial loss records become the Event's total financial loss;
- that total divided by the inclusive number of calendar days becomes daily financial loss; and
- energetic loss records become the Event's total energetic loss.
The coalesce step covers open Events and Events closed within the recent lookback, currently two days.
11. Notifications and active-Event refresh
PV and BESS notifications are generated only when notifications are enabled. A notification failure does not change the underlying Event interval.
At the end of processing for each project, the operational list of active Events is refreshed from the project's Event records. That list is a derived view rather than the source of truth; the Event and Event-loss records remain authoritative.
Event Detection Methods
Event detection converts telemetry into five-minute device flags that can be anomalous, nominal, or unknown. This page focuses on the evidence models. It is especially important to distinguish BESS status-based detection from BESS status-less detection: they run independently, answer the same availability question from different telemetry, and are merged only after each has produced its own result.
Nullable evidence semantics
Across the current pipeline, a device state has three values:
True— sufficient evidence that the device is anomalous or unavailable.False— sufficient evidence that the device is nominal or has recovered.NA— no defensible conclusion from this method at this timestamp.
This is not cosmetic missing-data handling. It controls Event opening, closing, merging, hierarchy behavior, and BESS slow-close state.
For BESS, status-based and status-less flags are combined with three-valued logic:
True OR anything = True
False OR False = False
False OR NA = NA
NA OR NA = NA
Therefore, one method can establish an Event even when the other is unknown, but one method's nominal result cannot erase another method's uncertainty.
PV power-based detection
PV power detection asks whether a device is producing a minimum fraction of its capacity while irradiance says it could reasonably be operating.
The current configuration uses:
- a POA gate of
125 W/m²; and - an offline threshold of
0.005times device or project capacity.
The relevant power channels include meter active power, inverter AC power, inverter-module AC power, and DC combiner power. Device capacity is converted to the units of each channel before comparison.
At each sample:
- measured power below the capacity threshold and POA at or above the gate produces
True; - measured power at or above the threshold under qualifying POA produces
False; - missing measured power produces
NA; and - samples below the POA gate produce
NA, because darkness or low irradiance is not evidence of equipment recovery or failure.
An all-missing device series is treated specially to preserve existing operational behavior: it can be flagged under qualifying POA. Individual missing samples in an otherwise reporting series remain unknown.
Dawn handling
The pipeline guards against nuisance Events during asynchronous startup. For inverter modules, it identifies cases where some but not all sibling modules have started while POA is below 600 W/m² and treats those samples as unknown.
It can also backfill the first daily offline detection by up to 60 minutes using a reduced POA threshold of 75 W/m² (125 - 50). Backfill requires at least two consecutive qualifying samples. This recovers a more realistic Event start without letting a single dawn sample create an Event.
Temporal qualification
An isolated True between nominal samples is removed. During interval creation, an interior True–NA–True sequence is treated as one continuous run so a short communications gap does not fragment an outage. Leading and trailing unknown samples do not independently open or prolong a new Event.
A new PV Event normally requires 15 minutes of anomalous time while POA qualifies. The duration is not simply wall-clock duration: nighttime or below-threshold samples that were carried forward for state continuity are excluded.
Tracker and curtailment paths
Tracker flags compare measured tracker position against the expected true-tracking and backtracking pattern. Localized deviations stay at tracker-row level; simultaneous row conditions may roll up to the tracker zone. Tracker flags join the general PV detection results after the ordinary power hierarchy pass.
Curtailment is detected from curtailment-specific controls and setpoints. Curtailment flags deliberately bypass ordinary hierarchy sweep and rollup so a curtailment classification is not converted into a generic device-offline ancestor Event. Curtailment Events are also exempted from the ordinary minimum-duration rejection when the curtailment evidence overlaps the detected interval.
BESS status-based detection
Status-based detection interprets configured status and alarm tags. It does not infer unavailability from power.
Inputs
Status and alarm tags are retrieved for BESS PCS modules, PCS devices, banks, project breakers, and project reclosers. Each tag has a status lookup that identifies a binary layout. Each bit definition can include:
- bit position;
- nominal bit state;
- human-readable true and false states;
- description; and
- a configured failure mode.
Bit decoding
For each observed tag value, every configured bit is inspected. A bit becomes an alert when its actual state differs from its configured nominal state. A bit with no nominal state contributes descriptive status but does not create an alert.
The device flag at a timestamp is True when any of its reporting status tags contains an alert bit. It is False when reporting tags are present and none is alerting. If all relevant tag values are missing, the device flag remains NA.
Status descriptions from multiple tags are merged into one per-device representation. Failure modes from all abnormal bits are de-duplicated. A single mode is represented directly; multiple simultaneous modes remain candidates until Event-level inference.
Window continuity
The status lookup extends six hours before the nominal analysis start so the close decision can observe a sufficiently long recovery. A preexisting open Event seeds its device to True immediately before the retrieved series; that state is then carried forward through missing samples for that preexisting device. A device without a preexisting Event does not receive that assumption.
Missing status telemetry therefore behaves asymmetrically by design:
- for a new device condition, missing data is not evidence to open an Event;
- for a preexisting open Event, missing data is not enough to close the Event.
BESS status-less detection
Status-less detection infers unavailability without decoding status words. It uses real-power participation and, when available, charge/discharge availability. The name means “without status telemetry,” not “without state.” It still produces the same three-valued availability state as the status-based path.
The supported target device types are currently:
- BESS PCS;
- BESS PCS module group;
- BESS PCS module; and
- BESS string.
Each type has configured channels for real power, available charge power, available discharge power, and preferred capacity metadata.
Project activity gate
The project meter establishes whether the plant is active enough to judge a device by participation. Absolute meter power below 10% of project POI is indeterminate for opening a power-based device condition. If POI is unavailable, project AC capacity is used.
Project activity is debounced over 15 minutes with a 90% required fraction. A device group can still use the power path when its peer fleet is demonstrably active, even if the project-level gate is not yet active. The peer fleet is active when median absolute group power exceeds 5% of the group's median device capacity.
Availability path: preferred when supported
When a device has both charge-availability and discharge-availability tags, a valid availability signal, and usable capacity, availability takes precedence over the real-power path.
A device is unavailable when both available charge power and available discharge power are below 5% of device capacity. It is available when either is at or above that threshold.
Opening requires the project activity gate and a 15-minute rolling window with at least 75% unavailable samples. Closing uses a shorter five-minute rolling window with at least 75% available samples and does not require project activity. This asymmetry prevents opening an Event while the plant is idle but permits prompt recovery when availability returns.
Availability is carried forward as a state signal. An entirely missing tag remains missing; the pipeline does not synthesize zero availability from missing telemetry.
Power-participation path
If usable availability telemetry is absent but device power is available, the pipeline compares the device's absolute power with both its peers and a meter-derived reference.
The peer reference is the median absolute power of other devices of the same target type. At least two reporting peers are required. The meter reference is:
abs(project meter power / fleet size × 0.25)
When capacity is known, the meter reference is floored at 5% of device capacity.
With a peer reference, a device is low when its absolute power is below 10% of peer median and, when capacity is known, below 5% of its own capacity. It is active when it clears either of those thresholds. If a peer reference is unavailable, the meter reference is used.
For fleets smaller than ten devices, the rule is more conservative:
- low power must satisfy both the peer and meter low-power tests; and
- active power may satisfy either recovery test.
Power entry uses a 15-minute rolling debounce. The required fraction is 95% for small fleets and 90% otherwise. Power exit uses a five-minute window with a 75% required fraction.
Status-less unknowns
Status-less detection returns NA when neither availability nor power provides evidence. The following do not become automatic offline flags:
- tags that exist but have no values;
- missing capacity when the selected path requires a capacity comparison;
- an inactive plant without active peer evidence; and
- a device type with no supported telemetry path.
The status-less lookup also extends six hours into the lookback and applies the same preexisting-Event continuity seed as the status path.
Merging the BESS paths
Status and status-less detection do not have a primary/secondary relationship. Their results are merged per timestamp and device, after which hierarchy processing and interval creation operate on a single evidence set.
Some practical consequences:
- an abnormal status bit opens an Event even if power participation looks normal;
- clear status cannot close an Event while the status-less path is still anomalous;
- clear status plus unavailable status-less data yields unknown, not healthy;
- power-based recovery cannot erase an active decoded alarm; and
- a device with no status configuration can still receive an Event from availability or participation telemetry.
Failure-mode evidence remains path-specific. Status-derived abnormal bits can supply a specific failure mode. A purely status-less Event normally reaches the fallback assignment based on device type.
BESS slow close
After the two BESS paths are merged, BESS uses a six-hour recovery grace period. A False segment following a True segment is treated as continuous until the nominal segment has lasted six hours. This applies across analysis boundaries because both detection paths include the lookback.
The direct evidence before that grace period is retained separately:
- open plus directly anomalous evidence becomes active;
- open plus unknown evidence remains active;
- open plus directly recovered evidence, while the grace period still holds the interval open, becomes pending close; and
- after six hours of continuous recovery, the end time is set to the first recovered sample and the Event becomes closed.
The close timestamp is the beginning of recovery, not the time at which the six-hour confirmation completes. The grace period changes confidence in closure; it does not bill the confirmation interval as anomalous once closure is established.
Interpreting a detection
For a BESS Event, determine the originating evidence before interpreting the failure mode:
- Check decoded status bits and their nominal-state configuration.
- Check whether charge/discharge availability was valid; if so, it superseded the status-less power path.
- Otherwise inspect meter power, peer median, device power, capacity floors, fleet size, and debounce state.
- Compare the status and status-less flags before they were merged.
- Inspect the direct evidentiary flag at the end of the window to distinguish active from pending close.
- Finally inspect hierarchy transformation, because the final Event device may be an ancestor of the device where the evidence originated.
Event Ancestral Hierarchy
The Events pipeline uses the project device hierarchy to answer a practical question: at what device level is an observed condition most actionable without double-reporting dependent symptoms?
The hierarchy process has two complementary operations:
- ancestor sweep suppresses descendants while an ancestor is already anomalous; and
- child rollup replaces a complete set of simultaneous sibling conditions with one parent condition.
These operations occur on time-indexed flags before Event intervals are created. Consequently, hierarchy can affect an Event's device, start, end, continuity, failure mode, and loss attribution.
Hierarchy representation
Each device has a parent and, where available, an ordered ancestry of devices from the project down to itself. The device itself is excluded from its ancestor list.
The parent is used for direct sibling groups and rollup. The full ancestry is used to identify all ancestors, not only the immediate parent. Incorrect or incomplete hierarchy metadata therefore changes attribution even if the telemetry itself is correct.
Operation 1: ancestor sweep
At each timestamp, if an ancestor flag is True, every represented descendant of that ancestor is set to NA.
Example before sweep:
Project: False
PCS: True
Module: True
String: True
Example after sweep:
Project: False
PCS: True
Module: NA
String: NA
The descendants become unknown rather than healthy. False would assert that the child had positively recovered, which is not supported when the ancestor condition can explain the child's behavior. NA prevents dependent child symptoms from becoming separate Events while preserving the distinction from nominal operation.
The sweep considers every ancestor present among the devices being evaluated, so a high-level Event can suppress descendants across multiple hierarchy levels in one pass.
Operation 2: complete-sibling rollup
Rollup groups direct children by both parent and device type. For each group and timestamp, rollup occurs only when:
- every configured child of that type under the parent is among the devices being evaluated; and
- every one of those children is
Trueat that timestamp.
When both conditions hold, all grouped child flags become NA and the parent becomes True.
Example with three PCS modules under one PCS:
Before: module A=True, module B=True, module C=True, PCS=False
After: module A=NA, module B=NA, module C=NA, PCS=True
If module C is False, NA, or present in metadata but missing from the devices being evaluated, the complete-sibling rollup does not occur. A sibling missing from metadata cannot be counted at all and may therefore make the configured group appear complete; this is one reason hierarchy metadata quality is critical.
Children are grouped by type. If a parent has two banks and three PCS modules, all banks being anomalous can roll up independently of the module group. The pipeline does not require every child of every type under the parent to be anomalous.
Rollup repeats until no further change occurs. A complete set of module Events can first become a PCS condition; a complete set of PCS conditions can then become a collector, transformer, or project condition on a later iteration.
Project-level BESS exception
BESS treats Project, Meter, and PPC devices as project-level evidence. An active Meter or PPC condition is moved to the Project device even when there is only one such device. This avoids leaving a project-wide condition represented as a meter-component Event.
The PV rollup differs: it avoids ordinary rollup directly into the Project parent. Project-level PV evidence is principally supplied by the meter/project power logic rather than by arbitrary complete child sets.
Singleton correction in BESS
Complete-sibling rollup has a degenerate case: a group containing one child is trivially “all true.” Blindly retaining that rollup would move many Events to a parent that adds no useful aggregation.
After iterative BESS rollup, the singleton correction walks an inferred parent flag back down to its sole child of that type. It repeats until no more moves occur.
There are two important guards:
- A parent flag that was present in the original evidence remains on the parent. Only a flag inferred by rollup is moved down.
- Walk-down skips a BESS DC skid singleton. For example, a module condition that rolls through one DC skid to a PCS is allowed to remain on the PCS rather than being forced back to the skid.
This distinction preserves real parent telemetry while correcting hierarchy artifacts introduced by one-child groups.
Imputed BESS ancestors
Some BESS ancestors may not have direct detection telemetry but are still meaningful Event devices. The current imputed-parent device types include:
- MV collector circuit;
- medium-voltage transformer;
- Project; and
- Meter.
Before intervals are created, the pipeline attempts to derive these parent flags from descendant PCS evidence.
The preferred derivation runs the normal rollup algorithm on leaf flags with existing imputed-parent results temporarily set aside. If ordinary hierarchy rollup reaches the parent, that result is used.
If it does not, a fallback examines all descendant PCS devices:
- all PCS flags
True, or a mixture ofTrueandNAwith noFalse, produces parentTrue; - any PCS
Falseproduces parentFalse; and - all PCS
NAproduces parentNA.
All descendant PCS devices must be present. Missing a PCS series prevents the fallback from asserting a parent condition.
When a parent also has direct status or status-less evidence, inferred evidence is combined carefully:
- inferred
Truecan establish the parent condition; - inferred
Falseis closing evidence; and - inferred
NAdoes not overwrite an existing parentTrue.
The last rule is crucial: missing leaf telemetry cannot erase direct evidence on the parent.
Existing ancestor Events and continuity
Hierarchy must remain consistent across overlapping analysis windows. A child may have current telemetry while its ancestor has an existing open Event but no direct telemetry in the current window.
The BESS path collects all ancestors of flagged devices and relevant existing Event devices, then constructs an ancestor-active mask:
- if the ancestor has raw telemetry, that telemetry is authoritative;
- if it is an imputed-parent type, its derived flag is authoritative; and
- otherwise, existing Event intervals are applied onto the current timestamps.
The six-hour recovery grace period is applied to each ancestor-active mask. While that mask is active, the later ancestor sweep suppresses descendant flags. This prevents a child Event from appearing merely because the current window did not include or produce a direct ancestor tag.
Existing Event intervals use the half-open convention described in Events Overview. A closed ancestor ceases to suppress descendants at its first recovered sample.
Continuity across analysis windows
Before hierarchy processing and interval creation, preexisting Events seed a True value just before the available timestamps. That state is then carried forward from the seed.
This solves a boundary problem: a window that begins in the middle of an Event should extend the existing Event rather than create a new Event at the window start.
Imputed BESS parent Events are excluded from ordinary preexisting seeding. Their current state must be re-derived from the leaves; otherwise a stale imputed parent could perpetuate itself without descendant evidence.
An Event ending exactly at the analysis start is also excluded. Since the end time is exclusive, that Event is already recovered and must not reopen through seeding.
Why NA is central to hierarchy
Hierarchy uses NA for two different but compatible meanings:
- the detector lacks sufficient telemetry; or
- an ancestor explains the descendant, so the descendant's independent state is intentionally not asserted.
Both meanings say “do not create an independent Event here.” They differ from False, which says “we have positive evidence of nominal operation.”
This produces several important outcomes:
- a swept child does not immediately close as healthy merely because its parent is active;
- a communications gap does not become an outage solely through missing data;
- all-unknown leaves do not create an imputed parent Event; and
- a clear child can provide closing evidence for an imputed parent.
Event continuity when parent and child timing differ
Hierarchy is evaluated per timestamp, not once per analysis window. The represented device can therefore change as the condition evolves.
Consider two sibling modules:
- Module A fails first, so its flag remains on Module A.
- Module B later fails, making every module
True; both module flags roll up to the PCS. - During the PCS-level interval, module flags are
NA. - Module B recovers while Module A remains failed; complete rollup ends and Module A can again carry a device-level condition.
The reconciliation stage then compares these generated intervals with existing Events. It preserves overlapping Event IDs on the same device, but it does not merge intervals across different devices merely because they share ancestry. Operators may therefore see a child Event followed by a parent Event, or the reverse, when the breadth of the condition changes.
An existing child Event is not automatically deleted just because a later parent Event appears. This is intentional when timing supports distinct addressable conditions. Dependent simultaneous samples are suppressed prospectively by the flag hierarchy, while historical Event reconciliation remains device-specific.
Failure modes and losses after hierarchy
Hierarchy chooses the Event device before final failure-mode fallback and loss assignment.
For BESS, a status-derived failure mode may be inferred over the Event window before device-type fallback. If no specific mode is available after rollup, the ancestor's device type may receive unknown because only PCS, bank, string, module-group, and module types currently have explicit offline fallbacks.
For PV, a rolled PV Block Event is reassigned to the first inverter below the block, optionally through an MV transformer. This is a later correction intended to keep the Event on an actionable inverter device.
Loss allocation also follows the final hierarchy. PV explicitly masks loss on descendants while an ancestor Event is active to avoid double counting. BESS capacity-based loss uses the final Event device's capacity, with Project Events using POI.
When hierarchy attribution looks wrong
When an Event appears on an unexpected device, inspect these items in order:
- Verify that the device's ancestry includes every expected ancestor in the correct order.
- Verify each device's direct parent.
- Verify sibling device types; rollup groups by type as well as parent.
- Confirm that every configured sibling is being evaluated and has evidence rather than a gap.
- Determine whether the parent flag was direct, rolled up, imputed, continued from an existing Event, or seeded from a preexisting Event.
- Check singleton correction and the DC-skid exception.
- Check whether a six-hour BESS grace mask is holding the ancestor active.
- Inspect the pre-hierarchy and post-hierarchy flags at the exact timestamp.
- Finally, inspect Event reconciliation and claim references before concluding that a redundant Event should have been deleted.
The hierarchy output is only as reliable as device metadata. A missing sibling, incorrect parent, malformed ancestry, or wrong device type can prevent rollup, over-suppress descendants, or attach the Event to an inappropriate ancestor even when detection evidence is correct.
Warranty Claims
Use Warranty Claims to prepare, submit, and track claims with equipment manufacturers (OEMs) for a project. A claim records the affected equipment, related events, supporting files, correspondence, and status in one place.
Open a project and go to Maintenance → Warranty Claims. Claims are visible to every company with access to the project.
Set up an OEM
Before submitting a claim, configure the OEM or other counterparty for the project. Select Add OEM and choose the counterparty, then set its preferred submission channel:
- Email sends the claim by email.
- Portal records the portal used to submit the claim.
- Hybrid supports both email and a portal.
Add the OEM's default contact and, when applicable, its portal URL. You can edit an OEM configuration later. An OEM cannot be deleted while claims use it.
Submit a new claim
Select Submit New Claim, then complete the guided workflow:
- Select the OEM.
- Optionally select related open events. You can include events closed in the last 90 days. Selected events add their affected devices to the claim.
- Review the devices and add serial numbers, part numbers, notes, or additional devices as needed.
- Review the OEM warranty claim form. If a matching warranty form is available for the OEM, you can use Auto-fill with AI to suggest values from the claim, device, and event information. Review and correct all suggested values before saving the form.
- Review the generated site map and attached support files.
- Review the delivery details, including recipients and the email message, then submit the claim.
You can save the claim as a draft before submitting it. Draft claims remain editable from the claims table.
For example, for an inverter failure, select the affected inverter's event, confirm its serial number and part number, review the completed OEM form, and send the claim with the supporting documents.
Track a claim
Select a submitted claim from the table to open its detail page. The page shows the claim's OEM, summary, affected devices, attachments, and timeline.
Use Add Update to record a note, OEM message, part update, field visit, submission, or status change. An update can include attachments up to 40 MB each. You can download claim attachments from the detail page.
Claims use the following statuses:
- Draft: saved but not submitted.
- Submitted: sent to the OEM.
- In Progress: being investigated or processed.
- Resolved: a resolution has been reached.
- Closed: the claim is complete.
Only draft attachments can be removed directly. Deleting a claim permanently removes its devices, timeline entries, and attachments.
Add a historical claim
Use Add Historical Claim to bring an existing claim into Proximal. Choose the OEM, upload the claim form and supporting PDFs, and select Analyze with AI. The analysis suggests claim details, devices, related events, and timeline entries. Review and edit every suggestion, choose the historical claim status, then create the claim.
Historical claim uploads accept PDF files up to 40 MB each. The original files are attached to the created claim.
Deal Rooms
Deal Rooms provide a controlled workspace for running a project sale or other buyer diligence process. A room brings together the linked projects, a structured data room, buyer participants, and a Q&A workflow so the seller can share the right information as the process progresses.
Who uses a deal room
- Seller team members organize the room, add buyer companies, manage the data room, and respond to diligence questions.
- Investment bank users, when included, can participate in managing the process according to the permissions assigned to them.
- Buyer users can view the information made available to their company and ask and track their own diligence questions. They cannot see other buyers' questions or restricted documents.
Your company administrator creates a deal room. Within the room, permissions determine which seller and bank users can manage it and which buyer companies can access it.
Create a deal room
- Open Deal Rooms and select New Deal Room.
- Select one or more projects, then enter a name and optional description.
- Select Create.
You can also add an off-platform asset during creation when the transaction includes an asset that is not already available in Proximal. Provide its project type, location, interconnection limit, relevant capacity values, and, optionally, commercial operation date.
The new room starts in Draft. Use the room's Participants and Settings tabs to prepare access before inviting buyers.
Organize the data room
Use the Data Room tab to create a folder structure and upload diligence materials. Seller-side users with upload access can:
- create, rename, move, and remove folders;
- upload, rename, move, and remove documents;
- browse and search the files in the room; and
- control whether a document may be downloaded.
Buyers can only browse folders and documents available to their current phase. They can download files only when the seller has enabled buyer data-room downloads and the individual files allow downloads. Large downloads may be prepared as an export rather than being delivered immediately.
PDFs can be processed for in-product viewing and used as supporting material for Q&A. Processing may take time after upload; a document is not immediately available as a Q&A source while it is still being processed.
Add and advance participants
On the Participants tab, add a buyer company and a contact. Send the buyer an invitation from the participant's detail panel. You can then move the buyer through the process stages:
- Prospecting
- Invited
- Round 1
- Round 2
- Exclusivity
Advancing a buyer can also advance the deal room's status. Before confirming a move, Proximal shows the folder and project-data access that will be granted or removed. Removing a buyer company revokes its access to the deal room.
Control access by phase
In Settings, configure the folders and linked-project data available at each buyer phase. Folder access controls what buyers can browse in the data room. Project-data access can separately enable access to Proximal, raw-data downloads, or the API for each linked project.
When a room is Closed, buyer access to deal-room files and project data is revoked. You can also configure exclusivity cleanup so that moving one buyer to Exclusivity removes earlier-stage access for other buyers.
Manage diligence Q&A
Buyers use the Q&A tab to submit questions for a selected asset or for the general transaction. They can filter and review only their own company's questions and responses. A buyer can also import questions from a CSV template that contains these columns:
Asset, Subject, Question, Priority
Seller-side users can group questions by topic, assign owners, draft and post answers, and attach document references. The Q&A workspace can suggest a topic, identify similar questions, retrieve supporting snippets from room documents, and prepare an AI draft. Treat every AI draft as a starting point: review its content and references before posting an answer to a buyer.
Example workflow
A seller creates a room for a solar project and adds an investment bank. The seller uploads a first-round data package, then configures that folder for Round 1 access. After adding each prospective buyer and sending invitations, the buyers can review the first-round files and submit questions. The seller routes questions to subject-matter experts, uses the cited documents to prepare answers, and posts the reviewed responses. When a buyer progresses to Round 2, the seller grants the next folder and any appropriate linked-project access without exposing those materials to other buyers.
Aria Chat
Aria Chat is an assistant for investigating the project you currently have open in Proximal. It can help you explore project performance, equipment, events, and other operational information without leaving the project workspace.
Start a conversation
- Open the project you want to investigate.
- Select Aria in the project navigation.
- Enter a question in the chat box.
- Press Enter or select Send.
Aria uses the context of the open project. Switch to the relevant project before asking about its data or operations.
Clear questions produce more useful answers. Include the relevant time period, equipment, or metric when possible. For example:
What were the largest production-impacting events at this project last week, and which ones are still open?
Aria's response may include text, tables, charts, record summaries, and related questions. Select a related question to continue the investigation.
Work with a response
Aria displays its progress while preparing an answer. Wait for the response to finish before relying on it.
To stop a response, select Stop in the chat box or press Escape. If you send another message while Aria is working, the message is placed in a queue. After the current response finishes, select Steer to send the queued message, or remove it if it is no longer needed.
Aria can make mistakes. Verify critical answers against project records and source data before taking action.
Use conversation history
Recent conversations for the open project appear in the navigation panel. Select a conversation to reopen it. On smaller screens, open the navigation panel to see recent conversations.
- Select New conversation to start with an empty chat.
- Select the delete button beside a recent conversation to remove it.
Export a conversation
After sending a message, use the export button at the top of the chat to:
- copy the conversation as Markdown;
- download the conversation as a Markdown file.
The export includes conversation content and diagnostic details. Review it for sensitive project information before sharing it, and attach it to a support request when troubleshooting an Aria response.
Keyboard controls
- Enter sends a message.
- Shift+Enter adds a new line.
- Command+K on macOS or Ctrl+K on Windows focuses the chat box.
- Escape stops a response that is in progress.
Aria Memory
Aria Memory gives Aria project-specific context that it can use when answering questions. There are two types of memory:
- Semantic Memory contains reference documents such as equipment manuals, datasheets, and warranties.
- Episodic Memory captures project-related information from email conversations. This feature is in development and is not yet searchable in Aria Chat.
Both types of memory are associated with specific projects so Aria only uses information in the appropriate project context.
Semantic Memory
Semantic Memory lets Aria search project reference documents when answering questions. Memory is scoped to the open project, so upload a document to the project where it should be used.
Good candidates for Semantic Memory include equipment manuals, equipment datasheets, warranties, and other reference material used to understand the project's equipment and operations.
Add a document from Aria Chat
- Open the relevant project and select Aria.
- Select the upload button in the upper-right corner.
- Choose a document.
- Complete the document metadata.
- Select Upload.
A confirmation appears when the upload succeeds. Allow up to five minutes for a new document to become searchable.
Add and manage project documents
Documents added from project settings are also included in Semantic Memory.
- Open the relevant project.
- Go to Settings → Documents.
- Select Upload Document.
- Choose one PDF, complete its metadata, and select Upload.
Each project-settings upload accepts one PDF up to 40 MB. The Documents page lists uploaded project documents and lets you open them. Users with delete permission can remove a document from the project and Semantic Memory.
Uploaded project documents are visible to all users in your company. You need document-upload permission to add them from project settings. If the upload button is disabled, contact an administrator.
Choose document metadata
Metadata helps Aria determine when and how to use a document:
- Status: Choose Active, Superseded, or Archived. Use Active for the current document and update the status when it is replaced or retired.
- Language: Choose English or Spanish to match the document.
- Valid until: Add an expiration date when the document is only valid for a limited period. Otherwise, leave this blank.
- Document type: Choose the closest available type. If left blank, the document is treated as Miscellaneous.
Available document types depend on where you upload the document. Common types include Equipment datasheet, Equipment manual, Miscellaneous, and Warranty.
Ask Aria about a document
After indexing is complete, identify the document or equipment in your question. For example:
According to the active inverter manual, what does alarm code 42 mean?
If Aria cannot find a newly uploaded document, wait five minutes and try again. Also confirm that you uploaded it to the project currently open in Proximal and that its metadata reflects how it should be used.
Episodic Memory
Episodic Memory is being developed to give Aria context from project-related email conversations. When complete, users will be able to include Aria on an email thread so that eligible messages become searchable within the relevant project.
Availability: Email receipt and project routing are under development, but accepted emails are not yet added to searchable Aria Memory. Do not rely on this feature to preserve or retrieve project information yet.
Start a project email thread
The planned production workflow uses aria@inbox.proximal.energy.
- Start the email from the address associated with your Proximal account.
- Add
aria@inbox.proximal.energyas a recipient. - Add the project's short name in square brackets to the subject. For
example:
[SUNSET] Weekly construction update. - Write the project information in the plain-text body and send the email.
You can associate an email with more than one project by adding multiple
project tags, such as [SUNSET] [RIVER] Shared procurement update. You must
have access to every tagged project when starting the thread.
When the first email is accepted, Aria sends the initiating user a confirmation email. If no project tag matches, Aria responds with the projects available to that user and the tags to use.
Continue a monitored thread
Keep Aria included on replies and retain at least one of the original project tags in the subject. Aria identifies the conversation from its email-thread headers, not from the subject alone.
After an eligible user starts a thread, people without Proximal accounts can participate in later replies. If a reply loses all of the thread's project tags, Aria stops monitoring the thread and notifies the user who started it.
Email content and visibility
Episodic Memory currently reads the email subject and plain-text body. It does not use attachments or HTML-only content, so include important information in plain text.
Memories remain associated with the tagged projects. Within a company, eligible project information can be shared with other users of that company. For cross-company email threads, include registered Proximal users in To or Cc so their company's visibility can be established for the tagged projects. Unregistered recipients do not extend memory visibility.
Aria only considers recipients on messages where it is included. Adding Aria later does not import earlier messages from the thread.
If an email is not accepted
Aria may not accept an email when:
- the first sender is not an active Proximal user;
- the subject does not contain a matching project tag;
- the sender cannot access every tagged project;
- the email cannot be authenticated; or
- a later reply no longer contains one of the original project tags.
Aria sends guidance for some of these cases, including an unmatched project tag or a thread that lost its tag. Other rejected messages may not receive a response.
Public MCP OAuth provisioning
The public MCP endpoint is https://mcp.proximal.energy/mcp. Clerk authenticates
the human user's identity and client they are using, for example Claude or Codex. The public AgentCore Gateway validates the Clerk access
token, and its request interceptor exchanges that token for a short-lived,
KMS-signed Mono delegation token. The original Clerk credential stops at the
Gateway. Mono authorizes the actual operation and the user's access to its
project and resources.
Web-app authentication flow:
- User → Aria web app → Clerk sign-in → Clerk session → Aria
MCP authentication flow:
- User → Client → Clerk sign-in → Oauth Token → Agentcore Gateway
Clerk instances and current setup
| Environment | Clerk issuer | Client ID Metadata Document clients |
|---|---|---|
| Staging (Clerk development) | https://concrete-snapper-8.clerk.accounts.dev | https://chatgpt.com/oauth/client.json, https://claude.ai/oauth/claude-code-client-metadata |
| Production | https://clerk.proximal.energy | The same two client IDs |
As of September 23, 2026, both instances require authorization code with S256
PKCE, issue signed OAuth access tokens, are configured to include an audience
when the client requests a resource, and have a configured Clerk Account Portal
for sign-in and consent. Both advertise Client ID Metadata Document support and admit only
pre-registered clients. Dynamic client registration is disabled. Clerk adds
offline_access to Client ID Metadata Document clients.
The default custom scopes for clients that omit scope are mcp:connect and
endpoint:read. No write scope is defined or granted for the initial release.
Both custom scopes are Advertised in Clerk, and each reviewed client is
limited to them. Clerk also requires offline_access for these clients.
| External scope | Intended internal delegated scope | Meaning |
|---|---|---|
mcp:connect | mcp:connect | Enter the MCP Gateway; does not authorize every tool. |
endpoint:read | endpoint:read | Use any read-only MCP tool, subject to the user's normal data permissions. |
The interceptor must explicitly allowlist this external-to-internal mapping and
use only scopes Clerk actually granted. Unknown or ungranted scopes confer no
Mono authority. The validated OAuth client_id must map to a canonical client
value: https://chatgpt.com/oauth/client.json to chatgpt, and
https://claude.ai/oauth/claude-code-client-metadata to claude-code. Do not
derive client identity from request headers, tool arguments, or the token
audience. The delegation token names the user, trusted actor, canonical client,
allowed scopes, and request identifiers; it does not need a predetermined MCP
tool claim. Mono resolves the actual operation before checking its required
scope. Every initial read-only operation requires endpoint:read.
Deployment inputs
The following non-secret Parameter Store values are in us-east-2:
| Path | Value |
|---|---|
/auth/clerk/prod/issuer | https://clerk.proximal.energy |
/auth/clerk/prod/mcp-audience | https://mcp.proximal.energy/mcp |
/auth/clerk/prod/mcp-allowed-clients | The two Client ID Metadata Document URLs above, comma-separated. |
/auth/clerk/staging/issuer | https://concrete-snapper-8.clerk.accounts.dev |
/auth/clerk/staging/mcp-allowed-clients | The same two Client ID Metadata Document URLs, comma-separated. |
Clerk places the requested OAuth resource in the access token's aud claim.
Clients must request the public MCP resource above; the Gateway validates that
exact audience. Staging still needs a stable resource URL before
/auth/clerk/staging/mcp-audience can be set. The interceptor stacks also need
/auth/mono-delegation/{staging,prod}/issuer and
/auth/mono-delegation/{staging,prod}/audience, coordinated with Mono's token
validator. The signing keys are created by the interceptor stacks.
Client admission
For each new client, review its HTTPS Client ID Metadata Document, redirect
URIs, and token authentication method. Pre-register the exact document URL in
Clerk's OAuth applications > Applications tab, assign only mcp:connect
and endpoint:read, and add the exact client ID to the Gateway allowed-client parameter.
Clerk's settings must keep admission at Pre-registered clients only. Enable
dynamic client registration only if a required client cannot use a metadata
document or a manually registered client ID; it exposes a public registration
endpoint.
ChatGPT publishes https://chatgpt.com/oauth/client.json, which was reviewed
and pre-registered. Clerk provides a Claude Code preset. Cursor has not been
registered: establish its current registration method and redirect URI before
adding it. A custom client likewise needs a published metadata document or a
manually registered client ID. Neither client should be added to the Gateway
allowed-client list before its Clerk configuration is reviewed.
Remaining work
The two custom scopes, default grants, and ChatGPT/Claude Code registrations are
configured in both Clerk instances. Authorization-server discovery has been
checked for both issuers: it advertises those two custom scopes and metadata-
document support, and no dynamic registration endpoint. This does not yet
verify sign-in, token issuance, or MCP connectivity. The unchecked items below
are the remaining work; task numbers refer to aria/scaffold.md.
Configuration and deployment
-
Choose the stable staging MCP resource URL and set
/auth/clerk/staging/mcp-audienceinus-east-2. Clients must request that exact URL as their OAuthresource. -
Agree on the Mono delegation issuer and audience for staging and production, then set
/auth/mono-delegation/{staging,prod}/{issuer,audience}inus-east-2. Match these values in the token issuer and Mono validator. -
Complete Mono's delegation settings, verification-key injection, token validation, delegated-agent authentication, project-access cache, request identity, operation-level
endpoint:readenforcement, and request-context wiring (Tasks 8-16). Normal Clerk and API-key callers must retain their existing behavior. -
Complete the single shared MCP server and canonical read-only tool registry: package the plugin, use one Mono client and trusted delegation path, require explicit
project_idon project tools, add project discovery and generated read tools, and serve both Gateways from the same Runtime (Tasks 17-26). Do not expose mutating or dashboard-only tools. - Bind Aria's trusted current project into the same canonical tools without changing their public schemas, and verify the shared Runtime, catalog, scope coverage, and credential propagation (Tasks 27-29).
- Add non-blocking MCP telemetry storage and instrumentation without storing credentials or treating telemetry as audit history (Tasks 30-32).
- Replace raw Clerk-token forwarding in internal Aria with project-bound delegation and complete its shared MCP execution path (Tasks 33-35).
-
Deploy the shared MCP service and Mono changes, then the staging and production interceptor, Gateway, and target-sync stacks. Deploy the production public edge stack in
us-east-1; these seven public MCP stacks are not deployed yet. Confirm pipeline dependencies and stack outputs before exposing the endpoint.
Client admission
-
Establish Cursor's current registration method and redirect URI. Review it, register it in Clerk, grant only
mcp:connectandendpoint:read, and add its exact client ID to the Gateway allowlist. - Do the same for at least one custom MCP client. Keep dynamic registration disabled unless a required client cannot use a metadata document or manually registered client ID.
Launch verification
-
Fetch
https://mcp.proximal.energy/.well-known/oauth-protected-resource/mcpafter the edge deploys; confirm the resource URL and Clerk authorization server. Check the equivalent staging metadata at its chosen URL. - Complete sign-in, consent, callback, and token issuance with ChatGPT and Claude Code in staging and production. Verify the issued token's signature, issuer, audience, client ID, subject, and the two granted MCP scopes. Starting an authorization redirect alone is insufficient.
-
Confirm the Gateway rejects a missing
mcp:connect, an unregistered client, a wrong audience, and an unsigned token. Confirm every read-only tool requiresendpoint:read, reaches Mono with only the internal delegation token, and still obeys the user's current project and resource permissions. - Run production MCP connectivity and canonical-tool-catalog checks with ChatGPT, Claude Code, Cursor, and the custom client (Task 36).
- Confirm internal Aria still works through its existing Gateway and shared Runtime using project-bound delegation, not a raw Clerk token (Task 37).
- Verify the validated execution context needed for future auditing survives the full request path; do not implement audit storage yet (Task 38).
There is one canonical MCP tool registry and one shared Runtime per environment. The initial canonical tools are read-only. Dashboard-only capabilities remain agent built-ins and never appear in MCP tool discovery. ClickHouse holds asynchronous operational telemetry, not authoritative audit history. Authoritative auditing is deferred; the validated request context must remain available for it later.
See Clerk's OAuth setup, Clerk's metadata-document guide, and AgentCore's inbound token validation.
BESS Revenue on Portfolio Home
Use the BESS table on Portfolio Home to compare revenue across battery projects. The table shows month-to-date (MTD) and year-to-date (YTD) revenue for each BESS or PV-plus-storage project, alongside availability and open-event information.
Choose a revenue source
Use the selector in the BESS table's Revenue header to choose the revenue view:
- Total adds the physical and virtual revenue values for each day.
- Physical shows only the physical revenue value.
- Virtual shows only the virtual revenue value.
The Average Revenue summary card and the BESS section of a downloaded CSV use the selected source. For example, select Physical to compare the physical MTD and YTD revenue of your battery projects, then download the CSV to share that same view.
For a PV-plus-storage project, the BESS table shows $0 in the Virtual
view. Its PPA-based PV revenue remains available in the PV table and PV section
of the CSV.
Interpret the values
MTD includes daily revenue from the first local calendar day of the current month through the completed local day before today. YTD uses the same approach from the first local calendar day of the year. Proximal uses each project's time zone when grouping daily values.
Total treats a missing physical or virtual value as $0 for that day. If
both values are missing, that day is not included.
Choose to view the unnormalized
amount. A project needs a positive POI capacity to show a $/kW value.
Availability and access
BESS revenue is available only when the project's QSE integration is configured.
Custom Dashboards
Custom Dashboards let you build a project-specific view of the metrics and telemetry you monitor most often. Use them to keep related operational charts, KPIs, and notes together instead of switching between separate product pages.
Custom Dashboards are available only for projects where they have been enabled. If the Custom Dashboards page says the feature is unavailable, use the feedback button in Proximal to request access.
Create a dashboard
- Open the relevant project and select Custom Dashboards.
- Select New Dashboard.
- Enter a dashboard name and choose defaults for the chart and KPI time ranges.
- Select Add Component and configure the components you need.
- Drag or resize components to arrange the layout.
- Select Save Layout.
Use Edit Layout on an existing dashboard to change its name, time ranges, components, or arrangement. Select Exit Without Saving to discard changes made during the current edit session.
Add components
Choose Add Component while editing a dashboard. Available component types are:
- Line chart: Plot one or more sensor traces over time. Choose a sensor type and aggregation for each trace. When aggregation is None, you can limit the trace to individual tags and add optional minimum and maximum thresholds.
- Bar chart: Compare an aggregated sensor value across the project's devices.
- Scatter plot: Compare two sensor types. Large selections are sampled to 1,000 representative points, so use the plot to investigate patterns rather than as a complete point-by-point export.
- KPI card: Show one of the project's visible KPIs. Selecting a card while viewing the dashboard opens that KPI's detail page.
- Gauge: Compare metered energy with expected energy. This component is available only when the project has an expected-energy integration.
- Rich text: Add formatted headings, context, assumptions, or handoff notes alongside the data.
The chart date control is available while viewing a dashboard. Chart components use the selected range, which can cover up to three days. KPI cards use the dashboard's KPI time-range default: one month, month to date, year to date, or beginning of life.
Build a draft with Aria
While editing, select Build with Aria and describe the dashboard you want. For example:
Create an operations overview with production trends and key metrics.
Aria can add or revise the dashboard during that edit session, and you can ask follow-up questions to refine the draft. Review the resulting components, configuration, and layout before selecting Save Layout. Aria's changes are not saved automatically, and Exit Without Saving discards them.
Share, duplicate, and remove dashboards
Dashboard owners can use the actions on the Custom Dashboards page to:
- share a dashboard with other users in their company;
- update or remove access for people it has been shared with;
- duplicate a dashboard in the current project or in other projects they can access; and
- delete a dashboard they own.
Dashboards shared with you are listed under Shared with me. You can view a shared dashboard, remove it from your own list, or duplicate it to create an editable copy. Only the owner can edit or delete the original shared dashboard.
When you duplicate a dashboard to another project, review every component before using it. In particular, line-chart tag selections may need to be chosen again for the destination project.
Example
An operations manager creates a Morning review dashboard for a solar project. They add a metered-versus-expected-energy gauge, a KPI card for performance ratio, line charts for production and irradiance, and a rich-text note describing the day's planned maintenance. They share the finished dashboard with the project team so everyone starts the review with the same project context.
KPI Overview
KPIs (Key Performance Indicators) are a set of metrics that are used to measure the performance of a system. Calculated on a daily basis, KPIs can be used to characterize a system either at a point in time or to trend data over a longer period.
KPIs are separated into two categories: Benchmark & Contractual.
Benchmark KPIs are used to characterize a system's performance relative to itself and other projects in a user's portfolio. These KPIs are consistent across all projects. Proximal intends to provide industry-supplied values to compare an individual project or portfolio to.
Contractual KPIs are used to track the specific behavior of a system or component as defined by a contract between two parties. These KPIs are project-specific, and are created by the Proximal team individually for each project. As such, documentation for these KPIs cannot be found in these pages, but will be more thoroughly documented in the KPI page on the Proximal platform. These KPIs are not available for benchmarking against other projects, nor industry standards. They have an associated contract available to view, and typically have an incurred liquidated damages calculation as well as the liable party.
Contractual KPIs
Contractual KPIs track performance requirements defined in contracts for a specific project. Proximal configures these KPIs for each project. They are not portfolio or industry benchmarks.
KPI page
The Contractual KPI page shows the KPI name and description. Select the performance-data year to view the annual performance chart and the contracts associated with that KPI.
Each associated contract has its own panel. The panel identifies the counterparty and contract execution date. When a contract document is available, it is displayed in the panel and can be opened for a larger view. If no document is available, the panel shows that it is unavailable.
Each panel has the following tabs:
- Threshold shows the contract-defined performance targets.
- Remedies shows contract-configured liquidated-damages information.
- Claim shows the configured submission method, timeframe, and required information.
Remedies and Claim details may not be specified for every contract. Proximal does not calculate damages or submit claims from this page.
Thresholds
Thresholds can be configured in one of two ways:
- Discrete annual targets show the target for each year.
- Surface-by-device targets define a guarantee surface of warranty year
(
x), cycles per year (y), and guaranteed value (z). Each device has a warranty start (x_origin) and optional pre-telemetry cycle offset (y_origin).
Surface-by-device evaluation
For surface-by-device targets, the current period is the device's current
warranty year: the largest tabulated x that is less than or equal to the
years since that device's x_origin.
Historical cycles per year are:
(y_origin + measured string cycle count through the as-of date) / years since x_origin
Measured cycles come from the BESS_STRING_CYCLE_COUNT KPI. Missing
y_origin is treated as 0.
The guaranteed value at that warranty year is linearly interpolated between
neighboring tabulated cycle-count (y) points. Cycle counts outside the
tabulated range are clamped to the nearest edge.
The performance and annual charts draw one applied threshold line: the simple mean of per-string guaranteed values. Strings that cannot be evaluated are omitted from the mean. If cycle data is not available, the charts fall back to showing every tabulated cycles-per-year slice.
The Threshold tab keeps the contract surface as a reference: device
warranty dates, cycles at connection, and a cycles-per-year selector to
explore tabulated z values.
The Applied Device Thresholds table shows the current, time-specific evaluation for each string: warranty year, historical cycles per year, guaranteed SoH, latest actual SoH, and margin. Rows below the guaranteed floor are highlighted.
If threshold data is unsupported or missing, it is shown as unavailable.
Availability of contract details
Contract documents, thresholds, liquidated-damages information, and claim instructions depend on the contract configuration for the project. When any of these details are absent, the Contractual KPI page shows them as unavailable or not specified.
PV
Combiner Field Health KPI
Description
The Combiner Field Health KPI measures the DC health of a project based on combiner current data. Each combiner receives a daily health score ranging from 0 to 1, where a score of 1 indicates the healthiest combiners on the project.
Methodology
- Retrieve DC combiner current data for each combiner box on a 5-minute interval. The data is filtered to focus on the time window from 11:30 AM to 12:30 PM to capture peak irradiance conditions.
- Normalize each combiner's current against its own DC capacity to account for differences in combiner size.
- Identify the "ideal" combiner by calculating the 99th percentile of all normalized combiner currents. The 99% threshold is chosen to exclude outliers and focus on typical combiner performance.
- Normalize all combiners' ratios against the ideal combiner. This gives the ideal combiner a score of 1.0, with all other combiners having a score ranging from 0 to 1. Outliers may exceed a score of 1.0.
- Calculate the daily mean score of each combiner trace to calculate the overall DC Field Health for each combiner on that day.
- Calculate the mean of all combiner scores to derive the overall DC Field Health for the project on that day.
Trackers
Description
Tracker KPIs are used to monitor performance of single-axis trackers. Multiple KPIs are calculated for each project.
- Row position deviation from setpoint.
- Row setpoint deviation from the project median setpoint.
- Row availability (when the prior two metrics are both less than 5°).
These KPIs can help identify offline trackers, errant zone controller setpoints, and communication issues.
Filters
To exclude time periods when trackers are not in use, any time intervals in which the sun elevation angle is less than or equal to 0° are excluded from the calculations.
Position Deviation from Setpoint
- Query 5-minute position and setpoint data for each row.
- Compare position to setpoint for each 5-minute interval for each row. Average the absolute value of the difference between these values for the entire day.
- Aggregate each tracker row into blocks, averaging the values again.
Setpoint Deviation from Median
- Query 5-minute setpoint data for each row.
- Calculate the median setpoint for the project.
- Compare setpoint to project median for each 5-minute interval for each row. Average the absolute value of the difference between these values for the entire day.
- Aggregate each tracker row into blocks, averaging the values again.
Availability
- Query 5-minute position and setpoint data for each row.
- Compare position to setpoint for each 5-minute interval for each row.
- If both the position and setpoint deviations are less than 5° for a given interval, the row is considered available.
- Aggregate each tracker row into blocks, averaging the values again.
Specific Yield KPI
Description
The Specific Yield KPI quantifies how much AC energy is delivered per unit of installed DC capacity. It provides a normalized metric for evaluating site performance independent of plant size and is especially useful for comparing across projects.
This KPI is calculated daily and expressed in units of kWh/kWp.
Methodology
-
Retrieve time-series data for:
meter_active_power: AC power delivered by the site over the day.
-
Clean and aggregate the data:
- Clip negative values to zero to eliminate erroneous readings.
- Resample data to hourly averages to standardize granularity.
-
Calculate total energy delivered:
- Integrate the hourly AC power measurements to get total daily energy output in kWh.
-
Normalize by DC capacity:
- Divide the total energy output by the site’s installed DC capacity (also referred to as kW-peak, or kWp) to get the specific yield.
-
Compute Specific Yield:
-
The formula is:
-
-
Store the KPI result:
- The resulting value is stored as a project-level KPI for the corresponding date.
Performance Ratio KPI
Description
The Performance Ratio KPI quantifies the overall efficiency of a PV site by comparing the actual energy produced to the theoretical maximum possible under prevailing irradiance. This KPI helps identify underperformance due to issues such as soiling, inverter clipping, or balance of system losses.
The KPI is calculated daily and results in a dimensionless number typically between 0 and 1, where 1 represents a perfectly efficient system.
Methodology
-
Retrieve time-series data at hourly resolution for:
meter_active_power: Total AC power delivered by the site.met_station_poa: Plane-of-array irradiance from on-site weather stations.
-
Clean the data by:
- Removing any columns (sensor streams) where the maximum value is less than or equal to 0.
- Clipping all negative values to zero to remove erroneous negative readings.
- Averaging the values to a uniform hourly granularity.
-
Calculate Specific Yield:
- Total AC energy delivered by the site (sum of
meter_active_poweracross all meters) divided by the total DC capacity of the project. - Units: kWh/kWp
- See also: Specific Yield
- Total AC energy delivered by the site (sum of
-
Calculate Reference Yield:
- Total POA irradiance summed across all sensors, averaged, and then normalized by a reference peak irradiance value of 1000 Wp/m² (Watt-peak per square meter).
-
Compute Performance Ratio:
- This results in a dimensionless efficiency metric.
-
Store the KPI result:
- The daily PR value is inserted as a project-level KPI for the given date.
BESS
State of Charge
Description
State of Charge (SOC) KPIs monitor BESS performance and health. Two key metrics help identify utilization patterns and operational efficiency:
- Average SOC - The mean state of charge over a time period
- Resting SOC - The state of charge when the battery is idle
Average SOC
Why It Matters
- Battery Health: Extreme SOC levels (very high or very low) accelerate battery degradation
- Longevity: Operating within optimal SOC ranges extends battery lifespan
- Performance: Consistent extreme SOC can reduce capacity and power capability over time
How It's Calculated
- Collect SOC data at regular intervals
- Calculate the arithmetic mean for the time period
Resting SOC
Why It Matters
- Battery Stress: Prolonged storage at extreme SOC levels causes chemical stress
- Aging: High resting SOC increases calendar aging, low resting SOC can cause capacity fade
- Safety: Extreme resting SOC levels may indicate potential safety concerns
How It's Calculated
- Collect SOC and power flow data
- Identify periods with minimal power flow
- Calculate mean SOC during these resting periods
Depth of Discharge KPI
Description
The Depth of Discharge (DoD) KPI quantifies the average depth to which a battery storage system is discharged during a given day. It is calculated as the inverse of the average State of Charge (SOC). A higher DoD indicates that the battery is being used more deeply, while a lower DoD suggests more conservative usage.
This KPI is useful for assessing operational behavior and wear-and-tear on battery storage systems. It is reported daily as a percentage between 0 and 1, where 1 means fully discharged on average, and 0 means fully charged on average.
Methodology
-
Retrieve time-series data for:
project_soc_percent: The State of Charge (%) of the project’s battery storage system.
-
Convert timestamp index:
- The index is converted to the project’s local timezone for consistent daily aggregation.
-
Calculate average SOC:
- Take the mean of all State of Charge (SOC) readings for the day. SOC values are expected to be in the range [0, 1].
-
Calculate Depth of Discharge:
-
DoD is the complement of SOC:
-
The result is rounded to four decimal places.
-
-
Store the KPI result:
- The daily average DoD is inserted as a project-level KPI for the corresponding date.
Project Cycle Count KPI
Description
The Project Cycle Count KPI estimates the number of full charge-discharge cycles a battery storage system performs in a single day. This KPI is essential for understanding battery utilization and degradation over time.
The KPI is calculated daily and reported as a floating-point number, where 1.0 represents one full cycle (100% discharge followed by 100% recharge, or equivalent cumulative partial cycles).
Methodology
-
Retrieve time-series data for:
project_soc_percent: The State of Charge (%) of the project’s battery system over the day.
-
Convert timestamp index:
- The index is standardized to ensure consistent time stepping.
-
Calculate absolute changes in SOC:
-
Take the absolute difference in SOC between each pair of consecutive time steps.
-
-
Sum the absolute changes and normalize by 2:
-
The total cycle count is estimated by summing all absolute SOC changes and dividing by 2. This accounts for the fact that a full cycle consists of both discharge and charge.
-
-
Round and store the KPI result:
- The daily cycle count is rounded to four decimal places and stored as a project-level KPI for the given date.
Reports Overview
Reports are automated, or semi-automated, studies performed by the Proximal platform which can keep you informed about the health of various aspects of the power plant. These reports generally have intelligent data filters which can be modified by a human in the loop.
The outputs of these reports are generated so that they can be shared with internal and external stakeholders who may or may not have access to the Proximal platform. The XLSX and CSV download features allow users to take the data generated by a report and do further manual analysis.
The PV PR Test Report is a dataset-preparation workflow for an external (typically PVSyst) performance-ratio test: it applies automatic and manual validity filters and exports weather, production, energy, and filter-audit files. It does not compute the contractual PR inside Proximal.
DC Amperage Report
Overview
This report shows the normalized current at every combiner at the PV power plant filtered for clearsky conditions. Combiner current is normalized based off of the nameplate capacity of each combiner. This makes it so that combiners with different amounts of dc capacity can be compared against one another on an apples-to-apples basis.
Different combiners may have different DC capacity due to differences in the number of strings attached to each combiner, module bin class, etc.
Filters
The analysis is generated with user input for clearsky data on a given day. Users may select thresholds for minimum POA, maximum POA derviative, and maximum POA derivative standard deviation. The input data is sampled at 5-minute intervals by default, which can be changed via the settings dropdown located in the filters card. The maximum POA derivative and maximum POA derivative standard deviation thresholds may be turned off at the risk of reduced report accuracy.
POA derivative is the rate of change of POA with respect to time. A lower POA derivative indicates a more stable POA, correlating to fewer moving clouds over the array. Proximal recommends a maximum POA derivative of 1 W/m^2^/minute.
POA derivative standard deviation is the standard deviation of the POA derivative over each 5-minute interval. A lower POA derivative standard deviation indicates that all sensors are moving in a similar way at the same time, indicating that the entire site is experiencing similar sky conditions. Proximal recommends a maximum POA derivative standard deviation of 1 W/m^2^/minute.
Both POA derivative and POA derivative standard deviation are calculated using the selected sample rate of the data, then aggregated to a 1-hour moving average.
Calculation
This report is calculated by pulling the 5-minute combiner current data, finding the nominal string current at the maximum voltage of the modules, then normalizing the actual current by the nominal string current. This normalization is then compared to the median combiner current for either the inverter associated with that combiner or the site as a whole. The intermediate calculations are available in the output XLSX file.
Outputs
By default, this report shows the normalzied DC performance of each combiner compared to its peers on the same inverter. Via the settings dropdown, this normalization can be changed to compare to the combiner performance of the entire site. Results are displayed as a normalized value, where 1.0 indicates that the combiner is operating at an equal level to the median combiner. Combiners colored in green are performing within 5% of the median combiner, while those colored in red are at least 5% below the median and those colored in pink are at least 5% above the median. This 5% threshold can be changed via the settings dropdown.
The combiner performance can be downloaded as an Excel file in the top-right corner of the page, while the raw POA and combiner current data can be downloaded as CSV files in the output settings dropdown.
Caveats
- There must be at least one clearsky timestamp during the day for this report to be generated.
- If the system definition is incorrect, (for example if the DC capacity reported to Proximal during commissioning was incorrect) then the report will be incorrect for those combiners which are defined incorrectly since the combiner DC capacity is used in the normalization calculation.
Module State of Health Report
Overview
This report is designed to characterize the performance of the modules using the combiners as a proxy. Through heavy filtering, the report aims to analyze only the combiners that are performing at the highest level, to achieve a picture representative of the best possible performance of the modules. The filters are designed to remove any effects that can be attributed to the underperformance of inverters, trackers, or other non-DC related effects.
After filtering, the performance of each combiner is characterized through the following formula:
Where:
- is the expected energy production of the combiner, detailed in the PV Model Overview. is representative of the warranted degradation curve of the modules at the time of analysis.
- is the actual energy production of the combiner, calculated as the combiner current × inverter DC voltage.
The resulting metric is representative of the performance of the modules, with 100% indicating that the modules are performing at the expected level.
Filters
Unlike the DC Amperage report, the module state of health report is not capable of user-defined filters. Instead, the report has a defined set of filters that are applied to the data, and the analysis is automatically generated on a daily basis. In addition to clearsky filters, several performance-based filters are applied to ensure that the analysis is only performed on combiners that can be considered representative of high performance.
Clearsky Filters
- Minimum POA: 250 W/m²
- Maximum POA Derivative: 2 W/m²/minute
- Standard Deviation filters
- Maximum POA Standard Deviation: 7.5 W/m²
- Maximum POA Derivative Standard Deviation: 0.25 W/m²/minute
- To filter on standard deviation and derivative standard deviation, both conditions must be met to exclude data. All other conditions are applied individually.
- POA sensors on errant trackers are excluded analytically
- At least 1 hour of clearsky-filtered data
Performance-Based Filters
- Inverter AC output between 5% and 95% of the inverter's nameplate capacity
- This ensures the inverter is online and not AC clipping
- Inverter module voltages are within 5V of each other (as applicable)
- Since combiner power must be calculated as (combiner current) × (inverter DC voltage), the module voltages must be within a narrow band to ensure that the voltage is representative of the combiners.
- Combiner DC Field Health is at least 97.5% of the project nonzero mean per day.
- If a combiner fails the fuse health filter, it is removed from the analysis.
- Tracker position deviating from setpoint is less than 1° on average per day.
- Tracker setpoint deviating from median is less than 1° on average per day
- Both tracker filters are applied to entire blocks. If a block fails the analysis, all combiners on the block are excluded for that day.
Other
- Soiling is accounted for in the expected performance calculation through the onsite soiling sensors. Since this adjustment is applied to both expected and actual performance, it is assumed to cancel out in the performance calculation and is not considered in the analysis.
Manual Filtering
- On the Clearsky tab, users may select individual days to view. The individual days show combiner-level performance as well as the clearsky POA data shaded in green for timestamps selected for analysis.
- On all tabs, users may select a specific date range to view. It is recommended to select a date range that is at least one month long to ensure enough data is available for analysis.
- The report is presented for the previous year of data by default, but either of these filters are applied to data presentation on all tabs.
Outputs
Outputs are available for each combiner, as well as various summary statistics. Graphics are available on the project level, individual combiner level, and aggregates for inverter and circuit level roll-ups. Combiner-level graphics are colored based on the capacity and bin classification of modules associated with each combiner. On the GIS tab, the report is available on a combiner-level basis.
Caveats
- Due to the heavy filtering applied to the data, the report may not generate for some days.
- If the system definition is incorrect, (for example if the DC capacity reported to Proximal during commissioning was incorrect) then the report will contains inaccuracies for those combiners which are defined incorrectly since the combiner DC capacity is used in the normalization calculation.
Inverter Availability
Description
Inverter availability KPIs measure how often each inverter (and, when present, its internal power-conversion modules) is producing at least a minimum power output under valid irradiance conditions.
One daily report is produced containing:
- Inverter Availability – percentage of daylight intervals in which each inverter’s AC power exceeds a user-defined threshold.
- Module Availability – same calculation applied to individual inverter-module channels (only shown if the project reports module-level power).
This report helps identify offline or under-performing inverters, balance-of-plant outages, and data-quality issues.
Parameters (default values)
| Parameter | Purpose | Default |
|---|---|---|
| Available Min (MW) | Minimum inverter (or module) AC power required to count as “available”. | 0 MW |
| Irradiance Min (W/m²) | Minimum plane-of-array irradiance at which availability is evaluated. | 0 W/m² |
| Inverter Availability (%) | Workbook formula – average of all inverter availabilities. | (output) |
| Inverter Module Availability (%) | Workbook formula – average of all module availabilities (shown only if module data exists). | (output) |
Filters
An individual 5-minute interval is excluded from availability calculations if:
- Plane-of-array irradiance ≤ Irradiance Min.
All other samples form the valid daylight set for the day.
Method – Inverter Availability
- Query 5-minute pv_inverter_ac_power and met_station_poa for every inverter in the project.
- Validate irradiance – keep only timestamps where POA > Irradiance Min.
- Evaluate power threshold – for each inverter, flag samples where
[ P_{\text{inv}}(t) > \text{Available Min} ] - Compute availability per inverter
[ A*{\text{inv}}=\frac{\text{count}\left(P*{\text{inv}}> \text{Available Min}\right)} {\text{count(valid daylight samples)}} ] - Export an Excel workbook containing:
- Parameters – editable inputs & live output KPIs.
- Inverter Availability – % available for each inverter.
- Inverter Power – raw 5-minute power time-series.
- Irradiance – POA irradiance (mean + individual sensors).
Availability formulas live in Excel, so users can adjust Available Min or Irradiance Min and see KPIs update instantly.
Module Availability (when reported)
If the project provides PV Inverter Module AC Power:
- Repeat Steps 1-4 using module-level power.
- Add sheets – Module Availability and Module Power – mirroring the inverter sheets.
Tracker Availability
Description
Tracker availability KPIs quantify how often each tracker row is correctly following its expected angle.
Two daily reports are generated:
- Row vs Row Setpoint – compares each row’s measured position to its own controller setpoint.
- Row vs Zone Median Setpoint – compares each row’s position to the median setpoint of all rows in its zone.
A row is considered available when the absolute position error is within an acceptable tolerance. These KPIs surface drifted trackers, stow-logic faults, communication drop-outs, and other issues.
Parameters (default values)
| Parameter | Purpose | Default |
|---|---|---|
| Available Max (deg) | Max position error allowed to count as “available”. | 5° |
| Irradiance Min (W/m²) | Minimum plane-of-array irradiance required to evaluate availability. | 0 W/m² |
| Exclude Stow Periods | If TRUE, stow periods are removed from the analysis. If a project lacks stow data this flag is ignored. | TRUE |
| Maximum Setpoint Change (deg) | Quality gate that rejects 5-min setpoint jumps above this value. | 60° |
Filters
Before availability is calculated, any 5-minute interval is discarded if any of the following are true:
- Tracker position or setpoint is blank.
- Plane-of-array irradiance ≤ Irradiance Min.
- Exclude Stow Periods is TRUE and the tracker zone is reported as stowed.
- |Position − Setpoint| ≥ 120°.
- |Setpoint(t) − Setpoint(t-1)| > Maximum Setpoint Change. (Rule 5 is skipped for the first sample of the day.)
Method 1 – Row vs Row Setpoint
- Query 5-minute tracker position, tracker setpoint, met station poa, and tracker zone status for every row in the project.
- Apply filters listed above to build the valid-data mask.
- Calculate position error
[ \Delta\theta*{\text{row}}(t)=\left|\text{Position}*{\text{row}}(t)-\text{Setpoint}_{\text{row}}(t)\right| ] - Compute availability for each row
[ A*{\text{row}}=\frac{\text{count}\left(\Delta\theta*{\text{row}}\le\text{Available Max}\right)} {\text{count(valid samples)}} ] - Export an Excel workbook containing:
- Parameters – editable inputs & descriptions.
- Availability – one value per row (percent).
- Difference – per-sample (\Delta\theta_{\text{row}}) table.
- Raw data sheets: Position, Setpoint, Stow, Irradiance.
Method 2 – Row vs Zone Median Setpoint
- Derive zone setpoints by taking the median of all row setpoints within each zone at every 5-minute timestamp.
- Repeat Steps 2-5 from Method 1, replacing Setpoint₍row₎(t) with Setpoint₍zone median₎(t) in the error formula.
- The workbook layout is identical; the Setpoint sheet now shows zone medians (prefixed “Zone”).
Usage Notes
- All calculations occur in the exported Excel file via formulas, allowing users to adjust parameters post-hoc.
PV PR Test Report
Description
The PV PR Test Report prepares measured weather, production, and energy datasets for an external performance-ratio (PR) test workflow, typically completed in PVSyst. Proximal does not compute the contractual PR, run a PVSyst simulation, or score modeled versus actual energy in this report. The platform's job is to assemble a defensible measured dataset: apply automatic and manual exclusions, document those exclusions, and export files that a modeler can import into PVSyst (or another independent tool) for the modeled-vs-actual comparison.
In the app the page is titled PR Test (project → Reports → PR Test). It currently shows an In Development banner. The report is organized as four sequential tabs:
- Test Setup – test identity, date range, timezone, source-data status, and optional import of a prior filter configuration.
- Automatic Filters – exclusion rules and a timestamp-level impact preview.
- Manual Filters – weather-trace review plus global and device-specific timestamp-range exclusions with reasons.
- Outputs – downloadable artifacts for PVSyst weather import, production/energy analysis, and audit of the filter set.
This page is the methodology and instruction reference for engineers who already know how a PR test is structured (valid-period selection, irradiance and soiling gates, clipping and outage exclusions, measured vs. modeled energy). It documents what Proximal assumes, what it calculates automatically, and what each exported file is for.
Scope and capabilities
The report can:
- Query on-site meteorological traces (GHI, POA, POA tilt, secondary/rear POA, ambient temperature, wind speed, soiling) over a user-selected inclusive calendar range.
- Query project-level and inverter-level AC power, the PPC active-power setpoint, and plant energy-meter registers.
- Query project-level Events for curtailment and availability/outage windows.
- Apply a configurable set of automatic exclusions, then optional manual exclusions.
- Roll weather up to hourly values in the project timezone and write a PVSyst-oriented custom weather CSV.
- Derive hourly DHI from GHI when no measured DHI tag is present and site coordinates are available.
- Produce irradiance-weighted monthly soiling and albedo summaries for PVSyst parameter tables.
- Export production (MW) and hourly energy (Wh) tables, a reusable JSON filter configuration, an hourly TRUE/FALSE filter matrix, a manual-exclusion audit log, and a README manifest.
The report cannot:
- Compute PR, reference yield, or specific yield (see the Performance Ratio KPI for the operational PR KPI, which is a different calculation).
- Import or score a PVSyst
.MET/ simulation output against metered energy inside Proximal. - Apply IEC 61724 or ASTM E2848 capacity-test regressions. Those remain external.
Assumptions
The following assumptions are built into the current implementation. They are not user-editable unless a corresponding filter or setup field exists.
-
This phase is dataset preparation only. Modeled-vs-actual scoring is performed outside Proximal.
-
All timestamps are interpreted in the project timezone (IANA name from the project record, overridable on Setup). Native-interval samples are bucketed to the civil hour
[h, h+1)in that timezone. Hour labels are written asYYYY-MM-DD HH:mm:ssat the start of the hour. -
The selected date range is inclusive of both calendar dates. Queries run from
startDate 00:00:00throughendDate 23:59:59. The hourly grid runs fromstartDate 00:00throughendDate 23:00. -
The query interval follows the project's configured data interval. One-second projects are queried at one minute. Unrecognized intervals fall back to five minutes. The interval is not a Setup control; it is taken from the project and stored in the exported config.
-
An exact-zero meteorological reading is treated as a malfunction, not as a physical night-time or dry-sensor value, except soiling loss. Finite non-zero readings are required for other met-station types.
MET_STATION_SOILING_LOSSof is a physical no-soiling value and is kept. -
Irradiance is nonphysical when or . The bound is applied to GHI and POA (and to DHI in the weather roll-up), and to up-facing / down-facing samples used to derive albedo from pairs. It is a per-sensor drop, not an automatic site-timestamp drop.
-
Minimum-POA uses the mean of remaining front-facing POA sensors, not the site minimum. Rear-, back-, down-facing, reflected, and ground-facing POA traces are ignored for this gate so that a single rear or low sensor cannot zero the valid set.
-
Hours with no remaining front-facing POA fail the minimum-POA gate in the hourly filter matrix (missing POA is treated as ). That matrix is what filtered weather, energy pass/fail columns, and the Excel filter file use.
-
All soiling traces are converted to soiling loss percent before thresholds and export. loss means no soiling.
- Soil percent (
MET_STATION_SOIL_PERCENT, id 39) and soiling ratio (MET_STATION_SOILING_RATIO, id 245) are remaining performance, typically –, where means no soiling. - Soiling loss (
MET_STATION_SOILING_LOSS, id 246) is already lost performance, typically –, where means no soiling.
Values in the unit-fraction range are scaled to percent; values above that range are already percent. Soiling ratio uses a wider unit-fraction band () so clean readings slightly above stay loss:
- Soil percent (
with for soil percent and for soiling ratio.
The weather CSV Soiling column, monthly soiling summary, and maximum-soiling-loss gate all use .
10. Clipping is evaluated at 98% of the relevant limit. Project clipping compares plant power to PPC_ACTIVE_POWER_SETPOINT. Inverter clipping uses capacity_power_ac_kva treated as kW (power factor of 1) and converted to MW. PVS projects use the MV collector-circuit meter power, summed across those meters, in place of METER_ACTIVE_POWER.
11. If the PPC setpoint is missing or non-positive, project clipping never excludes. If an inverter has no positive nameplate, that inverter is skipped for clipping. If no inverter AC-power traces exist, communication-gap exclusion does not remove native timestamps. Communication-gap exclusion is preview-only; it does not fail hours in the matrix or filtered exports.
12. Sensor validity, outlier sigma, and hourly completeness are front-facing POA-only. Rear-, back-, down-facing, reflected, and ground-facing POA traces are ignored for these gates, matching the minimum-POA filter. GHI remains in the weather CSV and is still dropped per-sensor when nonphysical, but it does not decide validity, outliers, or completeness.
13. POA outlier statistics are population mean and population standard deviation over every usable front-facing POA sample in the selected range (not a rolling or per-hour statistic). A timestamp/hour fails if any remaining front-facing POA sample at that key is more than from that site-wide mean.
14. Hourly completeness requires at least 60% of the expected sub-intervals in that civil hour to contain a valid front-facing POA timestamp. Expected count is , using the query interval (1, 5, 10, 15, 30, or 60 minutes).
15. The filtered weather CSV always applies the 60% completeness rule, even if the completeness switch is turned off. Turning the switch off only stops completeness from contributing to the hourly matrix verdict; the filtered-weather file still drops incomplete hours.
16. Event exclusions use project-level Events, not inverter- or device-level Events. Availability/outages are other project-level Events whose event_id is not in that curtailment set.
17. An Event overlaps an hour if the Event window and [hour, hour+1) share any open interval. Events that started before the report window are included when they still overlap the selected range.
18. DHI derivation uses the Erbs diffuse-fraction correlation and a simplified solar-position model (no equation of time). Measured DHI tags, when present, always take precedence. Derivation runs only for hours that already meet the 60% front-facing POA completeness rule and only when latitude and longitude are available.
19. Weather CSV GPI is the hourly mean of traces classified as POA (MET_STATION_POA and MET_STATION_POA_TILT). Secondary/down-facing POA is not mapped into GPI. Name-based rear/back traces that are still typed as MET_STATION_POA are included in GPI, unlike the minimum-POA filter, which excludes them.
20. Albedo is not a weather-CSV column. It is computed for the monthly summary from an albedo tag when present, otherwise from same-device up-facing / down-facing irradiance pairs ( when ).
21. Energy registers are assumed to be kWh. Hourly export is in Wh. A trace is treated as cumulative if at least 80% of consecutive valid samples are non-decreasing; otherwise samples in an hour are summed as interval energy.
22. Manual exclusions are not columns in the hourly filter matrix. They omit matched weather samples from hourly averages. Global ranges also remove those native timestamps from the Automatic Filters preview; device ranges remove every candidate timestamp in that range from the preview remaining set. The matrix Final verdict is automatic filters only.
Workflow
- Open the report on the project. The Documentation button in the upper-right opens this methodology page. Confirm Weather, Project production, Inverter production, Energy meter, and Project events source status on Test Setup after a date range is selected.
- Set Test run name, Date range, and Timezone. Import a previous
pr-test-filter-config/v1JSON if you are repeating a test. Reset restores the default setup and empty filter set and clears this project's saved browser state. - On Automatic Filters, enable the gates required by the test protocol. Defaults are listed below. Click Compute preview after changes; impact counts do not refresh automatically. Preview is for tuning; it is not required before exporting.
- On Manual Filters, review weather traces, then add global and/or device timestamp ranges for conditions the automatic engine cannot see (soiling events not captured by the soil sensor, known pyranometer outages, snow, etc.). Include a reason; it is written to the audit log (the form does not block an empty reason).
- On Outputs, download the artifacts required by the PVSyst workflow. At minimum this is usually the filtered weather CSV, production and/or energy CSV, filter matrix, and README. Re-download after any filter change.
Browser state for the project is written when you download an Outputs artifact and restored the next time you open the report. The exported JSON is the portable copy so another engineer can reload the same filter set.
Setup fields
| Field | Intention | Default |
|---|---|---|
| Test run name | Human label used in the JSON, README, and download filenames. | {project name} PR test |
| Date range | Inclusive civil dates that bound queries, the hourly grid, and every export. | Last 7 days through today (UTC calendar dates at page load) |
| Timezone | IANA timezone for local-hour bucketing, Event overlap, and CSV clocks. | Project timezone |
| Data interval | Native query step used for completeness (expected intervals per hour = 60 / Δt). Not shown as an editor; taken from the project. | Project data_interval (1 s → 1 min; otherwise 5 min fallback) |
| Import filter config | Reloads automatic filters, manual exclusions, test name, dates, timezone, and interval from a previously exported JSON. Project identity stays the current project. | (none) |
| Reset | Restores default setup (including the last-7-days date range), default automatic filters, and empty manual exclusions, and clears this project's browser storage. | — |
Source-status rows are availability checks only. Unavailable does not block configuration; exports that need Events will retry and fail if availability exclusions are on and Events cannot be fetched.
Source data
Weather
Queried sensor types:
- GHI
- Ambient temperature
- Wind speed
- Soil percent (legacy remaining performance, typically –)
- Soiling ratio (remaining performance, typically –; same conversion as soil percent)
- Soiling loss (lost performance, typically –; scaled to percent, not inverted)
- POA
- POA tilt
- POA secondary (typically rear / down-facing; used for albedo pairing, not for GPI or the minimum-POA mean)
Production
- Project power:
METER_ACTIVE_POWER, except PVS projects, which usePV_MV_COLLECTOR_CIRCUIT_METER_ACTIVE_POWERsummed across those meters. - PPC setpoint:
PPC_ACTIVE_POWER_SETPOINT, used as the project-clipping limit. - Inverter power:
PV_INVERTER_AC_POWER. - Inverter nameplate:
capacity_power_ac_kvaon PV inverter devices, treated as kW.
Energy
METER_ENERGY_EXPORTED_TO_GRIDMETER_NET_ENERGYPV_MV_COLLECTOR_CIRCUIT_METER_ENERGY_EXPORTED_TO_GRID(PVS)
Events
Two summaries are fetched over the same overlap window (open: false, losses not requested):
- Curtailment:
failure_mode_id = 205. - Project-level Events:
device_type_id = PROJECT. Availability/outage windows are this set minus curtailmentevent_ids.
Time, candidates, and two evaluation grids
The engine builds two related views of the same range.
Native-interval preview (Automatic Filters tab). Candidate timestamps are the union of GHI, front-facing POA, soiling, and production timestamps after conversion to project-local time. Filters are applied sequentially in the order listed under Automatic filters. Each filter's Removed count is the number of candidates that still remained after earlier filters and then failed this one (except nonphysical irradiance, which counts dropped sensor readings). Percent is that removed count divided by the original candidate count, except the nonphysical row, which divides by the irradiance-reading count. Scope device-specific means the filter dropped individual sensor readings (or is attributed per device); global means the whole timestamp is removed.
Hourly filter matrix (Outputs). One row per project-local hour from startDate 00:00 through endDate 23:00. Each enabled condition is evaluated independently against hourly aggregates (except communication gaps, which do not fail hours — see below). Disabled conditions are treated as TRUE. Final verdict is the logical AND of every condition. Filtered weather, energy pass/fail columns, and the Excel matrix all use this hourly verdict.
Because preview is sequential at native interval and the matrix is independent at hourly resolution, preview coverage and hourly pass counts will not match one-for-one. Use the preview to tune gates; use the matrix as the record of which hours entered the filtered weather/energy files.
Automatic filters
Defaults apply to a new test. Every switch and numeric threshold is written into the JSON config under automaticFilters.
| Control | Default | Intention |
|---|---|---|
| Exclude nonphysical irradiance | On | Drop individual GHI/POA samples that cannot be physical. |
| Minimum POA threshold | On, 150 W/m² | Keep only periods with enough front-facing POA for a PR-valid irradiance set. |
| Maximum soiling loss | On, 10% | Drop periods with excessive measured soiling loss so the valid set is not dominated by dirty-array hours. |
| Exclude project-level clipping | On | Remove periods where plant power is at or near the PPC setpoint, so PR is not credited/penalized for plant clipping. |
| Exclude inverter-level clipping | On | Same intent at inverter nameplate; any one inverter at the clip bound fails the timestamp/hour. |
| Exclude availability / outage periods | On | Remove project-level outage/availability Events other than curtailment. |
| Require hourly sub-interval completeness (60%) | On | Require enough front-facing POA sub-samples in the hour to treat the hourly mean as representative. |
| Exclude communication gaps | On | Drop native-interval timestamps with no inverter AC power reading (SCADA hole). Does not fail hours in the matrix or filtered weather. |
| Require valid POA sensors | On | Require at least one remaining valid front-facing POA reading. |
| POA sensor outlier threshold | On, 3 σ | Drop timestamps where any remaining front-facing POA sample is an extreme relative to the site-wide POA distribution. |
Evaluation order (preview)
On the native-interval preview, remaining timestamps are reduced in this order:
- Nonphysical irradiance (site timestamp removed only if no physical GHI or POA remains).
- Minimum POA.
- Maximum soiling loss.
- Sensor validity (valid front-facing POA present).
- POA outlier sigma.
- Hourly front-facing POA completeness.
- Communication gaps.
- Inverter clipping.
- Project clipping.
- Availability/outage Events.
- Manual global ranges.
- Manual device ranges.
The hourly matrix does not apply steps 11–12 and does not use sequential masking; it ANDs the enabled automatic conditions on hourly means. Communication-gap exclusion (step 7) is native-interval only: it does not fail hours in the matrix, so it does not remove hours from filtered weather, energy pass/fail columns, or the Excel file.
Nonphysical irradiance
A GHI or POA sample is nonphysical when
Each failing sample is dropped from that sensor only. Other sensors at the same timestamp remain. The site timestamp (preview) or hour (matrix) is removed only when every irradiance reading at that key was nonphysical, i.e. no physical GHI mean and no physical front-facing POA mean remain.
Preview Removed for this row counts dropped sensor readings, not site timestamps. That is why its scope is device-specific.
When this switch is off, nonphysical values are not dropped as nonphysical, but exact zeros are still rejected as invalid met-station readings.
Minimum POA
Front-facing POA traces are those classified as POA (MET_STATION_POA or MET_STATION_POA_TILT) that are not secondary/down/reflected/ground and whose names do not contain rear or back. After nonphysical samples are removed, remaining front-facing values at the key are averaged.
Hourly matrix (governs filtered exports):
If the hourly mean is missing, it is treated as , so the hour fails whenever the gate is enabled.
Native-interval preview: the timestamp is removed only when a mean exists and that mean is below . A timestamp with no front-facing POA therefore passes this preview gate (it may still fail sensor validity or other gates).
Maximum soiling loss
Soiling traces are converted to soiling loss percent (see assumption 9) and averaged across remaining sensors at the timestamp or hour. Soil percent and soiling ratio are remaining performance and are inverted to loss. Soiling loss is already lost performance and is only scaled to percent. The period fails when
If no valid soiling reading exists, the gate does not fail the period (null soiling is treated as “no evidence of excessive soiling”). A soiling-loss reading of is valid and counts as . An exact-zero soil-percent or soiling-ratio reading is dropped as a malfunction.
Sensor validity
Fails when no valid front-facing POA remains at the timestamp (preview) or when the hourly front-facing POA mean is missing / the hour has no POA values (matrix). This is independent of GHI. If the project has no front-facing POA traces, the preview skips this gate; the matrix still requires a POA mean when the switch is on, so hours without POA fail.
POA outlier sigma
Let and be the population mean and standard deviation of every usable front-facing POA sample in the selected range. A timestamp/hour fails if any remaining front-facing POA value at that key satisfies
If , nothing is flagged. If there are no usable front-facing POA samples, the gate is inactive.
Hourly completeness
For civil hour , let be the number of distinct local timestamps in that hour that still have valid front-facing POA, and let . The hour (and every native timestamp in it, on preview) fails unless
An hour with no front-facing POA timestamps has no completeness record and fails this gate when it is enabled.
Communication gaps
On the native-interval preview, fails when no inverter AC-power trace has a finite reading at that timestamp. If inverter power traces exist but a timestamp has none of them, the timestamp is a gap. If there are no inverter traces at all, the gate does not exclude.
This gate is not applied on the hourly matrix. Filtered weather, energy pass/fail, and the Excel matrix therefore still include hours that the preview would drop as communication gaps.
Inverter clipping
Fails if any inverter with a positive nameplate satisfies
Preview uses the instantaneous inverter power at the native timestamp. The hourly matrix uses the mean inverter power within the hour. Nameplate is capacity_power_ac_kva / 1000 (kVA stored as if it were kW).
Project clipping
Fails if the PPC active-power setpoint is a finite positive MW value and
Project power is METER_ACTIVE_POWER at that timestamp, or for PVS projects the sum of PV_MV_COLLECTOR_CIRCUIT_METER_ACTIVE_POWER traces. The hourly matrix uses the mean of those timestamp values versus the mean setpoint in the hour. Missing project power, or a missing/non-positive setpoint, does not fail the gate. project.poi is not used.
Availability Events
When enabled, an hour (and native timestamps whose hour overlaps) fail if any availability Event overlaps [hour, hour+1). Overlap is half-open on the Event end: time_end must be after the hour start; an Event that ends exactly at the hour start does not overlap that hour. time_end = null overlaps all later hours.
Availability uses project-level Events whose event_id is not in the curtailment set (failure_mode_id = 205). Curtailment Events are fetched only so they can be subtracted from that availability set; there is no automatic curtailment-event gate.
Manual filters
Manual exclusions are timestamp ranges. A reason string is stored on the row and written to the audit log; the form does not require it.
- Global: every weather sample whose local timestamp falls inside
[start, end](inclusive) is omitted from hourly averages. The native-interval preview also removes those timestamps from remaining. - Device / tag: in hourly weather construction, only the matched trace is omitted. Match is by
tag_idwhen set, otherwise bydevice_id(and tag-less traces on that device). In the native-interval preview, every candidate timestamp in that range is removed from remaining (not only the matched trace).
Use these for protocol-specific exclusions the automatic gates cannot encode (known instrument failure, snow cover, washing, shading from construction, etc.). They appear in the manual-exclusion CSV and in the JSON. They do not flip Excel matrix columns or Final verdict. They change the weather values (and weather-side 60% completeness counts) that go into hourly averages.
Hourly weather construction
After manual exclusions and the nonphysical / zero-reading rules, remaining samples of each weather metric are arithmetically averaged within each civil hour. Metrics are assigned from sensor type and, for DHI/albedo/up/down, from tag/name matching.
| Weather CSV column | Source | Units |
|---|---|---|
| Year, Month, Day, Hour, Minute | Hour-start timestamp expressed in the advertised GMT offset | — |
| GHI | Mean of GHI traces | W/m² |
| Tamb | Mean ambient temperature | °C |
| DHI | Measured DHI mean if any DHI tag exists in the hour; otherwise Erbs derivation from hourly GHI | W/m² |
| GPI | Mean of POA / POA-tilt traces | W/m² |
| WindVel | Mean wind speed | m/s |
| Soiling | Mean soiling loss percent after converting every soiling sensor type | % |
Missing numeric values are written as -99. A units row follows the header (W/m2, deg.C, m/sec, %).
Comment rows before the header use PVSyst custom-file convention: field name in column A (# Site, # Country, …) and value in column B.
| Comment | Value |
|---|---|
| Site | Project / site name |
| Country | Parsed from project address (US state abbreviation or “United States” → USA; otherwise last comma-separated segment if it looks like a country; else USA) |
| Data Source | Proximal Energy |
| Time step | Hour |
| Latitude / Longitude | Project point coordinates (GeoJSON [lon, lat]) |
| Altitude | Project elevation |
| Time Zone | GMT offset in hours at startDate 00:00 local. Every data-row timestamp is converted onto this same fixed offset so a DST transition does not shift PVSyst solar time. |
| Summarization period | Start and end dates as DD/MM/YYYY; DD/MM/YYYY |
Measured vs derived DHI
A trace is treated as measured DHI when its name/type contains dhi, diffuse_hor, diffuse horizontal, or met_station_dhi, and is not labeled as POA. If any such sample lands in the hour, DHI is the mean of those samples (dhiSource = measured).
Otherwise, for hours that already meet 60% front-facing POA completeness, with finite GHI and site latitude/longitude, DHI is derived:
- Day of year in the project timezone.
- Extraterrestrial irradiance:
- Solar declination:
- Hour angle from local clock time and longitude, without equation of time: with in degrees.
- Zenith angle from latitude and . If the sun is at or below the horizon (zenith ), derived DHI is .
- Clearness index:
- Erbs diffuse fraction :
- . GHI yields DHI .
If coordinates are missing, derived DHI is omitted (-99).
Albedo (monthly summary only)
If an albedo-named trace exists, its hourly mean is used. Otherwise albedo is the mean of per-device ratios in that hour, pairing up-facing GHI/front POA with down-facing/secondary POA on the same device_id. When nonphysical-irradiance exclusion is on, pair inputs must satisfy the same bound as GHI/POA. Up-facing irradiance for weighting falls back to GHI when POA is missing.
Outputs
Weather, production, energy, and monthly-summary filenames use the project's name_short. JSON, Excel, manual-exclusion log, and README filenames use {sanitized project name_long}-{sanitized test name}-{start}-{end}. All clocks in tabular files are project-local.
Weather CSV
Unfiltered hourly PVSyst custom file for the full selected range. Use this as the raw measured meteorological record: every hour is present, incomplete hours included, automatic-filter failures included. Typical uses: PVSyst custom weather import when you will apply validity inside PVSyst; audit of the as-measured hourly means; comparison against the filtered file.
Filtered weather CSV
Same schema as the weather CSV, restricted to hours that pass every enabled automatic filter on the hourly matrix (Final verdict = TRUE) and meet the 60% front-facing POA completeness rule (always, even if that switch is off). Communication-gap exclusion is not part of that hourly verdict. Use this as the candidate valid-period weather for the PR test in PVSyst when you want Proximal to have already applied the protocol gates. Hours removed by automatic filters or incompleteness are omitted rather than zero-filled.
Monthly weather summary CSV
Columns: Month (YYYY-MM), Soiling loss (%), Albedo, Soiling sample hours, Albedo sample hours.
Built only from hours that are complete (60% front-facing POA) and pass the hourly automatic-filter verdict:
- Soiling: POA-weighted mean of hourly soiling loss percent, using hours with .
- Albedo: up-irradiance-weighted mean of hourly albedo, using hours with up-facing irradiance (POA, else GHI) .
Use these monthly values as PVSyst soiling-loss and albedo parameters for the test period when the contract or model calls for irradiance-weighted monthly constants rather than hourly soiling in the weather file.
Production CSV
Wide table: Time (local) plus one column per meter, inverter AC-power, or PPC setpoint trace (MW, four decimal places). All native-interval timestamps in range are included; there is no validity mask. Empty cells are missing readings, not excluded hours. Use this for:
- Independent clipping checks against nameplate or the PPC setpoint.
- Aligning measured AC power with a PVSyst simulation timestep.
- Investigating hours the filter matrix rejected.
Energy CSV
Hourly Wh from plant energy meters, one column per energy trace, plus Passes all filters and Is excluded (TRUE/FALSE). The pass/fail pair is the hourly automatic-filter verdict (Is excluded is the negation). The file contains every hour in the grid, including failed hours.
Cumulative vs interval detection: if ≥ 80% of consecutive valid samples are non-decreasing, hourly energy is in Wh, and hours where the register drops are left blank. Otherwise valid samples in the hour are summed and converted kWh → Wh. The first hour of a cumulative series has no delta and is blank.
Use this as the measured energy time series for the PR numerator, with the pass column as the valid-period mask if you are not using the filtered weather file alone.
JSON filter file
Version pr-test-filter-config/v1. Contains generatedAt, setup metadata, automaticFilters, filterLabels, manualExclusions, and notes stating that Proximal is not completing modeled-vs-actual comparison. Import this on Setup to reproduce the same test configuration in another session or for another engineer. Legacy capacity-test-dataset-builder/v1 files still parse.
Excel filter matrix
HTML .xls table: Timestamp (hourly), one TRUE/FALSE column per automatic condition (using the labels below), and Final verdict. Independent hourly evaluation, not sequential preview masking. Use this as the auditable valid-period mask: which gate failed which hour, for inclusion in a test report appendix or for rebuilding a mask in Excel/PVSyst.
Matrix column labels:
- Nonphysical irradiance exclusion
- Minimum POA threshold
- Maximum soiling loss threshold
- POA sensor validity requirement
- POA sensor outlier sigma limit
- Hourly POA sub-interval completeness (60%)
- Communication gap exclusion
- Inverter-level clipping exclusion
- Project-level clipping exclusion
- Availability / outage exclusion
A disabled gate is TRUE for every hour. Communication-gap exclusion is also TRUE for every hour in this matrix; that gate is native-interval (preview) only.
Manual exclusion log
CSV columns: scope, start_timestamp, end_timestamp, device_id, device_label, reason. One row per global or device-specific range. Use this as the test-report appendix of engineering judgments that sat outside the automatic protocol.
Export manifest / README
Markdown summary of project, test name, date range, timezone, data interval, units, generation time, config version, every automatic-filter value, manual-exclusion counts, and a preview summary computed at download time from the current filters and source data (not the last Compute preview click on Automatic Filters). Use this as the cover sheet for a delivered PR-test data package so a reviewer can see units and gates without opening the JSON.
Caveats
- The in-app PR Test page is still marked In Development. Treat this document as the current methodology, and expect further changes.
- Browser state is written when you download an Outputs artifact, not on every filter edit. Use Reset on Test Setup, or the exported JSON, if you need a known starting point.
- Operational Performance Ratio KPI is a daily site KPI on unfiltered hourly POA and meter energy. It is not this report's valid-period PR and will not match a contractual PR test.
- Preview coverage is native-interval and sequential; do not treat it as the hourly valid fraction in the filtered weather file.
- Communication-gap exclusion affects the Automatic Filters preview only. It does not remove hours from filtered weather, energy pass/fail, or the Excel matrix.
- Rear/down-facing POA is excluded from the minimum-POA mean, sensor validity, outlier sigma, and completeness counts, but can still affect GPI if a rear sensor is typed as primary POA.
- Derived DHI is an Erbs estimate from GHI and a simplified solar position. Prefer measured DHI when the site has a shaded pyranometer.
- Inverter nameplate is taken from
capacity_power_ac_kvaas kW. Incorrect commissioning nameplates will mis-fire inverter clipping. - Missing or non-positive PPC setpoint silently disables project clipping.
- Exact-zero met readings are discarded. Night-time POA of true zero therefore never contributes; completeness is driven by daytime (or non-zero) front-facing POA samples only.
- Energy conversion assumes kWh registers. If a meter is already in Wh, exported values will be 1000× high.
- Event exclusions require a successful Events fetch. If Events fail and the availability gate is on, filter-dependent downloads stop after retry.
- Turning off hourly completeness still drops incomplete hours from filtered weather; only the matrix completeness column becomes unconditionally TRUE. Completeness is counted on unique front-facing POA timestamps, not GHI. Manual exclusions can reduce that weather-side count even though they do not change the matrix completeness column.
Combiner Mismatch Report
Use the Combiner Mismatch Report to identify likely mismatches between PV combiner locations in the site layout and their SCADA current tags. It analyzes each PV block and recommends mappings to review; it does not change field wiring, GIS, or SCADA mappings.
Open a project and go to Reports → Combiner Mismatch Report.
How the report works
The report uses a fixed 14-day window of high-resolution combiner-current data, ending on the date you select. It looks for moving cloud shadows crossing a PV block. When the layout and tags are correct, combiner currents should decrease in the same spatial order as the shadow. A tag that repeatedly responds where another combiner is located may be swapped.
It also compares combiner capacity with current. On the same days, larger combiners should generally draw more current than smaller combiners. This is an independent check that can identify a potential mismatch even when useful moving-cloud patterns are unavailable.
The report needs combiner current tags, combiner locations in the site layout, and combiner nameplate capacities. It skips days without a clear moving cloud edge or sufficient data.
Generate a report
- Select the end date for the analysis window. The report automatically uses the preceding 13 calendar days, for 14 days in total.
- Select Generate report.
- Wait for block results to finish loading. The site map and block table update as blocks are analyzed.
If the selected window has no high-variability days, select a different end date that includes cloudier conditions. A block can also show a warning or fail when it has too little usable moving-cloud data, no combiner-current tags, or an analysis error.
Completed reports remain available from the Report history tab. Select a past report to review its saved results.
Review block results
The block table and site map show the status of every analyzed PV block:
- Swaps: the report found a suggested remap.
- Review: there is a finding that needs investigation but is not a suggested remap.
- Clean: enough useful data was available and no mismatch was found.
- Warning or Failed: the block could not be reliably analyzed. Try a different 14-day window or check the available data and layout.
Select a block in the table or on the map to open its time-series viewer. The viewer replays combiner current by capacity across the selected block. Compare Before (the tagged currents) with After (the recommended remap) to see whether the current timing matches the combiner locations more closely.
Use Download CSV after the report completes to share the block results and findings outside Proximal.
Interpret findings
The results distinguish between the strength and type of evidence:
- Confirmed: cloud timing and capacity-versus-current both identify the same combiners. Prioritize these for a mapping or field check.
- Likely (timing): the cloud-order check remains consistent on later days. A capacity finding may be absent when the combiners have the same size.
- Likely (capacity): current and capacity indicate a mismatch, but cloud timing did not confirm it. Review it, but do not treat it as a completed remap.
- Walk the block: larger combiners appear to draw less current than smaller ones across the block. Individual pair recommendations are not reliable; check every combiner mapping in the block.
- Investigate: there was insufficient useful data or the two checks disagree. Review the block before taking action.
For example, if two same-sized combiners repeatedly show each other's cloud arrival pattern, the report can recommend swapping their tags. Open the block, compare the Before and After replay, then confirm the mapping in the field or in the mapping table before making any change.
Limitations
A recommended swap is evidence to investigate, not proof that field wiring was changed. The issue may be in GIS, SCADA tags, or another mapping source.
The report can identify two-combiner swaps and some three-combiner mix-ups. More complex mapping problems may appear as multiple findings or as Walk the block. Incorrect nameplate capacities, missing layout data, and unusual combiner geometry can also affect the analysis. Correct layout issues before relying on the results.
Forecasts Overview
Proximal forecasts hourly weather and solar power production for utility-scale solar projects. Each forecast combines project configuration, weather data from the Integrated Forecasting System (IFS), and the Proximal PV performance model.
Weather forecast
The forecast service requests the ECMWF Integrated Forecasting System (IFS) at the project's latitude and longitude. The request is aligned to the most recent available IFS model run. The current request returns 240 hourly forecast points, covering 10 days.
All forecast timestamps are stored in UTC:
time_forecast_runidentifies the IFS model run used by the forecast.time_forecastedidentifies the valid time of each weather and PV value.
The weather input contains:
| Field | Unit | Description |
|---|---|---|
ghi | W/m² | Global horizontal irradiance |
dni | W/m² | Direct normal irradiance |
dhi | W/m² | Diffuse horizontal irradiance |
ambient_temperature | °C | Air temperature |
wind_speed | m/s | Wind speed |
PV simulation
The forecast adapter passes the IFS weather series and project configuration to the Proximal PV performance model. See the PV model overview for the model chain and individual calculation steps.
The simulation runs one step for each weather timestamp. For the current IFS request, this is 240 hourly steps; the forecast does not add sub-hourly interpolation. Each step uses the weather values for that timestamp to calculate:
- Tracker position, using the project's true-tracking or backtracking configuration and rotation limits
- Plane-of-array and effective irradiance
- Module temperature and DC power
- Inverter and other electrical losses
- AC power at the point of interconnection
The simulation uses the project's DC capacity, module temperature coefficient, geometry, and interconnection limit. PV power is clipped at the interconnection limit before export.
p_mp is instantaneous AC power at the point of interconnection, stored in watts. It is not an energy value. To estimate energy for an hourly interval, multiply the power by one hour and convert watts to the desired energy unit.
Forecast outputs
The service stores both weather and PV results in two forms:
- Forecast history: Each run is retained with its
time_forecast_run, allowing forecasts to be compared with later runs and observations. - Latest forecast: The most recent run is retained for each
time_forecastedvalue for applications and dashboards.
PV Model Overview
Why Proximal
The Proximal PV performance model has been specifically designed with operating assets in mind. The following are a few highlights of the model that distinguish it from other PV models used in asset management.
Built on Open Source
Modern, tested, transparent, trusted by the community. By building on top of pvlib, we can ensure that the proximal energy model is understandable by all users and easily extendable.
Nodal
Expected energy can be calculated at the combiner, inverter, array, or substation level.
Sub-Hourly
Operating assets emit high frequency data which is captured by the energy model.
Geospatial
Each block of the system uses the meteorological data that is closest to it which can yield great improvements for large systems with passing clouds.
Documented
Each step of the model is documented in detail through pvlib and through this documentation set.
Efficient
Inputs to each individual model are automatically factored into unique combinations. This makes the model capable of handling large systems with high levels of detail at high frequency possible.
Model Chain
The proximal performance model at a high level is comprised of 6 major sub-models. Clicking on any of the models will take you to the actual model steps that occur in each sub-model.
flowchart TD
%% --- CLASSES ---
classDef source fill:#6B7A8F, color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef model_dashed fill:#202020, color:#CCCCCC, stroke-dasharray: 5 5
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
met_params[Meteorological Parameters]:::source
click met_params "./simulation/meteorological_parameters.html"
tracker_rotation_angles[Tracker Rotation Angles]:::source
click tracker_rotation_angles "./simulation/tracker_rotation_angles.html"
poai[Plane of Array Irradiance]:::source
click poai "./simulation/plane_of_array_irradiance.html"
epoai[
Effective
Plane of Array Irradiance
]:::source
click epoai "./simulation/effective_plane_of_array_irradiance.html"
DC[DC System Losses]:::source
click DC "./simulation/dc_system_losses.html"
AC[AC System Losses]:::source
click AC "./simulation/ac_system_losses.html"
met_params --> tracker_rotation_angles
tracker_rotation_angles --> poai
poai --> epoai
epoai --> DC
DC --> AC
Edits and Additions
If you would like to see support for another algorithm or would like to suggest edits or additions to this documentation page, please open an issue on the Proximal GitHub repository.
Simulation
General
The Proximal expected energy model converts measured weather conditions and the configured physical properties of a photovoltaic system into expected power at the point of interconnection. The model preserves the system hierarchy throughout the calculation, so results can also be reported for combiners, inverters, and transformers.
The simulation runs each model stage in order. Outputs from one stage become inputs to the next stage, while equipment assignments determine how values are mapped and combined between strings, combiners, inverters, transformers, and the project.
Acronyms
- POAI: Plane of Array Irradiance
- EPOAI: Effective Plane of Array Irradiance
- DC: Direct Current
- AC: Alternating Current
- POI: Point of Interconnection
Simulation Pipeline
The following flow diagram shows the major stages of the Proximal expected energy simulation. The flow chart is interactive. Clicking a documented model stage will take you to its detailed model chain.
Legend
flowchart LR classDef source fill:#6B7A8F, color:#CCCCCC classDef model fill:#202020, color:#CCCCCC classDef outputs fill:#B39245, color:#CCCCCC source[(Input Data)]:::source model_step[[Model Stage]]:::model model_outputs([Calculated Results]):::outputs source --> model_step --> model_outputs
Model Chain
flowchart TD
classDef source fill:#6B7A8F, color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
met_data[(
--- MEASURED DATA ---
irradiance
ambient temperature
relative humidity
wind speed
soiling
)]:::source
system_data[(
--- SYSTEM DATA ---
project location
module parameters
racking parameters
electrical hierarchy
inverter parameters
transformer parameters
)]:::source
meteorological[[Meteorological Parameters]]:::model
click meteorological "meteorological_parameters.html"
rotations[[Tracker Rotation Angles]]:::model
click rotations "tracker_rotation_angles.html"
poai[[Plane of Array Irradiance]]:::model
click poai "plane_of_array_irradiance.html"
epoai[[Effective Plane of Array Irradiance]]:::model
click epoai "effective_plane_of_array_irradiance.html"
dc[[DC System Losses]]:::model
click dc "dc_system_losses.html"
ac[[AC System Losses]]:::model
click ac "ac_system_losses.html"
poai_output([POAI by combiner]):::outputs
combiner_output([DC power by combiner]):::outputs
inverter_output([AC power by inverter]):::outputs
transformer_output([AC power by transformer]):::outputs
poi_output([Expected power at POI]):::outputs
met_data --> meteorological
system_data --> meteorological
meteorological --> rotations
system_data --> rotations
rotations --> poai
meteorological --> poai
system_data --> poai
poai --> poai_output
poai --> epoai
met_data --> epoai
system_data --> epoai
epoai --> dc
met_data --> dc
system_data --> dc
dc --> combiner_output
dc --> ac
system_data --> ac
ac --> inverter_output
ac --> transformer_output
ac --> poi_output
Simulation Outputs
The model emits intermediate results as soon as each electrical level is complete:
- Plane of array irradiance by combiner
- DC power by combiner
- AC power by inverter
- AC power by transformer
- Expected project power at the point of interconnection
Edits and Additions
If you would like to see support for another algorithm or would like to suggest edits or additions to this documentation page, please open an issue on the Proximal GitHub repository.
Meteorological Parameters
General
The first step of the Proximal expected energy simulation is to ingest data from the project meteorological stations. This data is then used to calculate the intermediate meteorological parameters that are required to calculate the Plane of Array Irradiance (POAI).
This section of the documentation shows all models in the order that they are calculated in the simulation.
Met Station Assignments
The Proximal performance model treats weather data slightly differently than other performance models users may be familiar with. Instead of using a single set of weather data for every electrical component being modeled, Proximal assigns electrical components to individual blocks and then assigns those blocks a met station to use for modeling purposes. Each block is then modeled with the data that corresponds to its assigned met station. Generally the closest met station to the block is chosen to be that blocks assigned met station.
F.A.Q.
- Why not interpolate geospatially between weather stations?
- Because passing clouds create a hard edge of irradiance, interpolating irradiance between sensors would create non-physical values in the data stream.
Acronyms:
- DHI: Diffuse Horizontal Irradiance
- DNI: Direct Normal Irradiance
- extraDNI: Extraterrestrial Direct Normal Irradiance
- PWAT: Precipitable Water
- RH: Relative Humidity
Simulation Pipeline
The following flow diagram shows how meteorological parameters is calculated in the Proximal expected energy simulation. The flow chart is meant to be interactive. Clicking on any of the modeling step nodes will take you to the documentation for that modeling step.
You may need to zoom in to be able to better see all of the details in the flow chart.
Legend
flowchart LR
%% --- CLASSES ---
classDef source fill:#6B7A8F, color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
database[(Database)]:::source
model_step[[
Modeling Step
DEFAULT MODEL CHOICE
]]:::model
model_inputs[\
Input Parameters
for Modeling Step
/]:::inputs
model_outputs([Calculated Parameters]):::outputs
database --> model_inputs
model_inputs --> model_step --> model_outputs --> model_inputs
Model Chain
flowchart TD
%% --- CLASSES ---
classDef source fill:#6B7A8F, color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef model_dashed fill:#202020, color:#CCCCCC, stroke-dasharray: 5 5
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
%% --- SOURCES ---
pv_system[(
--- PV SYSTEM ---
elevation
)]:::source
pv_system --> calc_pressure_inputs
met_station[(
--- MET STATION ---
time
ambient_temperature
global_horizontal_radiation
relative_humidity
wind_speed
*albedo
)]:::source
met_station --> TDEW_inputs
met_station --> solar_position_inputs
met_station --> extraDNI_inputs
met_station --> DHI_inputs
%% --- ATMOSPHERIC PRESSURE ---
calc_pressure_inputs[\elevation/]:::inputs
calc_pressure_inputs --> calc_pressure
calc_pressure[[
pvlib.atmosphere
.alt2pres
]]:::model
calc_pressure --> calc_pressure_outputs
click calc_pressure "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.atmosphere.alt2pres.html"
calc_pressure_outputs([
pressure
]):::outputs
calc_pressure_outputs --> DNI_inputs
%% --- SOLAR POSITION ---
solar_position_inputs[\
time
ambient_temperature
latitude
longitude
altitude
/]:::inputs
solar_position_inputs --> solar_position
solar_position[[
pvlib.solarposition
.get_solarposition
NREL_2008
]]:::model
solar_position --> solar_position_outputs
click solar_position "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.solarposition.get_solarposition.html#pvlib.solarposition.get_solarposition"
solar_position_outputs([
apparent_zenith
azimuth
]):::outputs
solar_position_outputs --> DNI_inputs
solar_position_outputs --> DHI_inputs
solar_position_outputs --> airmass_inputs
%% --- AIRMASS ---
airmass_inputs[\
apparent_zenith
/]:::inputs
airmass_inputs --> airmass
airmass[[
pvlib.atmosphere
.get_relative_airmass
KASTEN_YOUNG_1989
]]:::model
airmass --> airmass_outputs
click airmass "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.location.Location.get_airmass.html#pvlib.location.Location.get_airmass"
airmass_outputs([
airmass
]):::outputs
%% --- EXTRATERRESTRIAL DNI ---
extraDNI_inputs[\
time
solar_constant=1360.8
epoch_year=2014
/]:::inputs
extraDNI_inputs --> extraDNI
extraDNI[[
pvlib.irradiance
.get_extra_radiation
SPENCER
]]:::model
extraDNI --> extraDNI_outputs
click extraDNI "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.irradiance.get_extra_radiation.html#pvlib.irradiance.get_extra_radiation"
extraDNI_outputs([
extraterrestrial_DNI
]):::outputs
%% --- TDEW ---
TDEW_inputs[\
relative_humidity
/]:::inputs
TDEW_inputs --> TDEW
TDEW[[
pvlib.atmosphere
.tdew_from_rh
MAGNUS_TETENS
]]:::model_dashed
TDEW --> TDEW_outputs
click TDEW "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.atmosphere.tdew_from_rh.html#pvlib.atmosphere.tdew_from_rh"
TDEW_outputs([
temp_dew_point
]):::outputs
TDEW_outputs --> DNI_inputs
%% --- DNI ---
DNI_inputs[\
solar_zenith
ghi
pressure
temp_dew
use_delta_kt_prime=False,
min_cos_zenith=0.065
max_zenith=87
/]:::inputs
DNI_inputs --> DNI
DNI[[
pvlib.irradiance
.dirint
DIRINT
]]:::model
DNI --> DNI_outputs
click DNI "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.irradiance.dirint.html#pvlib.irradiance.dirint"
DNI_outputs([
DNI
]):::outputs
DNI_outputs --> DHI_inputs
%% --- DHI ---
DHI_inputs[\
GHI
DNI
solar_zenith
/]:::inputs
DHI_inputs --> DHI
DHI[[
pvlib.irradiance
.complete_irradiance
GEOMETRIC
]]:::model
DHI --> DHI_outputs
click DHI "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.irradiance.complete_irradiance.html#pvlib.irradiance.complete_irradiance"
DHI_outputs([
DHI
]):::outputs
Edits and Additions
If you would like to see support for another algorithm or would like to suggest edits or additions to this documentation page, please open an issue on the Proximal GitHub repository.
Tracker Rotation Angles
General
This section describes how tracker rotation angles are calculated in the Proximal Performance Model.
Caveats
- At the moment, only two dimensional modeling is taken into account. This means that 3D models such as terrain avoidance are not implemented (yet).
- At the moment, only solar position is taken into account. This means that tracker algorithms which take into account all-sky conditions are not implemented (yet).
- At the moment, only full cell module algorithms are taken into account. This means that tracker algorithms which take into account half-cell shading electrical effects are not implemented (yet).
Acronyms:
- Tracking
- aoi: Angle of Incidence
Legend
flowchart LR
%% --- CLASSES ---
classDef source fill:#6B7A8F, color:#CCCCCC
classDef previous fill:#4F5B6F,color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
database[(Database)]:::source
previous{{Previous Calculation}}:::previous
model_step[[
Modeling Step
DEFAULT MODEL CHOICE
]]:::model
model_inputs[\
Input Parameters
for Modeling Step
/]:::inputs
model_outputs([Calculated Parameters]):::outputs
database --> model_inputs
previous --> model_inputs
model_inputs --> model_step --> model_outputs --> model_inputs
Model Chain
flowchart TD
classDef source fill:#6B7A8F, color:#CCCCCC
classDef previous fill:#4F5B6F,color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef model_dashed fill:#202020, color:#CCCCCC, stroke-dasharray: 5 5
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
%% --- Data Sources ---
met_params{{
--- MET PARAMS ---
apparent_zenith
azimuth
}}:::previous
met_params --> tracker_rotation_angles_inputs
click met_params "meteorological_parameters.html"
pv_system[(
--- PV SYSTEM ---
tracker_tilt
tracker_azimuth
tracker_max_angle
tracking_type
gcr
)]:::source
pv_system --> tracker_rotation_angles_inputs
%% --- Tracker Rotation Angles ---
tracker_rotation_angles_inputs[\
apparent_zenith
azimuth
tracker_tilt
tracker_azimuth
tracker_max_angle
tracking_type
gcr
/]:::inputs
tracker_rotation_angles_inputs --> tracker_rotation_angles
tracker_rotation_angles[[
pvlib.tracking
.single_axis
ANDERSON_MIKOFSKI_2020
]]:::model
tracker_rotation_angles --> tracker_rotation_angles_outputs
click tracker_rotation_angles "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.tracking.singleaxis.html#pvlib.tracking.singleaxis"
tracker_rotation_angles_outputs([
tracker_rotation_angle
surface_tilt
surface_azimuth
aoi
]):::outputs
Edits and Additions
If you would like to see support for another algorithm or would like to suggest edits or additions to this documentation page, please open an issue on the Proximal GitHub repository.
Plane of Array Irradiance
General
The Plane of Array Irradiance (POAI) is the amount of irradiance that is incident upon the front face of the photovoltaic array.
This section of the documentation explains all of the different models and sub-models required to calculate POAI in the order that they are calculated in the simulation.
Switching Behavior
The Proximal Performance Model behaves different from other performance modeling software the user may be familiar with. It automatically switches between using the POA sensor as the input to the POA components model and the GHI sensor as the input to the POA components model. The model does this to account for the tendency of POA sensors to get shaded by nearby racks and become out of position due to tracking faults. When the predicted POA from the GHI sensor is greater than ten percent above the measured POA data, then the decomposed and transposed components from the GHI sensor are used for the rest of the model. This behavior is then noted in the data stream as lower quality data.
Acronyms:
- extraDNI: Extraterrestrial Direct Normal Irradiance
- DNI: Direct Normal Irradiance
- DHI: Diffuse Horizontal Irradiance
- RHI: Reflected Horizontal Irradiance
- POAI: Plane of Array Irradiance
Simulation Pipeline
The following flow diagram shows how the Plane of Array Irradiance is calculated in the Proximal expected energy simulation. The flow chart is meant to be interactive. Clicking on any of the modeling step nodes will take you to the documentation for that modeling step.
You may need to zoom in to be able to better see all of the details in the flow chart.
Legend
flowchart LR
%% --- CLASSES ---
classDef source fill:#6B7A8F, color:#CCCCCC
classDef previous fill:#4F5B6F,color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
database[(Database)]:::source
previous{{Previous Calculation}}:::previous
model_step[[
Modeling Step
DEFAULT MODEL CHOICE
]]:::model
model_inputs[\
Input Parameters
for Modeling Step
/]:::inputs
model_outputs([Calculated Parameters]):::outputs
database --> model_inputs
previous --> model_inputs
model_inputs --> model_step --> model_outputs --> model_inputs
Model Chain
flowchart TD
%% --- CLASSES ---
classDef source fill:#6B7A8F, color:#CCCCCC
classDef previous fill:#4F5B6F,color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef model_dashed fill:#202020, color:#CCCCCC, stroke-dasharray: 5 5
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
%% --- SOURCES ---
met_station[(
--- MET STATION ---
ghi
)]:::source
met_station --> ground_diffuse_inputs
tracker_params{{
--- TRACKER PARAMS ---
tracker_rotation_angle
tracker_surface_tilt
tracker_surface_azimuth
aoi
}}:::previous
click tracker_params "tracker_rotation_angles.html"
tracker_params --> sky_diffuse_inputs
tracker_params --> ground_diffuse_inputs
tracker_params --> beam_inputs
met_params{{
--- MET PARAMS ---
dhi
dni
dni_extra
apparent_zenith
azimuth
airmass_relative
}}:::previous
met_params --> sky_diffuse_inputs
met_params --> beam_inputs
click met_params "meteorological_parameters.html"
%% --- Ground Diffuse ---
ground_diffuse_inputs[\
surface_tilt
ghi
albedo
/]:::inputs
ground_diffuse_inputs --> ground_diffuse
ground_diffuse[[
pvlib.irradiance
.ground_diffuse
GEOMETRIC
]]:::model
ground_diffuse --> ground_diffuse_outputs
click ground_diffuse "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.irradiance.get_ground_diffuse.html"
ground_diffuse_outputs([
ground_diffuse
]):::outputs
ground_diffuse_outputs --> poai_inputs
%% --- Sky Diffuse ---
sky_diffuse_inputs[\
surface_tilt
surface_azimuth
dhi
dni
dni_extra
apparent_zenith
azimuth
airmass_relative
/]:::inputs
sky_diffuse_inputs --> sky_diffuse
sky_diffuse[[
pvlib.irradiance
.perez_driesse
POAI
]]:::model
sky_diffuse --> sky_diffuse_outputs
click sky_diffuse "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.irradiance.perez_driesse.html#pvlib.irradiance.perez_driesse"
sky_diffuse_outputs([
isotropic
horizon
circumsolar
]):::outputs
sky_diffuse_outputs --> poai_inputs
%% --- BEAM ---
beam_inputs[\
surface_tilt
surface_azimuth
solar_zenith
solar_azimuth
dni
/]:::inputs
beam_inputs --> beam
beam[[
pvlib.irradiance
.beam_component
GEOMETRIC
]]:::model
beam --> beam_outputs
click beam "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.irradiance.beam.html"
beam_outputs([
beam
]):::outputs
beam_outputs --> poai_inputs
%% --- POAI ---
poai_inputs[\
isotropic
circumsolar
horizon
ground_diffuse
beam
/]:::inputs
poai_inputs --> poai
poai[[
proximal.poai_components
SUM
]]:::model
poai --> poai_outputs
poai_outputs([
poai_global
]):::outputs
Edits and Additions
If you would like to see support for another algorithm or would like to suggest edits or additions to this documentation page, please open an issue on the Proximal GitHub repository.
Effective Irradiance
General
The Effective Plane of Array Irradiance (EPOAI) is the amount of irradiance that is incident upon the active cell area of the photovoltaic array. This is differentiated from the Plane of Array Irradiance (POAI) which is the amount of irradiance that is incident upon the front face of the photovoltaic array glass.
Conceptually, losses calculated while calculating the effective plane of array irradiance are generally calculated in the same order as the physical losses that occur between the sun's rays and t`he cell active material. For example, soiling loss on top of the module glass is calculated before the incidence angle effect inside of the module glass. On the other hand, some losses such as spectral correction, which are actually material science losses are calculated empirical losses in effective plane of array irradiance.
Acronyms:
- Irradiance
- POAI: Plane of Array Irradiance
- EPOAI: Effective Plane of Array Irradiance
Simulation Pipeline
The following flow diagram shows how the Effective Plane of Array Irradiance is calculated in the Proximal expected energy simulation. The flow chart is meant to be interactive. Clicking on any of the modeling step nodes will take you to the documentation for that modeling step.
You may need to zoom in to be able to better see all of the details in the flow chart.
Legend
flowchart LR
%% --- CLASSES ---
classDef source fill:#6B7A8F, color:#CCCCCC
classDef previous fill:#4F5B6F,color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
database[(Database)]:::source
previous{{Previous Calculation}}:::previous
model_step[[
Modeling Step
DEFAULT MODEL CHOICE
]]:::model
model_inputs[\
Input Parameters
for Modeling Step
/]:::inputs
model_outputs([Calculated Parameters]):::outputs
database --> model_inputs
previous --> model_inputs
model_inputs --> model_step --> model_outputs --> model_inputs
Model Chain
flowchart TD
%% --- CLASSES ---
classDef source fill:#6B7A8F, color:#CCCCCC
classDef previous fill:#4F5B6F,color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef model_dashed fill:#202020, color:#CCCCCC, stroke-dasharray: 5 5
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
%% --- SOURCES ---
met_station[(
--- MET STATION ---
soiling
)]:::source
met_station --> soiling_inputs
pv_system[(
--- PV Modules ---
n
K
L
n_ar
cell_technology
)]:::source
pv_system --> direct_iam_inputs
pv_system --> spectral_inputs
tracker_params{{
--- TRACKER PARAMS ---
rotation_angle
surface_tilt
surface_azimuth
aoi
}}:::previous
click tracker_params "tracker_rotation_angles.html"
tracker_params --> direct_shade_inputs
tracker_params --> direct_iam_inputs
met_params{{
--- MET PARAMS ---
dhi
dni
dni_extra
apparent_zenith
azimuth
airmass_relative
}}:::previous
click met_params "meteorological_parameters.html"
met_params --> direct_shade_inputs
met_params --> spectral_inputs
poai_params{{
--- POAI PARAMS ---
isotropic
horizon
ground_diffuse
circumsolar
beam
}}:::previous
click poai_params "plane_of_array_irradiance.html"
poai_params --> direct_shade_inputs
%% --- Direct Shade ---
direct_shade_inputs[\
apparent_zenith
azimuth
axis_tilt
axis_azimuth
rotation_angle
collector_width
pitch
surface_to_axis_offset
cross_axis_slope
shading_row_rotation
/]:::inputs
direct_shade_inputs --> direct_shade
direct_shade[[
pvlib.shading
.shaded_fraction_1d
]]:::model
click direct_shade "https://pvlib-python.readthedocs.io/en/latest/reference/generated/pvlib.shading.shaded_fraction1d.html"
direct_shade --> direct_shade_outputs
direct_shade_outputs([
isotropic
horizon
ground_diffuse
circumsolar - shade?
beam - shade
]):::outputs
direct_shade_outputs --> soiling_inputs
%% --- Soiling ---
soiling_inputs[\
soiling_loss
/]:::inputs
soiling_inputs --> soiling
soiling[[
proximal.soiling
RATIO
]]:::model
soiling --> soiling_outputs
soiling_outputs([
isotropic - soil
horizon - soil
ground_diffuse - soil
circumsolar - soil
beam - soil
]):::outputs
soiling_outputs --> direct_iam_inputs
%% --- Direct IAM ---
direct_iam_inputs[\
aoi
n
K
L
n_ar
/]:::inputs
direct_iam_inputs --> direct_iam
direct_iam[[
pvlib.iam.physical
PHYSICAL
]]:::model
click direct_iam "https://pvlib-python.readthedocs.io/en/latest/reference/generated/pvlib.iam.physical.html"
direct_iam --> direct_iam_outputs
direct_iam_outputs([
isotropic
horizon
ground_diffuse
circumsolar - iam?
beam - iam
]):::outputs
direct_iam_outputs --> spectral_inputs
%% --- Spectral ---
spectral_inputs[\
prcipitable_water
airmass_absolute
cdte_coefficients
min_p_wat=0.1
max_p_wat=8.0
min_airmass_abs=0.58
max_airmass_abs=10.0
/]:::inputs
spectral_inputs --> spectral
spectral[[
pvlib.spectral.spectral
SPECTRAL
]]:::model
click spectral "https://pvlib-python.readthedocs.io/en/latest/reference/generated/pvlib.spectrum.spectral_factor_firstsolar.html"
spectral --> spectral_outputs
spectral_outputs([
isotropic - spectral
horizon - spectral
ground_diffuse - spectral
circumsolar - spectral
beam - spectral
]):::outputs
spectral_outputs --> epoai_inputs
%% --- EPOIA ---
epoai_inputs[\
isotropic
horizon
ground_diffuse
circumsolar
beam
/]:::inputs
epoai_inputs --> epoai
epoai[[
proximal.epoai_components
SUM
]]:::model
epoai --> epoai_outputs
epoai_outputs([
epoai_global
]):::outputs
Edits and Additions
If you would like to see support for another algorithm or would like to suggest edits or additions to this documentation page, please open an issue on the Proximal GitHub repository.
DC System Losses
General
DC system losses include losses that occur between the photovoltaic cell and the DC wiring to the inverter. In the diagrams, steps for combining power into strings and into combiners has been left out for the sake of brevity.
Acronyms:
- DC: Direct Current
- EPOAI: Effective Plane of Array Irradiance
- i: Current
- v: Voltage
- p: Power
- mp: Maximum Power
- oc: Open Circuit
Simulation Pipeline
The following flow diagram shows how DC system losses are calculated in the Proximal expected energy simulation. The flow chart is meant to be interactive. Clicking on any of the modeling step nodes will take you to the documentation for that modeling step.
You may need to zoom in to be able to better see all of the details in the flow chart.
Legend
flowchart LR
%% --- CLASSES ---
classDef source fill:#6B7A8F, color:#CCCCCC
classDef previous fill:#4F5B6F,color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
database[(Database)]:::source
previous{{Previous Calculation}}:::previous
model_step[[
Modeling Step
DEFAULT MODEL CHOICE
]]:::model
model_inputs[\
Input Parameters
for Modeling Step
/]:::inputs
model_outputs([Calculated Parameters]):::outputs
database --> model_inputs
previous --> model_inputs
model_inputs --> model_step --> model_outputs --> model_inputs
Model Chain
flowchart TD
%% --- CLASSES ---
classDef source fill:#6B7A8F, color:#CCCCCC
classDef previous fill:#4F5B6F,color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef model_dashed fill:#202020, color:#CCCCCC, stroke-dasharray: 5 5
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
%% --- SOURCES ---
met_station[(
--- MET STATION ---
ambient temperature
wind speed
)]:::source
met_station --> cell_temperature_inputs
epoai{{
--- EPOAI ---
epoai
}}:::previous
click tracker_params "effective_plane_of_array_irradiance.html"
epoai --> cell_temperature_inputs
epoai --> single_diode_inputs
%% --- Cell Temperature ---
cell_temperature_inputs[\
epoai
ambient temperature
wind speed
/]:::inputs
cell_temperature_inputs --> cell_temperature
cell_temperature[[
pvlib.temperature
.pvsyst_cell
PVSYST_CELL
]]:::model
cell_temperature --> cell_temperature_outputs
click cell_temperature "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.temperature.pvsyst_cell.html#pvlib.temperature.pvsyst_cell"
cell_temperature_outputs([
cell_temperature
]):::outputs
cell_temperature_outputs --> single_diode_inputs
%% --- Single Diode Model ---
single_diode_inputs[\
epoai
cell temperature
module parameters
/]:::inputs
single_diode_inputs --> single_diode
single_diode[[
pvlib.pvsystem
.calcparams_desoto
DESOTO
]]:::model
click single_diode "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.calcparams_desoto.html#pvlib-pvsystem-calcparams-desoto"
single_diode --> single_diode_outputs
single_diode_outputs([
single diode parameters
]):::outputs
single_diode_outputs --> iv_inputs
%% --- IV Curve ---
iv_inputs[\
single diode parameters
/]:::inputs
iv_inputs --> iv
iv[[
pvlib.pvsystem
.singlediode
]]:::Model
click iv "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.pvsystem.singlediode.html#pvlib.pvsystem.singlediode"
iv --> iv_outputs
iv_outputs([
iv_curve
]):::outputs
iv_outputs --> degradation_inputs
%% --- Degradation ---
degradation_inputs[\
iv_curve
/]:::inputs
degradation_inputs --> degradation
degradation[[
proximal.degradation
RATIO
]]:::model
degradation --> degradation_outputs
degradation_outputs([
iv_curve
]):::outputs
degradation_outputs --> wiring_inputs
%% --- DC Wiring to Combiner ---
wiring_inputs[\
iv_curve
/]:::inputs
wiring_inputs --> wiring
wiring[[
proximal.target_stc
TARGET LOSS AT STC
]]:::model
wiring --> wiring_outputs
wiring_outputs([
iv_curve
]):::outputs
Edits and Additions
If you would like to see support for another algorithm or would like to suggest edits or additions to this documentation page, please open an issue on the Proximal GitHub repository.
PV Module Definition
Single Diode Model Parameters
The single diode model requires a set of PV module parameters. These parameters are generally calculated at a test lab and placed inside of a .PAN file. The Proximal platform can read data from a .PAN file or from the CEC database of pv modules.
Other Parameters
There are other parameters that may or may not be included in the .PAN file that Proximal needs for performance modeling purposes. These parameters may appear on a data sheet or can be found by contacting the manufacturer.
- Warranted Degradation Rate
- Warranted Degradation at Year Zero
- Length
- Width
- Frame overhang: Describes the non-active PV between the PV active cell and the edge of the module frame
- AR coating presence
Degradation
General
The Proximal platform automatically creates a model with warranted module degradation baked in. This module degradation occurs on the DC side of the plant and therefore cannot be post-processed due to the effects of clipping.
The warranted module degradation curve is module specific and usually comes in the form of an initial degradation value at year zero and a linear or piecewise linear drop from year one on-wards.
Degradation in PV modules can occur in both current and voltage. The Proximal model currently assumes a 50% degradation in current and 50% degradation in voltage for a given warranted degradation in power.
A different assumption can be used for a given PV module technology, if specified by the user.
AC System Losses
General
AC system modeling begins after DC power has been calculated at each combiner. The model applies the remaining DC wiring loss, combines child combiners at each inverter, converts DC power to AC power, applies transformer losses, and combines the result into expected power at the point of interconnection.
The electrical hierarchy stored for the project determines which combiners feed each inverter and which inverters feed each transformer.
Acronyms
- AC: Alternating Current
- DC: Direct Current
- i: Current
- v: Voltage
- p: Power
- mp: Maximum Power
- POI: Point of Interconnection
- STC: Standard Test Conditions
Simulation Pipeline
The following flow diagram shows how AC system losses are calculated in the Proximal expected energy simulation. The flow chart is interactive. Clicking a model step will take you to its external documentation when available.
You may need to zoom in to better see all of the details in the flow chart.
Legend
flowchart LR
classDef source fill:#6B7A8F, color:#CCCCCC
classDef previous fill:#4F5B6F,color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
database[(Database)]:::source
previous{{Previous Calculation}}:::previous
model_step[[
Modeling Step
DEFAULT MODEL CHOICE
]]:::model
model_inputs[\
Input Parameters
for Modeling Step
/]:::inputs
model_outputs([Calculated Parameters]):::outputs
database --> model_inputs
previous --> model_inputs
model_inputs --> model_step --> model_outputs --> model_inputs
Model Chain
flowchart TD
classDef source fill:#6B7A8F, color:#CCCCCC
classDef previous fill:#4F5B6F,color:#CCCCCC
classDef model fill:#202020, color:#CCCCCC
classDef inputs fill:#1A1A1A, color:#CCCCCC
classDef outputs fill:#B39245, color:#CCCCCC
combiner_power{{
--- COMBINER POWER ---
i_mp
v_mp
i_sc
v_oc
}}:::previous
click combiner_power "dc_system_losses.html"
system[(
--- SYSTEM ---
combiner to inverter assignments
inverter to transformer assignments
DC wiring loss at STC
POI limit
)]:::source
inverter[(
--- INVERTER ---
nominal AC power
nominal DC power and voltage
startup power
efficiency coefficients
night tare
)]:::source
transformer[(
--- TRANSFORMER ---
rating
no-load loss
load loss
)]:::source
dc_wiring_inputs[\
combiner IV values
DC wiring loss at STC
/]:::inputs
combiner_power --> dc_wiring_inputs
system --> dc_wiring_inputs
dc_wiring[[
proximal.dc_wiring_to_inverter
TARGET LOSS AT STC
]]:::model
dc_wiring_inputs --> dc_wiring --> dc_wiring_outputs
dc_wiring_outputs([
i_mp
v_mp after wiring loss
i_sc
v_oc
]):::outputs
combine_inverter_inputs[\
combiner IV values
combiner to inverter assignments
/]:::inputs
dc_wiring_outputs --> combine_inverter_inputs
system --> combine_inverter_inputs
combine_inverter[[
proximal.combine_at_inverter
ELECTRICAL AGGREGATION
]]:::model
combine_inverter_inputs --> combine_inverter --> combine_inverter_outputs
combine_inverter_outputs([
inverter DC power
inverter DC current
inverter DC voltage
]):::outputs
inverter_efficiency_inputs[\
DC power
DC voltage
inverter parameters
/]:::inputs
combine_inverter_outputs --> inverter_efficiency_inputs
inverter --> inverter_efficiency_inputs
inverter_efficiency[[
pvlib.inverter.sandia
SANDIA
]]:::model
click inverter_efficiency "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.inverter.sandia.html"
inverter_efficiency_inputs --> inverter_efficiency --> inverter_efficiency_outputs
inverter_efficiency_outputs([
AC power by inverter
]):::outputs
ac_wiring_inputs[\
inverter AC power
nominal inverter AC power
/]:::inputs
inverter_efficiency_outputs --> ac_wiring_inputs
inverter --> ac_wiring_inputs
ac_wiring[[
proximal.ac_wiring_to_transformer
LOAD-DEPENDENT LOSS
]]:::model
ac_wiring_inputs --> ac_wiring --> ac_wiring_outputs
ac_wiring_outputs([
AC power after wiring loss
]):::outputs
combine_transformer_inputs[\
inverter AC power
inverter to transformer assignments
/]:::inputs
ac_wiring_outputs --> combine_transformer_inputs
system --> combine_transformer_inputs
combine_transformer[[
proximal.combine_at_transformer
SUM
]]:::model
combine_transformer_inputs --> combine_transformer --> combine_transformer_outputs
combine_transformer_outputs([
input power by transformer
]):::outputs
transformer_efficiency_inputs[\
transformer input power
rating
no-load loss
load loss
/]:::inputs
combine_transformer_outputs --> transformer_efficiency_inputs
transformer --> transformer_efficiency_inputs
transformer_efficiency[[
pvlib.transformer.simple_efficiency
SIMPLE EFFICIENCY
]]:::model
click transformer_efficiency "https://pvlib-python.readthedocs.io/en/stable/reference/generated/pvlib.transformer.simple_efficiency.html"
transformer_efficiency_inputs --> transformer_efficiency --> transformer_efficiency_outputs
transformer_efficiency_outputs([
AC power by transformer
]):::outputs
poi_inputs[\
transformer AC power
POI limit
/]:::inputs
transformer_efficiency_outputs --> poi_inputs
system --> poi_inputs
poi[[
proximal.point_of_interconnection
SUM AND CLIP
]]:::model
poi_inputs --> poi --> poi_outputs
poi_outputs([
expected power at POI
]):::outputs
Model Behavior
- DC wiring loss from the combiner to the inverter is scaled from the configured loss at standard test conditions using the operating current.
- Combiner currents are summed at each inverter, while combiner voltages are averaged.
- The default inverter model is the Sandia inverter model. PVWatts is also supported.
- Transformer efficiency accounts for transformer rating, no-load loss, and load loss.
- Transformer power is summed at the project level and limited to the configured point of interconnection capacity. Negative power is limited to zero.
Edits and Additions
If you would like to see support for another algorithm or would like to suggest edits or additions to this documentation page, please open an issue on the Proximal GitHub repository.
Quality Control Docs
General
Even more important than the performance model (at times) are the quality control measures used to make sure that the input data to the model is correct. The following sections detail how input data is filtered in the proximal performance model.
Soiling Sensors
| Index | Physical Issue | Mitigation Strategy |
| 1 | Some soiling measurement stations only take one measurement per day. These sensors by definition cannot characterize the IAM effect of the soiling on top of the module glass. The effect of incidence angle on soiling can be up to 10% relative to the absolute soiling amount. For example, a 30% soiled module can have an IAM effect up to around 3%. | Proximal currently does not model the additional IAM effect |
| 2 | Some soiling measurement stations report erroneous values such as 100% soiled for unknown reasons. | Proximal filters out values with greater than 90% reported soiling. |
| 3 | Optical soiling sensors cannot characterize the electrical effect of non-uniform soiling | Proximal does not account for this |
| 4 | Single active component sensors cannot characterize the electrical effect of non-uniform snow soiling | Proximal does not account for this |
Measurement Uncertainty
General
All data in the Proximal platform is inherently uncertain. This is due to the fact that sensors have inherent uncertainty and models have uncertainty on top of that. The following tables are a reference for users to use in order to understand the data and models being reported by the platform.
Defaults
By default all reported values below are:
- 95% Uncertainty (Expanded) (U)
Irradiance Sensor Uncertainty
| Sensor | Measurement Uncertainty | Reference |
|---|---|---|
| Class A Pyranometer | ±2% (daily total absolute) | 1 |
| Class A Pyranometer | ±3% (hourly total absolute) | 1 |
Soiling Sensor Uncertainty
| Sensor | Measurement Uncertainty | Reference |
|---|---|---|
| Optical | ±4-7% (relative) | 2 |
| Cell-Cell | ±4-7% (relative) | 2 |
| Cell-Module (power) | ±1-2% (relative) | 2 |
| Cell-Module (current) | ±3-5% (relative) | 2 |
| Module-Module | ±4-7% (relative) | 2 |
| Cell-Cell | ±4-7% (relative) | 2 |
Notes
- Optical sensors may not capture the IAM effects of soiling
- Cell-Cell sensors will not capture the effects of non-uniform soiling
- Cell-Cell sensors may have a different glass than the install PV modules and may soil differently
Inverter
| Sensor | Measurement Uncertainty | Reference |
|---|---|---|
| Class A Current Input | ±2% (absolute) | 3 |
| Class A Voltage Input | ±2% (absolute) | 3 |
| Class A Power Input | ±3% (absolute) | 3 |
| Class A Current Output | ±2% (absolute) | 3 |
| Class A Voltage Output | ±2% (absolute) | 3 |
| Class A Power Output | ±3% (absolute) | 3 |
Meter
| Sensor | Measurement Uncertainty | Reference |
|---|---|---|
| Meter | ±0.2% (absolute) | 4 |
References
Changelog
2025-07-28
New Features
- Unveiling the new Portfolio Calendar View! Visualize your project timelines and key dates across your entire portfolio at a glance.
- Introducing dynamic Single Line Diagrams for projects, providing a clear visual representation of your electrical systems.
- Welcome the brand-new Oriden theme for a fresh, customized look and feel.
- Customize your workspace with the vibrant new Lightsource theme.
Improvements
- Enhanced performance and stability when processing large datasets, ensuring a smoother and more reliable experience.
Bug Fixes
- Resolved an edge-case issue to improve overall platform stability.
2025-07-07
Improvements
- Enhanced the KPI project comparison plot to display full legend names, making it easier to identify and compare different projects.
2025-06-30
New Features
- Added real-time data support for BESS (Battery Energy Storage Systems), enhancing visibility and operational insights.
Improvements
- Refactored PV equipment logic for improved performance and maintainability.
Bug Fixes
- Fixed an issue with the API endpoint for updating user projects in the admin module.
2025-06-23
New Features
- Custom Theming: Added extensive theming capabilities to provide a more customized user experience.
- KPI Portfolio Comparison: KPI reports can now include portfolio-level comparisons, enabling broader performance analysis across multiple projects.
Improvements
- GIS Map: The GIS map on the project Home page now features a new layer selector, making it easier to switch between different map views.
- Project Calendar: A Project calendar is now available for users to add project-related reporting deadlines, site visits and other items.
- Performance: Optimized the loading of pages that display open event counts.
- BESS Analysis: The date range selector for BESS Equipment Analysis has been updated for better usability.
Bug Fixes
- Navigation: Corrected navigation links from the Equipment Analysis page to Project Energy KPI and from Uptime metrics to Data Browsing.
- Real-Time Page: Added missing axis labels to heatmaps for improved clarity.
- Data Visualization: Resolved an issue where plots would not update correctly after changing filter selections.
- UI: Fixed a minor visual glitch in the calendar display.
2025-06-16
New Features
- Real Time Page: Added a x-axis labels to graphs on the real time page
Bug Fixes
- GIS Maps: Hovering over a met station no longer shows PCS data
2025-06-09
New Features
- Weather & Forecast: Improved display and added appropriate attribution to OpenWeatherMap.
Bug Fixes
- DC Amperage Report: Improved error handling to display feedback to user if the report fails to complete.
- CMMS Tab: Corrected error handling that would cause the page to crash.
2025-06-02
New Features
-
Inverter Availability Report: A new report page has been added to monitor inverter availability across projects. The report is downloadable as an Excel file, allowing users to modify input parameters directly within the spreadsheet to perform custom analyses or generate updated availability metrics.
-
Admin User Management: Introduced a comprehensive admin dashboard for managing users, assigning projects, and more.
-
CMMS Tab for All Projects: All projects now have access to the CMMS tab, streamlining asset ticket management.
Other Improvements
- Cleaned up UI in several report pages to improve clarity and consistency.