Update dependencies, improve document printer management, and add workspace configuration
Some checks failed
farmcontrol/farmcontrol-server/pipeline/head There was a failure building this commit
Some checks failed
farmcontrol/farmcontrol-server/pipeline/head There was a failure building this commit
This commit is contained in:
parent
3cc2cbe020
commit
ffa6d84251
@ -5,7 +5,7 @@
|
|||||||
"apiUrl": "https://dev.tombutcher.work/api",
|
"apiUrl": "https://dev.tombutcher.work/api",
|
||||||
"host": {
|
"host": {
|
||||||
"id": "691a1db49ce913faf0e51284",
|
"id": "691a1db49ce913faf0e51284",
|
||||||
"authCode": "FvD3qnNh8FP_xJShlECfYshqQawfD5oPP4xlGOFV2vQIDPRxkAjH4rO6sIgpLucX"
|
"authCode": "9uu3DC0si__-F9FnGWTKudle5z6yZasFMlKohnShElPekRYteh-LlZaksHOXFfOO"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"production": {
|
"production": {
|
||||||
|
|||||||
53
package.json
53
package.json
@ -20,45 +20,46 @@
|
|||||||
"author": "Tom Butcher",
|
"author": "Tom Butcher",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.13.2",
|
"axios": "^1.16.1",
|
||||||
"canvas": "^3.2.0",
|
"canvas": "^3.2.3",
|
||||||
"etcd3": "^1.1.2",
|
"etcd3": "^1.1.2",
|
||||||
"express": "^5.1.0",
|
"express": "^5.2.1",
|
||||||
|
"form-data": "^4.0.5",
|
||||||
"ipp": "^2.0.1",
|
"ipp": "^2.0.1",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.3",
|
||||||
"keycloak-connect": "^26.1.1",
|
"keycloak-connect": "^26.1.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.18.1",
|
||||||
"log4js": "^6.9.1",
|
"log4js": "^6.9.1",
|
||||||
"mongoose": "^9.0.0",
|
"mongoose": "^9.6.2",
|
||||||
"node-cache": "^5.1.2",
|
"node-cache": "^5.1.2",
|
||||||
"node-thermal-printer": "^4.5.0",
|
"node-thermal-printer": "^4.6.0",
|
||||||
"pdf-to-img": "^5.0.0",
|
"pdf-to-img": "^6.1.0",
|
||||||
"sharp": "^0.34.5",
|
"sharp": "^0.34.5",
|
||||||
"socket.io": "^4.8.1",
|
"socket.io": "^4.8.3",
|
||||||
"socket.io-client": "^4.8.1",
|
"socket.io-client": "^4.8.3",
|
||||||
"ws": "^8.18.3"
|
"ws": "^8.20.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ant-design/icons": "^6.1.0",
|
"@ant-design/icons": "^6.2.3",
|
||||||
"antd": "^5.28.0",
|
"@electron/rebuild": "^4.0.4",
|
||||||
"@electron/rebuild": "^4.0.1",
|
"@vitejs/plugin-react": "^6.0.2",
|
||||||
"@vitejs/plugin-react": "^5.1.1",
|
"antd": "^5.29.2",
|
||||||
"concurrently": "^9.2.1",
|
"concurrently": "^9.2.1",
|
||||||
"cross-env": "^10.1.0",
|
"cross-env": "^10.1.0",
|
||||||
"electron": "^38.7.1",
|
"electron": "^42.1.0",
|
||||||
"electron-builder": "^26.0.12",
|
"electron-builder": "^26.8.1",
|
||||||
"jest": "^30.2.0",
|
"jest": "^30.4.2",
|
||||||
"nodemon": "^3.1.11",
|
"nodemon": "^3.1.14",
|
||||||
"pkg": "^5.8.1",
|
"pkg": "^5.8.1",
|
||||||
"prop-types": "^15.8.1",
|
"prop-types": "^15.8.1",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.6",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.6",
|
||||||
"rimraf": "^6.1.2",
|
"rimraf": "^6.1.3",
|
||||||
"shx": "^0.3.4",
|
"shx": "^0.4.0",
|
||||||
"supertest": "^7.1.4",
|
"supertest": "^7.2.2",
|
||||||
"vite": "^7.2.4",
|
"vite": "^8.0.13",
|
||||||
"vite-plugin-svgo": "^2.0.0",
|
"vite-plugin-svgo": "^2.0.0",
|
||||||
"vite-plugin-svgr": "^4.5.0"
|
"vite-plugin-svgr": "^5.2.0"
|
||||||
},
|
},
|
||||||
"pkg": {
|
"pkg": {
|
||||||
"assets": [
|
"assets": [
|
||||||
|
|||||||
2922
pnpm-lock.yaml
generated
2922
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
9
pnpm-workspace.yaml
Normal file
9
pnpm-workspace.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
allowBuilds:
|
||||||
|
canvas: true
|
||||||
|
chromedriver: true
|
||||||
|
electron-winstaller: true
|
||||||
|
electron: true
|
||||||
|
esbuild: true
|
||||||
|
protobufjs: true
|
||||||
|
sharp: true
|
||||||
|
unrs-resolver: true
|
||||||
@ -15,7 +15,7 @@ export class DocumentPrinterClient {
|
|||||||
documentPrinter = {
|
documentPrinter = {
|
||||||
connection: { interface: "cups", host: "localhost", port: 9100 },
|
connection: { interface: "cups", host: "localhost", port: 9100 },
|
||||||
},
|
},
|
||||||
documentPrinterManager
|
documentPrinterManager,
|
||||||
) {
|
) {
|
||||||
this.id = documentPrinter._id;
|
this.id = documentPrinter._id;
|
||||||
this.documentPrinter = documentPrinter;
|
this.documentPrinter = documentPrinter;
|
||||||
@ -23,9 +23,10 @@ export class DocumentPrinterClient {
|
|||||||
this.queue = [];
|
this.queue = [];
|
||||||
this.documentPrinterManager = documentPrinterManager;
|
this.documentPrinterManager = documentPrinterManager;
|
||||||
this.currentJob = null;
|
this.currentJob = null;
|
||||||
|
this.active = documentPrinter.active == true;
|
||||||
this.socketClient = documentPrinterManager.socketClient;
|
this.socketClient = documentPrinterManager.socketClient;
|
||||||
this.interface = documentPrinter.connection.interface || "cups"; // cups, receipt, or os
|
this.interface = documentPrinter.connection.interface || "cups"; // cups, receipt, or os
|
||||||
this.state = { type: "offline" };
|
this.state = { type: this.active == true ? "offline" : "inactive" };
|
||||||
this.isOnline = documentPrinter.online || false;
|
this.isOnline = documentPrinter.online || false;
|
||||||
this.shouldReconnect = true;
|
this.shouldReconnect = true;
|
||||||
this.isProcessingQueue = false;
|
this.isProcessingQueue = false;
|
||||||
@ -38,7 +39,7 @@ export class DocumentPrinterClient {
|
|||||||
|
|
||||||
initializeInterface() {
|
initializeInterface() {
|
||||||
logger.info(
|
logger.info(
|
||||||
`Initializing ${this.interface} interface for document printer ${this.id}`
|
`Initializing ${this.interface} interface for document printer ${this.id}`,
|
||||||
);
|
);
|
||||||
switch (this.interface) {
|
switch (this.interface) {
|
||||||
case "cups":
|
case "cups":
|
||||||
@ -104,6 +105,16 @@ export class DocumentPrinterClient {
|
|||||||
await this.reconnect();
|
await this.reconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.documentPrinter = { ...this.documentPrinter, ...data };
|
||||||
|
|
||||||
|
if (Object.hasOwn(data || {}, "active") && data.active != this.active) {
|
||||||
|
if (data.active == true) {
|
||||||
|
await this.setActive();
|
||||||
|
} else {
|
||||||
|
await this.setInactive();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerEventHandlers() {
|
registerEventHandlers() {
|
||||||
@ -126,8 +137,18 @@ export class DocumentPrinterClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async connect() {
|
async connect() {
|
||||||
|
if (this.active == false) {
|
||||||
|
logger.info(
|
||||||
|
`Document printer ${this.id} is not active, skipping connection`,
|
||||||
|
);
|
||||||
|
this.shouldReconnect = false;
|
||||||
|
this.isOnline = false;
|
||||||
|
this.state = { type: "inactive" };
|
||||||
|
await this.updateDocumentPrinterState();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
logger.info(
|
logger.info(
|
||||||
`Connecting to document printer ${this.id} (${this.interface})`
|
`Connecting to document printer ${this.id} (${this.interface})`,
|
||||||
);
|
);
|
||||||
|
|
||||||
clearTimeout(this.reconnectTimeout);
|
clearTimeout(this.reconnectTimeout);
|
||||||
@ -140,7 +161,7 @@ export class DocumentPrinterClient {
|
|||||||
|
|
||||||
if (!this.printerInterface) {
|
if (!this.printerInterface) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot connect: No interface initialized for ${this.interface}`
|
`Cannot connect: No interface initialized for ${this.interface}`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -150,7 +171,7 @@ export class DocumentPrinterClient {
|
|||||||
if (result.error) {
|
if (result.error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error connecting to document printer ${this.documentPrinter.name}:`,
|
`Error connecting to document printer ${this.documentPrinter.name}:`,
|
||||||
result.error
|
result.error,
|
||||||
);
|
);
|
||||||
this.isOnline = false;
|
this.isOnline = false;
|
||||||
this.state = { type: "offline", message: result.error };
|
this.state = { type: "offline", message: result.error };
|
||||||
@ -158,27 +179,37 @@ export class DocumentPrinterClient {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
logger.info(
|
logger.info(
|
||||||
`Connected to document printer ${this.documentPrinter.name} (${this.interface})`
|
`Connected to document printer ${this.documentPrinter.name} (${this.interface})`,
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async reconnect() {
|
async reconnect() {
|
||||||
|
if (this.active == false) {
|
||||||
|
logger.info(
|
||||||
|
`Document printer ${this.documentPrinter.name} is inactive, skipping reconnect`,
|
||||||
|
);
|
||||||
|
this.shouldReconnect = false;
|
||||||
|
this.isOnline = false;
|
||||||
|
this.state = { type: "inactive" };
|
||||||
|
await this.updateDocumentPrinterState();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (this.isOnline == true) {
|
if (this.isOnline == true) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`Disconnecting from document printer ${this.documentPrinter.name} before reconnecting...`
|
`Disconnecting from document printer ${this.documentPrinter.name} before reconnecting...`,
|
||||||
);
|
);
|
||||||
await this.disconnect();
|
await this.disconnect();
|
||||||
}
|
}
|
||||||
logger.info(
|
logger.info(
|
||||||
`Reconnecting to document printer ${this.documentPrinter.name}`
|
`Reconnecting to document printer ${this.documentPrinter.name}`,
|
||||||
);
|
);
|
||||||
this.shouldReconnect = true;
|
this.shouldReconnect = true;
|
||||||
const connectResult = await this.connect();
|
const connectResult = await this.connect();
|
||||||
if (connectResult == false) {
|
if (connectResult == false) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error reconnecting to document printer ${this.documentPrinter.name}:`,
|
`Error reconnecting to document printer ${this.documentPrinter.name}:`,
|
||||||
connectResult.error
|
connectResult.error,
|
||||||
);
|
);
|
||||||
if (this.shouldReconnect) {
|
if (this.shouldReconnect) {
|
||||||
// Attempt to reconnect after delay
|
// Attempt to reconnect after delay
|
||||||
@ -190,7 +221,7 @@ export class DocumentPrinterClient {
|
|||||||
if (initializeResult == false) {
|
if (initializeResult == false) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error initializing document printer ${this.documentPrinter.name}:`,
|
`Error initializing document printer ${this.documentPrinter.name}:`,
|
||||||
initializeResult.error
|
initializeResult.error,
|
||||||
);
|
);
|
||||||
if (this.shouldReconnect) {
|
if (this.shouldReconnect) {
|
||||||
// Attempt to reconnect after delay
|
// Attempt to reconnect after delay
|
||||||
@ -213,7 +244,7 @@ export class DocumentPrinterClient {
|
|||||||
if (result.error) {
|
if (result.error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error initializing document printer ${this.documentPrinter.name}:`,
|
`Error initializing document printer ${this.documentPrinter.name}:`,
|
||||||
result.error
|
result.error,
|
||||||
);
|
);
|
||||||
this.state = { type: "offline", message: result.error };
|
this.state = { type: "offline", message: result.error };
|
||||||
await this.updateDocumentPrinterState();
|
await this.updateDocumentPrinterState();
|
||||||
@ -223,7 +254,7 @@ export class DocumentPrinterClient {
|
|||||||
await this.updateDocumentPrinterState();
|
await this.updateDocumentPrinterState();
|
||||||
this.eventUpdateInterval = setInterval(
|
this.eventUpdateInterval = setInterval(
|
||||||
this.handleEventUpdate.bind(this),
|
this.handleEventUpdate.bind(this),
|
||||||
3000
|
3000,
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -236,7 +267,7 @@ export class DocumentPrinterClient {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error retrieving status for document printer ${this.documentPrinter.name}:`,
|
`Error retrieving status for document printer ${this.documentPrinter.name}:`,
|
||||||
error
|
error,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -272,19 +303,19 @@ export class DocumentPrinterClient {
|
|||||||
|
|
||||||
async deployDocumentJob(documentJob) {
|
async deployDocumentJob(documentJob) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`Deploying document job ${documentJob._id} to ${this.documentPrinter.name}`
|
`Deploying document job ${documentJob._id} to ${this.documentPrinter.name}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot deploy job: Document printer not connected (${this.documentPrinter.name})`
|
`Cannot deploy job: Document printer not connected (${this.documentPrinter.name})`,
|
||||||
);
|
);
|
||||||
return { error: "Document printer not connected" };
|
return { error: "Document printer not connected" };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.printerInterface) {
|
if (!this.printerInterface) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot deploy job: No interface initialized (${this.documentPrinter.name})`
|
`Cannot deploy job: No interface initialized (${this.documentPrinter.name})`,
|
||||||
);
|
);
|
||||||
return { error: "No interface initialized" };
|
return { error: "No interface initialized" };
|
||||||
}
|
}
|
||||||
@ -310,7 +341,7 @@ export class DocumentPrinterClient {
|
|||||||
});
|
});
|
||||||
if (!documentTemplate) {
|
if (!documentTemplate) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Document template not found for job ${documentJob._id}`
|
`Document template not found for job ${documentJob._id}`,
|
||||||
);
|
);
|
||||||
return { error: "Document template not found" };
|
return { error: "Document template not found" };
|
||||||
}
|
}
|
||||||
@ -325,20 +356,20 @@ export class DocumentPrinterClient {
|
|||||||
});
|
});
|
||||||
if (!pdfObj) {
|
if (!pdfObj) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Failed to render document template for job ${documentJob._id}`
|
`Failed to render document template for job ${documentJob._id}`,
|
||||||
);
|
);
|
||||||
return { error: "Failed to render document template" };
|
return { error: "Failed to render document template" };
|
||||||
}
|
}
|
||||||
const result = await this.printerInterface.deploy(
|
const result = await this.printerInterface.deploy(
|
||||||
documentJob,
|
documentJob,
|
||||||
pdfObj.pdf
|
pdfObj.pdf,
|
||||||
);
|
);
|
||||||
await this.updateJobState(documentJob._id, {
|
await this.updateJobState(documentJob._id, {
|
||||||
type: "deploying",
|
type: "deploying",
|
||||||
progress: 1.0,
|
progress: 1.0,
|
||||||
});
|
});
|
||||||
logger.info(
|
logger.info(
|
||||||
`Deployed document job ${documentJob._id} to ${this.documentPrinter.name}`
|
`Deployed document job ${documentJob._id} to ${this.documentPrinter.name}`,
|
||||||
);
|
);
|
||||||
await this.updateJobState(documentJob._id, {
|
await this.updateJobState(documentJob._id, {
|
||||||
type: "queued",
|
type: "queued",
|
||||||
@ -349,21 +380,21 @@ export class DocumentPrinterClient {
|
|||||||
this.queue.push(documentJob._id);
|
this.queue.push(documentJob._id);
|
||||||
} else {
|
} else {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`Job ${documentJob._id} is already in the queue for ${this.documentPrinter.name}`
|
`Job ${documentJob._id} is already in the queue for ${this.documentPrinter.name}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.startQueue();
|
this.startQueue();
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Interface ${this.interface} does not support deployDocumentJob`
|
`Interface ${this.interface} does not support deployDocumentJob`,
|
||||||
);
|
);
|
||||||
return { error: "Interface does not support this operation" };
|
return { error: "Interface does not support this operation" };
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error deploying document job to ${this.documentPrinter.name}:`,
|
`Error deploying document job to ${this.documentPrinter.name}:`,
|
||||||
error
|
error,
|
||||||
);
|
);
|
||||||
await this.updateJobState(documentJob._id, {
|
await this.updateJobState(documentJob._id, {
|
||||||
type: "error",
|
type: "error",
|
||||||
@ -377,20 +408,20 @@ export class DocumentPrinterClient {
|
|||||||
async startQueue() {
|
async startQueue() {
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot start queue: Document printer not connected (${this.documentPrinter.name})`
|
`Cannot start queue: Document printer not connected (${this.documentPrinter.name})`,
|
||||||
);
|
);
|
||||||
return { error: "Document printer not connected" };
|
return { error: "Document printer not connected" };
|
||||||
}
|
}
|
||||||
if (!this.printerInterface) {
|
if (!this.printerInterface) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot start queue: No interface initialized (${this.documentPrinter.name})`
|
`Cannot start queue: No interface initialized (${this.documentPrinter.name})`,
|
||||||
);
|
);
|
||||||
return { error: "No interface initialized" };
|
return { error: "No interface initialized" };
|
||||||
}
|
}
|
||||||
// Prevent concurrent queue processing
|
// Prevent concurrent queue processing
|
||||||
if (this.isProcessingQueue) {
|
if (this.isProcessingQueue) {
|
||||||
logger.debug(
|
logger.debug(
|
||||||
`Queue is already being processed for ${this.documentPrinter.name}`
|
`Queue is already being processed for ${this.documentPrinter.name}`,
|
||||||
);
|
);
|
||||||
return { info: "Queue is already being processed" };
|
return { info: "Queue is already being processed" };
|
||||||
}
|
}
|
||||||
@ -404,19 +435,19 @@ export class DocumentPrinterClient {
|
|||||||
async runQueue() {
|
async runQueue() {
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot print next job: Document printer not connected (${this.documentPrinter.name})`
|
`Cannot print next job: Document printer not connected (${this.documentPrinter.name})`,
|
||||||
);
|
);
|
||||||
return { error: "Document printer not connected" };
|
return { error: "Document printer not connected" };
|
||||||
}
|
}
|
||||||
if (!this.printerInterface) {
|
if (!this.printerInterface) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot print next job: No interface initialized (${this.documentPrinter.name})`
|
`Cannot print next job: No interface initialized (${this.documentPrinter.name})`,
|
||||||
);
|
);
|
||||||
return { error: "No interface initialized" };
|
return { error: "No interface initialized" };
|
||||||
}
|
}
|
||||||
if (this.state.type != "standby") {
|
if (this.state.type != "standby") {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot print next job: Document printer not in standby mode (${this.documentPrinter.name})`
|
`Cannot print next job: Document printer not in standby mode (${this.documentPrinter.name})`,
|
||||||
);
|
);
|
||||||
return { error: "Document printer not in standby mode" };
|
return { error: "Document printer not in standby mode" };
|
||||||
}
|
}
|
||||||
@ -424,7 +455,7 @@ export class DocumentPrinterClient {
|
|||||||
// Prevent concurrent queue processing
|
// Prevent concurrent queue processing
|
||||||
if (this.isProcessingQueue) {
|
if (this.isProcessingQueue) {
|
||||||
logger.debug(
|
logger.debug(
|
||||||
`Queue is already being processed for ${this.documentPrinter.name}`
|
`Queue is already being processed for ${this.documentPrinter.name}`,
|
||||||
);
|
);
|
||||||
return { info: "Queue is already being processed" };
|
return { info: "Queue is already being processed" };
|
||||||
}
|
}
|
||||||
@ -439,7 +470,7 @@ export class DocumentPrinterClient {
|
|||||||
// Re-check connection status before each job
|
// Re-check connection status before each job
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Printer went offline while printing (${this.documentPrinter.name})`
|
`Printer went offline while printing (${this.documentPrinter.name})`,
|
||||||
);
|
);
|
||||||
this.state = {
|
this.state = {
|
||||||
type: "offline",
|
type: "offline",
|
||||||
@ -450,7 +481,7 @@ export class DocumentPrinterClient {
|
|||||||
}
|
}
|
||||||
if (!this.printerInterface) {
|
if (!this.printerInterface) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Printer interface lost while printing (${this.documentPrinter.name})`
|
`Printer interface lost while printing (${this.documentPrinter.name})`,
|
||||||
);
|
);
|
||||||
this.state = {
|
this.state = {
|
||||||
type: "offline",
|
type: "offline",
|
||||||
@ -472,7 +503,7 @@ export class DocumentPrinterClient {
|
|||||||
|
|
||||||
await this.printerInterface.print(jobId);
|
await this.printerInterface.print(jobId);
|
||||||
logger.info(
|
logger.info(
|
||||||
`Successfully printed job ${jobId} for ${this.documentPrinter.name}`
|
`Successfully printed job ${jobId} for ${this.documentPrinter.name}`,
|
||||||
);
|
);
|
||||||
// Only remove job from queue after successful printing
|
// Only remove job from queue after successful printing
|
||||||
this.queue.shift();
|
this.queue.shift();
|
||||||
@ -480,7 +511,7 @@ export class DocumentPrinterClient {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error printing job ${jobId} for ${this.documentPrinter.name}:`,
|
`Error printing job ${jobId} for ${this.documentPrinter.name}:`,
|
||||||
error
|
error,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Remove failed job from queue to prevent infinite retry loop
|
// Remove failed job from queue to prevent infinite retry loop
|
||||||
@ -492,7 +523,7 @@ export class DocumentPrinterClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
`Finished printing all jobs for ${this.documentPrinter.name}`
|
`Finished printing all jobs for ${this.documentPrinter.name}`,
|
||||||
);
|
);
|
||||||
this.state = { type: "standby", message: null };
|
this.state = { type: "standby", message: null };
|
||||||
await this.updateDocumentPrinterState();
|
await this.updateDocumentPrinterState();
|
||||||
@ -513,7 +544,7 @@ export class DocumentPrinterClient {
|
|||||||
await this.printerInterface.disconnect();
|
await this.printerInterface.disconnect();
|
||||||
}
|
}
|
||||||
this.isOnline = false;
|
this.isOnline = false;
|
||||||
this.state = { type: "offline" };
|
this.state = { type: this.active == false ? "inactive" : "offline" };
|
||||||
this.isProcessingQueue = false;
|
this.isProcessingQueue = false;
|
||||||
this.queue = []; // Clear queue on disconnect
|
this.queue = []; // Clear queue on disconnect
|
||||||
await this.updateDocumentPrinterState();
|
await this.updateDocumentPrinterState();
|
||||||
@ -521,4 +552,21 @@ export class DocumentPrinterClient {
|
|||||||
logger.info(`Successfully disconnected from ${this.documentPrinter.name}`);
|
logger.info(`Successfully disconnected from ${this.documentPrinter.name}`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async setInactive() {
|
||||||
|
this.active = false;
|
||||||
|
this.documentPrinter.active = false;
|
||||||
|
this.isOnline = false;
|
||||||
|
await this.disconnect();
|
||||||
|
this.state = { type: "inactive" };
|
||||||
|
await this.updateDocumentPrinterState();
|
||||||
|
}
|
||||||
|
|
||||||
|
async setActive() {
|
||||||
|
this.active = true;
|
||||||
|
this.documentPrinter.active = true;
|
||||||
|
this.shouldReconnect = true;
|
||||||
|
this.isOnline = false;
|
||||||
|
await this.reconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,7 +86,7 @@ export class DocumentPrinterManager {
|
|||||||
logger.debug("Handling document printer update for id:", id);
|
logger.debug("Handling document printer update for id:", id);
|
||||||
const documentPrinter = this.getDocumentPrinterClient(id);
|
const documentPrinter = this.getDocumentPrinterClient(id);
|
||||||
if (documentPrinter) {
|
if (documentPrinter) {
|
||||||
documentPrinter.updateDocumentPrinter(data.object);
|
await documentPrinter.updateDocumentPrinter(data.object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -64,8 +64,8 @@ const App = () => {
|
|||||||
prev.map((printer) =>
|
prev.map((printer) =>
|
||||||
printer._id === newPrinter._id
|
printer._id === newPrinter._id
|
||||||
? _.merge(printer, newPrinter)
|
? _.merge(printer, newPrinter)
|
||||||
: printer
|
: printer,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ const App = () => {
|
|||||||
"setDocumentPrinters",
|
"setDocumentPrinters",
|
||||||
(newDocumentPrinters) => {
|
(newDocumentPrinters) => {
|
||||||
setDocumentPrinters(newDocumentPrinters);
|
setDocumentPrinters(newDocumentPrinters);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
window.electronAPI.onIPCData("setDocumentPrinter", (newDocumentPrinter) => {
|
window.electronAPI.onIPCData("setDocumentPrinter", (newDocumentPrinter) => {
|
||||||
@ -81,8 +81,8 @@ const App = () => {
|
|||||||
prev.map((documentPrinter) =>
|
prev.map((documentPrinter) =>
|
||||||
documentPrinter._id === newDocumentPrinter._id
|
documentPrinter._id === newDocumentPrinter._id
|
||||||
? _.merge(documentPrinter, newDocumentPrinter)
|
? _.merge(documentPrinter, newDocumentPrinter)
|
||||||
: documentPrinter
|
: documentPrinter,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ const App = () => {
|
|||||||
className="ant-menu-horizontal ant-menu-light electron-drag-area"
|
className="ant-menu-horizontal ant-menu-light electron-drag-area"
|
||||||
style={{
|
style={{
|
||||||
lineHeight: "40px",
|
lineHeight: "40px",
|
||||||
padding: "0 8px 0 75px",
|
padding: "0 8px 0 83px",
|
||||||
}}
|
}}
|
||||||
justify="space-between"
|
justify="space-between"
|
||||||
>
|
>
|
||||||
@ -246,6 +246,7 @@ const App = () => {
|
|||||||
flexWrap: "wrap",
|
flexWrap: "wrap",
|
||||||
border: 0,
|
border: 0,
|
||||||
lineHeight: "38px",
|
lineHeight: "38px",
|
||||||
|
marginTop: "1px",
|
||||||
}}
|
}}
|
||||||
overflowedIndicator={
|
overflowedIndicator={
|
||||||
<Button type="text" icon={<MenuOutlined />} />
|
<Button type="text" icon={<MenuOutlined />} />
|
||||||
|
|||||||
@ -60,6 +60,14 @@ const StateTag = ({ state, showBadge = true, style = {} }) => {
|
|||||||
status = "success";
|
status = "success";
|
||||||
text = "Unconsumed";
|
text = "Unconsumed";
|
||||||
break;
|
break;
|
||||||
|
case "inactive":
|
||||||
|
status = "default";
|
||||||
|
text = "Inactive";
|
||||||
|
break;
|
||||||
|
case "connecting":
|
||||||
|
status = "warning";
|
||||||
|
text = "Connecting";
|
||||||
|
break;
|
||||||
case "error":
|
case "error":
|
||||||
status = "error";
|
status = "error";
|
||||||
text = "Error";
|
text = "Error";
|
||||||
|
|||||||
@ -23,7 +23,11 @@ export class PrinterClient {
|
|||||||
this.socketClient = printerManager.socketClient;
|
this.socketClient = printerManager.socketClient;
|
||||||
this.database = new PrinterDatabase(this.socketClient, this.printer);
|
this.database = new PrinterDatabase(this.socketClient, this.printer);
|
||||||
this.printerFileManager = new PrinterFileManager(this);
|
this.printerFileManager = new PrinterFileManager(this);
|
||||||
this.state = { type: "offline", message: "Moonraker disconnected." };
|
this.active = printer.active !== false;
|
||||||
|
this.state =
|
||||||
|
this.active == true
|
||||||
|
? { type: "offline", message: "Moonraker disconnected." }
|
||||||
|
: { type: "inactive" };
|
||||||
this.klippyState = { type: "offline", message: "Klippy disconnected." };
|
this.klippyState = { type: "offline", message: "Klippy disconnected." };
|
||||||
this.config = printer.moonraker;
|
this.config = printer.moonraker;
|
||||||
this.version = printer.version;
|
this.version = printer.version;
|
||||||
@ -37,10 +41,11 @@ export class PrinterClient {
|
|||||||
this.motionObject = {};
|
this.motionObject = {};
|
||||||
this.miscObject = {};
|
this.miscObject = {};
|
||||||
this.currentFilamentStock = printer.currentFilamentStock;
|
this.currentFilamentStock = printer.currentFilamentStock;
|
||||||
this.currentFilament = null;
|
this.currentFilamentSku = null;
|
||||||
this.currentFilamentUsed = 0;
|
this.currentFilamentUsed = 0;
|
||||||
this.registerEventHandlers();
|
this.registerEventHandlers();
|
||||||
this.subscribeToActions();
|
this.subscribeToActions();
|
||||||
|
this.subscribeToObjectUpdates();
|
||||||
this.baseSubscription = {
|
this.baseSubscription = {
|
||||||
print_stats: null,
|
print_stats: null,
|
||||||
display_status: null,
|
display_status: null,
|
||||||
@ -74,32 +79,32 @@ export class PrinterClient {
|
|||||||
registerEventHandlers() {
|
registerEventHandlers() {
|
||||||
// Register event handlers for Moonraker notifications
|
// Register event handlers for Moonraker notifications
|
||||||
this.jsonRpc.registerMethod(
|
this.jsonRpc.registerMethod(
|
||||||
"notify_gcode_response"
|
"notify_gcode_response",
|
||||||
//this.handleGcodeResponse.bind(this),
|
//this.handleGcodeResponse.bind(this),
|
||||||
);
|
);
|
||||||
this.jsonRpc.registerMethod(
|
this.jsonRpc.registerMethod(
|
||||||
"notify_status_update",
|
"notify_status_update",
|
||||||
this.handleStatusUpdate.bind(this)
|
this.handleStatusUpdate.bind(this),
|
||||||
);
|
);
|
||||||
this.jsonRpc.registerMethod(
|
this.jsonRpc.registerMethod(
|
||||||
"notify_klippy_disconnected",
|
"notify_klippy_disconnected",
|
||||||
this.handleKlippyDisconnected.bind(this)
|
this.handleKlippyDisconnected.bind(this),
|
||||||
);
|
);
|
||||||
this.jsonRpc.registerMethod(
|
this.jsonRpc.registerMethod(
|
||||||
"notify_klippy_ready",
|
"notify_klippy_ready",
|
||||||
this.handleKlippyReady.bind(this)
|
this.handleKlippyReady.bind(this),
|
||||||
);
|
);
|
||||||
this.jsonRpc.registerMethod(
|
this.jsonRpc.registerMethod(
|
||||||
"notify_filelist_changed",
|
"notify_filelist_changed",
|
||||||
this.handleFileListChanged.bind(this)
|
this.handleFileListChanged.bind(this),
|
||||||
);
|
);
|
||||||
this.jsonRpc.registerMethod(
|
this.jsonRpc.registerMethod(
|
||||||
"notify_metadata_update",
|
"notify_metadata_update",
|
||||||
this.handleMetadataUpdate.bind(this)
|
this.handleMetadataUpdate.bind(this),
|
||||||
);
|
);
|
||||||
this.jsonRpc.registerMethod(
|
this.jsonRpc.registerMethod(
|
||||||
"notify_power_changed",
|
"notify_power_changed",
|
||||||
this.handlePowerChanged.bind(this)
|
this.handlePowerChanged.bind(this),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +115,31 @@ export class PrinterClient {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subscribeToObjectUpdates() {
|
||||||
|
this.socketClient.subscribeToObjectUpdates({
|
||||||
|
objectType: "printer",
|
||||||
|
_id: this.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async updatePrinter(data) {
|
||||||
|
logger.debug(`Updating printer ${this.id} with data...`);
|
||||||
|
this.printer = { ...this.printer, ...data };
|
||||||
|
this.database.printer = this.printer;
|
||||||
|
|
||||||
|
if (data?.moonraker) {
|
||||||
|
this.config = data.moonraker;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.hasOwn(data || {}, "active") && data.active != this.active) {
|
||||||
|
if (data.active == true) {
|
||||||
|
await this.setActive();
|
||||||
|
} else {
|
||||||
|
await this.setInactive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async _runQueueMutation(task) {
|
async _runQueueMutation(task) {
|
||||||
const executeTask = async () => task();
|
const executeTask = async () => task();
|
||||||
this.queueMutationChain = this.queueMutationChain
|
this.queueMutationChain = this.queueMutationChain
|
||||||
@ -119,6 +149,15 @@ export class PrinterClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async connect() {
|
async connect() {
|
||||||
|
if (this.active == false) {
|
||||||
|
logger.info(`Printer ${this.id} is not active, skipping connection`);
|
||||||
|
this.shouldReconnect = false;
|
||||||
|
this.isOnline = false;
|
||||||
|
this.state = { type: "inactive" };
|
||||||
|
await this.updatePrinterState();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const { protocol, host, port } = this.config;
|
const { protocol, host, port } = this.config;
|
||||||
const wsUrl = `${protocol}://${host}:${port}/websocket`;
|
const wsUrl = `${protocol}://${host}:${port}/websocket`;
|
||||||
|
|
||||||
@ -143,7 +182,10 @@ export class PrinterClient {
|
|||||||
this.socket.addEventListener("close", () => {
|
this.socket.addEventListener("close", () => {
|
||||||
logger.info(`Disconnected from Moonraker (${this.printer.name})`);
|
logger.info(`Disconnected from Moonraker (${this.printer.name})`);
|
||||||
this.isOnline = false;
|
this.isOnline = false;
|
||||||
this.state = { type: "offline", message: "Moonraker disconnected." };
|
this.state =
|
||||||
|
this.active == true
|
||||||
|
? { type: "offline", message: "Moonraker disconnected." }
|
||||||
|
: { type: "inactive" };
|
||||||
this.connectedAt = null;
|
this.connectedAt = null;
|
||||||
this.updatePrinterState();
|
this.updatePrinterState();
|
||||||
this.connectionId = null;
|
this.connectionId = null;
|
||||||
@ -182,14 +224,14 @@ export class PrinterClient {
|
|||||||
.then(async (result) => {
|
.then(async (result) => {
|
||||||
this.connectionId = result.connection_id;
|
this.connectionId = result.connection_id;
|
||||||
logger.info(
|
logger.info(
|
||||||
`Connection identified with ID: ${this.connectionId} (${this.printer.name})`
|
`Connection identified with ID: ${this.connectionId} (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
await this.initialize();
|
await this.initialize();
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error identifying connection (${this.printer.name}):`,
|
`Error identifying connection (${this.printer.name}):`,
|
||||||
error
|
error,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -207,7 +249,7 @@ export class PrinterClient {
|
|||||||
await this.syncSubJobs();
|
await this.syncSubJobs();
|
||||||
this.eventUpdateInterval = setInterval(
|
this.eventUpdateInterval = setInterval(
|
||||||
this.handleEventUpdate.bind(this),
|
this.handleEventUpdate.bind(this),
|
||||||
500
|
500,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,20 +263,20 @@ export class PrinterClient {
|
|||||||
logger.info(
|
logger.info(
|
||||||
"Server:",
|
"Server:",
|
||||||
`Moonraker ${serverResult.moonraker_version} (${this.printer.name})`,
|
`Moonraker ${serverResult.moonraker_version} (${this.printer.name})`,
|
||||||
`State: ${this.klippyState.type}`
|
`State: ${this.klippyState.type}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const klippyResult = await this.jsonRpc.callMethod("printer.info");
|
const klippyResult = await this.jsonRpc.callMethod("printer.info");
|
||||||
logger.info(
|
logger.info(
|
||||||
`Klippy info for ${this.printer.name}: ${klippyResult.hostname}, ${klippyResult.software_version}`
|
`Klippy info for ${this.printer.name}: ${klippyResult.hostname}, ${klippyResult.software_version}`,
|
||||||
);
|
);
|
||||||
// Update firmware version in database
|
// Update firmware version in database
|
||||||
await this.database.updatePrinterFirmware(
|
await this.database.updatePrinterFirmware(
|
||||||
klippyResult.software_version
|
klippyResult.software_version,
|
||||||
);
|
);
|
||||||
logger.info(
|
logger.info(
|
||||||
`Updated firmware version for ${this.printer.name} to ${klippyResult.software_version}`
|
`Updated firmware version for ${this.printer.name} to ${klippyResult.software_version}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (klippyResult.state === "error" && klippyResult.state_message) {
|
if (klippyResult.state === "error" && klippyResult.state_message) {
|
||||||
@ -245,7 +287,7 @@ export class PrinterClient {
|
|||||||
type: "error",
|
type: "error",
|
||||||
message: klippyResult.state_message,
|
message: klippyResult.state_message,
|
||||||
actions: ["restartPrinter"],
|
actions: ["restartPrinter"],
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +299,7 @@ export class PrinterClient {
|
|||||||
type: "error",
|
type: "error",
|
||||||
message: klippyResult.state_message,
|
message: klippyResult.state_message,
|
||||||
actions: ["restartPrinter"],
|
actions: ["restartPrinter"],
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,19 +311,19 @@ export class PrinterClient {
|
|||||||
message: klippyResult.state_message,
|
message: klippyResult.state_message,
|
||||||
priority: 8,
|
priority: 8,
|
||||||
timestamp: new Date(),
|
timestamp: new Date(),
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error getting Klippy info for ${this.printer.name}:`,
|
`Error getting Klippy info for ${this.printer.name}:`,
|
||||||
error
|
error,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error getting server info for ${this.printer.name}:`,
|
`Error getting server info for ${this.printer.name}:`,
|
||||||
error
|
error,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,7 +336,7 @@ export class PrinterClient {
|
|||||||
for (const file of result) {
|
for (const file of result) {
|
||||||
if (file.path.startsWith("farmcontrol/")) {
|
if (file.path.startsWith("farmcontrol/")) {
|
||||||
this.printrFileIds.push(
|
this.printrFileIds.push(
|
||||||
file.path.replace("farmcontrol/", "").replace(".gcode", "")
|
file.path.replace("farmcontrol/", "").replace(".gcode", ""),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -305,17 +347,17 @@ export class PrinterClient {
|
|||||||
logger.info(`Getting current filament for printer: ${this.printer.name}`);
|
logger.info(`Getting current filament for printer: ${this.printer.name}`);
|
||||||
if (!this.currentFilamentStock || !this.currentFilamentStock?._id) {
|
if (!this.currentFilamentStock || !this.currentFilamentStock?._id) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`No current filament stock found for printer: ${this.printer.name}`
|
`No current filament stock found for printer: ${this.printer.name}`,
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const result = await this.socketClient.getObject({
|
const result = await this.socketClient.getObject({
|
||||||
objectType: "filamentStock",
|
objectType: "filamentStock",
|
||||||
_id: this.currentFilamentStock._id,
|
_id: this.currentFilamentStock._id,
|
||||||
populate: ["filament"],
|
populate: ["filamentSku"],
|
||||||
});
|
});
|
||||||
this.currentFilament = result.filament;
|
this.currentFilamentSku = result.filamentSku;
|
||||||
return this.currentFilament;
|
return this.currentFilamentSku;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getQueuedJobIds() {
|
async getQueuedJobIds() {
|
||||||
@ -332,7 +374,7 @@ export class PrinterClient {
|
|||||||
logger.info(`Getting state of (${this.printer.name})`);
|
logger.info(`Getting state of (${this.printer.name})`);
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot send command: Not connected to Moonraker. (${this.printer.name})`
|
`Cannot send command: Not connected to Moonraker. (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -354,7 +396,7 @@ export class PrinterClient {
|
|||||||
try {
|
try {
|
||||||
const result = await this.jsonRpc.callMethodWithKwargs(
|
const result = await this.jsonRpc.callMethodWithKwargs(
|
||||||
"printer.objects.query",
|
"printer.objects.query",
|
||||||
{ objects: this.baseSubscription }
|
{ objects: this.baseSubscription },
|
||||||
);
|
);
|
||||||
logger.debug(`Command sent to ${this.printer.name}`);
|
logger.debug(`Command sent to ${this.printer.name}`);
|
||||||
if (result.status != undefined) {
|
if (result.status != undefined) {
|
||||||
@ -380,12 +422,12 @@ export class PrinterClient {
|
|||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Combined subscriptions:",
|
"Combined subscriptions:",
|
||||||
Object.keys(allSubscriptions).join(", ")
|
Object.keys(allSubscriptions).join(", "),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot send command: Not connected to Moonraker (${this.printer.name})`
|
`Cannot send command: Not connected to Moonraker (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -406,7 +448,7 @@ export class PrinterClient {
|
|||||||
logger.info(`Sending ${command.method} command to (${this.printer.name})`);
|
logger.info(`Sending ${command.method} command to (${this.printer.name})`);
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot send command: Not connected to Moonraker (${this.printer.name})`
|
`Cannot send command: Not connected to Moonraker (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -414,7 +456,7 @@ export class PrinterClient {
|
|||||||
try {
|
try {
|
||||||
const result = await this.jsonRpc.callMethodWithKwargs(
|
const result = await this.jsonRpc.callMethodWithKwargs(
|
||||||
command.method,
|
command.method,
|
||||||
command.params
|
command.params,
|
||||||
);
|
);
|
||||||
logger.debug(`Command sent to ${this.printer.name}`);
|
logger.debug(`Command sent to ${this.printer.name}`);
|
||||||
if (result.status != undefined) {
|
if (result.status != undefined) {
|
||||||
@ -443,7 +485,7 @@ export class PrinterClient {
|
|||||||
const oldState = this.state.type;
|
const oldState = this.state.type;
|
||||||
if (newState !== oldState) {
|
if (newState !== oldState) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`Printer ${this.printer.name} state changed from ${this.state.type} to ${newState}`
|
`Printer ${this.printer.name} state changed from ${this.state.type} to ${newState}`,
|
||||||
);
|
);
|
||||||
if (oldState == "printing" && newState == "complete") {
|
if (oldState == "printing" && newState == "complete") {
|
||||||
printerFinished = true;
|
printerFinished = true;
|
||||||
@ -476,7 +518,7 @@ export class PrinterClient {
|
|||||||
const newProgress = status.display_status.progress;
|
const newProgress = status.display_status.progress;
|
||||||
if (newProgress !== this.state.progress) {
|
if (newProgress !== this.state.progress) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`Printer ${this.printer.name} progress changed from ${this.state.progress} to ${newProgress}`
|
`Printer ${this.printer.name} progress changed from ${this.state.progress} to ${newProgress}`,
|
||||||
);
|
);
|
||||||
this.state.progress = newProgress;
|
this.state.progress = newProgress;
|
||||||
progressChanged = true;
|
progressChanged = true;
|
||||||
@ -639,7 +681,7 @@ export class PrinterClient {
|
|||||||
if (newFilamentDetected !== this.filamentDetected) {
|
if (newFilamentDetected !== this.filamentDetected) {
|
||||||
console.log(status["filament_switch_sensor fsensor"]);
|
console.log(status["filament_switch_sensor fsensor"]);
|
||||||
logger.info(
|
logger.info(
|
||||||
`Printer ${this.printer.name} filament detection changed from ${this.filamentDetected} to ${newFilamentDetected}.`
|
`Printer ${this.printer.name} filament detection changed from ${this.filamentDetected} to ${newFilamentDetected}.`,
|
||||||
);
|
);
|
||||||
this.filamentDetected = newFilamentDetected;
|
this.filamentDetected = newFilamentDetected;
|
||||||
|
|
||||||
@ -701,11 +743,11 @@ export class PrinterClient {
|
|||||||
if (stateChanged == true) {
|
if (stateChanged == true) {
|
||||||
if (printerFinished == true && isCurrentJobSubJob == true) {
|
if (printerFinished == true && isCurrentJobSubJob == true) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`Subjob ${this.currentSubJob._id} completed, posting part stock items for printer ${this.id}`
|
`Subjob ${this.currentSubJob._id} completed, posting part stock items for printer ${this.id}`,
|
||||||
);
|
);
|
||||||
await this.database.setSubJobFinishedAt(
|
await this.database.setSubJobFinishedAt(
|
||||||
this.currentSubJob._id,
|
this.currentSubJob._id,
|
||||||
new Date()
|
new Date(),
|
||||||
);
|
);
|
||||||
await this.database.postSubJobPartStockItems(this.currentSubJob._id);
|
await this.database.postSubJobPartStockItems(this.currentSubJob._id);
|
||||||
}
|
}
|
||||||
@ -720,7 +762,7 @@ export class PrinterClient {
|
|||||||
this.currentSubJob.startedAt = new Date();
|
this.currentSubJob.startedAt = new Date();
|
||||||
await this.database.setSubJobStartedAt(
|
await this.database.setSubJobStartedAt(
|
||||||
this.currentSubJob._id,
|
this.currentSubJob._id,
|
||||||
new Date()
|
new Date(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (this.currentJob.startedAt == null) {
|
if (this.currentJob.startedAt == null) {
|
||||||
@ -738,7 +780,7 @@ export class PrinterClient {
|
|||||||
};
|
};
|
||||||
await this.database.updateSubJobState(
|
await this.database.updateSubJobState(
|
||||||
this.currentSubJob._id,
|
this.currentSubJob._id,
|
||||||
subJobState
|
subJobState,
|
||||||
);
|
);
|
||||||
await this.database.updateJobState(this.currentJob._id);
|
await this.database.updateJobState(this.currentJob._id);
|
||||||
}
|
}
|
||||||
@ -780,13 +822,13 @@ export class PrinterClient {
|
|||||||
) {
|
) {
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"Updating stock event value:",
|
"Updating stock event value:",
|
||||||
this.currentFilamentUsed.toFixed(2)
|
this.currentFilamentUsed.toFixed(2),
|
||||||
);
|
);
|
||||||
this.database.updateFilamentStockWeight(
|
this.database.updateFilamentStockWeight(
|
||||||
this.currentFilamentStock,
|
this.currentFilamentStock,
|
||||||
this.currentFilamentUsed,
|
this.currentFilamentUsed,
|
||||||
this.currentSubJob,
|
this.currentSubJob,
|
||||||
this.currentJob
|
this.currentJob,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -794,11 +836,15 @@ export class PrinterClient {
|
|||||||
async updatePrinterState() {
|
async updatePrinterState() {
|
||||||
try {
|
try {
|
||||||
const state =
|
const state =
|
||||||
this.klippyState.type !== "ready" ? this.klippyState : this.state;
|
this.active == false
|
||||||
|
? { type: "inactive" }
|
||||||
|
: this.klippyState.type !== "ready"
|
||||||
|
? this.klippyState
|
||||||
|
: this.state;
|
||||||
await this.database.updatePrinterState(
|
await this.database.updatePrinterState(
|
||||||
state,
|
state,
|
||||||
this.isOnline,
|
this.isOnline,
|
||||||
this.connectedAt
|
this.connectedAt,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(`Failed to update printer state:`, error);
|
logger.error(`Failed to update printer state:`, error);
|
||||||
@ -822,11 +868,11 @@ export class PrinterClient {
|
|||||||
const serverSubJobs = await this.database.getQueuedSubJobs();
|
const serverSubJobs = await this.database.getQueuedSubJobs();
|
||||||
|
|
||||||
const queuedSubJobs = serverSubJobs.filter((subJob) =>
|
const queuedSubJobs = serverSubJobs.filter((subJob) =>
|
||||||
this.queuedJobIds.includes(subJob.moonrakerJobId)
|
this.queuedJobIds.includes(subJob.moonrakerJobId),
|
||||||
);
|
);
|
||||||
|
|
||||||
const unqueuedSubJobs = serverSubJobs.filter(
|
const unqueuedSubJobs = serverSubJobs.filter(
|
||||||
(subJob) => !this.queuedJobIds.includes(subJob.moonrakerJobId)
|
(subJob) => !this.queuedJobIds.includes(subJob.moonrakerJobId),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.queue = queuedSubJobs;
|
this.queue = queuedSubJobs;
|
||||||
@ -850,7 +896,7 @@ export class PrinterClient {
|
|||||||
printingTypes.includes(stateType)
|
printingTypes.includes(stateType)
|
||||||
) {
|
) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`No current subjob or job, setting first unqueued subjob as current...`
|
`No current subjob or job, setting first unqueued subjob as current...`,
|
||||||
);
|
);
|
||||||
const targetSubJob = unqueuedSubJobs[0];
|
const targetSubJob = unqueuedSubJobs[0];
|
||||||
const targetJob = await this.database.getJobById(targetSubJob.job);
|
const targetJob = await this.database.getJobById(targetSubJob.job);
|
||||||
@ -869,7 +915,7 @@ export class PrinterClient {
|
|||||||
});
|
});
|
||||||
this.currentSubJob.state.type = stateType;
|
this.currentSubJob.state.type = stateType;
|
||||||
this.currentJob.state = await this.database.updateJobState(
|
this.currentJob.state = await this.database.updateJobState(
|
||||||
this.currentJob._id
|
this.currentJob._id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -941,7 +987,7 @@ export class PrinterClient {
|
|||||||
handleMetadataUpdate(metadata) {
|
handleMetadataUpdate(metadata) {
|
||||||
logger.info(
|
logger.info(
|
||||||
`Metadata updated for ${this.printer.name}:`,
|
`Metadata updated for ${this.printer.name}:`,
|
||||||
metadata.filename
|
metadata.filename,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,7 +999,7 @@ export class PrinterClient {
|
|||||||
logger.info(`Uploading G-code file ${fileName} to ${this.printer.name}`);
|
logger.info(`Uploading G-code file ${fileName} to ${this.printer.name}`);
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot upload file: Not connected to Moonraker (${this.printer.name})`
|
`Cannot upload file: Not connected to Moonraker (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -986,14 +1032,14 @@ export class PrinterClient {
|
|||||||
headers,
|
headers,
|
||||||
onUploadProgress: (progressEvent) => {
|
onUploadProgress: (progressEvent) => {
|
||||||
const percentCompleted = Math.round(
|
const percentCompleted = Math.round(
|
||||||
(progressEvent.loaded * 100) / progressEvent.total
|
(progressEvent.loaded * 100) / progressEvent.total,
|
||||||
);
|
);
|
||||||
logger.debug(
|
logger.debug(
|
||||||
`Uploading file to ${this.printer.name}: ` +
|
`Uploading file to ${this.printer.name}: ` +
|
||||||
fileName +
|
fileName +
|
||||||
" " +
|
" " +
|
||||||
percentCompleted +
|
percentCompleted +
|
||||||
"%"
|
"%",
|
||||||
);
|
);
|
||||||
this.socketManager.broadcast("notify_printer_update", {
|
this.socketManager.broadcast("notify_printer_update", {
|
||||||
printerId: this.id,
|
printerId: this.id,
|
||||||
@ -1011,7 +1057,7 @@ export class PrinterClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
`Successfully uploaded file ${fileName} to ${this.printer.name}`
|
`Successfully uploaded file ${fileName} to ${this.printer.name}`,
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -1024,7 +1070,7 @@ export class PrinterClient {
|
|||||||
// Add subJob to queue
|
// Add subJob to queue
|
||||||
this.deploySubJobQueue.push(subJob);
|
this.deploySubJobQueue.push(subJob);
|
||||||
logger.debug(
|
logger.debug(
|
||||||
`Queued sub job ${subJob._id} for deployment. Queue size: ${this.deploySubJobQueue.length}`
|
`Queued sub job ${subJob._id} for deployment. Queue size: ${this.deploySubJobQueue.length}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
@ -1065,7 +1111,7 @@ export class PrinterClient {
|
|||||||
this.deploySubJobQueue = [];
|
this.deploySubJobQueue = [];
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
`Processing ${subJobsToDeploy.length} queued sub job(s) for printer ${this.id}`
|
`Processing ${subJobsToDeploy.length} queued sub job(s) for printer ${this.id}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Process sub jobs in parallel with a 250ms stagger between starts
|
// Process sub jobs in parallel with a 250ms stagger between starts
|
||||||
@ -1082,10 +1128,10 @@ export class PrinterClient {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error deploying sub job ${subJob._id} to printer ${this.id}:`,
|
`Error deploying sub job ${subJob._id} to printer ${this.id}:`,
|
||||||
error
|
error,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})()
|
})(),
|
||||||
);
|
);
|
||||||
|
|
||||||
await Promise.all(deployPromises);
|
await Promise.all(deployPromises);
|
||||||
@ -1098,7 +1144,7 @@ export class PrinterClient {
|
|||||||
"to printer:",
|
"to printer:",
|
||||||
this.id,
|
this.id,
|
||||||
"with gcode file:",
|
"with gcode file:",
|
||||||
`${subJob.gcodeFile.name}`
|
`${subJob.gcodeFile.name}`,
|
||||||
);
|
);
|
||||||
const gcodeFile = await this.socketClient.getObject({
|
const gcodeFile = await this.socketClient.getObject({
|
||||||
objectType: "gcodeFile",
|
objectType: "gcodeFile",
|
||||||
@ -1117,7 +1163,7 @@ export class PrinterClient {
|
|||||||
progress: (progress / 100 / 2).toFixed(2),
|
progress: (progress / 100 / 2).toFixed(2),
|
||||||
});
|
});
|
||||||
await this.database.updateJobState(subJob.job._id);
|
await this.database.updateJobState(subJob.job._id);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
throw new Error("Error getting file");
|
throw new Error("Error getting file");
|
||||||
@ -1134,7 +1180,7 @@ export class PrinterClient {
|
|||||||
progress: (progress / 100 / 2 + 0.5).toFixed(2),
|
progress: (progress / 100 / 2 + 0.5).toFixed(2),
|
||||||
});
|
});
|
||||||
await this.database.updateJobState(subJob.job._id);
|
await this.database.updateJobState(subJob.job._id);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
this.printrFileIds.push(gcodeFile.file.toString());
|
this.printrFileIds.push(gcodeFile.file.toString());
|
||||||
if (!uploadResult) {
|
if (!uploadResult) {
|
||||||
@ -1161,7 +1207,7 @@ export class PrinterClient {
|
|||||||
const mostRecentQueuedJob = queuedJobs[queuedJobs.length - 1];
|
const mostRecentQueuedJob = queuedJobs[queuedJobs.length - 1];
|
||||||
const updatedSubJob = await this.database.setSubJobMoonrakerJobId(
|
const updatedSubJob = await this.database.setSubJobMoonrakerJobId(
|
||||||
subJob._id,
|
subJob._id,
|
||||||
mostRecentQueuedJob.job_id
|
mostRecentQueuedJob.job_id,
|
||||||
);
|
);
|
||||||
await this.database.updateSubJobState(subJob._id, {
|
await this.database.updateSubJobState(subJob._id, {
|
||||||
type: "queued",
|
type: "queued",
|
||||||
@ -1206,7 +1252,7 @@ export class PrinterClient {
|
|||||||
|
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot set temperature: Not connected to Moonraker (${this.printer.name})`
|
`Cannot set temperature: Not connected to Moonraker (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1217,20 +1263,20 @@ export class PrinterClient {
|
|||||||
// Handle extruder temperature
|
// Handle extruder temperature
|
||||||
if (temperature.extruder?.target !== undefined) {
|
if (temperature.extruder?.target !== undefined) {
|
||||||
gcodeCommands.push(
|
gcodeCommands.push(
|
||||||
`SET_HEATER_TEMPERATURE HEATER=extruder TARGET=${temperature.extruder.target}`
|
`SET_HEATER_TEMPERATURE HEATER=extruder TARGET=${temperature.extruder.target}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle bed temperature
|
// Handle bed temperature
|
||||||
if (temperature.bed?.target !== undefined) {
|
if (temperature.bed?.target !== undefined) {
|
||||||
gcodeCommands.push(
|
gcodeCommands.push(
|
||||||
`SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=${temperature.bed.target}`
|
`SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=${temperature.bed.target}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gcodeCommands.length === 0) {
|
if (gcodeCommands.length === 0) {
|
||||||
logger.warn(
|
logger.warn(
|
||||||
`No valid temperature targets provided for ${this.printer.name}`
|
`No valid temperature targets provided for ${this.printer.name}`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1245,7 +1291,7 @@ export class PrinterClient {
|
|||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Failed to set temperature with command: ${gcodeCommand}`
|
`Failed to set temperature with command: ${gcodeCommand}`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1258,7 +1304,7 @@ export class PrinterClient {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error setting temperature for ${this.printer.name}:`,
|
`Error setting temperature for ${this.printer.name}:`,
|
||||||
error
|
error,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1268,7 +1314,7 @@ export class PrinterClient {
|
|||||||
logger.info(`Restarting printer firmware for ${this.printer.name}`);
|
logger.info(`Restarting printer firmware for ${this.printer.name}`);
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot restart printer firmware: Not connected to Moonraker (${this.printer.name})`
|
`Cannot restart printer firmware: Not connected to Moonraker (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1281,13 +1327,13 @@ export class PrinterClient {
|
|||||||
throw new Error("Failed to restart printer firmware");
|
throw new Error("Failed to restart printer firmware");
|
||||||
}
|
}
|
||||||
logger.info(
|
logger.info(
|
||||||
`Successfully restarted printer firmware for ${this.printer.name}`
|
`Successfully restarted printer firmware for ${this.printer.name}`,
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error restarting printer firmware for ${this.printer.name}:`,
|
`Error restarting printer firmware for ${this.printer.name}:`,
|
||||||
error
|
error,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1297,7 +1343,7 @@ export class PrinterClient {
|
|||||||
logger.info(`Restarting printer for ${this.printer.name}`);
|
logger.info(`Restarting printer for ${this.printer.name}`);
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot restart printer: Not connected to Moonraker (${this.printer.name})`
|
`Cannot restart printer: Not connected to Moonraker (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1320,7 +1366,7 @@ export class PrinterClient {
|
|||||||
logger.info(`Restarting moonraker server for ${this.printer.name}`);
|
logger.info(`Restarting moonraker server for ${this.printer.name}`);
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot restart moonraker server: Not connected to moonraker server (${this.printer.name})`
|
`Cannot restart moonraker server: Not connected to moonraker server (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1333,13 +1379,13 @@ export class PrinterClient {
|
|||||||
throw new Error("Failed to restart moonraker server");
|
throw new Error("Failed to restart moonraker server");
|
||||||
}
|
}
|
||||||
logger.info(
|
logger.info(
|
||||||
`Successfully restarted moonraker server for ${this.printer.name}`
|
`Successfully restarted moonraker server for ${this.printer.name}`,
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Error restarting moonraker server for ${this.printer.name}:`,
|
`Error restarting moonraker server for ${this.printer.name}:`,
|
||||||
error
|
error,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1349,7 +1395,7 @@ export class PrinterClient {
|
|||||||
logger.info(`Starting queue for ${this.printer.name}`);
|
logger.info(`Starting queue for ${this.printer.name}`);
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot start queue: Not connected to Moonraker (${this.printer.name})`
|
`Cannot start queue: Not connected to Moonraker (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1372,7 +1418,7 @@ export class PrinterClient {
|
|||||||
logger.info(`Pausing job for ${this.printer.name}`);
|
logger.info(`Pausing job for ${this.printer.name}`);
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot pause job: Not connected to Moonraker (${this.printer.name})`
|
`Cannot pause job: Not connected to Moonraker (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1395,7 +1441,7 @@ export class PrinterClient {
|
|||||||
logger.info(`Resuming job for ${this.printer.name}`);
|
logger.info(`Resuming job for ${this.printer.name}`);
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot resume job: Not connected to Moonraker (${this.printer.name})`
|
`Cannot resume job: Not connected to Moonraker (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1418,7 +1464,7 @@ export class PrinterClient {
|
|||||||
logger.info(`Cancelling job for ${this.printer.name}`);
|
logger.info(`Cancelling job for ${this.printer.name}`);
|
||||||
if (!this.isOnline) {
|
if (!this.isOnline) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Cannot cancel job: Not connected to Moonraker (${this.printer.name})`
|
`Cannot cancel job: Not connected to Moonraker (${this.printer.name})`,
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1477,4 +1523,26 @@ export class PrinterClient {
|
|||||||
logger.info(`Successfully disconnected from ${this.printer.name}`);
|
logger.info(`Successfully disconnected from ${this.printer.name}`);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async setInactive() {
|
||||||
|
this.active = false;
|
||||||
|
this.printer.active = false;
|
||||||
|
this.database.printer = this.printer;
|
||||||
|
this.isOnline = false;
|
||||||
|
await this.disconnect();
|
||||||
|
this.state = { type: "inactive" };
|
||||||
|
this.klippyState = { type: "inactive" };
|
||||||
|
this.connectedAt = null;
|
||||||
|
await this.updatePrinterState();
|
||||||
|
}
|
||||||
|
|
||||||
|
async setActive() {
|
||||||
|
this.active = true;
|
||||||
|
this.printer.active = true;
|
||||||
|
this.database.printer = this.printer;
|
||||||
|
this.klippyState = { type: "offline", message: "Klippy disconnected." };
|
||||||
|
this.shouldReconnect = true;
|
||||||
|
this.isOnline = false;
|
||||||
|
await this.connect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -119,7 +119,7 @@ export class PrinterManager {
|
|||||||
return;
|
return;
|
||||||
case "loadFilamentStock":
|
case "loadFilamentStock":
|
||||||
const loadFilamentStockResult = await printer.loadFilamentStock(
|
const loadFilamentStockResult = await printer.loadFilamentStock(
|
||||||
action.data.filamentStock
|
action.data.filamentStock,
|
||||||
);
|
);
|
||||||
callback(loadFilamentStockResult);
|
callback(loadFilamentStockResult);
|
||||||
return;
|
return;
|
||||||
@ -127,6 +127,14 @@ export class PrinterManager {
|
|||||||
callback({ error: "Unknown command." });
|
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) {
|
getPrinterClient(printerId) {
|
||||||
return this.printerClients.get(printerId);
|
return this.printerClients.get(printerId);
|
||||||
}
|
}
|
||||||
@ -138,7 +146,7 @@ export class PrinterManager {
|
|||||||
// Close all printer connections
|
// Close all printer connections
|
||||||
async closeAllConnections() {
|
async closeAllConnections() {
|
||||||
logger.info(
|
logger.info(
|
||||||
`Closing all printer connections... current count: ${this.printerClients.size}`
|
`Closing all printer connections... current count: ${this.printerClients.size}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Take a snapshot so any mutations during disconnects don't affect iteration
|
// Take a snapshot so any mutations during disconnects don't affect iteration
|
||||||
@ -150,14 +158,14 @@ export class PrinterManager {
|
|||||||
printerClient.shouldReconnect = false;
|
printerClient.shouldReconnect = false;
|
||||||
await printerClient.disconnect();
|
await printerClient.disconnect();
|
||||||
logger.info(
|
logger.info(
|
||||||
`Disconnected printer client ${printerClient?.id || "unknown"}`
|
`Disconnected printer client ${printerClient?.id || "unknown"}`,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(
|
logger.error(
|
||||||
`Failed to disconnect printer client ${
|
`Failed to disconnect printer client ${
|
||||||
printerClient?.id || "unknown"
|
printerClient?.id || "unknown"
|
||||||
}:`,
|
}:`,
|
||||||
error
|
error,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,7 +177,7 @@ export class PrinterManager {
|
|||||||
this.printers = [];
|
this.printers = [];
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
`All printer connections closed. Remaining clients: ${this.printerClients.size}`
|
`All printer connections closed. Remaining clients: ${this.printerClients.size}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -216,6 +216,9 @@ export class SocketClient {
|
|||||||
callback
|
callback
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (data.objectType == "printer") {
|
||||||
|
this.printerManager.handlePrinterUpdate(data._id, data, callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleConnect() {
|
handleConnect() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user