Add lamp_station.py: barcode-driven measurement workflow

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.
This commit is contained in:
2026-07-09 12:13:03 +07:00
parent 488c9a399c
commit 817822594c
3 changed files with 415 additions and 3 deletions
+13 -3
View File
@@ -172,9 +172,19 @@ def write_bundle(reading, out_dir, meta, n_readings, supply=None):
for b in tm30["bins"]:
w.writerow({k: (f"{v:.6g}" if isinstance(v, float) else v) for k, v in b.items()})
# metrics.json — grouped scalars plus identification.
metrics = {
"name": meta["name"],
# metrics.json — grouped scalars plus identification. ean/variant are set
# by lamp_station.py when one barcode covers several versions of a lamp
# (e.g. daylight and warm white sharing box art and EAN).
metrics = {"name": meta["name"]}
if meta.get("ean"):
metrics["ean"] = meta["ean"]
if meta.get("variant"):
metrics["variant"] = meta["variant"]
if meta.get("rated"):
# Advertised values from the packaging, keyed like their measured
# counterparts so consumers can pair them (truth-in-advertising rows).
metrics["rated"] = meta["rated"]
metrics |= {
"manufacturer": meta["manufacturer"],
"model": meta["model"],
"notes": meta["notes"],