muse/book-reading-clip-lamp
A tscircuit package created by muse.
- Version
- 0.4.6
- License
- unset
- Stars
- 0
verify-base-catalog.py
"""Check the catalog fit study and single-potential terminal wiring independently."""
import csv,json,math
from pathlib import Path
p=Path(__file__).parent
j=json.loads((p/'mechanical/geometry-checks.json').read_text())
f=j['baseFit']
assert f['revision']=='M12-wired-stock'
assert f['baseSizeMm']==[64,92,42]
assert not j['intersections'],j['intersections']
assert not f['speakerMaxCollisions'] and not f['batteryMaxCollisions']
assert f['speakerMaximumLidGapMm']>=1.2
assert f['batteryEnvelopeToShelfGapMm']>=1.9
assert min(x['gapMm'] for x in f['connectorLidGaps'])>=.49
assert all(abs(n-120)<.01 for n in f['speakerLeadLengthsMm'])
assert all(abs(n-100)<.01 for n in f['serviceWireLengthsMm']['battery'])
assert max(f['harnessWireLengthsMm'][4:6])<417
assert max(f['serviceWireLengthsMm']['chat']+f['serviceWireLengthsMm']['power']+f['serviceWireLengthsMm']['extension'])+9.5<200
assert max(f['serviceWireLengthsMm']['ntc'])+9.5<600
assert all(x['nonManifoldEdges']==0 and x['connectedSolids']==1 for x in j['parts'] if x['printable'])
# Keep the known head-camera hold visible; never let an unrelated collision
# disappear into a blanket exemption or claim the full product passes.
holds=j['boardIntersections']
assert len(holds)==1 and holds[0]['part']=='flex-max-tolerance' and holds[0]['component']=='J2',holds
assert math.isclose(holds[0]['volumeMm3'],.022978337084999592,abs_tol=1e-8)
rows=list(csv.DictReader((p/'base-service-connectors.csv').open()))
blocks={}
for r in rows:
if r['Part'].startswith('222-'):blocks.setdefault(r['Connector'],set()).add(r['Net'])
assert len(blocks)==6 and all(len(n)==1 for n in blocks.values()),blocks
assert {next(iter(n)) for n in blocks.values()}=={'VBAT','GND','NTC','NTC_RETURN','ASK_REMOTE','PWR_REMOTE'}
assert all('SPK_' not in n for ns in blocks.values() for n in ns)
catalog=json.loads((p/'base-catalog-parts.json').read_text())
a=next(x for x in catalog['parts'] if x['ref']=='BAT1');assert a['dims']==[38.5,62,8.5] and '45' in a['note']
a=next(x for x in catalog['parts'] if x['ref']=='NTC1');assert a['part']=='103AT-11' and a['dims']==[5,15,6.2]
print('PASS: catalog max battery/speaker envelopes; closed printed meshes; no base collisions; factory lead lengths; 425 mm speaker harness; one net per WAGO; unchanged camera hold explicitly retained.')
print('Not physical qualification: battery hot cutoff, camera mating, moving spring/jaw, neck loads, real wire bends/OD and retention remain open.')
parts={e['id']:e for e in json.loads((p/'mechanical/parts.json').read_text())}
assert 'speaker-pigtail' not in parts, 'Factory cable/plug must move with speaker body'
assert parts['base-speaker']['explode']==[0,-15,10]
c=json.loads((p/'mechanical/cable-inventory.json').read_text())
assert len(c['cables'])==6
assert next(x for x in c['cables'] if x['ref']=='BAT1')['includesFactoryConnector']
assert 'NO custom solder joints' in next(x for x in c['cables'] if x['ref']=='NTC1')['preparation']
print('PASS: supplier cable ownership, factory connector grouping and usable stock lead lengths including clamp stripping.')