Add printer configuration methods for speed, extrude, velocity, acceleration, and corner settings
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.
This commit is contained in:
Tom Butcher 2026-08-01 19:37:13 +01:00
parent d4f3ba0fca
commit 503fd6e0de
2 changed files with 414 additions and 0 deletions

View File

@ -1502,6 +1502,378 @@ export class PrinterClient {
} }
} }
async setSpeedFactor({ speedFactor }) {
logger.info(`Setting speed factor for ${this.printer.name}:`, speedFactor);
if (!this.isOnline) {
logger.error(
`Cannot set speed factor: Not connected to Moonraker (${this.printer.name})`,
);
return this.printerActionResult(
false,
"Printer is not connected to Moonraker",
);
}
try {
if (speedFactor === undefined || speedFactor === null) {
logger.warn(
`No speed factor provided for ${this.printer.name}`,
);
return this.printerActionResult(false, "No speed factor provided");
}
const result = await this.runGcodeScript(`M220 S${speedFactor}`);
if (!result.success) {
logger.error(
`Failed to set speed factor for ${this.printer.name}`,
result.error,
);
return result;
}
_.merge(this.motionObject, { speedFactor: speedFactor / 100 });
logger.info(`Successfully set speed factor for ${this.printer.name}`);
return result;
} catch (error) {
logger.error(
`Error setting speed factor for ${this.printer.name}:`,
error,
);
await this.addMotionErrorAlert(error);
return this.printerActionResult(
false,
error?.message || "Failed to set speed factor",
error?.code,
);
}
}
async setExtrudeFactor({ extrudeFactor }) {
logger.info(`Setting extrude factor for ${this.printer.name}:`, extrudeFactor);
if (!this.isOnline) {
logger.error(
`Cannot set extrude factor: Not connected to Moonraker (${this.printer.name})`,
);
return this.printerActionResult(
false,
"Printer is not connected to Moonraker",
);
}
try {
if (extrudeFactor === undefined || extrudeFactor === null) {
logger.warn(
`No extrude factor provided for ${this.printer.name}`,
);
return this.printerActionResult(false, "No extrude factor provided");
}
const result = await this.runGcodeScript(`M221 S${extrudeFactor}`);
if (!result.success) {
logger.error(
`Failed to set extrude factor for ${this.printer.name}`,
result.error,
);
return result;
}
_.merge(this.motionObject, { extrudeFactor: extrudeFactor / 100 });
logger.info(`Successfully set extrude factor for ${this.printer.name}`);
return result;
} catch (error) {
logger.error(
`Error setting extrude factor for ${this.printer.name}:`,
error,
);
await this.addMotionErrorAlert(error);
return this.printerActionResult(
false,
error?.message || "Failed to set extrude factor",
error?.code,
);
}
}
async setMaxVelocity({ maxVelocity }) {
logger.info(`Setting max velocity for ${this.printer.name}:`, maxVelocity);
if (!this.isOnline) {
logger.error(
`Cannot set max velocity: Not connected to Moonraker (${this.printer.name})`,
);
return this.printerActionResult(
false,
"Printer is not connected to Moonraker",
);
}
try {
if (maxVelocity === undefined || maxVelocity === null) {
logger.warn(`No max velocity provided for ${this.printer.name}`);
return this.printerActionResult(false, "No max velocity provided");
}
const result = await this.runGcodeScript(
`SET_VELOCITY_LIMIT VELOCITY=${maxVelocity}`,
);
if (!result.success) {
logger.error(
`Failed to set max velocity for ${this.printer.name}`,
result.error,
);
return result;
}
_.merge(this.motionObject, { maxVelocity });
logger.info(`Successfully set max velocity for ${this.printer.name}`);
return result;
} catch (error) {
logger.error(
`Error setting max velocity for ${this.printer.name}:`,
error,
);
await this.addMotionErrorAlert(error);
return this.printerActionResult(
false,
error?.message || "Failed to set max velocity",
error?.code,
);
}
}
async setMaxAcceleration({ maxAcceleration }) {
logger.info(
`Setting max acceleration for ${this.printer.name}:`,
maxAcceleration,
);
if (!this.isOnline) {
logger.error(
`Cannot set max acceleration: Not connected to Moonraker (${this.printer.name})`,
);
return this.printerActionResult(
false,
"Printer is not connected to Moonraker",
);
}
try {
if (maxAcceleration === undefined || maxAcceleration === null) {
logger.warn(`No max acceleration provided for ${this.printer.name}`);
return this.printerActionResult(false, "No max acceleration provided");
}
const result = await this.runGcodeScript(
`SET_VELOCITY_LIMIT ACCEL=${maxAcceleration}`,
);
if (!result.success) {
logger.error(
`Failed to set max acceleration for ${this.printer.name}`,
result.error,
);
return result;
}
_.merge(this.motionObject, { maxAcceleration });
logger.info(`Successfully set max acceleration for ${this.printer.name}`);
return result;
} catch (error) {
logger.error(
`Error setting max acceleration for ${this.printer.name}:`,
error,
);
await this.addMotionErrorAlert(error);
return this.printerActionResult(
false,
error?.message || "Failed to set max acceleration",
error?.code,
);
}
}
async setSquareCornerVelocity({ squareCornerVelocity }) {
logger.info(
`Setting square corner velocity for ${this.printer.name}:`,
squareCornerVelocity,
);
if (!this.isOnline) {
logger.error(
`Cannot set square corner velocity: Not connected to Moonraker (${this.printer.name})`,
);
return this.printerActionResult(
false,
"Printer is not connected to Moonraker",
);
}
try {
if (
squareCornerVelocity === undefined ||
squareCornerVelocity === null
) {
logger.warn(
`No square corner velocity provided for ${this.printer.name}`,
);
return this.printerActionResult(
false,
"No square corner velocity provided",
);
}
const result = await this.runGcodeScript(
`SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=${squareCornerVelocity}`,
);
if (!result.success) {
logger.error(
`Failed to set square corner velocity for ${this.printer.name}`,
result.error,
);
return result;
}
_.merge(this.motionObject, { squareCornerVelocity });
logger.info(
`Successfully set square corner velocity for ${this.printer.name}`,
);
return result;
} catch (error) {
logger.error(
`Error setting square corner velocity for ${this.printer.name}:`,
error,
);
await this.addMotionErrorAlert(error);
return this.printerActionResult(
false,
error?.message || "Failed to set square corner velocity",
error?.code,
);
}
}
async setMinCruiseRatio({ minCruiseRatio }) {
logger.info(
`Setting min cruise ratio for ${this.printer.name}:`,
minCruiseRatio,
);
if (!this.isOnline) {
logger.error(
`Cannot set min cruise ratio: Not connected to Moonraker (${this.printer.name})`,
);
return this.printerActionResult(
false,
"Printer is not connected to Moonraker",
);
}
try {
if (minCruiseRatio === undefined || minCruiseRatio === null) {
logger.warn(`No min cruise ratio provided for ${this.printer.name}`);
return this.printerActionResult(false, "No min cruise ratio provided");
}
const result = await this.runGcodeScript(
`SET_VELOCITY_LIMIT MINIMUM_CRUISE_RATIO=${minCruiseRatio}`,
);
if (!result.success) {
logger.error(
`Failed to set min cruise ratio for ${this.printer.name}`,
result.error,
);
return result;
}
_.merge(this.motionObject, { minCruiseRatio });
logger.info(`Successfully set min cruise ratio for ${this.printer.name}`);
return result;
} catch (error) {
logger.error(
`Error setting min cruise ratio for ${this.printer.name}:`,
error,
);
await this.addMotionErrorAlert(error);
return this.printerActionResult(
false,
error?.message || "Failed to set min cruise ratio",
error?.code,
);
}
}
updateMiscObjectFromScript(script) {
const fanMatch = script.match(/^M106 S(\d+)/);
if (fanMatch) {
const speed = Number(fanMatch[1]) / 255;
_.merge(this.miscObject, { fan: { speed, target: speed } });
return;
}
const lcdMatch = script.match(
/SET_LCD LCD=lcd_backlight BRIGHTNESS=([\d.]+)/,
);
if (lcdMatch) {
_.merge(this.miscObject, {
lcdBacklight: { brightness: Number(lcdMatch[1]) },
});
return;
}
const beeperMatch = script.match(/M300 .+ V(\d+)/);
if (beeperMatch) {
_.merge(this.miscObject, {
beeper: { value: Number(beeperMatch[1]) / 100 },
});
}
}
async gcodeScript({ script }) {
logger.info(`Running g-code script for ${this.printer.name}:`, script);
if (!this.isOnline) {
logger.error(
`Cannot run g-code script: Not connected to Moonraker (${this.printer.name})`,
);
return this.printerActionResult(
false,
"Printer is not connected to Moonraker",
);
}
try {
if (!script) {
logger.warn(`No g-code script provided for ${this.printer.name}`);
return this.printerActionResult(false, "No g-code script provided");
}
const result = await this.runGcodeScript(script);
if (!result.success) {
logger.error(
`Failed to run g-code script for ${this.printer.name}`,
result.error,
);
return result;
}
this.updateMiscObjectFromScript(script);
logger.info(`Successfully ran g-code script for ${this.printer.name}`);
return result;
} catch (error) {
logger.error(
`Error running g-code script for ${this.printer.name}:`,
error,
);
await this.addMotionErrorAlert(error);
return this.printerActionResult(
false,
error?.message || "Failed to run g-code script",
error?.code,
);
}
}
async restartPrinterFirmware() { async restartPrinterFirmware() {
logger.info(`Restarting printer firmware for ${this.printer.name}`); logger.info(`Restarting printer firmware for ${this.printer.name}`);
if (!this.isOnline) { if (!this.isOnline) {

View File

@ -93,6 +93,48 @@ export class PrinterManager {
callback(moveAxisResult); callback(moveAxisResult);
return; 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": case "restartPrinterFirmware":
const restartPrinterFirmwareResult = const restartPrinterFirmwareResult =
await printer.restartPrinterFirmware(); await printer.restartPrinterFirmware();