mcp-3d-printer-server 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/3mf_parser.d.ts +3 -0
  2. package/dist/3mf_parser.js +216 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +1018 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/printers/bambu.d.ts +42 -0
  7. package/dist/printers/bambu.js +284 -0
  8. package/dist/printers/creality.d.ts +10 -0
  9. package/dist/printers/creality.js +90 -0
  10. package/dist/printers/duet.d.ts +10 -0
  11. package/dist/printers/duet.js +66 -0
  12. package/dist/printers/klipper.d.ts +10 -0
  13. package/dist/printers/klipper.js +62 -0
  14. package/dist/printers/octoprint.d.ts +10 -0
  15. package/dist/printers/octoprint.js +97 -0
  16. package/dist/printers/printer-factory.d.ts +9 -0
  17. package/dist/printers/printer-factory.js +33 -0
  18. package/dist/printers/prusa.d.ts +10 -0
  19. package/dist/printers/prusa.js +93 -0
  20. package/dist/printers/repetier.d.ts +10 -0
  21. package/dist/printers/repetier.js +59 -0
  22. package/dist/stl/stl-manipulator.d.ts +140 -0
  23. package/dist/stl/stl-manipulator.js +1081 -0
  24. package/dist/test/stl-manipulator-test.d.ts +2 -0
  25. package/dist/test/stl-manipulator-test.js +91 -0
  26. package/dist/types.d.ts +75 -0
  27. package/dist/types.js +26 -0
  28. package/package.json +9 -3
  29. package/src/printers/bambu.ts +8 -3
  30. package/.dockerignore +0 -52
  31. package/.env.example +0 -17
  32. package/Dockerfile +0 -31
  33. package/docker-compose.yml +0 -31
  34. package/scripts/docker-run.sh +0 -25
  35. package/scripts/mcp-inspector.js +0 -49
  36. package/test/sample_cube.stl +0 -86
  37. package/test/sample_cube_extended.stl +0 -172
  38. package/test/sample_cube_modified.stl +0 -86
  39. package/test/sample_cube_rotated.stl +0 -86
  40. package/test/sample_cube_scaled.stl +0 -86
  41. package/test/sample_cube_translated.stl +0 -86
  42. package/tsconfig.json +0 -16
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { PrinterImplementation, BambuPrinterStore } from "../types.js";
2
+ interface BambuPrintOptionsInternal {
3
+ projectName: string;
4
+ filePath: string;
5
+ useAMS?: boolean;
6
+ plateIndex?: number;
7
+ bedLeveling?: boolean;
8
+ flowCalibration?: boolean;
9
+ vibrationCalibration?: boolean;
10
+ layerInspect?: boolean;
11
+ timelapse?: boolean;
12
+ amsMapping?: number[];
13
+ md5?: string;
14
+ }
15
+ export declare class BambuImplementation extends PrinterImplementation {
16
+ private bambuPrinterStore;
17
+ private mqttClients;
18
+ private mqttConnectionPromises;
19
+ constructor(apiClient: any, bambuPrinterStore: BambuPrinterStore);
20
+ private getBambuPrinterForFTP;
21
+ private getMqttClient;
22
+ disconnectAllMqtt(): Promise<void>;
23
+ getStatus(host: string, port: string, apiKey: string): Promise<any>;
24
+ print3mf(host: string, serial: string, token: string, options: BambuPrintOptionsInternal): Promise<any>;
25
+ cancelJob(host: string, port: string, apiKey: string): Promise<any>;
26
+ setTemperature(host: string, port: string, apiKey: string, component: string, temperature: number): Promise<void>;
27
+ getFiles(host: string, port: string, apiKey: string): Promise<{
28
+ files: string[];
29
+ }>;
30
+ getFile(host: string, port: string, apiKey: string, filename: string): Promise<{
31
+ name: string;
32
+ exists: boolean;
33
+ }>;
34
+ uploadFile(host: string, port: string, apiKey: string, filePath: string, filename: string, print: boolean): Promise<{
35
+ status: string;
36
+ message: string;
37
+ }>;
38
+ startJob(host: string, port: string, apiKey: string, filename: string): Promise<void>;
39
+ private publishMqttCommand;
40
+ private extractBambuCredentials;
41
+ }
42
+ export {};
@@ -0,0 +1,284 @@
1
+ import { PrinterImplementation } from "../types.js";
2
+ import * as mqtt from 'mqtt'; // Import MQTT library
3
+ import * as path from 'path';
4
+ export class BambuImplementation extends PrinterImplementation {
5
+ constructor(apiClient, bambuPrinterStore) {
6
+ super(apiClient);
7
+ this.mqttClients = {}; // Store connected MQTT clients
8
+ this.mqttConnectionPromises = {}; // Track connection attempts
9
+ this.bambuPrinterStore = bambuPrinterStore;
10
+ }
11
+ // Get BambuPrinter instance for FTP
12
+ getBambuPrinterForFTP(host, serial, token) {
13
+ // This still uses bambu-js just for the FTP part
14
+ return this.bambuPrinterStore.get(host, serial, token);
15
+ }
16
+ // Get or establish MQTT connection
17
+ async getMqttClient(host, serial, token) {
18
+ const clientKey = `${host}-${serial}`;
19
+ if (this.mqttClients[clientKey] && this.mqttClients[clientKey].connected) {
20
+ return this.mqttClients[clientKey];
21
+ }
22
+ // If a connection attempt is already in progress, wait for it
23
+ if (this.mqttConnectionPromises[clientKey] !== undefined) {
24
+ console.log(`Waiting for existing MQTT connection attempt to ${clientKey}...`);
25
+ return this.mqttConnectionPromises[clientKey];
26
+ }
27
+ console.log(`Attempting to establish new MQTT connection to ${host} for ${serial}...`);
28
+ const connectPromise = new Promise((resolve, reject) => {
29
+ // Use port 8883 and TLS
30
+ const mqttOptions = {
31
+ port: 8883,
32
+ host: host,
33
+ protocol: 'mqtts',
34
+ username: 'bblp', // As per OpenBambuAPI docs
35
+ password: token,
36
+ clientId: `mcp_client_${serial}_${Date.now()}`,
37
+ rejectUnauthorized: false, // Might be needed for self-signed certs? Test carefully.
38
+ // ca: [fs.readFileSync('path/to/ca_cert.pem')], // Add CA cert if needed
39
+ connectTimeout: 10000, // 10 seconds
40
+ reconnectPeriod: 5000 // Try reconnecting every 5 seconds
41
+ };
42
+ const client = mqtt.connect(mqttOptions);
43
+ client.on('connect', () => {
44
+ console.log(`MQTT connected successfully to ${host} for ${serial}`);
45
+ this.mqttClients[clientKey] = client;
46
+ // Subscribe to necessary topics (e.g., responses/status)
47
+ client.subscribe(`device/${serial}/report`, (err) => {
48
+ if (err) {
49
+ console.error(`Failed to subscribe to report topic for ${serial}:`, err);
50
+ }
51
+ });
52
+ delete this.mqttConnectionPromises[clientKey]; // Clear promise tracker on success
53
+ resolve(client);
54
+ });
55
+ client.on('error', (err) => {
56
+ console.error(`MQTT connection error for ${serial} on ${host}:`, err);
57
+ delete this.mqttClients[clientKey]; // Remove potentially bad client
58
+ delete this.mqttConnectionPromises[clientKey]; // Clear promise tracker on error
59
+ reject(err);
60
+ });
61
+ client.on('close', () => {
62
+ console.log(`MQTT connection closed for ${serial} on ${host}`);
63
+ delete this.mqttClients[clientKey]; // Remove client on close
64
+ });
65
+ // Handle status messages from the report topic
66
+ client.on('message', (topic, message) => {
67
+ try {
68
+ const data = JSON.parse(message.toString());
69
+ // Processing logic for status updates would go here
70
+ // For now, we just acknowledge receiving it (optional logging)
71
+ // console.log(`MQTT message received on ${topic}:`, data?.print?.subtask_name ?? data?.print?.command ?? 'Unknown message type');
72
+ }
73
+ catch (e) {
74
+ console.error('Failed to parse MQTT message:', e);
75
+ }
76
+ });
77
+ });
78
+ this.mqttConnectionPromises[clientKey] = connectPromise; // Store the promise
79
+ return connectPromise;
80
+ }
81
+ // Disconnect MQTT clients on shutdown
82
+ async disconnectAllMqtt() {
83
+ console.log("Disconnecting all MQTT clients...");
84
+ for (const key in this.mqttClients) {
85
+ const client = this.mqttClients[key];
86
+ if (client) {
87
+ await new Promise((resolve, reject) => {
88
+ client.end(false, {}, (err) => {
89
+ if (err) {
90
+ console.error(`Error ending MQTT client ${key}:`, err);
91
+ reject(err);
92
+ }
93
+ else {
94
+ console.log(`MQTT client ${key} disconnected.`);
95
+ resolve();
96
+ }
97
+ });
98
+ });
99
+ }
100
+ }
101
+ this.mqttClients = {};
102
+ this.mqttConnectionPromises = {};
103
+ }
104
+ // --- getStatus (Limited Implementation) ---
105
+ async getStatus(host, port, apiKey) {
106
+ const [serial, token] = this.extractBambuCredentials(apiKey);
107
+ try {
108
+ // Ensure MQTT connection is attempted/established
109
+ const client = await this.getMqttClient(host, serial, token);
110
+ // Return minimal status indicating connection success
111
+ // Full status requires implementing state storage based on /report topic messages
112
+ return {
113
+ status: client.connected ? "connected" : "connecting",
114
+ serial: serial,
115
+ note: "Full status details require MQTT state tracking implementation."
116
+ };
117
+ }
118
+ catch (error) {
119
+ console.error(`Failed to get MQTT client/status for ${serial}:`, error);
120
+ return { status: "error", error: error.message };
121
+ }
122
+ }
123
+ // --- Refactored print3mf using direct MQTT ---
124
+ async print3mf(host, serial, token, options) {
125
+ // Still use bambu-js for FTP upload
126
+ const printerFTP = this.getBambuPrinterForFTP(host, serial, token);
127
+ const remoteFilename = path.basename(options.filePath);
128
+ // Ensure path uses forward slashes for printer consistency
129
+ const remotePath = `gcodes/${remoteFilename}`.replace(/\\/g, '/');
130
+ // 1. Connect FTP if necessary (via bambu-js helper)
131
+ if (!printerFTP.isConnected) {
132
+ console.log(`Connecting Bambu FTP ${host} (${serial}) on port 990 (assumed) before uploading...`);
133
+ try {
134
+ await printerFTP.connect(); // Connects MQTT and FTP
135
+ console.log(`Connected Bambu FTP successfully.`);
136
+ }
137
+ catch (ftpConnectError) {
138
+ console.error(`Bambu FTP Connection Error:`, ftpConnectError);
139
+ throw new Error(`Failed to connect to Bambu FTP: ${ftpConnectError.message}`);
140
+ }
141
+ // await printerFTP.awaitInitialState(10000); // Might not be needed just for FTP
142
+ }
143
+ // 2. Upload the file via FTP
144
+ console.log(`Uploading ${options.filePath} to ${remotePath} via FTP...`);
145
+ try {
146
+ await printerFTP.manipulateFiles(async (context) => {
147
+ await context.sendFile(options.filePath, remotePath);
148
+ });
149
+ console.log(`File ${remoteFilename} uploaded successfully.`);
150
+ }
151
+ catch (uploadError) {
152
+ console.error(`FTP Upload Error:`, uploadError);
153
+ throw new Error(`Failed to upload 3MF file via FTP: ${uploadError.message}`);
154
+ }
155
+ // 3. Get MQTT Client
156
+ const mqttClient = await this.getMqttClient(host, serial, token);
157
+ // 4. Construct the MQTT Print Command Payload based on OpenBambuAPI
158
+ const commandPayload = {
159
+ sequence_id: Date.now().toString(),
160
+ command: "project_file",
161
+ param: remotePath, // Path on SD card
162
+ project_name: options.projectName,
163
+ use_ams: options.amsMapping && options.amsMapping.length > 0 ? true : (options.useAMS ?? false),
164
+ plate_idx: options.plateIndex ?? 0,
165
+ bed_levelling: options.bedLeveling ?? true,
166
+ flow_cali: options.flowCalibration ?? false,
167
+ vibration_cali: options.vibrationCalibration ?? false,
168
+ layer_inspect: options.layerInspect ?? false,
169
+ timelapse: options.timelapse ?? false,
170
+ ams_mapping: options.amsMapping,
171
+ md5: options.md5
172
+ };
173
+ // Remove ams_mapping if not provided or empty
174
+ if (!commandPayload.ams_mapping || commandPayload.ams_mapping.length === 0) {
175
+ delete commandPayload.ams_mapping;
176
+ // Also ensure use_ams is false if no mapping exists
177
+ commandPayload.use_ams = false;
178
+ }
179
+ // Remove md5 if not provided
180
+ if (!commandPayload.md5) {
181
+ delete commandPayload.md5;
182
+ }
183
+ // 5. Publish the command
184
+ return this.publishMqttCommand(mqttClient, serial, 'print', commandPayload);
185
+ }
186
+ // --- Refactored cancelJob using MQTT ---
187
+ async cancelJob(host, port, apiKey) {
188
+ const [serial, token] = this.extractBambuCredentials(apiKey);
189
+ const mqttClient = await this.getMqttClient(host, serial, token);
190
+ // Command structure from OpenBambuAPI (assuming 'stop_print' is correct)
191
+ const payload = { sequence_id: Date.now().toString(), command: "stop_print" };
192
+ return this.publishMqttCommand(mqttClient, serial, 'print', payload);
193
+ }
194
+ // --- setTemperature (still not directly possible via MQTT command) ---
195
+ async setTemperature(host, port, apiKey, component, temperature) {
196
+ console.warn("Setting temperatures directly is not supported via known Bambu MQTT commands. Use G-code.");
197
+ // We could potentially implement a tool to send custom G-code?
198
+ throw new Error("Direct temperature setting via MQTT is not supported.");
199
+ }
200
+ // --- Other methods (getFiles, getFile, uploadFile, startJob) need review/refactoring ---
201
+ // For now, keep using bambu-js FTP for file ops, but MQTT for commands
202
+ async getFiles(host, port, apiKey) {
203
+ const [serial, token] = this.extractBambuCredentials(apiKey);
204
+ const printerFTP = this.getBambuPrinterForFTP(host, serial, token);
205
+ if (!printerFTP.isConnected)
206
+ await printerFTP.connect();
207
+ const fileList = [];
208
+ await printerFTP.manipulateFiles(async (context) => {
209
+ const files = await context.readDir("gcodes");
210
+ fileList.push(...files);
211
+ });
212
+ return { files: fileList };
213
+ }
214
+ async getFile(host, port, apiKey, filename) {
215
+ // Still relies on checking existence via FTP
216
+ const [serial, token] = this.extractBambuCredentials(apiKey);
217
+ const printerFTP = this.getBambuPrinterForFTP(host, serial, token);
218
+ if (!printerFTP.isConnected)
219
+ await printerFTP.connect();
220
+ let fileExists = false;
221
+ await printerFTP.manipulateFiles(async (context) => {
222
+ const files = await context.readDir("gcodes");
223
+ fileExists = files.includes(filename);
224
+ });
225
+ if (!fileExists)
226
+ throw new Error(`File not found: ${filename}`);
227
+ return { name: filename, exists: true };
228
+ }
229
+ async uploadFile(host, port, apiKey, filePath, filename, print) {
230
+ // This method just uploads now, doesn't handle printing
231
+ const [serial, token] = this.extractBambuCredentials(apiKey);
232
+ const printerFTP = this.getBambuPrinterForFTP(host, serial, token);
233
+ const remotePath = `gcodes/${filename}`.replace(/\\/g, '/');
234
+ if (!printerFTP.isConnected)
235
+ await printerFTP.connect();
236
+ console.log(`Uploading ${filePath} to ${remotePath} via FTP...`);
237
+ try {
238
+ await printerFTP.manipulateFiles(async (context) => {
239
+ await context.sendFile(filePath, remotePath);
240
+ });
241
+ console.log(`File ${filename} uploaded successfully.`);
242
+ if (print) {
243
+ console.warn("'print=true' ignored in uploadFile for Bambu. Use print_3mf tool instead.");
244
+ }
245
+ return { status: "success", message: `File ${filename} uploaded successfully` };
246
+ }
247
+ catch (uploadError) {
248
+ console.error(`FTP Upload Error:`, uploadError);
249
+ throw new Error(`Failed to upload file via FTP: ${uploadError.message}`);
250
+ }
251
+ }
252
+ async startJob(host, port, apiKey, filename) {
253
+ // This should likely be deprecated or only work for G-code files via a different MQTT command?
254
+ console.warn("startJob is not recommended for Bambu .3mf files. Use print_3mf tool.");
255
+ throw new Error("startJob is not implemented for Bambu printers using MQTT commands yet.");
256
+ }
257
+ // --- Helper to publish MQTT commands ---
258
+ async publishMqttCommand(client, serial, commandType, payload) {
259
+ const topic = `device/${serial}/request`;
260
+ const message = JSON.stringify({ [commandType]: payload });
261
+ console.log(`Publishing MQTT to ${topic}: ${message}`);
262
+ return new Promise((resolve, reject) => {
263
+ client.publish(topic, message, { qos: 1 }, (err) => {
264
+ if (err) {
265
+ console.error(`MQTT Publish Error to ${topic}:`, err);
266
+ reject(new Error(`Failed to publish MQTT command: ${err.message}`));
267
+ }
268
+ else {
269
+ console.log(`MQTT command published successfully to ${topic}`);
270
+ // Note: We don't wait for a response here. Status updates come via /report topic.
271
+ resolve({ status: "success", message: "Command sent successfully via MQTT." });
272
+ }
273
+ });
274
+ });
275
+ }
276
+ // Helper method to extract Bambu-specific credentials from apiKey
277
+ extractBambuCredentials(apiKey) {
278
+ const parts = apiKey.split(':');
279
+ if (parts.length !== 2) {
280
+ throw new Error("Invalid Bambu credentials format. Expected 'serial:token'");
281
+ }
282
+ return [parts[0], parts[1]];
283
+ }
284
+ }
@@ -0,0 +1,10 @@
1
+ import { PrinterImplementation } from "../types.js";
2
+ export declare class CrealityImplementation extends PrinterImplementation {
3
+ getStatus(host: string, port: string, apiKey: string): Promise<any>;
4
+ getFiles(host: string, port: string, apiKey: string): Promise<any>;
5
+ getFile(host: string, port: string, apiKey: string, filename: string): Promise<any>;
6
+ uploadFile(host: string, port: string, apiKey: string, filePath: string, filename: string, print: boolean): Promise<any>;
7
+ startJob(host: string, port: string, apiKey: string, filename: string): Promise<any>;
8
+ cancelJob(host: string, port: string, apiKey: string): Promise<any>;
9
+ setTemperature(host: string, port: string, apiKey: string, component: string, temperature: number): Promise<any>;
10
+ }
@@ -0,0 +1,90 @@
1
+ import { PrinterImplementation } from "../types.js";
2
+ import fs from "fs";
3
+ import FormData from "form-data";
4
+ export class CrealityImplementation extends PrinterImplementation {
5
+ async getStatus(host, port, apiKey) {
6
+ const url = `http://${host}:${port}/api/device/status`;
7
+ const response = await this.apiClient.get(url, {
8
+ headers: {
9
+ "Authorization": `Bearer ${apiKey}`
10
+ }
11
+ });
12
+ return response.data;
13
+ }
14
+ async getFiles(host, port, apiKey) {
15
+ const url = `http://${host}:${port}/api/storage/list`;
16
+ const response = await this.apiClient.get(url, {
17
+ headers: {
18
+ "Authorization": `Bearer ${apiKey}`
19
+ }
20
+ });
21
+ return response.data;
22
+ }
23
+ async getFile(host, port, apiKey, filename) {
24
+ const url = `http://${host}:${port}/api/storage/info?filename=${encodeURIComponent(filename)}`;
25
+ const response = await this.apiClient.get(url, {
26
+ headers: {
27
+ "Authorization": `Bearer ${apiKey}`
28
+ }
29
+ });
30
+ return response.data;
31
+ }
32
+ async uploadFile(host, port, apiKey, filePath, filename, print) {
33
+ const url = `http://${host}:${port}/api/storage/upload`;
34
+ const formData = new FormData();
35
+ formData.append("file", fs.createReadStream(filePath));
36
+ formData.append("filename", filename);
37
+ const response = await this.apiClient.post(url, formData, {
38
+ headers: {
39
+ "Authorization": `Bearer ${apiKey}`,
40
+ ...formData.getHeaders()
41
+ }
42
+ });
43
+ if (print && response.data.success) {
44
+ await this.startJob(host, port, apiKey, filename);
45
+ }
46
+ return response.data;
47
+ }
48
+ async startJob(host, port, apiKey, filename) {
49
+ const url = `http://${host}:${port}/api/job/start`;
50
+ const response = await this.apiClient.post(url, {
51
+ filename: filename
52
+ }, {
53
+ headers: {
54
+ "Authorization": `Bearer ${apiKey}`,
55
+ "Content-Type": "application/json"
56
+ }
57
+ });
58
+ return response.data;
59
+ }
60
+ async cancelJob(host, port, apiKey) {
61
+ const url = `http://${host}:${port}/api/job/cancel`;
62
+ const response = await this.apiClient.post(url, {}, {
63
+ headers: {
64
+ "Authorization": `Bearer ${apiKey}`,
65
+ "Content-Type": "application/json"
66
+ }
67
+ });
68
+ return response.data;
69
+ }
70
+ async setTemperature(host, port, apiKey, component, temperature) {
71
+ const url = `http://${host}:${port}/api/printer/temperature`;
72
+ let data = {};
73
+ if (component === "bed") {
74
+ data.bed = temperature;
75
+ }
76
+ else if (component === "extruder") {
77
+ data.hotend = temperature;
78
+ }
79
+ else {
80
+ throw new Error(`Unsupported component: ${component}`);
81
+ }
82
+ const response = await this.apiClient.post(url, data, {
83
+ headers: {
84
+ "Authorization": `Bearer ${apiKey}`,
85
+ "Content-Type": "application/json"
86
+ }
87
+ });
88
+ return response.data;
89
+ }
90
+ }
@@ -0,0 +1,10 @@
1
+ import { PrinterImplementation } from "../types.js";
2
+ export declare class DuetImplementation extends PrinterImplementation {
3
+ getStatus(host: string, port: string, apiKey: string): Promise<any>;
4
+ getFiles(host: string, port: string, apiKey: string): Promise<any>;
5
+ getFile(host: string, port: string, apiKey: string, filename: string): Promise<any>;
6
+ uploadFile(host: string, port: string, apiKey: string, filePath: string, filename: string, print: boolean): Promise<any>;
7
+ startJob(host: string, port: string, apiKey: string, filename: string): Promise<any>;
8
+ cancelJob(host: string, port: string, apiKey: string): Promise<any>;
9
+ setTemperature(host: string, port: string, apiKey: string, component: string, temperature: number): Promise<any>;
10
+ }
@@ -0,0 +1,66 @@
1
+ import { PrinterImplementation } from "../types.js";
2
+ import fs from "fs";
3
+ import FormData from "form-data";
4
+ export class DuetImplementation extends PrinterImplementation {
5
+ async getStatus(host, port, apiKey) {
6
+ const url = `http://${host}:${port}/machine/status`;
7
+ const response = await this.apiClient.get(url);
8
+ return response.data;
9
+ }
10
+ async getFiles(host, port, apiKey) {
11
+ const url = `http://${host}:${port}/machine/file-list`;
12
+ const response = await this.apiClient.get(url);
13
+ return response.data;
14
+ }
15
+ async getFile(host, port, apiKey, filename) {
16
+ const url = `http://${host}:${port}/machine/file/${encodeURIComponent(filename)}`;
17
+ const response = await this.apiClient.get(url);
18
+ return response.data;
19
+ }
20
+ async uploadFile(host, port, apiKey, filePath, filename, print) {
21
+ const url = `http://${host}:${port}/machine/file-upload`;
22
+ const formData = new FormData();
23
+ formData.append("file", fs.createReadStream(filePath));
24
+ formData.append("filename", filename);
25
+ const response = await this.apiClient.post(url, formData, {
26
+ headers: {
27
+ ...formData.getHeaders()
28
+ }
29
+ });
30
+ if (print && response.data.err === 0) {
31
+ await this.startJob(host, port, apiKey, filename);
32
+ }
33
+ return response.data;
34
+ }
35
+ async startJob(host, port, apiKey, filename) {
36
+ const url = `http://${host}:${port}/machine/code`;
37
+ const response = await this.apiClient.post(url, {
38
+ code: `M32 "${filename}"`
39
+ });
40
+ return response.data;
41
+ }
42
+ async cancelJob(host, port, apiKey) {
43
+ const url = `http://${host}:${port}/machine/code`;
44
+ const response = await this.apiClient.post(url, {
45
+ code: "M0"
46
+ });
47
+ return response.data;
48
+ }
49
+ async setTemperature(host, port, apiKey, component, temperature) {
50
+ const url = `http://${host}:${port}/machine/code`;
51
+ let gcode;
52
+ if (component === "bed") {
53
+ gcode = `M140 S${temperature}`;
54
+ }
55
+ else if (component === "extruder") {
56
+ gcode = `M104 S${temperature}`;
57
+ }
58
+ else {
59
+ throw new Error(`Unsupported component: ${component}`);
60
+ }
61
+ const response = await this.apiClient.post(url, {
62
+ code: gcode
63
+ });
64
+ return response.data;
65
+ }
66
+ }
@@ -0,0 +1,10 @@
1
+ import { PrinterImplementation } from "../types.js";
2
+ export declare class KlipperImplementation extends PrinterImplementation {
3
+ getStatus(host: string, port: string, apiKey: string): Promise<any>;
4
+ getFiles(host: string, port: string, apiKey: string): Promise<any>;
5
+ getFile(host: string, port: string, apiKey: string, filename: string): Promise<any>;
6
+ uploadFile(host: string, port: string, apiKey: string, filePath: string, filename: string, print: boolean): Promise<any>;
7
+ startJob(host: string, port: string, apiKey: string, filename: string): Promise<any>;
8
+ cancelJob(host: string, port: string, apiKey: string): Promise<any>;
9
+ setTemperature(host: string, port: string, apiKey: string, component: string, temperature: number): Promise<any>;
10
+ }
@@ -0,0 +1,62 @@
1
+ import { PrinterImplementation } from "../types.js";
2
+ import fs from "fs";
3
+ import FormData from "form-data";
4
+ export class KlipperImplementation extends PrinterImplementation {
5
+ async getStatus(host, port, apiKey) {
6
+ const url = `http://${host}:${port}/printer/info`;
7
+ const response = await this.apiClient.get(url);
8
+ return response.data;
9
+ }
10
+ async getFiles(host, port, apiKey) {
11
+ const url = `http://${host}:${port}/server/files/list`;
12
+ const response = await this.apiClient.get(url);
13
+ return response.data;
14
+ }
15
+ async getFile(host, port, apiKey, filename) {
16
+ const url = `http://${host}:${port}/server/files/metadata?filename=${encodeURIComponent(filename)}`;
17
+ const response = await this.apiClient.get(url);
18
+ return response.data;
19
+ }
20
+ async uploadFile(host, port, apiKey, filePath, filename, print) {
21
+ const url = `http://${host}:${port}/server/files/upload`;
22
+ const formData = new FormData();
23
+ formData.append("file", fs.createReadStream(filePath));
24
+ formData.append("filename", filename);
25
+ const response = await this.apiClient.post(url, formData, {
26
+ headers: {
27
+ ...formData.getHeaders()
28
+ }
29
+ });
30
+ if (print && response.data.result === "success") {
31
+ await this.startJob(host, port, apiKey, filename);
32
+ }
33
+ return response.data;
34
+ }
35
+ async startJob(host, port, apiKey, filename) {
36
+ const url = `http://${host}:${port}/printer/print/start`;
37
+ const response = await this.apiClient.post(url, { filename });
38
+ return response.data;
39
+ }
40
+ async cancelJob(host, port, apiKey) {
41
+ const url = `http://${host}:${port}/printer/print/cancel`;
42
+ const response = await this.apiClient.post(url, null);
43
+ return response.data;
44
+ }
45
+ async setTemperature(host, port, apiKey, component, temperature) {
46
+ const url = `http://${host}:${port}/printer/gcode/script`;
47
+ let gcode;
48
+ if (component === "bed") {
49
+ gcode = `SET_HEATER_TEMPERATURE HEATER=heater_bed TARGET=${temperature}`;
50
+ }
51
+ else if (component === "extruder") {
52
+ gcode = `SET_HEATER_TEMPERATURE HEATER=extruder TARGET=${temperature}`;
53
+ }
54
+ else {
55
+ throw new Error(`Unsupported component: ${component}`);
56
+ }
57
+ const response = await this.apiClient.post(url, {
58
+ script: gcode
59
+ });
60
+ return response.data;
61
+ }
62
+ }
@@ -0,0 +1,10 @@
1
+ import { PrinterImplementation } from "../types.js";
2
+ export declare class OctoPrintImplementation extends PrinterImplementation {
3
+ getStatus(host: string, port: string, apiKey: string): Promise<any>;
4
+ getFiles(host: string, port: string, apiKey: string): Promise<any>;
5
+ getFile(host: string, port: string, apiKey: string, filename: string): Promise<any>;
6
+ uploadFile(host: string, port: string, apiKey: string, filePath: string, filename: string, print: boolean): Promise<any>;
7
+ startJob(host: string, port: string, apiKey: string, filename: string): Promise<any>;
8
+ cancelJob(host: string, port: string, apiKey: string): Promise<any>;
9
+ setTemperature(host: string, port: string, apiKey: string, component: string, temperature: number): Promise<any>;
10
+ }