Some checks failed
farmcontrol/farmcontrol-server/pipeline/head There was a failure building this commit
- 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.
245 lines
7.5 KiB
JavaScript
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;
|
|
}
|
|
}
|
|
}
|