Initial commit: Busbar Designer
Web tool for designing nickel/copper busbars over cylindrical-cell battery packs (21700, 18650) in hex holders. Flask + build123d backend exports STEP/DXF/SVG; vanilla JS frontend with live preview, multi-project SQLite persistence, snapshot history. Deploy scripts in deploy/ (proxmox-lxc.sh, install.sh, update.sh).
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
/* groups.js — busbar (parallel cell group) CRUD.
|
||||
*
|
||||
* A Busbar is { id, name, color, cells: [cellId, …] }.
|
||||
* Cell `assigned` lookup is maintained so the canvas can render colors.
|
||||
*/
|
||||
|
||||
const Groups = (() => {
|
||||
// Friendly hue palette — rotates as new busbars are added.
|
||||
const COLORS = [
|
||||
"#f08a24", "#4fa3ff", "#3ecf8e", "#e85aad",
|
||||
"#a78bfa", "#f5d142", "#52d6c6", "#ff6b6b",
|
||||
"#7cb342", "#ba68c8", "#26c6da", "#ffa726",
|
||||
];
|
||||
|
||||
let nextId = 1;
|
||||
let nextNameIdx = 1;
|
||||
|
||||
function create(state, cellIds) {
|
||||
if (!cellIds || cellIds.length === 0) return null;
|
||||
const id = nextId++;
|
||||
const bb = {
|
||||
id,
|
||||
name: `P${nextNameIdx++}`,
|
||||
color: COLORS[(id - 1) % COLORS.length],
|
||||
shape: "panel", // "panel" (default, production plate) | "wire"
|
||||
cells: [...cellIds],
|
||||
};
|
||||
state.busbars.push(bb);
|
||||
_reassign(state);
|
||||
return bb;
|
||||
}
|
||||
|
||||
function remove(state, busbarId) {
|
||||
state.busbars = state.busbars.filter((b) => b.id !== busbarId);
|
||||
_reassign(state);
|
||||
}
|
||||
|
||||
function rename(state, busbarId, name) {
|
||||
const bb = state.busbars.find((b) => b.id === busbarId);
|
||||
if (bb) bb.name = name;
|
||||
}
|
||||
|
||||
function recolor(state, busbarId, color) {
|
||||
const bb = state.busbars.find((b) => b.id === busbarId);
|
||||
if (bb) bb.color = color;
|
||||
}
|
||||
|
||||
function addCells(state, busbarId, cellIds) {
|
||||
const bb = state.busbars.find((b) => b.id === busbarId);
|
||||
if (!bb) return;
|
||||
const set = new Set(bb.cells);
|
||||
for (const id of cellIds) {
|
||||
if (!set.has(id)) { bb.cells.push(id); set.add(id); }
|
||||
}
|
||||
_reassign(state);
|
||||
}
|
||||
|
||||
function removeCells(state, busbarId, cellIds) {
|
||||
const bb = state.busbars.find((b) => b.id === busbarId);
|
||||
if (!bb) return;
|
||||
const rm = new Set(cellIds);
|
||||
bb.cells = bb.cells.filter((id) => !rm.has(id));
|
||||
_reassign(state);
|
||||
}
|
||||
|
||||
function _reassign(state) {
|
||||
state.cellToBusbar = new Map();
|
||||
for (const bb of state.busbars) {
|
||||
for (const cid of bb.cells) state.cellToBusbar.set(cid, bb.id);
|
||||
}
|
||||
}
|
||||
|
||||
function findByCell(state, cellId) {
|
||||
return state.cellToBusbar.get(cellId);
|
||||
}
|
||||
|
||||
function reset() {
|
||||
nextId = 1;
|
||||
nextNameIdx = 1;
|
||||
}
|
||||
|
||||
return { create, remove, rename, recolor, addCells, removeCells, findByCell, reset };
|
||||
})();
|
||||
Reference in New Issue
Block a user