MCP 3D Printer Server

by DMontgomery40
Verified
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const node_events_1 = __importDefault(require("node:events")); const node_path_1 = __importDefault(require("node:path")); const BambuFTP_1 = __importDefault(require("./BambuFTP")); const BambuMQTT_1 = __importDefault(require("./BambuMQTT")); const stateConverter_1 = __importDefault(require("../utilities/stateConverter")); /** * A class for interfacing with a Bambu Lab printer. * @emits update - Emitted when the printer's state is updated. * @emits connect - Emitted when the printer is connected. * @emits disconnect - Emitted when the printer is disconnected. */ class BambuPrinter extends node_events_1.default { constructor(host, serial, accessCode) { super(); this.host = host; this.serial = serial; this.accessCode = accessCode; this.state = { timestamp: Date.now(), }; this.hasInitialUpdate = false; this.mqtt = new BambuMQTT_1.default(host, accessCode, serial); } /** * Connect to the printer. */ connect() { return __awaiter(this, void 0, void 0, function* () { yield this.mqtt.connect(); this.mqtt.on("update", this.onStateUpdate.bind(this)); this.mqtt.on("disconnect", () => this.emit("disconnect")); this.mqtt.on("connect", () => this.emit("connect")); this.mqtt.on("error", (error) => this.emit("error", error)); }); } /** * Disconnect from the printer. */ disconnect() { return __awaiter(this, void 0, void 0, function* () { yield this.mqtt.disconnect(); }); } /** * Create a context for manipulating files on the printer's SD card. * @param callback - Callback to manipulate files within the context. */ manipulateFiles(callback) { return __awaiter(this, void 0, void 0, function* () { yield BambuFTP_1.default.createContext(this.host, this.accessCode, callback); }); } /** * Get the raw state of the printer. * @returns The raw state of the printer. */ getRawState() { return this.state; } /** * Get the state of the printer. */ getState() { return (0, stateConverter_1.default)(this.state); } /** * Await the printer to send its initial state. * @param timeout - The maximum time to wait for the initial state. * @returns The initial state of the printer. */ awaitInitialState() { return __awaiter(this, arguments, void 0, function* (timeout = 30000) { return new Promise((resolve, reject) => { // Timeout if the initial state is not received let timeoutId = setTimeout(() => { reject(new Error("Timed out waiting for initial state")); }, timeout); // Resolve when the initial state is received this.once("update", (state) => { clearTimeout(timeoutId); resolve(state); }); // If the initial state has already been received, resolve immediately if (this.hasInitialUpdate) { clearTimeout(timeoutId); resolve(this.getState()); } }); }); } /** * Pause the current print job. */ pause() { let data = { print: { sequence_id: "0", command: "pause", param: "", }, }; this.mqtt.sendRequest(data); } /** * Resume the current print job. */ resume() { let data = { print: { sequence_id: "0", command: "resume", param: "", }, }; this.mqtt.sendRequest(data); } /** * Stop the current print job. */ stop() { let data = { print: { sequence_id: "0", command: "stop", param: "", }, }; this.mqtt.sendRequest(data); } /** * Set the state of the printer's LED. * @param options - Options for setting the LED state. */ setLed(options) { let data = { system: { sequence_id: "0", command: "ledctrl", led_node: "chamber_light", led_mode: options.mode, }, }; if (options.mode === "flashing") { data.system.led_on_time = options.onTime; data.system.led_off_time = options.offTime; data.system.loop_times = options.loopTimes; data.system.interval_time = options.intervalTime; } this.mqtt.sendRequest(data); } /** * Print a 3MF project file from the printer's SD card. * @param projectPath - The absolute path to the 3MF file on the printer's SD card. * @param file - The absolute path of the gcode file in the 3MF project to be printed (e.g. "Metadata/plate_1.gcode") * @param name - The name to use for the print job. Serves no functional purpose. * @param hash - The MD5 hash of the gcode file. * @param options - Options for the print job. */ printProjectFile(projectPath, file, name, hash, options = {}) { var _a, _b, _c, _d, _e, _f; // Create the payload let data = { print: { command: "project_file", // File info param: node_path_1.default.join("Metadata/", file), url: "file://" + node_path_1.default.join("/sdcard/", projectPath), subtask_name: name, md5: hash, // Options flow_cali: (_a = options.flowCalibration) !== null && _a !== void 0 ? _a : true, layer_inspect: (_b = options.layerInspect) !== null && _b !== void 0 ? _b : true, timelapse: (_c = options.timelaspe) !== null && _c !== void 0 ? _c : false, vibration_cali: (_d = options.vibrationCalibration) !== null && _d !== void 0 ? _d : true, bed_leveling: (_e = options.bedLeveling) !== null && _e !== void 0 ? _e : true, bed_type: (_f = options.bedType) !== null && _f !== void 0 ? _f : "textured_plate", use_ams: true, // Required misc profile_id: "0", project_id: "0", sequence_id: "0", subtask_id: "0", task_id: "0", }, }; // Send the request this.mqtt.sendRequest(data); } /** * Get the current connection status. */ get isConnected() { return this.mqtt.isConnected; } /** * Handle the state update event. * @param state - The new state of the printer. */ onStateUpdate(state) { return __awaiter(this, void 0, void 0, function* () { // Merge the new state with the old state this.state = Object.assign(Object.assign(Object.assign({}, this.state), state), { timestamp: Date.now() }); this.hasInitialUpdate = true; this.emit("update", this.getState()); }); } } exports.default = BambuPrinter; //# sourceMappingURL=BambuPrinter.js.map