Performance data & photometrics
Audience: developers & AI agents · Scope: the photometric data behind the configurator and the spec sheets · Last reviewed: 2026-07-20
TL;DR — Lumens, watts and lumens-per-watt are imported from two Google Sheets and matched to a configuration by its code segments. Everything else that looks photometric — "sections", "TM-30", "candela curves", "polar plots" — is hand-entered per product, and one of them ("polar plots") is not photometric at all. The import is a full replace, and it has a side effect that surprises people.
The vocabulary
The names in this area do not all mean what they sound like. Read this table before the rest.
| Term | What it actually is |
|---|---|
| Performance data (base) | imported rows of lumens_direct, lumens_indirect, watts, lumens_per_watt, keyed by a set of code segments |
| Multipliers | imported rows that scale the lumen figures for a matching set of code segments |
| Sections | a hand-entered 3-column table per product (default headings Lumen/Ft, Watt/Ft, LPW) with a heading, sub-heading and a decorative image. Not imported, not matched to a configuration. |
| Decorative PDs | the same idea for decorative fixtures, with one or two code groups |
| TM-30 | IES TM-30 colour-rendition blocks: a heading, the TM-30 graphic, and two value columns — hand-entered per product |
| Candela curves | per-answer photometric curve images, shown on the configurator and compiled into the PDF that the downloads page labels IES/LDT |
| Polar plots | not photometric data. They are icon images shown in the configurator/spec-sheet icon strip, alongside mounting and industry icons |
| LOF | Length Of Fixture — a custom question type capturing feet/inches/eighths (or mm) that contributes a padded code segment. Nothing to do with photometrics. |
The import
Two importers, both full replace inside a transaction, both reading a Google Sheet:
| Import | Sheet columns | Replaces |
|---|---|---|
| Base performance data | A:F — product id, code string, lumens direct, lumens indirect, watts, LPW | the whole base table |
| Multipliers | A:C | the whole multiplier table |
The code string is stripped of spaces and split on - into a JSON array of segments. An unknown product
id aborts the import and names the offending sheet row.
Progress is published through APCu and polled by the admin screen; the overall state lives in a system
variable (working / finished / failed).
⚠️ The import silently switches a feature off. After loading, it sets
enable_performance_data_display = '0'for every product not present in the sheet. A row accidentally deleted from the Google Sheet therefore turns off performance-data display for that product on the next import, with no warning.
⚠️ The transaction does not protect you. The admin screen opens a transaction and then each importer opens and commits its own. MySQL has no nested transactions, so the inner commit ends the outer one and the outer rollback can no longer undo the delete-and-reload. The failure message claiming existing data remains untouched is not accurate.
The lookup
Given a product and the configuration's code segments:
- Load all performance-data rows for that product.
- Uppercase and de-space the incoming segments.
- Return the first row whose stored segments are all present in the configuration — a subset match, not equality. First match wins, and the ordering is whatever the database returns.
- Look for a multiplier the same way. If one matches, both lumen figures are scaled and
lumens_per_wattis recomputed as(direct + indirect) / watts. - Pick the disclaimer: the secondary one when a multiplier applied, the primary one otherwise.
Consumers: the live figures under the configurator, and the cover of a configured spec sheet.
Two sharp edges: the subset match means a more specific row can lose to a less specific one that happens to come back first, and the recomputation divides by
wattswith no zero check.
Data model
| Table | Holds |
|---|---|
#__configbox_external_performance_data | the imported base rows |
#__configbox_external_performance_data_multipliers | the imported multipliers |
#__configbox_external_performance_data_disclaimers | disclaimer texts |
#__configbox_external_performance_data_sections | the hand-entered per-product sections |
#__configbox_external_decorative_pds | decorative-product sections |
#__configbox_external_tm30_records | TM-30 blocks |
#__configbox_external_candela_curves | per-answer curve images |
#__configbox_external_polar_plots | the icon images |
Per-product flags live on #__configbox_external_product_appends.
#__configbox_external_tm30sand its model are dead — the TM-30 admin view is backed by the records model instead, and the older class has no references outside its own file. Don't extend it.
Admin settings
Custom Settings → Performance Data (the only global settings in this area):
| Setting | Label |
|---|---|
performance_data_import_sheet | Performance Data Import Sheet (required) |
performance_data_multiplier_import_sheet | Performance Data Multiplier Import Sheet (required) |
Both are sheet picker values — see Google Sheets → settings.
Per product (product form):
| Group | Settings |
|---|---|
| Performance Data Display | Enable Performance Data Display (off by default — the tooltip says to enable it only once engineering confirms the data is complete), plus a primary and secondary disclaimer |
| Performance Data / Decorative PD / TM-30 / Candela Curves | the hand-entered blocks described above |
Admin screens
| Screen | Where |
|---|---|
| Performance Data Import | left menu — runs both imports and shows progress |
| Performance Data Disclaimers | left menu |
| Imported base data & multipliers (read-only) | embedded in the import page |
| Sections, Decorative PDs, TM-30, Candela Curves | groups on the product form |
The operator how-to is admin-guide/products-configurator/import-performance-data.md.
Deployment runbook (manual steps)
- Share both Google Sheets with the site's service account — see Google Sheets.
- Custom Settings → Performance Data → select both sheets.
- Run the import from the Performance Data Import screen.
- For each product with complete data, switch Enable Performance Data Display on and pick the disclaimers.
- Smoke test: configure a product and confirm the lumen/watt figures appear under the configurator and on a configured spec sheet, with the right disclaimer.
Turning it off: clear Enable Performance Data Display on the product. Note the import does this for you to any product missing from the sheet.
Monitoring
Log type custom_pd_imports. The import has no CloudWatch metrics of its own; the spec-sheet cache refresh
that consumes the data does — see monitoring.md.
Gotchas & caveats
- Re-running the import is destructive by design — it replaces both tables wholesale. The safety net you'd expect from the surrounding transaction isn't there (see above).
- "Polar plots" will mislead you — they are icons, not plots of anything.
- Sections are not matched to a configuration. They are static per-product tables; only the base data and multipliers respond to what the visitor configured.
- A product with performance data disabled still imports fine — the flag only controls display.
Related docs
- Overview · downloads.md
- Google Sheets — the import layer