abse/smartwatch-flex-top-only

Three-panel flex smartwatch with two parallel R3.9 bends, all components flat-top, low-profile JST connector harnesses, split heartbeat optical windows and screw-retained PCB mounting. Modeled 39 × 50.5 × 14.5mm prototype; 100% routing, zero native DRC and shorts. Hardware qualification pending.

Version
0.2.20
License
unset
Stars
0

scripts/collect-cabled-validation.py

from pathlib import Path
from datetime import datetime,timezone
import json,hashlib
root=Path(__file__).resolve().parent.parent
read=lambda p:json.loads((root/p).read_text())
sha=lambda p:hashlib.sha256((root/p).read_bytes()).hexdigest()
delta=read('reports/electrical-fixes/approved-design-delta.json')
copper=read('reports/copper-audit.json')
assert not any(copper[k] for k in ['connectivityFailures','orphanTraceIds','floatingGroundPourIds','drillFailures','viaPadFailures','viaSizeFailures'])
assert len(copper['netResults'])==94 and sum(e['requiredPadCount'] for e in copper['netResults'])==500
assert all(e['connectedPadGroups']==1 for e in copper['netResults'])
for p,key in [('clearance-audit','failures'),('board-edge-audit','failures'),('native-drill-audit','failures'),('flex-geometry','failures'),('printed-coil-audit','failures'),('pour-board-edge-audit','failures')]:assert not read(f'reports/{p}.json')[key],p
checks=read('reports/final-checks.json');assert len(checks)==5 and all(e['exitCode']==0 for e in checks)
for e in checks:
 assert sha(e['log'])==e['logSha256']
 if e['name'] in ['source','netlist','pins']:assert e['errors']==0
shorts=read('reports/shorts/manifest.json')['runs'];assert len(shorts)==16
for e in shorts:
 assert e['exitCode']==0 and e['reportedShorts']==0
 assert sha(e['sourceFile'])==e['sourceSha256'] and sha(e['log'])==e['logSha256']
entries=[]
for name in ['index','flat','enclosure-fit','assembly','watch','pcb']:
 c=read(f'dist/{name}/circuit.json');errors=[e for e in c if 'error' in e['type']];assert not errors,name
 pcb=[e for e in c if e['type']=='pcb_component']
 assert len(pcb)==162 and all(e['layer']=='top' for e in pcb)
 entries.append({'entry':name,'nativeDrcErrors':len(errors),'pcbComponents':len(pcb),'circuitJsonSha256':sha(f'dist/{name}/circuit.json')})
native_builds=read('reports/native-entry-builds.json')
assert len(native_builds)==6 and all(e['exitCode']==0 for e in native_builds)
for e in native_builds:
 assert (root/e['log']).is_file()
 if 'logSha256' in e:assert sha(e['log'])==e['logSha256']
 if 'nativeCircuitSha256' in e:assert sha('dist/index/circuit.json')==e['nativeCircuitSha256']
style_release=read('reports/electrical-fixes/pcb-style.json')
assert style_release['routeCacheSha256']==sha('routing/final/cache.json')
assert style_release['nativeCircuitSha256']==sha('dist/index/circuit.json')
thermal=read('reports/electrical-fixes/thermal-vias.json');assert thermal['status']=='PASS' and not thermal['failures'] and thermal['nativeThermalVias']==9
assert thermal['cacheSha256']==sha('routing/final/cache.json') and thermal['sourceSha256']==sha('dist/index/circuit.json')
mechanical={}
for key,file in [('emittedPreview','emitted-preview'),('pcbInsertion','pcb-insertion'),('pcbMountClearance','pcb-mount-clearance'),('pcbMountPrintFiles','pcb-mount-print-files'),('mountFitSample','mount-fit-sample'),('assemblyClearance','cabled-assembly'),('harnessClearance','harness-clearance'),('wirePairs','harness-wire-pairs'),('opticalPaths','optical-paths'),('opticalTunnel','optical-tunnel'),('buttonActuator','button-actuator'),('renderedBends','rendered-bends'),('foldedPanelClearance','folded-panel-clearance'),('sourceIntegrity','source-integrity'),('displayBody','display-body'),('pcbComponentMeshes','pcb-component-meshes')]:
 r=read(f'reports/{file}.json');assert r['status']=='PASS',file;mechanical[key]=r
mechanical['pcbMountInstallation']=read('reports/mount-installation.json');assert mechanical['pcbMountInstallation']['status']=='PASS'
assert mechanical['assemblyClearance']['modeledOutsideDimensionsMM'][2]<=14.50001
out={'status':'PASS','version':read('package.json')['version'],'checkedAt':datetime.now(timezone.utc).isoformat(),'routingPercent':100,'requiredFunctionalPads':500,'nets':94,'thermalVias':thermal,'electricalDesignDelta':delta,'orderQualification':read('reports/electrical-fixes/order-qualification.json'),'nativeDrcErrors':0,'shorts':0,'routeCacheSha256':sha('routing/final/cache.json'),'assemblyGlbSha256':sha('mechanical/upright-watch.glb'),'sourceChecks':checks,'shortChecks':shorts,'nativeEntries':entries,'traceStyle':style_release,**mechanical,'qualification':'Nominal prototype geometry. Actual display populated-flex/factory-fold dimensions and full tolerance stack must be verified before guaranteeing physical 14.5mm maximum. Materials, static flex bend, optical performance/seal, crimp process, battery, mount strength, RF and charging require hardware qualification.'}
(root/'reports/validation-report.json').write_text(json.dumps(out,indent=2)+'\n');print(json.dumps({k:out[k] for k in ['status','version','routingPercent','nativeDrcErrors','shorts','qualification']},indent=2))