@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
JavaScript
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