Station no longer scaffolds device pages

The website derives its lamp list from the comparison-data bundles,
so measuring and pushing is the whole publish flow. Dead web-repo
constant removed with it.
This commit is contained in:
2026-07-09 17:09:15 +07:00
parent 503fbaa420
commit 6140e1d4c9
2 changed files with 11 additions and 66 deletions
+5 -4
View File
@@ -106,9 +106,10 @@ from the packaging (flux, CCT, power, CRI, lifetime, equivalent W -> stored
under "rated" in metrics.json for claimed-vs-measured comparison), insert the
lamp, and the tool measures per the published procedure (230 V / 50 Hz, 60 s
settle, 5 readings averaged), writes lamps/<ID>/ into the comparison-data
checkout, commits, and pushes. If the web repo is present it also scaffolds
the device page stub with the rated specs pre-filled (review and commit that
one manually).
checkout, commits, and pushes. The website picks the lamp up automatically:
its device list is data-driven from the comparison-data bundles and the push
triggers the auto-bump deploy. An .md page in the web repo is only ever needed
for photos, where-to-buy links, or notes.
```bash
uv run lamp_station.py # scan -> measure -> commit -> push
@@ -118,7 +119,7 @@ uv run lamp_station.py --settle 0 --readings 1 # quick smoke test
```
Defaults assume `C:/dev/buildfor_life_web` with the comparison-data submodule
initialized; override with --data-repo / --web-repo.
initialized; override with --data-repo.
## Offline Parsing
+6 -62
View File
@@ -23,10 +23,10 @@ supports unbranded lamps without any barcode.
published procedure (230 V / 50 Hz, 60 s settle, 5 readings averaged)
and the bundle (spd.csv, tm30.csv, metrics.json) is written to
<data-repo>/lamps/<ID>/.
5. The bundle is committed to the comparison-data repo and pushed.
If --web-repo points at buildfor_life_web, a device page stub is
scaffolded when missing (review, fill remaining specs, commit
manually).
5. The bundle is committed to the comparison-data repo and pushed. The
website picks it up automatically (data-driven device list plus the
auto-bump deploy); an .md page in the web repo is only ever needed
for photos, where-to-buy links, or notes.
Usage:
uv run lamp_station.py # defaults below
@@ -46,7 +46,6 @@ from hpcs6500 import find_hpcs_port
from lamp_export import average_readings, readings_from_device, write_bundle
DEFAULT_DATA_REPO = Path(r"C:\dev\buildfor_life_web\apps\web\comparison-data")
DEFAULT_WEB_REPO = Path(r"C:\dev\buildfor_life_web")
CACHE_FILE = Path.home() / ".cache" / "hpcs6500" / "ean-cache.json"
LOOKUP_URL = "https://api.upcitemdb.com/prod/trial/lookup?upc={}"
ID_RE = re.compile(r"^L(\d{4,})$")
@@ -204,59 +203,6 @@ def commit_bundle(data_repo, lamp_id, label, existed, push):
print("Pushed.")
def scaffold_device_page(web_repo, lamp_id, meta):
pages = web_repo / "apps" / "web" / "src" / "content" / "comparisons" / "lamps"
if not pages.is_dir():
return
page = pages / f"{lamp_id}.md"
if page.exists():
return
weights = [int(m.group(1)) for f in pages.glob("*.md") if f.name != "index.md"
for m in [re.search(r"^weight:\s*(\d+)", f.read_text(), re.M)] if m]
title = meta["model"] or lamp_id
if meta["variant"]:
title = f"{title} ({meta['variant']})"
# Identity fields (ID, EAN, type, dimmable, variant) live in metrics.json,
# which the detail page renders directly — only human-editable extras like
# the rated values go into the page's specs front matter.
rated = meta.get("rated", {})
specs = []
if "Power_W" in rated:
power = f"{rated['Power_W']:g} W"
if "W_equiv" in rated:
power += f" ({rated['W_equiv']:g} W equivalent)"
specs.append(("Rated power", power))
if "Phi_lm" in rated:
specs.append(("Rated flux", f"{rated['Phi_lm']:g} lm"))
if "CCT_K" in rated:
specs.append(("CCT (rated)", f"{rated['CCT_K']:g} K"))
if "Ra" in rated:
specs.append(("CRI (rated)", f"{rated['Ra']:g}"))
if "lifetime_h" in rated:
specs.append(("Rated lifetime", f"{rated['lifetime_h']:,} h".replace(",", " ")))
type_word = {"led": "LED", "cfl": "CFL"}.get(meta.get("type", "led"), meta.get("type", "LED"))
lines = ["---", f'title: "{title}"']
if meta["manufacturer"]:
lines.append(f'manufacturer: "{meta["manufacturer"]}"')
lines += [
f'description: "Household {type_word} lamp, measured in our integrating sphere."',
f'csv: "/data/comparisons/lamps/{lamp_id}/spd.csv"',
# a bare "specs:" would parse as YAML null and fail the site's schema
*(["specs:"] if specs else []),
*[f' - {{ label: "{k}", value: "{v}" }}' for k, v in specs],
f"weight: {max(weights, default=0) + 1}",
"---",
"",
"Measured as purchased, no burn-in beyond the procedure's stabilization period.",
"",
]
page.write_text("\n".join(lines))
print(f"Scaffolded device page: {page}")
print(" -> review it and commit the web repo (the submodule bump lands there")
print(" automatically via comparison-data's bump-website workflow; git pull first).")
def measure_one(ean, args, data_repo):
lamps = lamp_index(data_repo)
@@ -350,16 +296,14 @@ def measure_one(ean, args, data_repo):
if not args.no_commit:
commit_bundle(data_repo, lamp_id, ", ".join(label_parts) or "unidentified",
existed=bool(previous), push=not args.no_push)
if args.web_repo:
scaffold_device_page(Path(args.web_repo), lamp_id, meta)
print(" The lamp publishes automatically (auto-bump deploy); add an .md under")
print(" src/content/comparisons/lamps/ only for photos, buy links, or notes.")
def main():
parser = argparse.ArgumentParser(description="Barcode-driven lamp measurement station")
parser.add_argument("--data-repo", default=str(DEFAULT_DATA_REPO),
help="comparison-data checkout (bundles land in lamps/<ID>/)")
parser.add_argument("--web-repo", default=str(DEFAULT_WEB_REPO),
help="buildfor_life_web checkout for device page stubs ('' to skip)")
parser.add_argument("--port", help="COM port (auto-detect if omitted)")
parser.add_argument("--readings", type=int, default=5)
parser.add_argument("--voltage", type=float, default=230.0)