Documentation

What each PV Ivy tool does, what it expects as input, and how to read its output. Live tools first; five in-preview tools and the public API reference are covered further down.

IV Curve Explorer /charts/

Pick a Manufacturer and Model from the ~14k-module CEC database and PV Ivy plots the IV and PV curves using pvlib's calcparams_cec + singlediode(method='lambertw') single-diode model — the same six-parameter (De Soto) coefficients used throughout the site.

  • Operating conditions — irradiance (W/m²), cell temperature (°C), and modules per string; the curve re-renders on every change. "Reset to STC" restores 1000 W/m², 25 °C, 1 module.
  • Add measured data — paste V/I pairs (tab- or space-separated, up to 5000 rows) to overlay your own field or flash-test data on the modeled curve; the Selected Module table gains a Measured column (Voc/Isc/Vmp/Imp/Power) for a quick side-by-side.
  • Degradation settings — first-year drop % + annual %/yr, auto-filled from the manufacturer's published warranty when PV Ivy has one on file (data/degradation_rates.csv), editable otherwise. Set a start/end date and the curve scales by the retention factor at that many years: 100% − first-year − annual×(years−1).
  • Anomaly detection (beta) — runs a random-forest classifier over shape features of your measured vs. modeled curve and flags a likely anomaly category. Treat it as a first pass, not a diagnosis — for a full root-cause writeup use the IV Data Analyzer (preview) below.
  • Selected module card — nameplate Voc/Isc/Vmp/Imp/Power, Fill Factor (computed live from current conditions), Length/Width, and — when PV Ivy has verified one — a link to the manufacturer's official datasheet.
  • Exports — PNG snapshot, copy-to-clipboard, a CSV of every plotted point (modeled + any measured overlay), and a CSV of the Selected Module table itself (nameplate + coefficients).
  • Shareable permalink — "Copy link" writes the module selection and operating conditions (irradiance, temperature, modules per string) into the URL query string, so a link reproduces the same curve for whoever opens it; opening a link with those params pre-fills the page automatically.
  • Save configuration — signed-in users can save the module, conditions, degradation inputs and measured overlay, then reload it later or from the profile page (see "Saving to your profile" below).

Module Lookup /module-lookup/

Reverse search: you know a module's characteristics (from a nameplate, a datasheet, or a field measurement) but not its exact CEC database entry. Enter any combination of STC power, Voc, Isc, Vmp, Imp, Fill Factor, Length, Width and PV Ivy returns the best-fitting Manufacturer/Model rows.

  • A module matches when every field you filled in is within the tolerance (percent, default 5%, adjustable) of the target value — fields left blank are ignored rather than treated as zero.
  • Optional Manufacturer / Technology substring filters narrow the search further.
  • Fill Factor, if not entered directly, is computed as (Vmp·Imp)/(Voc·Isc) from whichever of those four you supplied.
  • Results are ranked by mean relative deviation across the fields you supplied — the closest overall match first — capped at a result limit (default 50).
  • The results table has a CSV export button for the matches shown.

Module Database /modules/

A browsable, SEO-indexed catalog of the full CEC module set: a manufacturer index, a per-manufacturer model list (sortable by STC power, with a CSV export), and a per-module detail page with nameplate keypoints, efficiency, geometry, the CEC single-diode coefficients (alpha_sc, beta_oc, gamma_r, a_ref, I_L_ref, I_o_ref, R_s, R_sh_ref, Adjust), degradation warranty (when on file), datasheet link (when verified), and a precomputed IV chart.

This is the same underlying dataset (module_db.csv) that powers the Explorer, Module Lookup, and PAN Builder — the detail page is a good way to sanity-check exactly which coefficients PV Ivy is using for a given module.

  • Source line, not a "CEC" heading. The parameters table is headed "Single-Diode Model Parameters" with a citation line underneath (California Energy Commission module list, linked) — PV Ivy treats CEC as one source among several rather than a brand on the page.
  • Additional Model Sources — when a module also has an independently fitted PVsyst-model parameter set on file (Sandia's translation), a second table lists it alongside its fit-quality metric (NMBE on Pmp) and citation, so you can see at a glance that two different single-diode fits exist for the same physical module.
  • Measured data card — published field/lab measurements for the module (currently keypoints from the Sandia 2019 performance-matrix workbook, plus any approved user contributions), grouped by source with a record count, irradiance/temperature range, condition tags, and a citation per source. Empty until a module has measured data on file.

PAN File Builder /PAN-builder/

Translates a module's CEC single-diode coefficients into a PVsyst-importable .PAN file. Pick a Manufacturer/Model and PV Ivy shows the full parameter mapping before you download anything:

  • Datasheet comparison — nameplate Voc/Isc/Vmp/Imp/Pmp vs. the same keypoints recomputed from the exact values written into the file (a self-consistency check on the .PAN itself, not just the source coefficients).
  • Parameter table — every translated field tagged direct (copied straight across, e.g. RSerie = R_s), derived (computed from CEC, e.g. Gamma = a_ref/(Ns·k·Tref/q)), or assumption (a PVsyst default with no CEC equivalent, e.g. NDiode = 3) — click a row for the derivation.
  • Sandia PVsyst fit override — when Sandia's independent PVsyst-model fit is available for that module, its Rp_0 and muGamma are used directly instead of the generic defaults, and the corresponding rows flip from "assumption" to "direct".
  • Warnings — geometry estimated from module area (when Length/Width aren't in the CEC row), and a heads-up that PVsyst re-fits Gamma/I₀ from the written keypoints and Rs/Rsh rather than taking them verbatim (occasionally producing a negative maximum series resistance for thin-film modules, which PVsyst will prompt you to adjust).

Import via PVsyst's Databases → PV modules → Import.

Saving to your profile

Signed-in users can save named snapshots of the IV Curve Explorer, the IV Data Analyzer, and the Solmetric Project Builder. Each page has Save / Load controls (disabled with a sign-in prompt for anonymous visitors); your profile page lists everything you've saved across all three tools, with Open, rename, and delete. "Open" is a direct link back into the tool (e.g. /charts/?saved=<id>) that restores the saved state automatically.

Saved analyzer runs store the input settings plus a summary of the last run's results (status, keypoints, diagnosis) — not the raw uploaded Solmetric files, so re-run Analyze after loading if you want fresh numbers from the same files.

Compare /compare/

In preview — not yet linked in navigation

Side-by-side comparison of two modules: pick Module A and Module B (each links back to its own Explorer page) and PV Ivy overlays their IV and PV curves at shared operating conditions (irradiance, cell temperature), plus a full spec-diff table of nameplate and single-diode coefficients.

  • Spec-diff table — every nameplate/coefficient field for both modules side by side, with a CSV export button.
  • String quick-calcs — enter modules-per-string and a cold/hot cell temperature pair, optionally pick a CEC/SAM inverter (or enter Vac/MPPT window by hand), and PV Ivy computes each module's cold Voc, hot Vmp, and whether the string stays inside the inverter's MPPT and max-DC-voltage window.
  • Shareable link — "Copy link" encodes both modules, conditions, string size and inverter selection into the URL.

IV Data Analyzer /analyzer/

In preview — not yet linked in navigation

Upload one or many Solmetric PVA IV-curve exports (or paste a single V/I curve), and the Analyzer validates the data, translates it to Standard Test Conditions, compares it to the modeled module curve, and suggests a root cause — the goal is to take the spreadsheet crunching out of reviewing field IV curves.

Data validation

Informed by IEC 60904-1 / IEC 61829. Each measurement gets a list of flags:

  • POA_INVALID (error) — irradiance outside 0–1200 W/m².
  • POA_VARIABLE (warning) — >30% irradiance swing between measurements within 15 minutes of each other.
  • POA_RANGE (warning) — irradiance outside the IEC 61829-recommended 700–1200 W/m² window.
  • TEMP_INVALID (error) — back-of-module temperature outside −25…75 °C.
  • TEMP_SENSOR_MOUNTING (warning) — a thermocouple reading exactly 0 °C, or the two thermocouples disagreeing by >5 °C.
  • CURVE_TRUNCATED (warning), plus error-level curve sanity checks — fewer than 20 points, non-monotonic voltage, or negative Isc/Voc.

Errors mark the measurement Retest (excluded from diagnosis, still shown); warnings are reported and reduce confidence but don't block results.

STC translation — IEC 60891 Procedure 1

Point-wise translation of the measured curve to 1000 W/m² / 25 °C using the module's CEC temperature coefficients:

I₂ = I₁ + Isc·(G₂/G₁ − 1) + α·(T₂ − T₁)
V₂ = V₁ − Rs·(I₂ − I₁) − κ·I₂·(T₂ − T₁) + β·(T₂ − T₁)

Keypoints (Isc, Voc, Pmp, Vmp, Imp, FF) are then extracted from both the raw and translated curves — Pmp via a local quadratic fit around the maximum, Isc/Voc by linear extrapolation to the axes.

Root-cause diagnosis

A rule-based engine compares shape features of the translated curve against the modeled (and degraded-modeled) curve — keypoint ratios, slope near Isc (shunt indicator) and near Voc (series-resistance indicator), and step/kink detection (mismatch or a shorted bypass diode) — and proposes causes such as series-resistance increase, shunt/PID, soiling or low-light bias, partial shading, or uniform (warranty-matching) degradation, each with a confidence, supporting evidence, and a suggested action.

It never forces an answer: if no rule reaches ≥50% confidence, the top two candidates conflict, or data-quality warnings dominate, the result is "Indeterminate — retest under stable irradiance ≥700 W/m²" with the observations listed rather than a guess.

Status per measurement

  • Pass — STC power meets the degraded-model threshold and no high-confidence defect was found.
  • Retest — validation errors present, or the diagnosis was indeterminate at low confidence.
  • Otherwise, the suggested action itself is shown as the status (e.g. "Inspect for PID / shunt paths").

MPPT-limiting check

Compares the measured (and hot-day/degraded, worst-case) string Vmp against the inverter's minimum MPPT voltage, V_mppt,min = max(Mppt_low, Vac·√2) — the inverter can't track the MPP below the DC-link voltage it needs to synthesize the AC waveform. A shortfall is flagged with the projected power impact.

Reports: a full-detail Excel workbook and a branded PDF, both downloadable per analysis.

Solmetric Project Builder /solmetric-project-builder/

In preview — not yet linked in navigation

Generates a Solmetric PV Analyzer project file (.pvapx) with Site Info and the full Array Navigator tree pre-populated — inverters, combiners, an optional harness level, and strings — instead of tapping through the hierarchy by hand on the instrument.

  • Naming patterns with live preview: tokens like {n:02} (zero-padded index) and {i} (parent index), e.g. INV-{n:02} or CB-{i}.{n}. Changing a pattern renames the whole affected level at once; individual nodes can also be renamed inline in the tree preview.
  • Downloads — the .pvapx project file, plus a flat CSV manifest of every string (a fallback you can use regardless of whether the project file imports cleanly).

Format status. The .pvapx writer is built against a real project file saved by Solmetric PV Analyzer PC software (a genuine .pvapx, recovered and diffed field-by-field) — a ZIP archive containing a setting9.xml project document plus an empty data/ directory — so the tree structure, node numbering (measureId/LastNodeId), and custom-naming fields are verified against that reference rather than guessed. One field is deliberately omitted: the reference file's optional ModuleDefinition is a base64-encoded .NET BinaryFormatter blob of Solmetric's internal module record, which is impractical to fabricate safely — PVA still opens the project fine without it, but you'll need to re-confirm the module from PVA's own equipment database on first open (the plain parametric data PV Ivy does write, from the CEC database, still populates the module's electrical characteristics). The CSV manifest always works and needs no such caveat.

Contribute /contribute/

In preview — sign-in required, not yet linked in navigation

Submit a measured IV curve for an existing module in the registry — you can never create a new module identity from this page, only add evidence for one that's already here. Pick a Manufacturer/Model, then either paste V/I pairs (one voltage current pair per line) or upload a Solmetric PVA CSV, which also auto-fills irradiance/temperature/string configuration from the file.

  • Required: irradiance (W/m²), a module- or cell-temperature reading, and an attestation that you own or have rights to share the measurement (with a choice to be credited by name or anonymously). Optional: site name, coordinates, measurement date, condition tags (soiled, cleaned, hot spot, PID-suspected, cracked cell, …), and notes.
  • Keypoints are always re-derived server-side from the trace you supply — submitted keypoints are never trusted directly — and shown to you as a preview before you submit.
  • Physics sanity check — your derived Isc/Voc/Pmp are compared against the module's reference parameter set; anything far outside a plausible band (a unit error, wrong string configuration) is flagged for the moderator, not silently accepted.
  • Moderation — every submission lands as pending and is invisible to everyone but you until a moderator approves it in the admin queue. Track your own submissions and their status on your profile page under "My Contributions."
  • Duplicate traces (by module + rounded curve) are rejected, and each account is capped at 10 pending submissions at a time.

Case Studies /case-studies/

In preview — not yet linked in navigation

A small set of written articles that run real or realistic IV-curve data through the PV Ivy analysis tools and show the working — content, not a CMS: each article is a Markdown file with YAML front matter (title, summary, date, tags, a headline stat for the list card) under content/case_studies/, parsed at request time with no database involved.

  • Every article ends with a Method footer stating exactly what data was used and linking the PV Ivy tool(s) that produced the figures — the point is that a reader can reproduce it, not just take the headline number on faith.
  • A draft: true front-matter flag hides an article (and its list entry) unless the page is loaded with ?drafts=1 — used for in-progress articles awaiting a data-owner's approval before publishing.

API Reference

Read-only public endpoints. No auth, no API keys.

These are the read-only JSON endpoints behind PV Ivy's own pages — every one of them is what the Explorer, Module Lookup, Module Database, and Analyzer already call, so nothing here is provisional. There is also an auto-generated OpenAPI schema at /api/docs/ (drf-spectacular); it only reflects the one DRF viewset in the app (/api/product/), since everything below is a plain Django view — this page is the source of truth for those.

Fair use. There is no API key and no rate limiting today — please keep request rates reasonable (cache manufacturer/model lists client-side; don't poll). Keys and limits are on the roadmap once there's a paid tier to attach them to (see docs/MONETIZATION.md) — this section will be updated when that lands. Endpoints and response shapes may still change; nothing here is versioned yet.

GET/api/manufacturers/

Every distinct manufacturer name in module_db.csv, alphabetically sorted (case-insensitive).

Params: none.

Response: {"manufacturers": ["Ablytek", "Advance Power", …]}

curl https://www.pvivy.com/api/manufacturers/

GET/api/models/

Models for one manufacturer.

Params: manufacturer (required — exact string as returned by /api/manufacturers/; blank or unmatched returns an empty list, not an error).

Response: {"models": ["MSE260SO5T", "MSE265SO5T", …]}

curl "https://www.pvivy.com/api/models/?manufacturer=Mission%20Solar%20Energy%20LLC"

GET/api/module-details/

The full module_db.csv row for one module, as JSON — every column PV Ivy has for it: nameplate keypoints, the CEC single-diode coefficients, geometry, degradation (deg_*), datasheet URL, and the pvsyst_* columns when Sandia's PVsyst fit exists for that module.

Params: manufacturer, model (both required — exact strings).

Response: a flat object keyed by the CSV's own column names (not renamed/namespaced) — 400 if either param is missing, 404 (empty body) if no row matches. NaN/blank cells come back as JSON null.

Verified quirk: some CSV cells (including some Model values) carry a leading space from the source data — compare with .strip(), don't assume the string is already trimmed.

curl "https://www.pvivy.com/api/module-details/?manufacturer=Mission%20Solar%20Energy%20LLC&model=MSE300SQ8K"

GET/POST/api/module-lookup/

Reverse search by characteristics — see the Module Lookup section above for the matching rule.

Params (query string on GET, JSON body on POST): stc, v_oc_ref, i_sc_ref, v_mp_ref, i_mp_ref, fill_factor, length, width (numeric, all optional — zero/blank are ignored), manufacturer / technology (substring, case-insensitive), tolerance (percent, default 5), limit (default 50, capped at 500). At least one of the numeric fields, manufacturer, or technology is required — otherwise 400.

Response: {count, total_matches, tolerance_pct, criteria, results: [{Manufacturer, Model, Technology, STC, V_oc_ref, I_sc_ref, V_mp_ref, I_mp_ref, fill_factor, Length, Width, match_pct}, …]}, sorted by match_pct ascending (best match first).

curl "https://www.pvivy.com/api/module-lookup/?stc=300&tolerance=3&limit=5"

GET/POST/api/iv-curve/

A 100-point IV/PV curve computed with pvlib calcparams_cec + singlediode(method='lambertw') — the same call the Explorer makes.

Params: manufacturer, model (required); irradiance/poa (W/m², default 1000); temperature/cell_temperature (°C, default 25); modules (modules per string, default 1 — scales the returned voltage/power, not the current).

Response: {"voltage": [...100 floats], "current": [...], "power": [...]}. 404 with closest_matches (up to 5 manufacturer/model guesses) when the exact pair isn't found; 500 if pvlib can't solve the curve for that module's coefficients.

curl -X POST https://www.pvivy.com/api/iv-curve/ \
  -H "Content-Type: application/json" \
  -d '{"manufacturer":"Mission Solar Energy LLC","model":"MSE300SQ8K","irradiance":800,"temperature":45}'

GET/api/inverters/manufacturers/, /api/inverters/models/, /api/inverters/details/

The CEC/SAM inverter library (3,264 inverters, data/cec_inverters.csv) that backs the Analyzer's and Compare's MPPT check — mirrors the manufacturer/model/details shape above.

manufacturers: no params → {"manufacturers": [...]}.

models: manufacturer (required) → {"models": [...]}.

details: manufacturer, model (both required, else 400; 404 if not found) → {manufacturer, model, vac, paco, vdcmax, idcmax, mppt_low, mppt_high, pnt, cec_date, v_mppt_min}, where v_mppt_min = max(mppt_low, vac·√2) is the derived MPPT-floor value the Analyzer/Compare use.

Verified quirk: cec_date comes back as the literal string "nan" (not JSON null) for inverters with no CEC certification date on file — check for that string, not just falsiness.

curl "https://www.pvivy.com/api/inverters/details/?manufacturer=ABB&model=MICRO-0.25-I-OUTD-US-208"

GET/api/module-sources/

The multi-source registry view of a module — every published parameter set (CEC, and PVsyst when Sandia's fit exists) plus a summary of every published measured-data record, keyed by the module identity rather than the flat CSV row.

Params: manufacturer, model (required, exact).

Response: {module: {...identity}, parameter_sets: [{model_type, model_type_label, source_name, source_type, citation, license, is_default, fit_quality, params}, …], measured_records: [{id, kind, source_name, citation, conditions, keypoints, condition_tags, has_trace, …} (no trace points — fetch those per-record)]}.

Errors: 400 if either param is missing; 404 "Module not in registry" if the module hasn't been synced into apps.moduledata yet (run sync_module_registry — this is a separate table from module_db.csv, see CLAUDE.md).

curl "https://www.pvivy.com/api/module-sources/?manufacturer=Mission%20Solar%20Energy%20LLC&model=MSE300SQ8K"

GET/api/measured-record/<id>/

One published measured record in full, including trace points when kind == "trace".

Params: none (id is in the path).

Response: everything /api/module-sources/ summarizes for this record, plus module (identity), modules_in_string, strings_in_parallel, latitude/longitude, notes, external_id, and the raw v_points/i_points arrays (null for keypoints-only records). 404 for a missing or unpublished (pending/rejected) id — pending contributions are never visible through this endpoint.

curl https://www.pvivy.com/api/measured-record/361/

GET/api/secondary-measurements/

The older, flat read-out of data/secondary_measurements.csv (Sandia's 2019 performance-matrix + temperature-coefficient workbook, 9 modules / 360 points) — kept alongside /api/module-sources/ for existing integrations; the two overlap for the modules Sandia measured.

Params: manufacturer, model (both optional, case-insensitive substring — omitting both returns every row in the file).

Response: {"rows": [{manufacturer, model, source, test, module_id, temperature_c, irradiance_wm2, isc_a, voc_v, imp_a, vmp_v, pmp_w}, …]}. Note: fill factor is not included in this row shape (unlike /api/module-lookup/) — derive it from (imp_a·vmp_v)/(isc_a·voc_v) if you need it.

curl "https://www.pvivy.com/api/secondary-measurements/?manufacturer=Hanwha"

© 2026 PV Ivy. All Rights Reserved.