shibosoftwaredev/f1c100s-linux-nema17-stepper-controller

A four-layer NEMA 17 motor-controller PCB combining an Allwinner F1C100S Linux computer, USB‑PD/buck power system, W5500 Ethernet, STM32 real-time motion control, DRV8825 stepper driver, protection/temperature/current telemetry, USB interfaces, and local LED/buzzer diagnostics.

Version
0.4.56
License
unset
Stars
0

scripts/update-round8-cap-stock.mjs

import fs from "node:fs"
import assert from "node:assert/strict"
import crypto from "node:crypto"
import {validateCatalogPart} from "./validate-bom.mjs"
const read=p=>JSON.parse(fs.readFileSync(p,"utf8"))
const report=read("reports/jlcpcb-stock-audit.json")
const candidate=read("reports/round8-cap-final-catalog.json").find(p=>p.code==="C7393837")
assert.ok(candidate)
assert.deepEqual(candidate.attributes,{"Voltage Rating":"10V","Tolerance":"±10%","Capacitance":"100nF","Temperature Coefficient":"X7R"})
assert.equal(candidate.package,"0201")
const old=report.parts.find(p=>p.code==="C18164586")
assert.ok(old,"retain the actual depleted-inventory evidence")
assert.deepEqual(old.designators.sort(),["C_CURRENT_A_SUPPLY","C_CURRENT_B_SUPPLY"])
const needed=Math.max(report.boardQuantity*2+(candidate.assemblyLossQuantity??0),candidate.minimumAssemblyQuantity??0)
assert.ok(candidate.canBuy&&candidate.displayedStock>0&&candidate.orderableStock>=needed)
const c=read("dist/index/circuit.json")
for(const name of old.designators){const part=c.find(e=>e.type==="source_component"&&e.name===name);assert.deepEqual(validateCatalogPart(part,candidate),[]);assert.equal(part.supplier_part_numbers.jlcpcb[0],candidate.code)}
fs.writeFileSync("reports/round8-depleted-cap-stock.json",JSON.stringify(old,null,2)+"\n")
const replacement={...candidate,designators:old.designators,quantityPerBoard:2,requiredForBatch:needed,status:"in-stock",url:`https://jlcpcb.com/partdetail/${candidate.code}`}
report.parts=report.parts.map(p=>p===old?replacement:p).sort((a,b)=>Number(a.code.slice(1))-Number(b.code.slice(1)))
assert.ok(report.parts.every(p=>p.status==="in-stock"))
report.catalogReplacement={oldCode:old.code,newCode:candidate.code,at:new Date().toISOString(),reason:"Actual assembly-stock shortage. Same 0201, 100 nF, ±10%, X7R; 10 V rating explicitly declared on the regulated 3.3 V supply. No geometry or net change. Original inventory timestamps retained."}
report.circuitSha256=crypto.createHash("sha256").update(fs.readFileSync("dist/index/circuit.json")).digest("hex")
fs.writeFileSync("reports/jlcpcb-stock-audit.json",JSON.stringify(report,null,2)+"\n")
const row=cells=>cells.map(v=>`"${String(v??"").replaceAll('"','""')}"`).join(",")
const csv=[row(["Designators","Quantity Per Board","Board Quantity","Assembly Minimum","Assembly Loss","Required For Batch","JLCPCB Part #","Manufacturer Part Number","Package","Displayed Stock","Orderable Stock","Status","Checked At UTC","Source"]),...report.parts.map(r=>row([r.designators.join(", "),r.quantityPerBoard,report.boardQuantity,r.minimumAssemblyQuantity,r.assemblyLossQuantity,r.requiredForBatch,r.code,r.manufacturerPartNumber,r.package,r.displayedStock,r.orderableStock,r.status,r.checkedAt,r.url]))].join("\n")+"\n"
fs.writeFileSync("reports/jlcpcb-stock-audit.csv",csv)
console.log(JSON.stringify({populated:report.populatedComponentCount,codes:report.uniquePartCount,replacement,notReserved:true}))