All checks were successful
farmcontrol/farmcontrol-server/pipeline/head This commit looks good
- Introduced a `getDocumentSizeId` utility function to streamline document size ID retrieval. - Updated `DocumentPrinterClient` to manage subscriptions for current document sizes, ensuring accurate updates and handling of document size changes. - Enhanced `DocumentPrinterManager` to handle document size updates and propagate changes to connected clients. - Improved `CupsInterface` and `ReceiptInterface` to support document size resolution and default media application based on current document sizes. - Added detailed logging for document size updates and error handling to improve debugging and user feedback.
854 lines
22 KiB
JavaScript
854 lines
22 KiB
JavaScript
import log4js from "log4js";
|
|
import { WebSocketScanner } from "../network/websocketScanner.js";
|
|
import { io } from "socket.io-client";
|
|
import axios from "axios";
|
|
// Load configuration
|
|
import { loadConfig } from "../config.js";
|
|
import { sendIPC } from "../desktop/notify.js";
|
|
import { PrinterManager } from "../printer/printermanager.js";
|
|
import { HostManager } from "../host/hostmanager.js";
|
|
import { FileManager } from "../files/filemanager.js";
|
|
import { DocumentPrinterManager } from "../documentprinter/documentprintermanager.js";
|
|
import { startWaiting, stopWaiting } from "../spinner.js";
|
|
|
|
const config = loadConfig();
|
|
|
|
const logger = log4js.getLogger("Socket Client");
|
|
logger.level = config.logLevel;
|
|
|
|
export class SocketClient {
|
|
constructor() {
|
|
this.socket = null;
|
|
this.authenticated = false;
|
|
this.connected = false;
|
|
this.loading = false;
|
|
this.reconnectTimeout = null;
|
|
this.hostManager = new HostManager(this);
|
|
this.fileManager = new FileManager(this);
|
|
this.printerManager = new PrinterManager(this);
|
|
this.documentPrinterManager = new DocumentPrinterManager(this);
|
|
this.scanner = new WebSocketScanner({ maxThreads: 50 });
|
|
this.readLine = null;
|
|
this.objectEventCallbacks = new Map();
|
|
sendIPC("setOnline", false);
|
|
sendIPC("setAuthenticated", false);
|
|
sendIPC("setLoading", false);
|
|
}
|
|
|
|
get id() {
|
|
return this.hostManager.id;
|
|
}
|
|
|
|
get host() {
|
|
return this.hostManager.host;
|
|
}
|
|
|
|
setupSocketEventHandlers() {
|
|
this.socket.on("connect", this.handleConnect.bind(this));
|
|
this.socket.on("connect_error", this.handleError.bind(this));
|
|
this.socket.on("objectUpdate", this.handleObjectUpdate.bind(this));
|
|
this.socket.on("objectAction", this.handleObjectAction.bind(this));
|
|
this.socket.on("objectEvent", this.handleObjectEvent.bind(this));
|
|
this.socket.on("disconnect", this.handleDisconnect.bind(this));
|
|
}
|
|
|
|
scheduleReconnect() {
|
|
// Clear any pending reconnect timeout
|
|
if (this.reconnectTimeout) {
|
|
clearTimeout(this.reconnectTimeout);
|
|
this.reconnectTimeout = null;
|
|
}
|
|
|
|
startWaiting("Will attempt to reconnect in 3 seconds...", logger);
|
|
this.reconnectTimeout = setTimeout(async () => {
|
|
await stopWaiting();
|
|
this.connect();
|
|
}, 3000);
|
|
}
|
|
|
|
async connect() {
|
|
try {
|
|
await stopWaiting();
|
|
startWaiting(`Connecting to Socket.IO server: ${config.url}`, logger);
|
|
this.socket = io(config.url, {
|
|
auth: { type: "host" },
|
|
reconnection: false,
|
|
timeout: 3000, // 3 second timeout
|
|
});
|
|
this.loading = true;
|
|
sendIPC("setLoading", true);
|
|
this.connected = false;
|
|
sendIPC("setConnected", false);
|
|
this.authenticated = false;
|
|
sendIPC("setAuthenticated", false);
|
|
this.setupSocketEventHandlers();
|
|
} catch (error) {
|
|
await stopWaiting();
|
|
logger.error("Failed to create Socket.IO connection:", error);
|
|
}
|
|
}
|
|
|
|
disconnect() {
|
|
this.hostManager.unsubscribeFromObjectEvents();
|
|
this.socket.disconnect();
|
|
}
|
|
|
|
async waitForConnection(timeoutMs = 10000) {
|
|
if (this.socket?.connected) {
|
|
return;
|
|
}
|
|
|
|
if (!this.socket) {
|
|
throw new Error("Socket client is not connected");
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
const timeout = setTimeout(() => {
|
|
this.socket.off("connect", onConnect);
|
|
reject(new Error("Socket connection timed out"));
|
|
}, timeoutMs);
|
|
|
|
const onConnect = () => {
|
|
clearTimeout(timeout);
|
|
resolve();
|
|
};
|
|
|
|
if (this.socket.connected) {
|
|
clearTimeout(timeout);
|
|
resolve();
|
|
return;
|
|
}
|
|
|
|
this.socket.once("connect", onConnect);
|
|
});
|
|
}
|
|
|
|
authenticateWithOtp(otp, options) {
|
|
return this.hostManager.authenticateWithOtp(otp, options);
|
|
}
|
|
|
|
authenticate(authenticationData, options) {
|
|
return this.hostManager.authenticate(authenticationData, options);
|
|
}
|
|
|
|
handleObjectAction(data, callback) {
|
|
logger.debug("Running object action...", data);
|
|
const id = data._id;
|
|
const objectType = data.objectType;
|
|
const action = data.action;
|
|
|
|
if (id == this.id && objectType == "host") {
|
|
this.hostManager.handleAction(action, callback);
|
|
}
|
|
|
|
if (objectType == "printer") {
|
|
this.printerManager.handlePrinterAction(id, action, callback);
|
|
}
|
|
|
|
if (objectType == "documentPrinter") {
|
|
this.documentPrinterManager.handleDocumentPrinterAction(
|
|
id,
|
|
action,
|
|
callback,
|
|
);
|
|
}
|
|
}
|
|
|
|
handleObjectUpdate(data, callback) {
|
|
logger.debug(
|
|
"Got object update for type:",
|
|
data.objectType,
|
|
" id:",
|
|
data._id,
|
|
);
|
|
if (data.objectType == "host") {
|
|
this.hostManager.handleUpdate(data);
|
|
}
|
|
if (data.objectType == "documentPrinter") {
|
|
this.documentPrinterManager.handleDocumentPrinterUpdate(
|
|
data._id,
|
|
data,
|
|
callback,
|
|
);
|
|
}
|
|
if (data.objectType == "documentSize") {
|
|
this.documentPrinterManager.handleDocumentSizeUpdate(data._id, data);
|
|
}
|
|
if (data.objectType == "printer") {
|
|
this.printerManager.handlePrinterUpdate(data._id, data, callback);
|
|
}
|
|
}
|
|
|
|
async handleConnect() {
|
|
await stopWaiting();
|
|
logger.info("Connected to FarmControl Api.");
|
|
this.connected = true;
|
|
sendIPC("setConnected", true);
|
|
this.loading = false;
|
|
sendIPC("setLoading", false);
|
|
|
|
// Clear any pending reconnect timeout
|
|
if (this.reconnectTimeout) {
|
|
clearTimeout(this.reconnectTimeout);
|
|
this.reconnectTimeout = null;
|
|
}
|
|
|
|
this.hostManager.onConnect();
|
|
}
|
|
|
|
async handleError(error) {
|
|
await stopWaiting();
|
|
logger.error("Connection error:", error.message);
|
|
this.loading = false;
|
|
sendIPC("setLoading", false);
|
|
this.connected = false;
|
|
sendIPC("setConnected", false);
|
|
this.authenticated = false;
|
|
sendIPC("setAuthenticated", false);
|
|
this.socket.disconnect();
|
|
this.scheduleReconnect();
|
|
}
|
|
|
|
async listObjects({
|
|
objectType,
|
|
populate,
|
|
filter,
|
|
sort,
|
|
order,
|
|
project,
|
|
cached,
|
|
}) {
|
|
logger.trace("Listing objects...", {
|
|
objectType,
|
|
populate,
|
|
filter,
|
|
sort,
|
|
order,
|
|
project,
|
|
cached,
|
|
});
|
|
return new Promise((resolve, reject) => {
|
|
this.socket.emit(
|
|
"listObjects",
|
|
{
|
|
objectType,
|
|
populate,
|
|
filter,
|
|
sort,
|
|
order,
|
|
project,
|
|
cached,
|
|
},
|
|
(result) => {
|
|
if (result && result.error) {
|
|
reject(new Error(result.error));
|
|
} else {
|
|
logger.trace("Listed objects.", {
|
|
objectType,
|
|
populate,
|
|
filter,
|
|
sort,
|
|
order,
|
|
project,
|
|
cached,
|
|
length: result.length,
|
|
});
|
|
resolve(result);
|
|
}
|
|
},
|
|
);
|
|
});
|
|
}
|
|
|
|
async newObject({ objectType, newData }) {
|
|
logger.debug("Creating object...", {
|
|
objectType,
|
|
newData,
|
|
});
|
|
return new Promise((resolve, reject) => {
|
|
this.socket.emit(
|
|
"newObject",
|
|
{
|
|
objectType,
|
|
newData,
|
|
},
|
|
(result) => {
|
|
if (result && result.error) {
|
|
reject(new Error(result.error));
|
|
} else {
|
|
logger.trace("Created object.", {
|
|
objectType,
|
|
newData,
|
|
});
|
|
resolve(result);
|
|
}
|
|
},
|
|
);
|
|
});
|
|
}
|
|
|
|
async editObject({
|
|
objectType,
|
|
_id,
|
|
populate,
|
|
updateData,
|
|
auditLog = true,
|
|
notify = true,
|
|
}) {
|
|
logger.trace("Editing object...", {
|
|
objectType,
|
|
_id,
|
|
populate,
|
|
});
|
|
return new Promise((resolve, reject) => {
|
|
this.socket.emit(
|
|
"editObject",
|
|
{
|
|
objectType,
|
|
_id,
|
|
populate,
|
|
updateData,
|
|
auditLog,
|
|
notify,
|
|
},
|
|
(result) => {
|
|
if (result && result.error) {
|
|
reject(new Error(result.error));
|
|
} else {
|
|
logger.trace("Edited object.", {
|
|
objectType,
|
|
_id,
|
|
populate,
|
|
});
|
|
resolve(result);
|
|
}
|
|
},
|
|
);
|
|
});
|
|
}
|
|
|
|
async getObject({ objectType, _id, populate }) {
|
|
logger.debug("Getting object...", {
|
|
objectType,
|
|
_id,
|
|
populate,
|
|
});
|
|
return new Promise((resolve, reject) => {
|
|
this.socket.emit(
|
|
"getObject",
|
|
{
|
|
objectType,
|
|
_id,
|
|
populate,
|
|
},
|
|
(result) => {
|
|
if (result && result.error) {
|
|
reject(new Error(result.error));
|
|
} else {
|
|
logger.trace("Retreived object.", {
|
|
objectType,
|
|
_id,
|
|
populate,
|
|
});
|
|
resolve(result);
|
|
}
|
|
},
|
|
);
|
|
});
|
|
}
|
|
|
|
async objectEvent({ objectType, _id, eventType, eventData }) {
|
|
logger.trace("Sending object event...", {
|
|
objectType,
|
|
_id,
|
|
eventType,
|
|
eventData,
|
|
});
|
|
return new Promise((resolve, reject) => {
|
|
this.socket.emit("objectEvent", {
|
|
objectType,
|
|
_id,
|
|
event: {
|
|
type: eventType,
|
|
data: eventData,
|
|
},
|
|
});
|
|
});
|
|
}
|
|
|
|
getApiUrl() {
|
|
return this.fileManager.getApiUrl();
|
|
}
|
|
|
|
getApiHeaders() {
|
|
return {
|
|
"X-Auth-Code": config.host.authCode,
|
|
"X-Host-Id": config.host.id || this.id,
|
|
};
|
|
}
|
|
|
|
parseTemplateDownloadError(error) {
|
|
const data = error?.response?.data;
|
|
if (data instanceof ArrayBuffer || Buffer.isBuffer(data)) {
|
|
try {
|
|
const parsed = JSON.parse(Buffer.from(data).toString("utf8"));
|
|
return parsed?.error || error.message;
|
|
} catch (parseError) {
|
|
return error.message;
|
|
}
|
|
}
|
|
return data?.error || error.message;
|
|
}
|
|
|
|
getObjectEventKey(objectType, _id, eventType) {
|
|
return `${objectType}:${_id}:events:${eventType}`;
|
|
}
|
|
|
|
async downloadTemplate(templateData, type, extra = {}) {
|
|
const { async: asyncMode, renderRequestId } = extra;
|
|
const padding = extra.padding === true;
|
|
const response = await axios.post(
|
|
`${this.getApiUrl()}/documenttemplates/${templateData._id}/download`,
|
|
{
|
|
content: templateData.content,
|
|
object: templateData.object,
|
|
width: templateData.width,
|
|
padding,
|
|
...(asyncMode === true ? { async: true } : {}),
|
|
...(renderRequestId ? { renderRequestId } : {}),
|
|
},
|
|
{
|
|
params: {
|
|
type,
|
|
padding: padding ? "true" : "false",
|
|
...(asyncMode === true ? { async: true } : {}),
|
|
...(renderRequestId ? { renderRequestId } : {}),
|
|
},
|
|
responseType: "arraybuffer",
|
|
headers: this.getApiHeaders(),
|
|
},
|
|
);
|
|
const contentType = response.headers["content-type"] || "";
|
|
if (contentType.includes("application/json")) {
|
|
return JSON.parse(Buffer.from(response.data).toString("utf8"));
|
|
}
|
|
return {
|
|
type,
|
|
mime: contentType,
|
|
buffer: Buffer.from(response.data),
|
|
};
|
|
}
|
|
|
|
async renderTemplateWithProgress(templateData, type, onProgress) {
|
|
const startResult = await this.downloadTemplate(templateData, type, {
|
|
async: true,
|
|
});
|
|
if (startResult?.error) {
|
|
throw new Error(startResult.error);
|
|
}
|
|
if (!startResult?.renderRequestId) {
|
|
return startResult;
|
|
}
|
|
|
|
const renderRequestId = startResult.renderRequestId;
|
|
const eventType = `render:${renderRequestId}`;
|
|
if (typeof onProgress === "function") {
|
|
await onProgress({ progress: 0, message: "Starting render..." });
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
let settled = false;
|
|
let unsubscribe;
|
|
|
|
const finish = (result, error) => {
|
|
if (settled) {
|
|
return;
|
|
}
|
|
settled = true;
|
|
clearTimeout(timeoutId);
|
|
clearInterval(pollId);
|
|
if (typeof unsubscribe === "function") {
|
|
unsubscribe();
|
|
}
|
|
if (error) {
|
|
reject(error);
|
|
return;
|
|
}
|
|
resolve(result);
|
|
};
|
|
|
|
const tryFetchRenderedFile = async () => {
|
|
try {
|
|
const result = await this.downloadTemplate(templateData, type, {
|
|
renderRequestId,
|
|
});
|
|
if (result?.error) {
|
|
finish(null, new Error(result.error));
|
|
return true;
|
|
}
|
|
finish(result);
|
|
return true;
|
|
} catch (error) {
|
|
if (error?.response?.status === 404) {
|
|
return false;
|
|
}
|
|
finish(null, new Error(this.parseTemplateDownloadError(error)));
|
|
return true;
|
|
}
|
|
};
|
|
|
|
unsubscribe = this.subscribeToObjectEvent({
|
|
objectType: "render",
|
|
_id: renderRequestId,
|
|
eventType,
|
|
callback: (event) => {
|
|
if (typeof onProgress === "function") {
|
|
onProgress({
|
|
progress: Number(event?.progress) || 0,
|
|
message: event?.message || "",
|
|
error: event?.error,
|
|
});
|
|
}
|
|
if (event?.error) {
|
|
finish(null, new Error(event.error));
|
|
return;
|
|
}
|
|
if (Number(event?.progress) >= 1) {
|
|
tryFetchRenderedFile();
|
|
}
|
|
},
|
|
});
|
|
|
|
const pollId = setInterval(tryFetchRenderedFile, 1000);
|
|
const timeoutId = setTimeout(() => {
|
|
finish(null, new Error("Timed out waiting for template render."));
|
|
}, 120000);
|
|
});
|
|
}
|
|
|
|
async renderTemplatePDF(templateData, onProgress) {
|
|
logger.debug("Rendering template PDF...", templateData);
|
|
try {
|
|
const result = await this.renderTemplateWithProgress(
|
|
templateData,
|
|
"pdf",
|
|
onProgress,
|
|
);
|
|
logger.trace("Template PDF rendered successfully.");
|
|
if (result?.pdf) {
|
|
return result;
|
|
}
|
|
return { pdf: result.buffer };
|
|
} catch (error) {
|
|
const message = this.parseTemplateDownloadError(error) || error.message;
|
|
logger.error("Failed to render template PDF:", message);
|
|
throw new Error(message);
|
|
}
|
|
}
|
|
|
|
async renderTemplateJPG(templateData, type = "jpeg", onProgress) {
|
|
logger.debug(`Rendering template ${type.toUpperCase()}...`, templateData);
|
|
try {
|
|
const result = await this.renderTemplateWithProgress(
|
|
templateData,
|
|
type,
|
|
onProgress,
|
|
);
|
|
logger.trace("Template JPG rendered successfully.");
|
|
if (Array.isArray(result?.images)) {
|
|
return {
|
|
images: result.images.map((image) =>
|
|
Buffer.isBuffer(image) ? image : Buffer.from(image, "base64"),
|
|
),
|
|
};
|
|
}
|
|
return { images: [result.buffer] };
|
|
} catch (error) {
|
|
const message = this.parseTemplateDownloadError(error) || error.message;
|
|
logger.error("Failed to render template JPG:", message);
|
|
throw new Error(message);
|
|
}
|
|
}
|
|
|
|
async subscribeToObjectActions({ objectType, _id }) {
|
|
logger.debug("Suscribing to object actions...", {
|
|
objectType,
|
|
_id,
|
|
});
|
|
this.socket.emit("subscribeToObjectActions", {
|
|
objectType,
|
|
_id,
|
|
});
|
|
}
|
|
|
|
async subscribeToObjectUpdates({ objectType, _id }) {
|
|
logger.debug("Suscribing to object updates...", {
|
|
objectType,
|
|
_id,
|
|
});
|
|
this.socket.emit("subscribeToObjectUpdates", {
|
|
objectType,
|
|
_id,
|
|
});
|
|
}
|
|
|
|
async unsubscribeFromObjectUpdates({ objectType, _id }) {
|
|
logger.debug("Unsuscribing from object updates...", {
|
|
objectType,
|
|
_id,
|
|
});
|
|
this.socket.emit("unsubscribeFromObjectUpdates", {
|
|
objectType,
|
|
_id,
|
|
});
|
|
}
|
|
|
|
subscribeToObjectEvent({ objectType, _id, eventType, callback }) {
|
|
logger.debug("Suscribing to object event...", {
|
|
objectType,
|
|
_id,
|
|
eventType,
|
|
});
|
|
|
|
const emitSubscribe = () => {
|
|
this.socket.emit("subscribeToObjectEvent", {
|
|
objectType,
|
|
_id,
|
|
eventType,
|
|
});
|
|
};
|
|
|
|
if (typeof callback === "function") {
|
|
const key = this.getObjectEventKey(objectType, _id, eventType);
|
|
if (!this.objectEventCallbacks.has(key)) {
|
|
this.objectEventCallbacks.set(key, []);
|
|
}
|
|
const callbacks = this.objectEventCallbacks.get(key);
|
|
const needsSocketSubscribe = callbacks.length === 0;
|
|
callbacks.push(callback);
|
|
if (needsSocketSubscribe) {
|
|
emitSubscribe();
|
|
}
|
|
return () =>
|
|
this.unsubscribeFromObjectEvent({
|
|
objectType,
|
|
_id,
|
|
eventType,
|
|
callback,
|
|
});
|
|
}
|
|
|
|
emitSubscribe();
|
|
}
|
|
|
|
unsubscribeFromObjectEvent({ objectType, _id, eventType, callback }) {
|
|
logger.debug("Unsuscribing from object event...", {
|
|
objectType,
|
|
_id,
|
|
eventType,
|
|
});
|
|
|
|
const emitUnsubscribe = () => {
|
|
this.socket.emit("unsubscribeObjectEvent", {
|
|
objectType,
|
|
_id,
|
|
eventType,
|
|
});
|
|
};
|
|
|
|
const key = this.getObjectEventKey(objectType, _id, eventType);
|
|
if (typeof callback === "function" && this.objectEventCallbacks.has(key)) {
|
|
const remaining = this.objectEventCallbacks
|
|
.get(key)
|
|
.filter((registered) => registered !== callback);
|
|
if (remaining.length === 0) {
|
|
this.objectEventCallbacks.delete(key);
|
|
emitUnsubscribe();
|
|
} else {
|
|
this.objectEventCallbacks.set(key, remaining);
|
|
}
|
|
return;
|
|
}
|
|
|
|
this.objectEventCallbacks.delete(key);
|
|
emitUnsubscribe();
|
|
}
|
|
|
|
async handleObjectEvent({ objectType, _id, event }) {
|
|
logger.debug("Received object event...", {
|
|
objectType,
|
|
_id,
|
|
event,
|
|
});
|
|
|
|
const key = this.getObjectEventKey(objectType, _id, event?.type);
|
|
const callbacks = this.objectEventCallbacks.get(key);
|
|
if (Array.isArray(callbacks) && callbacks.length > 0) {
|
|
callbacks.forEach((callback) => {
|
|
try {
|
|
callback(event);
|
|
} catch (error) {
|
|
logger.error("Error in object event callback:", error);
|
|
}
|
|
});
|
|
}
|
|
|
|
const data = event.data;
|
|
if (
|
|
(event.type == "childUpdate" ||
|
|
event.type == "childDelete" ||
|
|
event.type == "childNew") &&
|
|
objectType == "host" &&
|
|
_id == this.id
|
|
) {
|
|
await this.hostManager.handleChildEvent(data);
|
|
}
|
|
}
|
|
|
|
//-------------------------------------- RE-WRITE ENDS HERE ---------------------------------------
|
|
|
|
async handleScanNetworkStart(data, callback) {
|
|
if (this.scanner.scanning == false) {
|
|
try {
|
|
this.scanner = new WebSocketScanner({ maxThreads: 50 });
|
|
// Listen for found services
|
|
this.scanner.on("serviceFound", (data) => {
|
|
logger.info(
|
|
`Found websocket service at ${data.hostname} (${data.ip})`,
|
|
);
|
|
this.socket.emit("notify_scan_network_found", data);
|
|
});
|
|
|
|
// Listen for scan progress
|
|
this.scanner.on("scanProgress", ({ currentIP, progress }) => {
|
|
logger.info(
|
|
`Scanning ${currentIP} (${progress.toFixed(2)}% complete)`,
|
|
);
|
|
this.socket.emit("notify_scan_network_progress", {
|
|
currentIP: currentIP,
|
|
progress: progress,
|
|
});
|
|
});
|
|
|
|
// Start scanning on port
|
|
logger.info(
|
|
"Scanning network for websocket services on port:",
|
|
data?.port || 7125,
|
|
"using protocol:",
|
|
data?.protocol || "ws",
|
|
);
|
|
this.scanner
|
|
.scanNetwork(data?.port || 7125, data?.protocol || "ws")
|
|
.then((foundServices) => {
|
|
logger.info("Scan complete. Found services:", foundServices);
|
|
this.socket.emit("notify_scan_network_complete", foundServices);
|
|
})
|
|
.catch((error) => {
|
|
logger.error("Scan error:", error);
|
|
this.socket.emit("notify_scan_network_complete", false);
|
|
});
|
|
} catch (error) {
|
|
logger.error("Scan error:", error);
|
|
this.socket.emit("notify_scan_network_complete", false);
|
|
}
|
|
}
|
|
}
|
|
|
|
handleScanNetworkStop(callback) {
|
|
if (this.scanner.scanning == true) {
|
|
logger.info("Stopping network scan");
|
|
this.scanner.removeAllListeners("serviceFound");
|
|
this.scanner.removeAllListeners("scanProgress");
|
|
this.scanner.removeAllListeners("scanComplete");
|
|
this.scanner.stopScan();
|
|
callback(true);
|
|
} else {
|
|
logger.info("Scan not in progress");
|
|
callback(false);
|
|
}
|
|
}
|
|
|
|
async handlePrinterObjectsQuery(data, callback) {
|
|
logger.debug("Received printer.objects.query event:", data);
|
|
try {
|
|
const result = await this.printerManager.processPrinterCommand({
|
|
method: "printer.objects.query",
|
|
params: data,
|
|
});
|
|
|
|
if (callback) {
|
|
callback(result);
|
|
}
|
|
} catch (e) {
|
|
logger.error("Error processing printer objects query request:", e);
|
|
if (callback) {
|
|
callback({ error: e.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async handleEmergencyStop(data, callback) {
|
|
logger.debug("Received printer.gcode.script event:", data);
|
|
try {
|
|
const result = await this.printerManager.processPrinterCommand({
|
|
method: "printer.emergency_stop",
|
|
params: data,
|
|
});
|
|
|
|
if (callback) {
|
|
callback(result);
|
|
}
|
|
} catch (e) {
|
|
logger.error("Error processing gcode script request:", e);
|
|
if (callback) {
|
|
callback({ error: e.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async handleFilamentStockLoad(data, callback) {
|
|
logger.debug("Received printer.filamentstock.load event:", data);
|
|
try {
|
|
if (!data || !data.printerId) {
|
|
throw new Error("Missing required printer ID");
|
|
}
|
|
if (!data || !data.filamentStockId) {
|
|
throw new Error("Missing required filament stock ID");
|
|
}
|
|
|
|
// Get the printer client
|
|
const printerClient = this.printerManager.getPrinterClient(
|
|
data.printerId,
|
|
);
|
|
if (!printerClient) {
|
|
throw new Error(`Printer with ID ${data.printerId} not found`);
|
|
}
|
|
|
|
// Load the filament stock
|
|
const result = await printerClient.loadFilamentStock(
|
|
data.filamentStockId,
|
|
);
|
|
|
|
if (callback) {
|
|
callback(result);
|
|
}
|
|
} catch (e) {
|
|
logger.error("Error processing filament load request:", e);
|
|
if (callback) {
|
|
callback({ error: e.message });
|
|
}
|
|
}
|
|
}
|
|
|
|
async handleDisconnect() {
|
|
logger.info("Disconnected from FarmControl Api.");
|
|
await this.printerManager.closeAllConnections();
|
|
await this.documentPrinterManager.closeAllConnections();
|
|
this.connected = false;
|
|
sendIPC("setConnected", false);
|
|
this.authenticated = false;
|
|
sendIPC("setAuthenticated", false);
|
|
this.scheduleReconnect();
|
|
}
|
|
}
|