@fdm-monster/server 1.9.0 → 1.9.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.
- package/.yarn/install-state.gz +0 -0
- package/.yarn/releases/{yarn-4.9.1.cjs → yarn-4.12.0.cjs} +329 -335
- package/.yarnrc.yml +1 -1
- package/README.md +3 -2
- package/RELEASE_NOTES.MD +17 -0
- package/dist/consoles/mock-bambu.server.js +305 -0
- package/dist/consoles/mock-bambu.server.js.map +1 -0
- package/dist/consoles/utils/api-messages.js +5 -5
- package/dist/consoles/utils/api-messages.js.map +1 -1
- package/dist/constants/authorization.constants.js +9 -9
- package/dist/constants/authorization.constants.js.map +1 -1
- package/dist/constants/event.constants.js +8 -8
- package/dist/constants/event.constants.js.map +1 -1
- package/dist/constants/server-settings.constants.js +15 -14
- package/dist/constants/server-settings.constants.js.map +1 -1
- package/dist/constants/service.constants.js +4 -4
- package/dist/constants/service.constants.js.map +1 -1
- package/dist/container.js +11 -3
- package/dist/container.js.map +1 -1
- package/dist/container.tokens.js +4 -0
- package/dist/container.tokens.js.map +1 -1
- package/dist/controllers/auth.controller.js.map +1 -1
- package/dist/controllers/batch-call.controller.js.map +1 -1
- package/dist/controllers/camera-stream.controller.js.map +1 -1
- package/dist/controllers/custom-gcode.controller.js.map +1 -1
- package/dist/controllers/first-time-setup.controller.js +33 -2
- package/dist/controllers/first-time-setup.controller.js.map +1 -1
- package/dist/controllers/floor.controller.js.map +1 -1
- package/dist/controllers/metrics.controller.js.map +1 -1
- package/dist/controllers/print-completion.controller.js.map +1 -1
- package/dist/controllers/printer-files.controller.js.map +1 -1
- package/dist/controllers/printer-group.controller.js.map +1 -1
- package/dist/controllers/printer-settings.controller.js.map +1 -1
- package/dist/controllers/printer.controller.js.map +1 -1
- package/dist/controllers/server-private.controller.js +10 -10
- package/dist/controllers/server-private.controller.js.map +1 -1
- package/dist/controllers/server-public.controller.js +4 -0
- package/dist/controllers/server-public.controller.js.map +1 -1
- package/dist/controllers/settings.controller.js +22 -0
- package/dist/controllers/settings.controller.js.map +1 -1
- package/dist/controllers/user.controller.js.map +1 -1
- package/dist/controllers/validation/batch-controller.validation.js +4 -4
- package/dist/controllers/validation/batch-controller.validation.js.map +1 -1
- package/dist/controllers/validation/generic.validation.js +3 -3
- package/dist/controllers/validation/generic.validation.js.map +1 -1
- package/dist/controllers/validation/printer-controller.validation.js +6 -6
- package/dist/controllers/validation/printer-controller.validation.js.map +1 -1
- package/dist/controllers/validation/printer-files-controller.validation.js +5 -5
- package/dist/controllers/validation/printer-files-controller.validation.js.map +1 -1
- package/dist/controllers/validation/setting.validation.js +4 -4
- package/dist/controllers/validation/setting.validation.js.map +1 -1
- package/dist/controllers/validation/user-controller.validation.js +8 -8
- package/dist/controllers/validation/user-controller.validation.js.map +1 -1
- package/dist/entities/index.js +12 -12
- package/dist/entities/index.js.map +1 -1
- package/dist/entities/settings.entity.js.map +1 -1
- package/dist/exceptions/failed-dependency.exception.js.map +1 -1
- package/dist/exceptions/job.exceptions.js.map +1 -1
- package/dist/exceptions/runtime.exceptions.js +10 -10
- package/dist/exceptions/runtime.exceptions.js.map +1 -1
- package/dist/handlers/logger.js.map +1 -1
- package/dist/handlers/logging/static.logger.js +4 -4
- package/dist/handlers/logging/static.logger.js.map +1 -1
- package/dist/handlers/validators.js +3 -3
- package/dist/handlers/validators.js.map +1 -1
- package/dist/middleware/authenticate.js +4 -4
- package/dist/middleware/authenticate.js.map +1 -1
- package/dist/middleware/global.middleware.js +4 -3
- package/dist/middleware/global.middleware.js.map +1 -1
- package/dist/middleware/param-converter.middleware.js +5 -5
- package/dist/middleware/param-converter.middleware.js.map +1 -1
- package/dist/middleware/passport.js +4 -4
- package/dist/middleware/passport.js.map +1 -1
- package/dist/middleware/printer.js +17 -6
- package/dist/middleware/printer.js.map +1 -1
- package/dist/models/Printer.js +3 -3
- package/dist/models/Printer.js.map +1 -1
- package/dist/models/Settings.js +5 -0
- package/dist/models/Settings.js.map +1 -1
- package/dist/models/index.js +11 -11
- package/dist/models/index.js.map +1 -1
- package/dist/server.constants.js +1 -1
- package/dist/server.env.js +9 -9
- package/dist/server.env.js.map +1 -1
- package/dist/server.host.js.map +1 -1
- package/dist/services/authentication/auth.service.js +1 -2
- package/dist/services/authentication/auth.service.js.map +1 -1
- package/dist/services/authentication/jwt.service.js.map +1 -1
- package/dist/services/bambu/bambu-ftp.adapter.js +204 -0
- package/dist/services/bambu/bambu-ftp.adapter.js.map +1 -0
- package/dist/services/bambu/bambu-mqtt.adapter.js +387 -0
- package/dist/services/bambu/bambu-mqtt.adapter.js.map +1 -0
- package/dist/services/bambu/bambu.client.js +67 -0
- package/dist/services/bambu/bambu.client.js.map +1 -0
- package/dist/services/bambu/mqtt-message.types.js +6 -0
- package/dist/services/bambu/mqtt-message.types.js.map +1 -0
- package/dist/services/bambu.api.js +221 -0
- package/dist/services/bambu.api.js.map +1 -0
- package/dist/services/core/batch-call.service.js.map +1 -1
- package/dist/services/core/client-bundle.service.js +4 -8
- package/dist/services/core/client-bundle.service.js.map +1 -1
- package/dist/services/core/cradle.service.js.map +1 -1
- package/dist/services/core/github.service.js.map +1 -1
- package/dist/services/core/http-client.factory.js.map +1 -1
- package/dist/services/core/logs-manager.service.js.map +1 -1
- package/dist/services/core/monsterpi.service.js.map +1 -1
- package/dist/services/core/multer.service.js +6 -7
- package/dist/services/core/multer.service.js.map +1 -1
- package/dist/services/core/server-release.service.js +6 -12
- package/dist/services/core/server-release.service.js.map +1 -1
- package/dist/services/core/yaml.service.js +123 -37
- package/dist/services/core/yaml.service.js.map +1 -1
- package/dist/services/interfaces/camera-stream.dto.js +4 -4
- package/dist/services/interfaces/camera-stream.dto.js.map +1 -1
- package/dist/services/interfaces/floor.dto.js +6 -6
- package/dist/services/interfaces/floor.dto.js.map +1 -1
- package/dist/services/interfaces/print-completion.dto.js +3 -3
- package/dist/services/interfaces/print-completion.dto.js.map +1 -1
- package/dist/services/interfaces/printer-group.dto.js +3 -3
- package/dist/services/interfaces/printer-group.dto.js.map +1 -1
- package/dist/services/interfaces/printer.dto.js +3 -3
- package/dist/services/interfaces/printer.dto.js.map +1 -1
- package/dist/services/interfaces/settings.dto.js.map +1 -1
- package/dist/services/interfaces/user.dto.js +3 -3
- package/dist/services/interfaces/user.dto.js.map +1 -1
- package/dist/services/mongoose/camera-stream.service.js +1 -2
- package/dist/services/mongoose/camera-stream.service.js.map +1 -1
- package/dist/services/mongoose/floor.service.js +1 -1
- package/dist/services/mongoose/floor.service.js.map +1 -1
- package/dist/services/mongoose/permission.service.js.map +1 -1
- package/dist/services/mongoose/print-completion.service.js.map +1 -1
- package/dist/services/mongoose/printer.service.js.map +1 -1
- package/dist/services/mongoose/refresh-token.service.js.map +1 -1
- package/dist/services/mongoose/role.service.js +1 -2
- package/dist/services/mongoose/role.service.js.map +1 -1
- package/dist/services/mongoose/settings.service.js.map +1 -1
- package/dist/services/mongoose/user.service.js +7 -0
- package/dist/services/mongoose/user.service.js.map +1 -1
- package/dist/services/moonraker/constants/moonraker-event.dto.js +3 -3
- package/dist/services/moonraker/constants/moonraker-event.dto.js.map +1 -1
- package/dist/services/moonraker/dto/objects/idle-timeout.dto.js +3 -3
- package/dist/services/moonraker/dto/objects/idle-timeout.dto.js.map +1 -1
- package/dist/services/moonraker/dto/objects/print-stats.dto.js +3 -3
- package/dist/services/moonraker/dto/objects/print-stats.dto.js.map +1 -1
- package/dist/services/moonraker/dto/objects/printer-objects-list.dto.js +3 -3
- package/dist/services/moonraker/dto/objects/printer-objects-list.dto.js.map +1 -1
- package/dist/services/moonraker/dto/printer-info.dto.js +3 -3
- package/dist/services/moonraker/dto/printer-info.dto.js.map +1 -1
- package/dist/services/moonraker/dto/server-history/job.dto.js +3 -3
- package/dist/services/moonraker/dto/server-history/job.dto.js.map +1 -1
- package/dist/services/moonraker/dto/websocket/methods.js +3 -3
- package/dist/services/moonraker/dto/websocket/methods.js.map +1 -1
- package/dist/services/moonraker/dto/websocket/notify-update-response.params.js +3 -3
- package/dist/services/moonraker/dto/websocket/notify-update-response.params.js.map +1 -1
- package/dist/services/moonraker/moonraker-websocket.adapter.js +13 -13
- package/dist/services/moonraker/moonraker-websocket.adapter.js.map +1 -1
- package/dist/services/moonraker/moonraker.client.js.map +1 -1
- package/dist/services/moonraker.api.js.map +1 -1
- package/dist/services/octoprint/constants/octoprint-service.constants.js +7 -7
- package/dist/services/octoprint/constants/octoprint-service.constants.js.map +1 -1
- package/dist/services/octoprint/constants/octoprint-websocket.constants.js +3 -3
- package/dist/services/octoprint/constants/octoprint-websocket.constants.js.map +1 -1
- package/dist/services/octoprint/dto/octoprint-event.dto.js +4 -4
- package/dist/services/octoprint/dto/octoprint-event.dto.js.map +1 -1
- package/dist/services/octoprint/octoprint-websocket.adapter.js +17 -17
- package/dist/services/octoprint/octoprint-websocket.adapter.js.map +1 -1
- package/dist/services/octoprint/octoprint.client.js.map +1 -1
- package/dist/services/octoprint/utils/api.utils.js +3 -3
- package/dist/services/octoprint/utils/api.utils.js.map +1 -1
- package/dist/services/octoprint.api.js.map +1 -1
- package/dist/services/orm/base.service.js.map +1 -1
- package/dist/services/orm/floor.service.js +1 -1
- package/dist/services/orm/floor.service.js.map +1 -1
- package/dist/services/orm/permission.service.js.map +1 -1
- package/dist/services/orm/print-completion.service.js.map +1 -1
- package/dist/services/orm/printer-group.service.js.map +1 -1
- package/dist/services/orm/printer.service.js.map +1 -1
- package/dist/services/orm/refresh-token.service.js.map +1 -1
- package/dist/services/orm/role.service.js +2 -2
- package/dist/services/orm/role.service.js.map +1 -1
- package/dist/services/orm/settings.service.js +0 -4
- package/dist/services/orm/settings.service.js.map +1 -1
- package/dist/services/orm/user.service.js +8 -0
- package/dist/services/orm/user.service.js.map +1 -1
- package/dist/services/printer-api.factory.js +7 -1
- package/dist/services/printer-api.factory.js.map +1 -1
- package/dist/services/printer-api.interface.js +11 -6
- package/dist/services/printer-api.interface.js.map +1 -1
- package/dist/services/prusa-link/prusa-link-http-polling.adapter.js +2 -4
- package/dist/services/prusa-link/prusa-link-http-polling.adapter.js.map +1 -1
- package/dist/services/prusa-link/prusa-link.api.js +1 -2
- package/dist/services/prusa-link/prusa-link.api.js.map +1 -1
- package/dist/services/socket.factory.js +3 -0
- package/dist/services/socket.factory.js.map +1 -1
- package/dist/services/task-manager.service.js +1 -2
- package/dist/services/task-manager.service.js.map +1 -1
- package/dist/services/validators/floor-service.validation.js +10 -10
- package/dist/services/validators/floor-service.validation.js.map +1 -1
- package/dist/services/validators/printer-service.validation.js +15 -15
- package/dist/services/validators/printer-service.validation.js.map +1 -1
- package/dist/services/validators/settings-service.validation.js +21 -14
- package/dist/services/validators/settings-service.validation.js.map +1 -1
- package/dist/services/validators/user-service.validation.js +3 -3
- package/dist/services/validators/user-service.validation.js.map +1 -1
- package/dist/services/validators/yaml-service.validation.js +33 -7
- package/dist/services/validators/yaml-service.validation.js.map +1 -1
- package/dist/shared/default-http-client.builder.js.map +1 -1
- package/dist/shared/runtime-settings.migration.js +1 -0
- package/dist/shared/runtime-settings.migration.js.map +1 -1
- package/dist/shared/websocket.adapter.js.map +1 -1
- package/dist/state/file-upload-tracker.cache.js +1 -2
- package/dist/state/file-upload-tracker.cache.js.map +1 -1
- package/dist/state/file.cache.js.map +1 -1
- package/dist/state/floor.store.js.map +1 -1
- package/dist/state/printer-events.cache.js +13 -0
- package/dist/state/printer-events.cache.js.map +1 -1
- package/dist/state/printer-files.store.js.map +1 -1
- package/dist/state/printer-socket.store.js +1 -2
- package/dist/state/printer-socket.store.js.map +1 -1
- package/dist/state/printer-thumbnail.cache.js +3 -3
- package/dist/state/printer-thumbnail.cache.js.map +1 -1
- package/dist/state/printer.cache.js.map +1 -1
- package/dist/state/settings.store.js +14 -6
- package/dist/state/settings.store.js.map +1 -1
- package/dist/state/socket-io.gateway.js +3 -3
- package/dist/state/socket-io.gateway.js.map +1 -1
- package/dist/state/test-printer-socket.store.js.map +1 -1
- package/dist/tasks/boot.task.js.map +1 -1
- package/dist/tasks/client-bundle.task.js.map +1 -1
- package/dist/tasks/print-completion.socketio.task.js +1 -2
- package/dist/tasks/print-completion.socketio.task.js.map +1 -1
- package/dist/tasks/printer-file-clean.task.js.map +1 -1
- package/dist/tasks/printer-websocket-restore.task.js.map +1 -1
- package/dist/tasks/printer-websocket.task.js.map +1 -1
- package/dist/tasks/socketio.task.js.map +1 -1
- package/dist/tasks/software-update.task.js.map +1 -1
- package/dist/tasks.js +3 -3
- package/dist/tasks.js.map +1 -1
- package/dist/utils/array.util.js +3 -3
- package/dist/utils/array.util.js.map +1 -1
- package/dist/utils/crypto.utils.js +3 -3
- package/dist/utils/crypto.utils.js.map +1 -1
- package/dist/utils/env.utils.js +6 -6
- package/dist/utils/env.utils.js.map +1 -1
- package/dist/utils/fs.utils.js +4 -4
- package/dist/utils/fs.utils.js.map +1 -1
- package/dist/utils/gcode.utils.js +3 -3
- package/dist/utils/gcode.utils.js.map +1 -1
- package/dist/utils/pretty-print.utils.js +3 -3
- package/dist/utils/pretty-print.utils.js.map +1 -1
- package/dist/utils/semver.utils.js +3 -3
- package/dist/utils/semver.utils.js.map +1 -1
- package/dist/utils/url.utils.js +3 -3
- package/dist/utils/url.utils.js.map +1 -1
- package/package.json +48 -41
- package/dist/utils/printer-type.utils.js +0 -32
- package/dist/utils/printer-type.utils.js.map +0 -1
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "BambuFtpAdapter", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return BambuFtpAdapter;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _basicftp = require("basic-ftp");
|
|
12
|
+
const _eventconstants = require("../../constants/event.constants");
|
|
13
|
+
const _nodefs = require("node:fs");
|
|
14
|
+
const _nodeos = require("node:os");
|
|
15
|
+
const _nodepath = require("node:path");
|
|
16
|
+
class BambuFtpAdapter {
|
|
17
|
+
settingsStore;
|
|
18
|
+
eventEmitter2;
|
|
19
|
+
logger;
|
|
20
|
+
ftpClient = null;
|
|
21
|
+
host = null;
|
|
22
|
+
accessCode = null;
|
|
23
|
+
isConnecting = false;
|
|
24
|
+
constructor(settingsStore, loggerFactory, eventEmitter2){
|
|
25
|
+
this.settingsStore = settingsStore;
|
|
26
|
+
this.eventEmitter2 = eventEmitter2;
|
|
27
|
+
this.settingsStore = settingsStore;
|
|
28
|
+
this.eventEmitter2 = eventEmitter2;
|
|
29
|
+
this.logger = loggerFactory(BambuFtpAdapter.name);
|
|
30
|
+
}
|
|
31
|
+
async connect(host, accessCode) {
|
|
32
|
+
if (this.ftpClient && !this.ftpClient.closed) {
|
|
33
|
+
this.logger.debug("FTP already connected");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (this.isConnecting) {
|
|
37
|
+
throw new Error("Connection already in progress");
|
|
38
|
+
}
|
|
39
|
+
const sanitizedHost = this.sanitizeHost(host);
|
|
40
|
+
const sanitizedAccessCode = this.sanitizeAccessCode(accessCode);
|
|
41
|
+
this.host = sanitizedHost;
|
|
42
|
+
this.accessCode = sanitizedAccessCode;
|
|
43
|
+
this.isConnecting = true;
|
|
44
|
+
const timeout = this.settingsStore.getTimeoutSettings().apiTimeout;
|
|
45
|
+
this.logger.log(`Connecting to Bambu FTP at ${sanitizedHost}:990`);
|
|
46
|
+
try {
|
|
47
|
+
this.ftpClient = new _basicftp.Client(timeout);
|
|
48
|
+
this.ftpClient.ftp.verbose = false;
|
|
49
|
+
await this.ftpClient.access({
|
|
50
|
+
host: sanitizedHost,
|
|
51
|
+
port: 990,
|
|
52
|
+
user: "bblp",
|
|
53
|
+
password: sanitizedAccessCode,
|
|
54
|
+
secure: true,
|
|
55
|
+
secureOptions: {
|
|
56
|
+
rejectUnauthorized: false,
|
|
57
|
+
minVersion: 'TLSv1.2',
|
|
58
|
+
maxVersion: 'TLSv1.3'
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
this.isConnecting = false;
|
|
62
|
+
this.logger.log("FTP connected successfully");
|
|
63
|
+
} catch (error) {
|
|
64
|
+
this.isConnecting = false;
|
|
65
|
+
this.cleanup();
|
|
66
|
+
this.logger.error("FTP connection failed:", error);
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async disconnect() {
|
|
71
|
+
if (!this.ftpClient) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
this.logger.log("Disconnecting FTP");
|
|
75
|
+
try {
|
|
76
|
+
this.ftpClient.close();
|
|
77
|
+
} catch (error) {
|
|
78
|
+
this.logger.error("Error closing FTP:", error);
|
|
79
|
+
} finally{
|
|
80
|
+
this.cleanup();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async listFiles(dirPath = "/") {
|
|
84
|
+
this.ensureConnected();
|
|
85
|
+
try {
|
|
86
|
+
const files = await this.ftpClient.list(dirPath);
|
|
87
|
+
this.logger.debug(`Listed ${files.length} files in ${dirPath}`);
|
|
88
|
+
return files;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
this.logger.error(`Failed to list files in ${dirPath}:`, error);
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async uploadFile(fileBuffer, filename, progressToken) {
|
|
95
|
+
this.ensureConnected();
|
|
96
|
+
const remotePath = `/sdcard/${filename}`;
|
|
97
|
+
const tempPath = (0, _nodepath.join)((0, _nodeos.tmpdir)(), `bambu-upload-${Date.now()}-${filename}`);
|
|
98
|
+
try {
|
|
99
|
+
(0, _nodefs.writeFileSync)(tempPath, fileBuffer);
|
|
100
|
+
this.logger.debug(`Wrote temp file: ${tempPath}`);
|
|
101
|
+
if (progressToken) {
|
|
102
|
+
this.ftpClient.trackProgress((info)=>{
|
|
103
|
+
this.eventEmitter2.emit(`${(0, _eventconstants.uploadProgressEvent)(progressToken)}`, progressToken, {
|
|
104
|
+
loaded: info.bytes,
|
|
105
|
+
total: info.bytesOverall
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
this.logger.log(`Uploading ${filename} to ${remotePath}`);
|
|
110
|
+
await this.ftpClient.uploadFrom(tempPath, remotePath);
|
|
111
|
+
this.ftpClient.trackProgress();
|
|
112
|
+
if (progressToken) {
|
|
113
|
+
this.eventEmitter2.emit(`${(0, _eventconstants.uploadDoneEvent)(progressToken)}`, progressToken);
|
|
114
|
+
}
|
|
115
|
+
this.logger.log(`File uploaded successfully: ${filename}`);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (progressToken) {
|
|
118
|
+
this.eventEmitter2.emit(`${(0, _eventconstants.uploadFailedEvent)(progressToken)}`, progressToken, error?.message);
|
|
119
|
+
}
|
|
120
|
+
this.logger.error(`Upload failed for ${filename}:`, error);
|
|
121
|
+
throw error;
|
|
122
|
+
} finally{
|
|
123
|
+
try {
|
|
124
|
+
(0, _nodefs.unlinkSync)(tempPath);
|
|
125
|
+
this.logger.debug(`Cleaned up temp file: ${tempPath}`);
|
|
126
|
+
} catch (cleanupError) {
|
|
127
|
+
this.logger.warn(`Failed to cleanup temp file ${tempPath}:`, cleanupError);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async downloadFile(remotePath, localPath) {
|
|
132
|
+
this.ensureConnected();
|
|
133
|
+
try {
|
|
134
|
+
this.logger.log(`Downloading ${remotePath} to ${localPath}`);
|
|
135
|
+
await this.ftpClient.downloadTo(localPath, remotePath);
|
|
136
|
+
this.logger.log(`File downloaded successfully: ${remotePath}`);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
this.logger.error(`Download failed for ${remotePath}:`, error);
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async deleteFile(remotePath) {
|
|
143
|
+
this.ensureConnected();
|
|
144
|
+
try {
|
|
145
|
+
this.logger.log(`Deleting file: ${remotePath}`);
|
|
146
|
+
await this.ftpClient.remove(remotePath);
|
|
147
|
+
this.logger.log(`File deleted successfully: ${remotePath}`);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
this.logger.error(`Delete failed for ${remotePath}:`, error);
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
get isConnected() {
|
|
154
|
+
return this.ftpClient != null && !this.ftpClient.closed;
|
|
155
|
+
}
|
|
156
|
+
ensureConnected() {
|
|
157
|
+
if (!this.isConnected) {
|
|
158
|
+
throw new Error("FTP not connected. Call connect() first.");
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
cleanup() {
|
|
162
|
+
this.ftpClient = null;
|
|
163
|
+
}
|
|
164
|
+
sanitizeHost(host) {
|
|
165
|
+
if (!host?.length) {
|
|
166
|
+
throw new Error("Host must be a non-empty string");
|
|
167
|
+
}
|
|
168
|
+
const trimmed = host.trim();
|
|
169
|
+
if (trimmed.length === 0) {
|
|
170
|
+
throw new Error("Host cannot be empty");
|
|
171
|
+
}
|
|
172
|
+
const ipv4Pattern = /^(\d{1,3}\.){3}\d{1,3}$/;
|
|
173
|
+
const hostnamePattern = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
174
|
+
if (!ipv4Pattern.test(trimmed) && !hostnamePattern.test(trimmed)) {
|
|
175
|
+
throw new Error("Invalid host format. Must be a valid IP address or hostname");
|
|
176
|
+
}
|
|
177
|
+
if (ipv4Pattern.test(trimmed)) {
|
|
178
|
+
const parts = trimmed.split(".").map(Number);
|
|
179
|
+
if (parts.some((part)=>part < 0 || part > 255)) {
|
|
180
|
+
throw new Error("Invalid IPv4 address. Octets must be between 0 and 255");
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return trimmed;
|
|
184
|
+
}
|
|
185
|
+
sanitizeAccessCode(accessCode) {
|
|
186
|
+
if (!accessCode?.length) {
|
|
187
|
+
throw new Error("Access code must be a non-empty string");
|
|
188
|
+
}
|
|
189
|
+
const trimmed = accessCode.trim();
|
|
190
|
+
if (trimmed.length === 0) {
|
|
191
|
+
throw new Error("Access code cannot be empty");
|
|
192
|
+
}
|
|
193
|
+
if (trimmed.length < 4 || trimmed.length > 32) {
|
|
194
|
+
throw new Error("Access code must be between 4 and 32 characters");
|
|
195
|
+
}
|
|
196
|
+
const alphanumericPattern = /^[a-zA-Z0-9]+$/;
|
|
197
|
+
if (!alphanumericPattern.test(trimmed)) {
|
|
198
|
+
throw new Error("Access code must contain only alphanumeric characters");
|
|
199
|
+
}
|
|
200
|
+
return trimmed;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
//# sourceMappingURL=bambu-ftp.adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/bambu/bambu-ftp.adapter.ts"],"names":["BambuFtpAdapter","logger","ftpClient","host","accessCode","isConnecting","settingsStore","loggerFactory","eventEmitter2","name","connect","closed","debug","Error","sanitizedHost","sanitizeHost","sanitizedAccessCode","sanitizeAccessCode","timeout","getTimeoutSettings","apiTimeout","log","Client","ftp","verbose","access","port","user","password","secure","secureOptions","rejectUnauthorized","minVersion","maxVersion","error","cleanup","disconnect","close","listFiles","dirPath","ensureConnected","files","list","length","uploadFile","fileBuffer","filename","progressToken","remotePath","tempPath","join","tmpdir","Date","now","writeFileSync","trackProgress","info","emit","uploadProgressEvent","loaded","bytes","total","bytesOverall","uploadFrom","uploadDoneEvent","uploadFailedEvent","message","unlinkSync","cleanupError","warn","downloadFile","localPath","downloadTo","deleteFile","remove","isConnected","trimmed","trim","ipv4Pattern","hostnamePattern","test","parts","split","map","Number","some","part","alphanumericPattern"],"mappings":"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"}
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get BambuMqttAdapter () {
|
|
13
|
+
return BambuMqttAdapter;
|
|
14
|
+
},
|
|
15
|
+
get bambuEvent () {
|
|
16
|
+
return bambuEvent;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const _mqtt = /*#__PURE__*/ _interop_require_default(require("mqtt"));
|
|
20
|
+
const _socketstatetype = require("../../shared/dtos/socket-state.type");
|
|
21
|
+
const _apistatetype = require("../../shared/dtos/api-state.type");
|
|
22
|
+
const _printerapiinterface = require("../printer-api.interface");
|
|
23
|
+
function _interop_require_default(obj) {
|
|
24
|
+
return obj && obj.__esModule ? obj : {
|
|
25
|
+
default: obj
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const bambuEvent = (event)=>`bambu.${event}`;
|
|
29
|
+
class BambuMqttAdapter {
|
|
30
|
+
logger;
|
|
31
|
+
settingsStore;
|
|
32
|
+
eventEmitter2;
|
|
33
|
+
printerType = _printerapiinterface.BambuType;
|
|
34
|
+
printerId;
|
|
35
|
+
socketState = _socketstatetype.SOCKET_STATE.unopened;
|
|
36
|
+
apiState = _apistatetype.API_STATE.unset;
|
|
37
|
+
login;
|
|
38
|
+
lastMessageReceivedTimestamp = null;
|
|
39
|
+
mqttClient = null;
|
|
40
|
+
host = null;
|
|
41
|
+
accessCode = null;
|
|
42
|
+
serial = null;
|
|
43
|
+
lastState = null;
|
|
44
|
+
isConnecting = false;
|
|
45
|
+
eventsAllowed = true;
|
|
46
|
+
constructor(settingsStore, loggerFactory, eventEmitter2){
|
|
47
|
+
this.settingsStore = settingsStore;
|
|
48
|
+
this.eventEmitter2 = eventEmitter2;
|
|
49
|
+
this.logger = loggerFactory(BambuMqttAdapter.name);
|
|
50
|
+
}
|
|
51
|
+
registerCredentials(socketLogin) {
|
|
52
|
+
const { printerId, loginDto } = socketLogin;
|
|
53
|
+
this.printerId = printerId;
|
|
54
|
+
this.login = loginDto;
|
|
55
|
+
this.host = loginDto.printerURL?.replace(/^https?:\/\//, '');
|
|
56
|
+
this.accessCode = loginDto.password || null;
|
|
57
|
+
this.serial = loginDto.username || null;
|
|
58
|
+
}
|
|
59
|
+
needsReopen() {
|
|
60
|
+
const isApiOnline = this.apiState === _apistatetype.API_STATE.responding;
|
|
61
|
+
return isApiOnline && (this.socketState === _socketstatetype.SOCKET_STATE.closed || this.socketState === _socketstatetype.SOCKET_STATE.error);
|
|
62
|
+
}
|
|
63
|
+
needsSetup() {
|
|
64
|
+
return this.socketState === _socketstatetype.SOCKET_STATE.unopened;
|
|
65
|
+
}
|
|
66
|
+
needsReauth() {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
isClosedOrAborted() {
|
|
70
|
+
return this.socketState === _socketstatetype.SOCKET_STATE.closed || this.socketState === _socketstatetype.SOCKET_STATE.aborted;
|
|
71
|
+
}
|
|
72
|
+
async reauthSession() {
|
|
73
|
+
this.logger.debug("reauthSession called but not needed for Bambu");
|
|
74
|
+
}
|
|
75
|
+
open() {
|
|
76
|
+
if (!this.host || !this.accessCode || !this.serial) {
|
|
77
|
+
throw new Error("Cannot open connection: credentials not registered");
|
|
78
|
+
}
|
|
79
|
+
this.connect(this.host, this.accessCode, this.serial).catch((err)=>{
|
|
80
|
+
this.logger.error("Failed to open MQTT connection: " + err.toString());
|
|
81
|
+
this.socketState = _socketstatetype.SOCKET_STATE.error;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
close() {
|
|
85
|
+
this.disconnect().catch((err)=>{
|
|
86
|
+
this.logger.error("Error during MQTT disconnect:", err);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async setupSocketSession() {
|
|
90
|
+
if (!this.host || !this.accessCode || !this.serial) {
|
|
91
|
+
this.socketState = _socketstatetype.SOCKET_STATE.aborted;
|
|
92
|
+
this.apiState = _apistatetype.API_STATE.noResponse;
|
|
93
|
+
throw new Error("Credentials not properly registered");
|
|
94
|
+
}
|
|
95
|
+
this.socketState = _socketstatetype.SOCKET_STATE.opening;
|
|
96
|
+
this.apiState = _apistatetype.API_STATE.responding;
|
|
97
|
+
}
|
|
98
|
+
allowEmittingEvents() {
|
|
99
|
+
this.eventsAllowed = true;
|
|
100
|
+
}
|
|
101
|
+
disallowEmittingEvents() {
|
|
102
|
+
this.eventsAllowed = false;
|
|
103
|
+
}
|
|
104
|
+
async connect(host, accessCode, serial) {
|
|
105
|
+
if (this.mqttClient?.connected) {
|
|
106
|
+
this.logger.debug("MQTT already connected");
|
|
107
|
+
this.socketState = _socketstatetype.SOCKET_STATE.opened;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (this.isConnecting) {
|
|
111
|
+
throw new Error("Connection already in progress");
|
|
112
|
+
}
|
|
113
|
+
this.host = host;
|
|
114
|
+
this.accessCode = accessCode;
|
|
115
|
+
this.serial = serial;
|
|
116
|
+
this.isConnecting = true;
|
|
117
|
+
this.socketState = _socketstatetype.SOCKET_STATE.opening;
|
|
118
|
+
const mqttUrl = `mqtt://${host}:1883`;
|
|
119
|
+
const timeout = this.settingsStore.getTimeoutSettings().apiTimeout;
|
|
120
|
+
this.logger.log(`Connecting to Bambu MQTT at ${mqttUrl}`);
|
|
121
|
+
return new Promise((resolve, reject)=>{
|
|
122
|
+
const connectionTimeout = setTimeout(()=>{
|
|
123
|
+
this.isConnecting = false;
|
|
124
|
+
this.socketState = _socketstatetype.SOCKET_STATE.error;
|
|
125
|
+
this.cleanup();
|
|
126
|
+
reject(new Error("MQTT connection timeout"));
|
|
127
|
+
}, timeout);
|
|
128
|
+
try {
|
|
129
|
+
this.mqttClient = _mqtt.default.connect(mqttUrl, {
|
|
130
|
+
username: "bblp",
|
|
131
|
+
password: accessCode,
|
|
132
|
+
clientId: `fdm_monster_${serial}_${Date.now()}`,
|
|
133
|
+
protocol: "mqtt",
|
|
134
|
+
connectTimeout: timeout,
|
|
135
|
+
reconnectPeriod: 5000,
|
|
136
|
+
keepalive: 60
|
|
137
|
+
});
|
|
138
|
+
this.mqttClient.on("connect", ()=>{
|
|
139
|
+
clearTimeout(connectionTimeout);
|
|
140
|
+
this.isConnecting = false;
|
|
141
|
+
this.socketState = _socketstatetype.SOCKET_STATE.authenticated;
|
|
142
|
+
this.apiState = _apistatetype.API_STATE.responding;
|
|
143
|
+
this.logger.log("MQTT connected successfully");
|
|
144
|
+
const reportTopic = `device/${serial}/report`;
|
|
145
|
+
this.mqttClient.subscribe(reportTopic, {
|
|
146
|
+
qos: 0
|
|
147
|
+
}, (err)=>{
|
|
148
|
+
if (err) {
|
|
149
|
+
this.logger.error(`Failed to subscribe to ${reportTopic}:`, err);
|
|
150
|
+
this.socketState = _socketstatetype.SOCKET_STATE.error;
|
|
151
|
+
reject(new Error(`Subscribe failed: ${err.message}`));
|
|
152
|
+
} else {
|
|
153
|
+
this.logger.debug(`Subscribed to ${reportTopic}`);
|
|
154
|
+
resolve();
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
this.mqttClient.on("error", (error)=>{
|
|
159
|
+
clearTimeout(connectionTimeout);
|
|
160
|
+
this.isConnecting = false;
|
|
161
|
+
this.socketState = _socketstatetype.SOCKET_STATE.error;
|
|
162
|
+
this.logger.error("MQTT error:", error);
|
|
163
|
+
if (!this.mqttClient?.connected) {
|
|
164
|
+
reject(error);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
this.mqttClient.on("message", (topic, message)=>{
|
|
168
|
+
this.lastMessageReceivedTimestamp = Date.now();
|
|
169
|
+
this.handleMessage(topic, message);
|
|
170
|
+
});
|
|
171
|
+
this.mqttClient.on("disconnect", ()=>{
|
|
172
|
+
this.socketState = _socketstatetype.SOCKET_STATE.closed;
|
|
173
|
+
this.logger.warn("MQTT disconnected");
|
|
174
|
+
});
|
|
175
|
+
this.mqttClient.on("reconnect", ()=>{
|
|
176
|
+
this.socketState = _socketstatetype.SOCKET_STATE.opening;
|
|
177
|
+
this.logger.debug("MQTT reconnecting...");
|
|
178
|
+
});
|
|
179
|
+
this.mqttClient.on("close", ()=>{
|
|
180
|
+
this.socketState = _socketstatetype.SOCKET_STATE.closed;
|
|
181
|
+
this.logger.debug("MQTT connection closed");
|
|
182
|
+
});
|
|
183
|
+
} catch (error) {
|
|
184
|
+
clearTimeout(connectionTimeout);
|
|
185
|
+
this.isConnecting = false;
|
|
186
|
+
this.socketState = _socketstatetype.SOCKET_STATE.error;
|
|
187
|
+
this.cleanup();
|
|
188
|
+
reject(error);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
async disconnect() {
|
|
193
|
+
if (!this.mqttClient) {
|
|
194
|
+
this.socketState = _socketstatetype.SOCKET_STATE.closed;
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
this.logger.log("Disconnecting MQTT");
|
|
198
|
+
this.socketState = _socketstatetype.SOCKET_STATE.closed;
|
|
199
|
+
return new Promise((resolve)=>{
|
|
200
|
+
if (this.mqttClient?.connected) {
|
|
201
|
+
this.mqttClient.end(false, {}, ()=>{
|
|
202
|
+
this.cleanup();
|
|
203
|
+
resolve();
|
|
204
|
+
});
|
|
205
|
+
} else {
|
|
206
|
+
this.cleanup();
|
|
207
|
+
resolve();
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
getLastState() {
|
|
212
|
+
return this.lastState;
|
|
213
|
+
}
|
|
214
|
+
async sendCommand(payload) {
|
|
215
|
+
if (!this.mqttClient?.connected) {
|
|
216
|
+
throw new Error("MQTT not connected");
|
|
217
|
+
}
|
|
218
|
+
if (!this.serial) {
|
|
219
|
+
throw new Error("Serial number not set");
|
|
220
|
+
}
|
|
221
|
+
const requestTopic = `device/${this.serial}/request`;
|
|
222
|
+
const message = JSON.stringify(payload);
|
|
223
|
+
return new Promise((resolve, reject)=>{
|
|
224
|
+
this.mqttClient.publish(requestTopic, message, {
|
|
225
|
+
qos: 0
|
|
226
|
+
}, (err)=>{
|
|
227
|
+
if (err) {
|
|
228
|
+
this.logger.error("Failed to send command:", err);
|
|
229
|
+
reject(err);
|
|
230
|
+
} else {
|
|
231
|
+
this.logger.debug("Command sent:", payload);
|
|
232
|
+
resolve();
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
async startPrint(filename) {
|
|
238
|
+
await this.sendCommand({
|
|
239
|
+
print: {
|
|
240
|
+
command: "project_file",
|
|
241
|
+
param: filename,
|
|
242
|
+
url: `file:///sdcard/${filename}`,
|
|
243
|
+
subtask_name: filename,
|
|
244
|
+
sequence_id: String(Date.now())
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
async pausePrint() {
|
|
249
|
+
await this.sendCommand({
|
|
250
|
+
print: {
|
|
251
|
+
command: "pause",
|
|
252
|
+
sequence_id: String(Date.now())
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
async resumePrint() {
|
|
257
|
+
await this.sendCommand({
|
|
258
|
+
print: {
|
|
259
|
+
command: "resume",
|
|
260
|
+
sequence_id: String(Date.now())
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
async stopPrint() {
|
|
265
|
+
await this.sendCommand({
|
|
266
|
+
print: {
|
|
267
|
+
command: "stop",
|
|
268
|
+
sequence_id: String(Date.now())
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
async sendGcode(gcode) {
|
|
273
|
+
await this.sendCommand({
|
|
274
|
+
print: {
|
|
275
|
+
command: "gcode_line",
|
|
276
|
+
param: gcode,
|
|
277
|
+
sequence_id: String(Date.now())
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
resetSocketState() {
|
|
282
|
+
this.lastState = null;
|
|
283
|
+
}
|
|
284
|
+
async emitEvent(event, payload) {
|
|
285
|
+
if (!this.eventsAllowed) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
await this.eventEmitter2.emitAsync(bambuEvent(event), {
|
|
289
|
+
event,
|
|
290
|
+
payload,
|
|
291
|
+
printerId: this.printerId,
|
|
292
|
+
printerType: _printerapiinterface.BambuType
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
emitEventSync(event, payload) {
|
|
296
|
+
if (!this.eventsAllowed) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
this.eventEmitter2.emit(bambuEvent(event), {
|
|
300
|
+
event,
|
|
301
|
+
payload,
|
|
302
|
+
printerId: this.printerId,
|
|
303
|
+
printerType: _printerapiinterface.BambuType
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
transformStateToCurrentMessage(state) {
|
|
307
|
+
const isPrinting = state.gcode_state === "PRINTING" || state.mc_print_stage === "printing";
|
|
308
|
+
const isPaused = state.mc_print_stage === "paused";
|
|
309
|
+
const isPausedText = isPaused ? "Paused" : "Printing";
|
|
310
|
+
return {
|
|
311
|
+
state: {
|
|
312
|
+
text: isPrinting ? isPausedText : "Operational",
|
|
313
|
+
flags: {
|
|
314
|
+
operational: true,
|
|
315
|
+
printing: isPrinting && !isPaused,
|
|
316
|
+
paused: isPaused,
|
|
317
|
+
ready: !isPrinting,
|
|
318
|
+
error: state.print_error !== 0,
|
|
319
|
+
cancelling: false,
|
|
320
|
+
pausing: false,
|
|
321
|
+
sdReady: true,
|
|
322
|
+
closedOrError: false
|
|
323
|
+
}
|
|
324
|
+
},
|
|
325
|
+
temps: [
|
|
326
|
+
{
|
|
327
|
+
time: Date.now(),
|
|
328
|
+
tool0: {
|
|
329
|
+
actual: state.nozzle_temper || 0,
|
|
330
|
+
target: state.nozzle_target_temper || 0
|
|
331
|
+
},
|
|
332
|
+
bed: {
|
|
333
|
+
actual: state.bed_temper || 0,
|
|
334
|
+
target: state.bed_target_temper || 0
|
|
335
|
+
},
|
|
336
|
+
chamber: {
|
|
337
|
+
actual: state.chamber_temper || 0,
|
|
338
|
+
target: 0
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
],
|
|
342
|
+
progress: {
|
|
343
|
+
completion: state.mc_percent || 0,
|
|
344
|
+
printTime: null,
|
|
345
|
+
printTimeLeft: state.mc_remaining_time ? state.mc_remaining_time * 60 : null
|
|
346
|
+
},
|
|
347
|
+
job: {
|
|
348
|
+
file: {
|
|
349
|
+
name: state.gcode_file || state.subtask_name || null
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
currentZ: state.layer_num || null,
|
|
353
|
+
offsets: {},
|
|
354
|
+
resends: {
|
|
355
|
+
count: 0,
|
|
356
|
+
transmitted: 0,
|
|
357
|
+
ratio: 0
|
|
358
|
+
},
|
|
359
|
+
logs: [],
|
|
360
|
+
messages: []
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
handleMessage(topic, message) {
|
|
364
|
+
try {
|
|
365
|
+
const payload = JSON.parse(message.toString());
|
|
366
|
+
if (topic.endsWith("/report") && payload.print) {
|
|
367
|
+
this.lastState = payload.print;
|
|
368
|
+
this.logger.debug("Received printer state update");
|
|
369
|
+
const currentMessage = this.transformStateToCurrentMessage(this.lastState);
|
|
370
|
+
this.emitEvent("current", currentMessage).catch((err)=>{
|
|
371
|
+
this.logger.error("Failed to emit current event:", err);
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
} catch (error) {
|
|
375
|
+
this.logger.error("Failed to parse MQTT message:", error);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
cleanup() {
|
|
379
|
+
if (this.mqttClient) {
|
|
380
|
+
this.mqttClient.removeAllListeners();
|
|
381
|
+
this.mqttClient = null;
|
|
382
|
+
}
|
|
383
|
+
this.lastState = null;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
//# sourceMappingURL=bambu-mqtt.adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/services/bambu/bambu-mqtt.adapter.ts"],"names":["BambuMqttAdapter","bambuEvent","event","logger","settingsStore","eventEmitter2","printerType","BambuType","printerId","socketState","SOCKET_STATE","unopened","apiState","API_STATE","unset","login","lastMessageReceivedTimestamp","mqttClient","host","accessCode","serial","lastState","isConnecting","eventsAllowed","loggerFactory","name","registerCredentials","socketLogin","loginDto","printerURL","replace","password","username","needsReopen","isApiOnline","responding","closed","error","needsSetup","needsReauth","isClosedOrAborted","aborted","reauthSession","debug","open","Error","connect","catch","err","toString","close","disconnect","setupSocketSession","noResponse","opening","allowEmittingEvents","disallowEmittingEvents","connected","opened","mqttUrl","timeout","getTimeoutSettings","apiTimeout","log","Promise","resolve","reject","connectionTimeout","setTimeout","cleanup","mqtt","clientId","Date","now","protocol","connectTimeout","reconnectPeriod","keepalive","on","clearTimeout","authenticated","reportTopic","subscribe","qos","message","topic","handleMessage","warn","end","getLastState","sendCommand","payload","requestTopic","JSON","stringify","publish","startPrint","filename","print","command","param","url","subtask_name","sequence_id","String","pausePrint","resumePrint","stopPrint","sendGcode","gcode","resetSocketState","emitEvent","emitAsync","emitEventSync","emit","transformStateToCurrentMessage","state","isPrinting","gcode_state","mc_print_stage","isPaused","isPausedText","text","flags","operational","printing","paused","ready","print_error","cancelling","pausing","sdReady","closedOrError","temps","time","tool0","actual","nozzle_temper","target","nozzle_target_temper","bed","bed_temper","bed_target_temper","chamber","chamber_temper","progress","completion","mc_percent","printTime","printTimeLeft","mc_remaining_time","job","file","gcode_file","currentZ","layer_num","offsets","resends","count","transmitted","ratio","logs","messages","parse","endsWith","currentMessage","removeAllListeners"],"mappings":"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"}
|