UNPKG

@fdm-monster/server

Version:

FDM Monster is a bulk OctoPrint, Klipper, PrusaLink and BambuLab manager to set up, configure and monitor 3D printers. Our aim is to provide neat overview over your farm.

172 lines (171 loc) 5.67 kB
import { uploadFileInputSchema } from "./printer-api.interface.js"; import { NotImplementedException } from "../exceptions/runtime.exceptions.js"; //#region src/services/moonraker.api.ts /** * Moonraker Remote API * https://moonraker.readthedocs.io/en/latest/web_api/#query-server-info */ var MoonrakerApi = class { client; constructor(moonrakerClient, printerLogin) { this.printerLogin = printerLogin; this.client = moonrakerClient; } get type() { return 1; } /** * When no request scope is present, this setter is to be used before calling any function. * @param login */ set login(login) { this.printerLogin = login; } get login() { return this.printerLogin; } async getVersion() { return (await this.client.getApiVersion(this.login)).data?.server; } async validateConnection() { await this.getVersion(); } async connect() { throw new NotImplementedException(); } async disconnect() { throw new NotImplementedException(); } async restartServer() { await this.client.postRestartServer(this.login); } async restartHost() { await this.client.postHostRestart(this.login); } async restartPrinterFirmware() { await this.client.postFirmwareRestart(this.login); } async startPrint(filename) { await this.client.postPrintStart(this.login, filename); } async pausePrint() { await this.client.postPrintPause(this.login); } async resumePrint() { await this.client.postPrintResume(this.login); } async cancelPrint() { await this.client.postPrintCancel(this.login); } async sendGcode(script) { await this.client.postGcodeScript(this.login, script); } async quickStop() { await this.client.postQuickStop(this.login); } async movePrintHead(amounts) { const setSpeed = !!amounts.speed ? amounts.speed : 10; let g1CommandAxes = ""; if (!Number.isNaN(amounts.x)) g1CommandAxes += ` X${amounts.x}`; if (!Number.isNaN(amounts.y)) g1CommandAxes += ` Y${amounts.y}`; if (!Number.isNaN(amounts.z)) g1CommandAxes += ` Z${amounts.z}`; await this.client.postGcodeScript(this.login, ` G91 G1 ${g1CommandAxes} F${setSpeed} G90`); } async getFile(path) { const file = (await this.client.getServerFileMetadata(this.login, path)).data.result; return { size: file.size, path, date: Math.floor(file.modified * 1e3), dir: false }; } async getFiles(recursive = false, startDir = "") { if (recursive && startDir) throw new Error("Recursive mode does not support startDir parameter for Moonraker"); const stripGcodes = (path) => path.startsWith("gcodes/") ? path.substring(7) : path; const buildPath = (name) => startDir ? `${startDir}/${name}` : name; if (recursive) { const response = await this.client.getServerFilesList(this.login, "gcodes"); const dirsSet = /* @__PURE__ */ new Set(); const files = response.data.result.map((f) => { const strippedPath = stripGcodes(f.path); const pathParts = strippedPath.split("/"); for (let i = 0; i < pathParts.length - 1; i++) dirsSet.add(pathParts.slice(0, i + 1).join("/")); return this.toFileDto(strippedPath, f.size, f.modified, false); }); dirsSet.forEach((dirPath) => files.push(this.toFileDto(dirPath, 0, null, true))); return { dirs: files.filter((f) => f.dir), files: files.filter((f) => !f.dir) }; } const moonrakerPath = startDir ? `gcodes/${startDir}` : "gcodes"; const { dirs: apiDirs, files: apiFiles } = (await this.client.getServerFilesDirectoryInfo(this.login, moonrakerPath, false)).data.result; return { dirs: apiDirs.map((d) => this.toFileDto(buildPath(d.dirname), d.size, d.modified, true)), files: apiFiles.map((f) => this.toFileDto(buildPath(f.filename), f.size, f.modified, false)) }; } toFileDto(path, size, modified, dir) { return { path, size, date: modified !== null ? Math.floor(modified * 1e3) : null, dir }; } async homeAxes(axes) { let homeCommand = `G28`; if (!!axes.x) homeCommand += ` X`; if (!!axes.y) homeCommand += ` Y`; if (!!axes.z) homeCommand += ` Z`; await this.client.postGcodeScript(this.login, homeCommand); } async downloadFile(path) { return await this.client.getServerFilesDownload(this.login, "gcodes", path); } async getFileChunk(path, startBytes, endBytes) { return await this.client.getServerFilesDownloadChunk(this.login, "gcodes", path, startBytes, endBytes); } async uploadFile(input) { const validated = uploadFileInputSchema.parse(input); await this.client.postServerFileUpload(this.login, validated.stream, validated.fileName, validated.contentLength, validated.startPrint, validated.uploadToken); } async deleteFile(path) { await this.client.deleteServerFile(this.login, "gcodes", path); } async deleteFolder(path) { await this.client.deleteServerFilesDirectory(this.login, path, false); } async getSettings() { return (await this.client.getServerConfig(this.login)).data?.result; } async getReprintState() { const operational = (await this.client.getPrinterObjectsQuery(this.login, { print_stats: [], webhooks: [] })).data.result.status.webhooks.state === "ready"; const jobs = ((await this.client.getServerHistoryList(this.login, 5, 0)).data?.result.jobs ?? []).sort((a, b) => a.start_time > b.start_time ? 1 : 0); if (jobs.length === 0 || !operational) return { connectionState: operational ? "Operational" : "Error", reprintState: 1 }; const job = jobs[0]; return { connectionState: "Operational", reprintState: 2, file: { date: job.start_time, path: job.filename, size: job.metadata.size, dir: false } }; } }; //#endregion export { MoonrakerApi }; //# sourceMappingURL=moonraker.api.js.map