n8n-nodes-bambulab 0.1.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 (31) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +273 -0
  3. package/dist/credentials/BambuLabApi.credentials.d.ts +10 -0
  4. package/dist/credentials/BambuLabApi.credentials.d.ts.map +1 -0
  5. package/dist/credentials/BambuLabApi.credentials.js +73 -0
  6. package/dist/credentials/BambuLabApi.credentials.js.map +1 -0
  7. package/dist/nodes/BambuLab/BambuLab.node.d.ts +6 -0
  8. package/dist/nodes/BambuLab/BambuLab.node.d.ts.map +1 -0
  9. package/dist/nodes/BambuLab/BambuLab.node.js +647 -0
  10. package/dist/nodes/BambuLab/BambuLab.node.js.map +1 -0
  11. package/dist/nodes/BambuLab/bambulab.svg +29 -0
  12. package/dist/nodes/BambuLab/helpers/FtpHelper.d.ts +60 -0
  13. package/dist/nodes/BambuLab/helpers/FtpHelper.d.ts.map +1 -0
  14. package/dist/nodes/BambuLab/helpers/FtpHelper.js +238 -0
  15. package/dist/nodes/BambuLab/helpers/FtpHelper.js.map +1 -0
  16. package/dist/nodes/BambuLab/helpers/MqttHelper.d.ts +52 -0
  17. package/dist/nodes/BambuLab/helpers/MqttHelper.d.ts.map +1 -0
  18. package/dist/nodes/BambuLab/helpers/MqttHelper.js +314 -0
  19. package/dist/nodes/BambuLab/helpers/MqttHelper.js.map +1 -0
  20. package/dist/nodes/BambuLab/helpers/commands.d.ts +116 -0
  21. package/dist/nodes/BambuLab/helpers/commands.d.ts.map +1 -0
  22. package/dist/nodes/BambuLab/helpers/commands.js +242 -0
  23. package/dist/nodes/BambuLab/helpers/commands.js.map +1 -0
  24. package/dist/nodes/BambuLab/helpers/types.d.ts +277 -0
  25. package/dist/nodes/BambuLab/helpers/types.d.ts.map +1 -0
  26. package/dist/nodes/BambuLab/helpers/types.js +7 -0
  27. package/dist/nodes/BambuLab/helpers/types.js.map +1 -0
  28. package/examples/README.md +140 -0
  29. package/examples/monitor-print-progress.json +123 -0
  30. package/examples/upload-and-print.json +108 -0
  31. package/package.json +72 -0
@@ -0,0 +1,314 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.BambuLabMqttClient = void 0;
37
+ const mqtt = __importStar(require("mqtt"));
38
+ /**
39
+ * MQTT Helper for Bambu Lab Printer Communication
40
+ * Handles connection, command publishing, and status subscription
41
+ */
42
+ class BambuLabMqttClient {
43
+ client = null;
44
+ credentials;
45
+ reportTopic;
46
+ requestTopic;
47
+ messageBuffer = [];
48
+ connectionTimeout = 10000; // 10 seconds
49
+ responseTimeout = 30000; // 30 seconds
50
+ updateCallback;
51
+ constructor(credentials) {
52
+ this.credentials = credentials;
53
+ this.reportTopic = `device/${credentials.serialNumber}/report`;
54
+ this.requestTopic = `device/${credentials.serialNumber}/request`;
55
+ }
56
+ /**
57
+ * Connect to the Bambu Lab printer via MQTT
58
+ */
59
+ async connect() {
60
+ return new Promise((resolve, reject) => {
61
+ const protocol = this.credentials.useTls ? 'mqtts' : 'mqtt';
62
+ const brokerUrl = `${protocol}://${this.credentials.printerIp}:${this.credentials.mqttPort}`;
63
+ const options = {
64
+ username: 'bblp',
65
+ password: this.credentials.accessCode,
66
+ protocol: this.credentials.useTls ? 'mqtts' : 'mqtt',
67
+ port: this.credentials.mqttPort,
68
+ // Bambu Lab printers use self-signed certificates
69
+ rejectUnauthorized: false,
70
+ connectTimeout: this.connectionTimeout,
71
+ reconnectPeriod: 0, // Disable auto-reconnect, we'll handle it manually
72
+ };
73
+ try {
74
+ this.client = mqtt.connect(brokerUrl, options);
75
+ // Connection timeout
76
+ const timeout = setTimeout(() => {
77
+ this.client?.end(true);
78
+ reject(new Error(`MQTT connection timeout after ${this.connectionTimeout}ms. Please check printer IP and network connection.`));
79
+ }, this.connectionTimeout);
80
+ // Connection successful
81
+ this.client.on('connect', () => {
82
+ clearTimeout(timeout);
83
+ // Subscribe to printer reports
84
+ this.client?.subscribe(this.reportTopic, (err) => {
85
+ if (err) {
86
+ reject(new Error(`Failed to subscribe to ${this.reportTopic}: ${err.message}`));
87
+ }
88
+ else {
89
+ resolve();
90
+ }
91
+ });
92
+ });
93
+ // Connection error
94
+ this.client.on('error', (error) => {
95
+ clearTimeout(timeout);
96
+ reject(new Error(`MQTT connection error: ${error.message}`));
97
+ });
98
+ // Handle incoming messages
99
+ this.client.on('message', (topic, message) => {
100
+ try {
101
+ const parsedMessage = JSON.parse(message.toString());
102
+ this.messageBuffer.push(parsedMessage);
103
+ // Also call the update callback if registered
104
+ if (this.updateCallback && topic === this.reportTopic) {
105
+ this.updateCallback(parsedMessage);
106
+ }
107
+ }
108
+ catch (error) {
109
+ console.error('Failed to parse MQTT message:', error);
110
+ }
111
+ });
112
+ }
113
+ catch (error) {
114
+ reject(new Error(`Failed to create MQTT client: ${error.message}`));
115
+ }
116
+ });
117
+ }
118
+ /**
119
+ * Publish a command to the printer
120
+ */
121
+ async publishCommand(command, waitForResponse = false) {
122
+ return new Promise((resolve, reject) => {
123
+ if (!this.client || !this.client.connected) {
124
+ reject(new Error('MQTT client is not connected'));
125
+ return;
126
+ }
127
+ // Clear message buffer if we're waiting for a response
128
+ if (waitForResponse) {
129
+ this.messageBuffer = [];
130
+ }
131
+ const commandStr = JSON.stringify(command);
132
+ this.client.publish(this.requestTopic, commandStr, { qos: 1 }, (error) => {
133
+ if (error) {
134
+ reject(new Error(`Failed to publish command: ${error.message}`));
135
+ return;
136
+ }
137
+ if (!waitForResponse) {
138
+ const seqId = 'print' in command
139
+ ? command.print.sequence_id
140
+ : 'pushing' in command
141
+ ? command.pushing.sequence_id
142
+ : 'system' in command && command.system
143
+ ? command.system.sequence_id
144
+ : 'gcode_line' in command
145
+ ? command.gcode_line.sequence_id
146
+ : undefined;
147
+ resolve({
148
+ success: true,
149
+ message: 'Command sent successfully',
150
+ sequence_id: seqId,
151
+ });
152
+ return;
153
+ }
154
+ // Wait for response with proper cleanup
155
+ let timeout = null;
156
+ let checkInterval = null;
157
+ const cleanup = () => {
158
+ if (timeout)
159
+ clearTimeout(timeout);
160
+ if (checkInterval)
161
+ clearInterval(checkInterval);
162
+ };
163
+ timeout = setTimeout(() => {
164
+ cleanup();
165
+ reject(new Error(`Command response timeout after ${this.responseTimeout}ms`));
166
+ }, this.responseTimeout);
167
+ // Poll for response in message buffer
168
+ // Extract sequence_id from the command to match responses
169
+ const commandSeqId = 'print' in command
170
+ ? command.print.sequence_id
171
+ : 'pushing' in command
172
+ ? command.pushing.sequence_id
173
+ : 'system' in command && command.system
174
+ ? command.system.sequence_id
175
+ : 'gcode_line' in command
176
+ ? command.gcode_line.sequence_id
177
+ : undefined;
178
+ checkInterval = setInterval(() => {
179
+ if (this.messageBuffer.length > 0) {
180
+ let response;
181
+ // If we have a sequence ID, try to find matching response
182
+ if (commandSeqId) {
183
+ response = this.messageBuffer.find((msg) => msg.print?.sequence_id === commandSeqId ||
184
+ msg.pushing?.sequence_id === commandSeqId ||
185
+ msg.system?.sequence_id === commandSeqId ||
186
+ msg.gcode_line?.sequence_id === commandSeqId);
187
+ }
188
+ // Fallback: if no sequence ID or no match found, take the last message
189
+ if (!response) {
190
+ response = this.messageBuffer[this.messageBuffer.length - 1];
191
+ }
192
+ // If we found a response, return it
193
+ if (response) {
194
+ cleanup();
195
+ this.messageBuffer = [];
196
+ resolve({
197
+ success: true,
198
+ message: 'Command executed and response received',
199
+ data: response,
200
+ });
201
+ }
202
+ }
203
+ }, 100);
204
+ });
205
+ });
206
+ }
207
+ /**
208
+ * Get current printer status
209
+ * Sends a "pushall" command and waits for the response
210
+ */
211
+ async getStatus() {
212
+ return new Promise((resolve, reject) => {
213
+ if (!this.client || !this.client.connected) {
214
+ reject(new Error('MQTT client is not connected'));
215
+ return;
216
+ }
217
+ // Clear message buffer
218
+ this.messageBuffer = [];
219
+ // Send pushall command to request full status
220
+ const pushCommand = {
221
+ pushing: {
222
+ sequence_id: Date.now().toString(),
223
+ command: 'pushall',
224
+ version: 1,
225
+ push_target: 1,
226
+ },
227
+ };
228
+ this.client.publish(this.requestTopic, JSON.stringify(pushCommand), { qos: 1 }, (error) => {
229
+ if (error) {
230
+ reject(new Error(`Failed to request status: ${error.message}`));
231
+ return;
232
+ }
233
+ // Wait for response with proper cleanup
234
+ let timeout = null;
235
+ let checkInterval = null;
236
+ const cleanup = () => {
237
+ if (timeout)
238
+ clearTimeout(timeout);
239
+ if (checkInterval)
240
+ clearInterval(checkInterval);
241
+ };
242
+ timeout = setTimeout(() => {
243
+ cleanup();
244
+ reject(new Error(`Status request timeout after ${this.responseTimeout}ms`));
245
+ }, this.responseTimeout);
246
+ // Poll for response in message buffer
247
+ const expectedSeqId = pushCommand.pushing.sequence_id;
248
+ checkInterval = setInterval(() => {
249
+ if (this.messageBuffer.length > 0) {
250
+ let status;
251
+ // Try to find the response matching our sequence ID
252
+ status = this.messageBuffer.find((msg) => msg.pushing?.sequence_id === expectedSeqId);
253
+ // Fallback: if no match found, take the last message
254
+ if (!status) {
255
+ status = this.messageBuffer[this.messageBuffer.length - 1];
256
+ }
257
+ // If we found a status, return it
258
+ if (status) {
259
+ cleanup();
260
+ this.messageBuffer = [];
261
+ resolve(status);
262
+ }
263
+ }
264
+ }, 100);
265
+ });
266
+ });
267
+ }
268
+ /**
269
+ * Subscribe to printer status updates with a callback
270
+ * Useful for real-time monitoring
271
+ */
272
+ subscribeToUpdates(callback) {
273
+ if (!this.client) {
274
+ throw new Error('MQTT client is not initialized');
275
+ }
276
+ // Store the callback - will be invoked by the existing message handler
277
+ this.updateCallback = callback;
278
+ }
279
+ /**
280
+ * Get the MQTT client instance (for advanced usage)
281
+ */
282
+ getClient() {
283
+ return this.client;
284
+ }
285
+ /**
286
+ * Check if the client is connected
287
+ */
288
+ isConnected() {
289
+ return this.client?.connected ?? false;
290
+ }
291
+ /**
292
+ * Disconnect from the printer
293
+ */
294
+ disconnect() {
295
+ if (this.client) {
296
+ this.client.end(false, {}, () => {
297
+ this.client = null;
298
+ this.messageBuffer = [];
299
+ });
300
+ }
301
+ }
302
+ /**
303
+ * Force disconnect (immediate)
304
+ */
305
+ forceDisconnect() {
306
+ if (this.client) {
307
+ this.client.end(true);
308
+ this.client = null;
309
+ this.messageBuffer = [];
310
+ }
311
+ }
312
+ }
313
+ exports.BambuLabMqttClient = BambuLabMqttClient;
314
+ //# sourceMappingURL=MqttHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MqttHelper.js","sourceRoot":"","sources":["../../../../nodes/BambuLab/helpers/MqttHelper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ import type { PrintCommand, PushingCommand, SystemCommand, GcodeLineCommand, PrintJobOptions, LEDMode, LEDNode } from './types';
2
+ /**
3
+ * Command Builder for Bambu Lab Printer MQTT Commands
4
+ * Generates properly formatted commands with sequence IDs
5
+ */
6
+ export declare class BambuLabCommands {
7
+ private sequenceId;
8
+ /**
9
+ * Get next sequence ID (incremental)
10
+ */
11
+ private getNextSequenceId;
12
+ /**
13
+ * Start a print job
14
+ * @param fileName Name of the file on the printer's SD card
15
+ * @param options Print job options
16
+ */
17
+ startPrint(fileName: string, options?: Partial<PrintJobOptions>): PrintCommand;
18
+ /**
19
+ * Pause the current print job
20
+ */
21
+ pausePrint(): PrintCommand;
22
+ /**
23
+ * Resume a paused print job
24
+ */
25
+ resumePrint(): PrintCommand;
26
+ /**
27
+ * Stop the current print job
28
+ */
29
+ stopPrint(): PrintCommand;
30
+ /**
31
+ * Request full printer status (pushall)
32
+ */
33
+ getPushAll(): PushingCommand;
34
+ /**
35
+ * Start continuous status updates
36
+ */
37
+ startPushing(): PushingCommand;
38
+ /**
39
+ * Stop continuous status updates
40
+ */
41
+ stopPushing(): PushingCommand;
42
+ /**
43
+ * Control printer LED lights
44
+ * @param node Which LED to control
45
+ * @param mode LED mode (on, off, flashing)
46
+ * @param onTime Time LED is on (for flashing mode, in ms)
47
+ * @param offTime Time LED is off (for flashing mode, in ms)
48
+ */
49
+ setLED(node: LEDNode, mode: LEDMode, onTime?: number, offTime?: number): SystemCommand;
50
+ /**
51
+ * Send custom G-code command to the printer
52
+ * @param gcode G-code command (without line number)
53
+ * @param param Optional parameter
54
+ */
55
+ sendGcode(gcode: string, param?: string): GcodeLineCommand;
56
+ /**
57
+ * Home the printer axes
58
+ */
59
+ homeAxes(): GcodeLineCommand;
60
+ /**
61
+ * Set print speed
62
+ * @param speed Speed percentage (50-166)
63
+ */
64
+ setSpeed(speed: number): SystemCommand;
65
+ /**
66
+ * Control chamber fan
67
+ * @param speed Fan speed percentage (0-100)
68
+ */
69
+ setChamberFan(speed: number): GcodeLineCommand;
70
+ /**
71
+ * Control auxiliary (part cooling) fan
72
+ * @param speed Fan speed percentage (0-100)
73
+ */
74
+ setPartCoolingFan(speed: number): GcodeLineCommand;
75
+ /**
76
+ * Unload filament from AMS
77
+ * @param trayId Tray ID (0-3)
78
+ */
79
+ unloadFilament(trayId: number): GcodeLineCommand;
80
+ /**
81
+ * Load filament from AMS
82
+ * @param trayId Tray ID (0-3)
83
+ */
84
+ loadFilament(trayId: number): GcodeLineCommand;
85
+ /**
86
+ * Resume filament loading after manual intervention
87
+ */
88
+ resumeFilamentLoad(): GcodeLineCommand;
89
+ /**
90
+ * Set bed temperature
91
+ * @param temperature Target temperature in Celsius
92
+ */
93
+ setBedTemperature(temperature: number): GcodeLineCommand;
94
+ /**
95
+ * Set nozzle temperature
96
+ * @param temperature Target temperature in Celsius
97
+ */
98
+ setNozzleTemperature(temperature: number): GcodeLineCommand;
99
+ /**
100
+ * Turn off all heaters
101
+ */
102
+ turnOffHeaters(): GcodeLineCommand;
103
+ /**
104
+ * Emergency stop (turns off all heaters and motors)
105
+ */
106
+ emergencyStop(): GcodeLineCommand;
107
+ /**
108
+ * Get current sequence ID (for reference)
109
+ */
110
+ getCurrentSequenceId(): number;
111
+ /**
112
+ * Reset sequence ID counter
113
+ */
114
+ resetSequenceId(): void;
115
+ }
116
+ //# sourceMappingURL=commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../nodes/BambuLab/helpers/commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,YAAY,EACZ,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,OAAO,EACP,OAAO,EACP,MAAM,SAAS,CAAC;AAEjB;;;GAGG;AACH,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,UAAU,CAAK;IAEvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;;;OAIG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,YAAY;IA4B9E;;OAEG;IACH,UAAU,IAAI,YAAY;IAS1B;;OAEG;IACH,WAAW,IAAI,YAAY;IAS3B;;OAEG;IACH,SAAS,IAAI,YAAY;IASzB;;OAEG;IACH,UAAU,IAAI,cAAc;IAU5B;;OAEG;IACH,YAAY,IAAI,cAAc;IAS9B;;OAEG;IACH,WAAW,IAAI,cAAc;IAS7B;;;;;;OAMG;IACH,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,SAAM,EAAE,OAAO,SAAM,GAAG,aAAa;IAahF;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB;IAU1D;;OAEG;IACH,QAAQ,IAAI,gBAAgB;IAI5B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa;IAWtC;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB;IAK9C;;;OAGG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB;IAKlD;;;OAGG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB;IAIhD;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB;IAI9C;;OAEG;IACH,kBAAkB,IAAI,gBAAgB;IAItC;;;OAGG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB;IAIxD;;;OAGG;IACH,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB;IAI3D;;OAEG;IACH,cAAc,IAAI,gBAAgB;IAIlC;;OAEG;IACH,aAAa,IAAI,gBAAgB;IAIjC;;OAEG;IACH,oBAAoB,IAAI,MAAM;IAI9B;;OAEG;IACH,eAAe,IAAI,IAAI;CAGvB"}
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BambuLabCommands = void 0;
4
+ /**
5
+ * Command Builder for Bambu Lab Printer MQTT Commands
6
+ * Generates properly formatted commands with sequence IDs
7
+ */
8
+ class BambuLabCommands {
9
+ sequenceId = 0;
10
+ /**
11
+ * Get next sequence ID (incremental)
12
+ */
13
+ getNextSequenceId() {
14
+ return (this.sequenceId++).toString();
15
+ }
16
+ /**
17
+ * Start a print job
18
+ * @param fileName Name of the file on the printer's SD card
19
+ * @param options Print job options
20
+ */
21
+ startPrint(fileName, options) {
22
+ // Ensure filename has proper path format
23
+ const fileUrl = fileName.startsWith('file:///')
24
+ ? fileName
25
+ : `file:///mnt/sdcard/${fileName}`;
26
+ // Extract just the filename (not the full path) for display
27
+ const displayName = fileName.split('/').pop() || fileName;
28
+ return {
29
+ print: {
30
+ sequence_id: this.getNextSequenceId(),
31
+ command: 'project_file',
32
+ // Bambu Lab API requires this metadata parameter for all print jobs
33
+ // This points to the plate metadata within the 3MF/gcode file
34
+ param: 'Metadata/plate_1.gcode',
35
+ url: fileUrl,
36
+ subtask_name: displayName,
37
+ bed_leveling: options?.bedLeveling ?? true,
38
+ flow_cali: options?.flowCalibration ?? false,
39
+ vibration_cali: options?.vibrationCalibration ?? false,
40
+ layer_inspect: options?.layerInspect ?? false,
41
+ use_ams: options?.useAMS ?? false,
42
+ ams_mapping: options?.amsMapping ?? [],
43
+ },
44
+ };
45
+ }
46
+ /**
47
+ * Pause the current print job
48
+ */
49
+ pausePrint() {
50
+ return {
51
+ print: {
52
+ sequence_id: this.getNextSequenceId(),
53
+ command: 'pause',
54
+ },
55
+ };
56
+ }
57
+ /**
58
+ * Resume a paused print job
59
+ */
60
+ resumePrint() {
61
+ return {
62
+ print: {
63
+ sequence_id: this.getNextSequenceId(),
64
+ command: 'resume',
65
+ },
66
+ };
67
+ }
68
+ /**
69
+ * Stop the current print job
70
+ */
71
+ stopPrint() {
72
+ return {
73
+ print: {
74
+ sequence_id: this.getNextSequenceId(),
75
+ command: 'stop',
76
+ },
77
+ };
78
+ }
79
+ /**
80
+ * Request full printer status (pushall)
81
+ */
82
+ getPushAll() {
83
+ return {
84
+ pushing: {
85
+ sequence_id: this.getNextSequenceId(),
86
+ command: 'pushall',
87
+ push_target: 1,
88
+ },
89
+ };
90
+ }
91
+ /**
92
+ * Start continuous status updates
93
+ */
94
+ startPushing() {
95
+ return {
96
+ pushing: {
97
+ sequence_id: this.getNextSequenceId(),
98
+ command: 'start',
99
+ },
100
+ };
101
+ }
102
+ /**
103
+ * Stop continuous status updates
104
+ */
105
+ stopPushing() {
106
+ return {
107
+ pushing: {
108
+ sequence_id: this.getNextSequenceId(),
109
+ command: 'stop',
110
+ },
111
+ };
112
+ }
113
+ /**
114
+ * Control printer LED lights
115
+ * @param node Which LED to control
116
+ * @param mode LED mode (on, off, flashing)
117
+ * @param onTime Time LED is on (for flashing mode, in ms)
118
+ * @param offTime Time LED is off (for flashing mode, in ms)
119
+ */
120
+ setLED(node, mode, onTime = 500, offTime = 500) {
121
+ return {
122
+ system: {
123
+ sequence_id: this.getNextSequenceId(),
124
+ command: 'ledctrl',
125
+ led_node: node,
126
+ led_mode: mode,
127
+ led_on_time: onTime,
128
+ led_off_time: offTime,
129
+ },
130
+ };
131
+ }
132
+ /**
133
+ * Send custom G-code command to the printer
134
+ * @param gcode G-code command (without line number)
135
+ * @param param Optional parameter
136
+ */
137
+ sendGcode(gcode, param) {
138
+ return {
139
+ gcode_line: {
140
+ sequence_id: this.getNextSequenceId(),
141
+ command: gcode,
142
+ param: param || '',
143
+ },
144
+ };
145
+ }
146
+ /**
147
+ * Home the printer axes
148
+ */
149
+ homeAxes() {
150
+ return this.sendGcode('G28');
151
+ }
152
+ /**
153
+ * Set print speed
154
+ * @param speed Speed percentage (50-166)
155
+ */
156
+ setSpeed(speed) {
157
+ const clampedSpeed = Math.max(50, Math.min(166, speed));
158
+ return {
159
+ system: {
160
+ sequence_id: this.getNextSequenceId(),
161
+ command: 'print_speed',
162
+ param: clampedSpeed.toString(),
163
+ },
164
+ };
165
+ }
166
+ /**
167
+ * Control chamber fan
168
+ * @param speed Fan speed percentage (0-100)
169
+ */
170
+ setChamberFan(speed) {
171
+ const clampedSpeed = Math.max(0, Math.min(100, speed));
172
+ return this.sendGcode('M106', `P2 S${Math.round((clampedSpeed / 100) * 255)}`);
173
+ }
174
+ /**
175
+ * Control auxiliary (part cooling) fan
176
+ * @param speed Fan speed percentage (0-100)
177
+ */
178
+ setPartCoolingFan(speed) {
179
+ const clampedSpeed = Math.max(0, Math.min(100, speed));
180
+ return this.sendGcode('M106', `P3 S${Math.round((clampedSpeed / 100) * 255)}`);
181
+ }
182
+ /**
183
+ * Unload filament from AMS
184
+ * @param trayId Tray ID (0-3)
185
+ */
186
+ unloadFilament(trayId) {
187
+ return this.sendGcode('M620', `P${trayId}A`);
188
+ }
189
+ /**
190
+ * Load filament from AMS
191
+ * @param trayId Tray ID (0-3)
192
+ */
193
+ loadFilament(trayId) {
194
+ return this.sendGcode('M620', `P${trayId}T255`);
195
+ }
196
+ /**
197
+ * Resume filament loading after manual intervention
198
+ */
199
+ resumeFilamentLoad() {
200
+ return this.sendGcode('M621', 'S255');
201
+ }
202
+ /**
203
+ * Set bed temperature
204
+ * @param temperature Target temperature in Celsius
205
+ */
206
+ setBedTemperature(temperature) {
207
+ return this.sendGcode('M140', `S${temperature}`);
208
+ }
209
+ /**
210
+ * Set nozzle temperature
211
+ * @param temperature Target temperature in Celsius
212
+ */
213
+ setNozzleTemperature(temperature) {
214
+ return this.sendGcode('M104', `S${temperature}`);
215
+ }
216
+ /**
217
+ * Turn off all heaters
218
+ */
219
+ turnOffHeaters() {
220
+ return this.sendGcode('M104 S0; M140 S0');
221
+ }
222
+ /**
223
+ * Emergency stop (turns off all heaters and motors)
224
+ */
225
+ emergencyStop() {
226
+ return this.sendGcode('M112');
227
+ }
228
+ /**
229
+ * Get current sequence ID (for reference)
230
+ */
231
+ getCurrentSequenceId() {
232
+ return this.sequenceId;
233
+ }
234
+ /**
235
+ * Reset sequence ID counter
236
+ */
237
+ resetSequenceId() {
238
+ this.sequenceId = 0;
239
+ }
240
+ }
241
+ exports.BambuLabCommands = BambuLabCommands;
242
+ //# sourceMappingURL=commands.js.map