farmcontrol-server/src/printer/printermanager.js
Tom Butcher 503fd6e0de
Some checks failed
farmcontrol/farmcontrol-server/pipeline/head There was a failure building this commit
Add printer configuration methods for speed, extrude, velocity, acceleration, and corner settings
- Implemented new methods in PrinterClient to set speed factor, extrude factor, max velocity, max acceleration, square corner velocity, and min cruise ratio.
- Enhanced error handling and logging for each method to ensure robust operation and user feedback.
- Updated PrinterManager to handle new actions for these settings, allowing for dynamic adjustments during operation.
2026-08-01 19:37:13 +01:00

245 lines
7.5 KiB
JavaScript

// printer-manager.js - Manages multiple printer connections through MongoDB
import { PrinterClient } from "./printerclient.js";
import { loadConfig } from "../config.js";
import log4js from "log4js";
import { sendIPC } from "../desktop/notify.js";
import { startWaiting, stopWaiting } from "../spinner.js";
// Load configuration
const config = loadConfig();
const logger = log4js.getLogger("Printer Manager");
logger.level = config.logLevel;
export class PrinterManager {
constructor(socketClient) {
this.socketClient = socketClient;
this.printerClients = new Map();
this.printers = [];
}
async reloadPrinters() {
startWaiting("Reloading printers...", logger);
try {
this.printers = await this.socketClient.listObjects({
objectType: "printer",
filter: { host: this.socketClient.id },
populate: [
"currentFilamentStock",
"currentJob",
"currentSubJob",
"queue",
],
});
sendIPC("setPrinters", this.printers);
var removedPrintersCount = 0;
// Remove printer clients that are no longer in the printers list
const printerIds = this.printers.map((printer) => printer._id);
for (const [printerId, printerClient] of this.printerClients.entries()) {
if (!printerIds.includes(printerId)) {
// Close the connection before removing
if (printerClient.socket) {
printerClient.shouldReconnect = false;
printerClient.socket.close();
}
this.printerClients.delete(printerId);
logger.info(`Removed printer client for printer ID: ${printerId}`);
removedPrintersCount++;
}
}
var addedPrintersCount = 0;
// Add new printer clients for printers not in the printerClients map
for (const printer of this.printers) {
const printerId = printer._id;
if (!this.printerClients.has(printerId)) {
const printerClient = new PrinterClient(printer, this);
await printerClient.connect();
this.printerClients.set(printerId, printerClient);
logger.info(`Added printer client for printer ID: ${printerId}`);
addedPrintersCount++;
}
}
await stopWaiting();
logger.debug("Printers added:", addedPrintersCount);
logger.debug("Printers removed:", removedPrintersCount);
} catch (error) {
await stopWaiting();
logger.error("Failed to update printers:", error);
this.printers = [];
}
}
async handlePrinterAction(id, action, callback) {
logger.debug("Running printer action...", action);
const printer = this.getPrinterClient(id);
switch (action.type) {
case "setTemperature":
const setTempResult = await printer.setTemperature(action.data);
callback(setTempResult);
return;
case "homeAxis":
const homeAxisResult = await printer.homeAxis(action.data);
callback(homeAxisResult);
return;
case "moveAxis":
const moveAxisResult = await printer.moveAxis(action.data);
callback(moveAxisResult);
return;
case "setSpeedFactor":
const setSpeedFactorResult = await printer.setSpeedFactor(action.data);
callback(setSpeedFactorResult);
return;
case "setExtrudeFactor":
const setExtrudeFactorResult = await printer.setExtrudeFactor(
action.data,
);
callback(setExtrudeFactorResult);
return;
case "setMaxVelocity":
const setMaxVelocityResult = await printer.setMaxVelocity(action.data);
callback(setMaxVelocityResult);
return;
case "setMaxAcceleration":
const setMaxAccelerationResult = await printer.setMaxAcceleration(
action.data,
);
callback(setMaxAccelerationResult);
return;
case "setSquareCornerVelocity":
const setSquareCornerVelocityResult =
await printer.setSquareCornerVelocity(action.data);
callback(setSquareCornerVelocityResult);
return;
case "setMinCruiseRatio":
const setMinCruiseRatioResult = await printer.setMinCruiseRatio(
action.data,
);
callback(setMinCruiseRatioResult);
return;
case "gcodeScript":
const gcodeScriptResult = await printer.gcodeScript(action.data);
callback(gcodeScriptResult);
return;
case "restartPrinterFirmware":
const restartPrinterFirmwareResult =
await printer.restartPrinterFirmware();
callback(restartPrinterFirmwareResult);
return;
case "restartPrinter":
const restartPrinterResult = await printer.restartPrinter();
callback(restartPrinterResult);
return;
case "restartMoonraker":
const restartMoonrakerResult = await printer.restartMoonraker();
callback(restartMoonrakerResult);
return;
case "deploy":
const deployResult = await printer.deploySubJob(action.data);
callback(deployResult);
return;
case "startQueue":
const startQueueResult = await printer.startQueue();
callback(startQueueResult);
return;
case "pauseJob":
const pauseJobResult = await printer.pauseJob();
callback(pauseJobResult);
return;
case "resumeJob":
const resumeJobResult = await printer.resumeJob();
callback(resumeJobResult);
return;
case "cancelJob":
const cancelJobResult = await printer.cancelJob();
callback(cancelJobResult);
return;
case "unloadFilamentStock":
const unloadFilamentStockResult = await printer.unloadFilamentStock();
callback(unloadFilamentStockResult);
return;
case "loadFilamentStock":
const loadFilamentStockResult = await printer.loadFilamentStock(
action.data.filamentStock,
);
callback(loadFilamentStockResult);
return;
}
callback({ error: "Unknown command." });
}
async handlePrinterUpdate(id, data) {
logger.debug("Handling printer update for id:", id);
const printer = this.getPrinterClient(id);
if (printer) {
await printer.updatePrinter(data.object);
}
}
getPrinterClient(printerId) {
return this.printerClients.get(printerId);
}
getAllPrinterClients() {
return this.printerClients.values();
}
// Close all printer connections
async closeAllConnections() {
startWaiting(
`Closing all printer connections... current count: ${this.printerClients.size}`,
logger,
);
try {
const clients = Array.from(this.printerClients.values());
for (const printerClient of clients) {
try {
// Ensure we never auto-reconnect after a manual close-all
printerClient.shouldReconnect = false;
await printerClient.disconnect();
logger.info(
`Disconnected printer client ${printerClient?.id || "unknown"}`,
);
} catch (error) {
logger.error(
`Failed to disconnect printer client ${
printerClient?.id || "unknown"
}:`,
error,
);
}
}
console.log("Printer clients:", this.printerClients);
// Clear local references so no stale clients remain
this.printerClients.clear();
this.printers = [];
logger.info(
`All printer connections closed. Remaining clients: ${this.printerClients.size}`,
);
await stopWaiting();
} catch (error) {
await stopWaiting();
throw error;
}
}
}