Interactive loop around lamp_export.py: scan an EAN (checksum
validated, optional for barcode-less lamps), resolve it against
previous lamps / a local cache / upcitemdb.com, confirm
identification, record the packaging's advertised values, measure
per the published procedure, and commit the bundle to the
comparison-data repo with a device page stub for the web repo.
Every lamp is keyed by an internal ID (L0001, L0002, ...) so one EAN
can cover several versions (daylight/warm white variants) and
unbranded lamps work. lamp_export.py passes optional ean, variant,
and rated (advertised values) fields through into metrics.json.
lamp_export.py writes the per-lamp bundle consumed by the buildfor.life
comparison pages: spd.csv (full 380-1050 nm spectrum), tm30.csv (ANSI/IES
TM-30-18 hue-bin data for the color vector graphic), and metrics.json
(photometric, colorimetric, CRI R1-R15, TM-30 Rf/Rg, electrical, supply
settings).
- tm30.py computes TM-30-18 via colour-science from the measured spectrum,
resampled to a uniform 1 nm grid; validated against CIE FL2 (Rf 70, Rg 86)
- Optional built-in PSU control (--mode/--voltage/--frequency/--current),
switched on for the measurement and off afterwards, with --settle warm-up
and --interval between readings
- Readings use the vendor single-shot cycle verified from USB captures:
test config -> trigger (8C 0E 02) -> poll -> read -> reset per reading
- Also supports --passive and --parse <pcap> sources
Single measurements don't toggle PSU - the device handles it.
PSU auto-control now only happens with --continuous flag.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Only use take_reading() (continuous-style) when --continuous flag is set.
Default single measurement now matches vendor single-test behavior.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove send_test_config() call - vendor software doesn't send 8C 2B for
each single test, only when changing modes. Remove set_integration_time()
from spectrometer.py - vendor doesn't send 8C 01 either.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The device needs the test config commands to enter single-test mode.
Without them it behaves as continuous start+stop. Supports auto_psu flag
so the device can handle PSU on/off automatically.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Stop command triggers a one-shot reading instead of start+poll+stop.
spectrometer.py now uses take_single_reading() for this flow.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>