@iobroker/js-controller-adapter 7.2.3 → 8.0.0-alpha.2-20260923-99da17fcc
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/build/cjs/index.d.ts +0 -1
- package/build/cjs/index.js +5 -8
- package/build/cjs/index.js.map +2 -2
- package/build/cjs/lib/_Types.d.ts +394 -63
- package/build/cjs/lib/adapter/adapter.d.ts +1896 -177
- package/build/cjs/lib/adapter/adapter.js +788 -1035
- package/build/cjs/lib/adapter/adapter.js.map +2 -2
- package/build/cjs/lib/adapter/asyncAdapter.d.ts +167 -0
- package/build/cjs/lib/adapter/asyncAdapter.js +252 -0
- package/build/cjs/lib/adapter/asyncAdapter.js.map +7 -0
- package/build/cjs/lib/adapter/context.d.ts +34 -0
- package/build/cjs/lib/adapter/context.js +17 -0
- package/build/cjs/lib/adapter/context.js.map +7 -0
- package/build/cjs/lib/adapter/defaultObjs.d.ts +5 -0
- package/build/cjs/lib/adapter/defaultObjs.js +2 -0
- package/build/cjs/lib/adapter/defaultObjs.js.map +2 -2
- package/build/cjs/lib/adapter/log.d.ts +25 -0
- package/build/cjs/lib/adapter/log.js +29 -0
- package/build/cjs/lib/adapter/log.js.map +2 -2
- package/build/cjs/lib/adapter/managers/AdapterContextBase.d.ts +49 -0
- package/build/cjs/lib/adapter/managers/AdapterContextBase.js +98 -0
- package/build/cjs/lib/adapter/managers/AdapterContextBase.js.map +7 -0
- package/build/cjs/lib/adapter/managers/AliasManager.d.ts +103 -0
- package/build/cjs/lib/adapter/managers/AliasManager.js +293 -0
- package/build/cjs/lib/adapter/managers/AliasManager.js.map +7 -0
- package/build/cjs/lib/adapter/managers/CertificateManager.d.ts +50 -0
- package/build/cjs/lib/adapter/managers/CertificateManager.js +174 -0
- package/build/cjs/lib/adapter/managers/CertificateManager.js.map +7 -0
- package/build/cjs/lib/adapter/managers/MessagingManager.d.ts +58 -0
- package/build/cjs/lib/adapter/managers/MessagingManager.js +289 -0
- package/build/cjs/lib/adapter/managers/MessagingManager.js.map +7 -0
- package/build/cjs/lib/adapter/managers/ResourceManager.d.ts +69 -0
- package/build/cjs/lib/adapter/managers/ResourceManager.js +170 -0
- package/build/cjs/lib/adapter/managers/ResourceManager.js.map +7 -0
- package/build/cjs/lib/adapter/managers/SubscriptionManager.d.ts +107 -0
- package/build/cjs/lib/adapter/managers/SubscriptionManager.js +349 -0
- package/build/cjs/lib/adapter/managers/SubscriptionManager.js.map +7 -0
- package/build/cjs/lib/adapter/userInterfaceMessagingController.d.ts +10 -0
- package/build/cjs/lib/adapter/userInterfaceMessagingController.js +9 -2
- package/build/cjs/lib/adapter/userInterfaceMessagingController.js.map +2 -2
- package/build/cjs/lib/adapter/utils.js +15 -1
- package/build/cjs/lib/adapter/utils.js.map +2 -2
- package/build/cjs/lib/adapter/validator.d.ts +10 -5
- package/build/cjs/lib/adapter/validator.js +6 -5
- package/build/cjs/lib/adapter/validator.js.map +2 -2
- package/build/esm/index.d.ts +0 -1
- package/build/esm/index.d.ts.map +1 -1
- package/build/esm/index.js +0 -1
- package/build/esm/index.js.map +1 -1
- package/build/esm/lib/_Types.d.ts +394 -63
- package/build/esm/lib/_Types.d.ts.map +1 -1
- package/build/esm/lib/adapter/adapter.d.ts +1896 -177
- package/build/esm/lib/adapter/adapter.d.ts.map +1 -1
- package/build/esm/lib/adapter/adapter.js +900 -1215
- package/build/esm/lib/adapter/adapter.js.map +1 -1
- package/build/esm/lib/adapter/asyncAdapter.d.ts +167 -0
- package/build/esm/lib/adapter/asyncAdapter.d.ts.map +1 -0
- package/build/esm/lib/adapter/asyncAdapter.js +225 -0
- package/build/esm/lib/adapter/asyncAdapter.js.map +1 -0
- package/build/esm/lib/adapter/context.d.ts +34 -0
- package/build/esm/lib/adapter/context.d.ts.map +1 -0
- package/build/esm/lib/adapter/context.js +2 -0
- package/build/esm/lib/adapter/context.js.map +1 -0
- package/build/esm/lib/adapter/defaultObjs.d.ts +5 -0
- package/build/esm/lib/adapter/defaultObjs.d.ts.map +1 -1
- package/build/esm/lib/adapter/defaultObjs.js +5 -0
- package/build/esm/lib/adapter/defaultObjs.js.map +1 -1
- package/build/esm/lib/adapter/log.d.ts +25 -0
- package/build/esm/lib/adapter/log.d.ts.map +1 -1
- package/build/esm/lib/adapter/log.js +25 -0
- package/build/esm/lib/adapter/log.js.map +1 -1
- package/build/esm/lib/adapter/managers/AdapterContextBase.d.ts +49 -0
- package/build/esm/lib/adapter/managers/AdapterContextBase.d.ts.map +1 -0
- package/build/esm/lib/adapter/managers/AdapterContextBase.js +77 -0
- package/build/esm/lib/adapter/managers/AdapterContextBase.js.map +1 -0
- package/build/esm/lib/adapter/managers/AliasManager.d.ts +103 -0
- package/build/esm/lib/adapter/managers/AliasManager.d.ts.map +1 -0
- package/build/esm/lib/adapter/managers/AliasManager.js +269 -0
- package/build/esm/lib/adapter/managers/AliasManager.js.map +1 -0
- package/build/esm/lib/adapter/managers/CertificateManager.d.ts +50 -0
- package/build/esm/lib/adapter/managers/CertificateManager.d.ts.map +1 -0
- package/build/esm/lib/adapter/managers/CertificateManager.js +142 -0
- package/build/esm/lib/adapter/managers/CertificateManager.js.map +1 -0
- package/build/esm/lib/adapter/managers/MessagingManager.d.ts +58 -0
- package/build/esm/lib/adapter/managers/MessagingManager.d.ts.map +1 -0
- package/build/esm/lib/adapter/managers/MessagingManager.js +267 -0
- package/build/esm/lib/adapter/managers/MessagingManager.js.map +1 -0
- package/build/esm/lib/adapter/managers/ResourceManager.d.ts +69 -0
- package/build/esm/lib/adapter/managers/ResourceManager.d.ts.map +1 -0
- package/build/esm/lib/adapter/managers/ResourceManager.js +151 -0
- package/build/esm/lib/adapter/managers/ResourceManager.js.map +1 -0
- package/build/esm/lib/adapter/managers/SubscriptionManager.d.ts +107 -0
- package/build/esm/lib/adapter/managers/SubscriptionManager.d.ts.map +1 -0
- package/build/esm/lib/adapter/managers/SubscriptionManager.js +374 -0
- package/build/esm/lib/adapter/managers/SubscriptionManager.js.map +1 -0
- package/build/esm/lib/adapter/userInterfaceMessagingController.d.ts +10 -0
- package/build/esm/lib/adapter/userInterfaceMessagingController.d.ts.map +1 -1
- package/build/esm/lib/adapter/userInterfaceMessagingController.js +8 -2
- package/build/esm/lib/adapter/userInterfaceMessagingController.js.map +1 -1
- package/build/esm/lib/adapter/utils.d.ts.map +1 -1
- package/build/esm/lib/adapter/utils.js +1 -1
- package/build/esm/lib/adapter/utils.js.map +1 -1
- package/build/esm/lib/adapter/validator.d.ts +10 -5
- package/build/esm/lib/adapter/validator.d.ts.map +1 -1
- package/build/esm/lib/adapter/validator.js +8 -5
- package/build/esm/lib/adapter/validator.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +25 -20
|
@@ -5,6 +5,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
8
9
|
var __export = (target, all) => {
|
|
9
10
|
for (var name in all)
|
|
10
11
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -45,14 +46,18 @@ var import_node = __toESM(require("node.extend"), 1);
|
|
|
45
46
|
var import_yargs = __toESM(require("yargs/yargs"), 1);
|
|
46
47
|
var import_fs_extra = __toESM(require("fs-extra"), 1);
|
|
47
48
|
var url = __toESM(require("node:url"), 1);
|
|
48
|
-
var import_plugin_base = require("@iobroker/plugin-base");
|
|
49
49
|
var import_js_controller_common = require("@iobroker/js-controller-common");
|
|
50
50
|
var import_utils = require("../../lib/adapter/utils.js");
|
|
51
51
|
var import_package = __toESM(require("@iobroker/js-controller-adapter/package.json"), 1);
|
|
52
52
|
var import_log = require("../../lib/adapter/log.js");
|
|
53
53
|
var import_validator = require("./validator.js");
|
|
54
54
|
var import_constants = require("../../lib/adapter/constants.js");
|
|
55
|
+
var import_plugin_base = require("@iobroker/plugin-base");
|
|
55
56
|
var import_userInterfaceMessagingController = require("../../lib/adapter/userInterfaceMessagingController.js");
|
|
57
|
+
var import_asyncAdapter = require("../../lib/adapter/asyncAdapter.js");
|
|
58
|
+
var import_CertificateManager = require("../../lib/adapter/managers/CertificateManager.js");
|
|
59
|
+
var import_AliasManager = require("../../lib/adapter/managers/AliasManager.js");
|
|
60
|
+
var import_SubscriptionManager = require("../../lib/adapter/managers/SubscriptionManager.js");
|
|
56
61
|
var import_constants2 = require("@iobroker/js-controller-common-db/constants");
|
|
57
62
|
var import_tools = require("@iobroker/js-controller-common-db/tools");
|
|
58
63
|
const controllerVersion = import_package.default.version;
|
|
@@ -60,6 +65,9 @@ const { FORBIDDEN_CHARS } = import_js_controller_common.tools;
|
|
|
60
65
|
const thisDir = url.fileURLToPath(new URL(".", __import_meta_url || `file://${__filename}`));
|
|
61
66
|
import_js_controller_common.tools.ensureDNSOrder();
|
|
62
67
|
class AdapterClass extends import_node_events.EventEmitter {
|
|
68
|
+
static {
|
|
69
|
+
__name(this, "AdapterClass");
|
|
70
|
+
}
|
|
63
71
|
/** Cache of all deprecations which have already been transmitted */
|
|
64
72
|
reportedDeprecations = /* @__PURE__ */ new Set();
|
|
65
73
|
/** Instance to access states DB */
|
|
@@ -76,14 +84,10 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
76
84
|
startedInCompactMode;
|
|
77
85
|
/** List of instances which want our logs */
|
|
78
86
|
logList = /* @__PURE__ */ new Set();
|
|
79
|
-
aliases = /* @__PURE__ */ new Map();
|
|
80
|
-
aliasPatterns = /* @__PURE__ */ new Set();
|
|
81
87
|
enums = {};
|
|
82
88
|
eventLoopLags = [];
|
|
83
89
|
overwriteLogLevel = false;
|
|
84
90
|
adapterReady = false;
|
|
85
|
-
/** Callbacks from sendTo */
|
|
86
|
-
messageCallbacks = /* @__PURE__ */ new Map();
|
|
87
91
|
/**
|
|
88
92
|
* Contains a live cache of the adapter's states.
|
|
89
93
|
* NOTE: This is only defined if the adapter was initialized with the option states: true.
|
|
@@ -95,7 +99,6 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
95
99
|
*/
|
|
96
100
|
oObjects;
|
|
97
101
|
_stopInProgress = false;
|
|
98
|
-
_callbackId = 1;
|
|
99
102
|
_firstConnection = true;
|
|
100
103
|
_timers = /* @__PURE__ */ new Set();
|
|
101
104
|
_intervals = /* @__PURE__ */ new Set();
|
|
@@ -104,12 +107,14 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
104
107
|
log;
|
|
105
108
|
performStrictObjectChecks;
|
|
106
109
|
_logger;
|
|
107
|
-
_restartScheduleJob;
|
|
110
|
+
_restartScheduleJob = null;
|
|
108
111
|
_schedule;
|
|
109
112
|
namespaceLog;
|
|
110
113
|
namespace;
|
|
111
114
|
name;
|
|
112
115
|
_systemSecret;
|
|
116
|
+
/** Attributes of `encryptedNative`: their values in `this.config` are decrypted on start */
|
|
117
|
+
_decryptedNativeAttributes = new Array();
|
|
113
118
|
/** Whether the adapter has already terminated */
|
|
114
119
|
terminated = false;
|
|
115
120
|
/** The cache of usernames */
|
|
@@ -123,8 +128,6 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
123
128
|
// todo
|
|
124
129
|
/** The cache of user groups */
|
|
125
130
|
groups = {};
|
|
126
|
-
/** An array of instances, that support auto subscribe */
|
|
127
|
-
autoSubscribe = [];
|
|
128
131
|
defaultHistory = null;
|
|
129
132
|
pluginHandler;
|
|
130
133
|
_reportInterval;
|
|
@@ -156,11 +159,9 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
156
159
|
/** latitude configured in system.config, only available if requested via AdapterOptions `useFormatDate`*/
|
|
157
160
|
latitude;
|
|
158
161
|
_defaultObjs;
|
|
159
|
-
_aliasObjectsSubscribed;
|
|
160
162
|
config = {};
|
|
161
163
|
host;
|
|
162
164
|
common;
|
|
163
|
-
mboxSubscribed;
|
|
164
165
|
/** Stop the adapter */
|
|
165
166
|
stop;
|
|
166
167
|
version;
|
|
@@ -188,6 +189,32 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
188
189
|
SUPPORTED_FEATURES = (0, import_utils.getSupportedFeatures)();
|
|
189
190
|
/** Controller for messaging related functionality */
|
|
190
191
|
uiMessagingController;
|
|
192
|
+
/** Shared runtime context handed to managers */
|
|
193
|
+
#context;
|
|
194
|
+
#async;
|
|
195
|
+
#certWatchers = /* @__PURE__ */ new Map();
|
|
196
|
+
#aliasInstance;
|
|
197
|
+
/** Lazily-constructed alias subscription manager. */
|
|
198
|
+
get #alias() {
|
|
199
|
+
return this.#aliasInstance ??= new import_AliasManager.AliasManager(this.#context, (id, allowSystem, options) => this._utils.validateId(id, allowSystem, options));
|
|
200
|
+
}
|
|
201
|
+
#subscriptionsInstance;
|
|
202
|
+
/** Lazily-constructed object/file/state subscription manager. */
|
|
203
|
+
get #subscriptions() {
|
|
204
|
+
return this.#subscriptionsInstance ??= new import_SubscriptionManager.SubscriptionManager(this.#context, (id, isPattern) => this._utils.fixId(id, isPattern), this.#alias, {
|
|
205
|
+
getForeignStateObjects: /* @__PURE__ */ __name((pattern, options) => (
|
|
206
|
+
// @ts-expect-error adjust types
|
|
207
|
+
this.getForeignObjectsAsync(pattern, null, null, options)
|
|
208
|
+
), "getForeignStateObjects")
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/** True once `system.certificates` is subscribed, i.e. certificates have been requested */
|
|
212
|
+
#certObjectSubscribed = false;
|
|
213
|
+
/** True once a certificate change scheduled a restart, so concurrent changes schedule only one */
|
|
214
|
+
#certRestartScheduled = false;
|
|
215
|
+
/**
|
|
216
|
+
* @param options Adapter options, or the adapter name as a string
|
|
217
|
+
*/
|
|
191
218
|
constructor(options) {
|
|
192
219
|
super();
|
|
193
220
|
if (typeof options === "string") {
|
|
@@ -309,12 +336,41 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
309
336
|
subscribeCallback: this._options.uiClientSubscribe,
|
|
310
337
|
unsubscribeCallback: this._options.uiClientUnsubscribe
|
|
311
338
|
});
|
|
339
|
+
const self = this;
|
|
340
|
+
this.#context = {
|
|
341
|
+
logger: this._logger,
|
|
342
|
+
uiMessagingController: this.uiMessagingController,
|
|
343
|
+
countOutput: /* @__PURE__ */ __name(() => {
|
|
344
|
+
self.outputCount++;
|
|
345
|
+
}, "countOutput"),
|
|
346
|
+
get namespace() {
|
|
347
|
+
return self.namespace;
|
|
348
|
+
},
|
|
349
|
+
get namespaceLog() {
|
|
350
|
+
return self.namespaceLog;
|
|
351
|
+
},
|
|
352
|
+
get host() {
|
|
353
|
+
return self.host;
|
|
354
|
+
},
|
|
355
|
+
get states() {
|
|
356
|
+
return self.#states;
|
|
357
|
+
},
|
|
358
|
+
get objects() {
|
|
359
|
+
return self.#objects;
|
|
360
|
+
},
|
|
361
|
+
get common() {
|
|
362
|
+
return self.common;
|
|
363
|
+
},
|
|
364
|
+
get config() {
|
|
365
|
+
return self.config;
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
this.#async = new import_asyncAdapter.AsyncAdapter(this.#context);
|
|
312
369
|
this.getPortAsync = import_js_controller_common.tools.promisifyNoError(this.getPort, this);
|
|
313
370
|
this.checkPasswordAsync = import_js_controller_common.tools.promisifyNoError(this.checkPassword, this);
|
|
314
371
|
this.setPasswordAsync = import_js_controller_common.tools.promisify(this.setPassword, this);
|
|
315
372
|
this.checkGroupAsync = import_js_controller_common.tools.promisifyNoError(this.checkGroup, this);
|
|
316
373
|
this.calculatePermissionsAsync = import_js_controller_common.tools.promisifyNoError(this.calculatePermissions, this);
|
|
317
|
-
this.getCertificatesAsync = import_js_controller_common.tools.promisify(this.getCertificates, this);
|
|
318
374
|
this.setObjectAsync = import_js_controller_common.tools.promisify(this.setObject, this);
|
|
319
375
|
this.getAdapterObjectsAsync = import_js_controller_common.tools.promisifyNoError(this.getAdapterObjects, this);
|
|
320
376
|
this.extendObjectAsync = import_js_controller_common.tools.promisify(this.extendObject, this);
|
|
@@ -361,7 +417,6 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
361
417
|
this.readFileAsync = import_js_controller_common.tools.promisify(this.readFile, this, ["file", "mimeType"]);
|
|
362
418
|
this.writeFileAsync = import_js_controller_common.tools.promisify(this.writeFile, this);
|
|
363
419
|
this.fileExistsAsync = import_js_controller_common.tools.promisify(this.fileExists, this);
|
|
364
|
-
this.sendToHostAsync = import_js_controller_common.tools.promisifyNoError(this.sendToHost, this);
|
|
365
420
|
this.setStateAsync = import_js_controller_common.tools.promisify(this.setState, this);
|
|
366
421
|
this.setStateChangedAsync = import_js_controller_common.tools.promisify(this.setStateChanged, this, ["id", "notChanged"]);
|
|
367
422
|
this.setForeignStateAsync = import_js_controller_common.tools.promisify(this.setForeignState, this);
|
|
@@ -378,7 +433,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
378
433
|
this.subscribeStatesAsync = import_js_controller_common.tools.promisify(this.subscribeStates, this);
|
|
379
434
|
this.unsubscribeStatesAsync = import_js_controller_common.tools.promisify(this.unsubscribeStates, this);
|
|
380
435
|
this.setExecutableCapabilities = import_js_controller_common.tools.setExecutableCapabilities;
|
|
381
|
-
this._init();
|
|
436
|
+
this._init().catch((e) => this._logger.error(`${this.namespaceLog} Cannot initialize adapter: ${e.message}`));
|
|
382
437
|
}
|
|
383
438
|
/**
|
|
384
439
|
* Get the adapter scoped package identifier of a node module
|
|
@@ -468,6 +523,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
468
523
|
return import_js_controller_common.tools.encrypt(secretVal, value);
|
|
469
524
|
}
|
|
470
525
|
// unknown guard implementation
|
|
526
|
+
/**
|
|
527
|
+
* Read a session from the states DB
|
|
528
|
+
*
|
|
529
|
+
* @param id the session id
|
|
530
|
+
* @param callback return result
|
|
531
|
+
*/
|
|
471
532
|
getSession(id, callback) {
|
|
472
533
|
import_validator.Validator.assertString(id, "id");
|
|
473
534
|
import_validator.Validator.assertCallback(callback, "callback");
|
|
@@ -477,11 +538,19 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
477
538
|
_getSession(options) {
|
|
478
539
|
if (!this.#states) {
|
|
479
540
|
this._logger.info(`${this.namespaceLog} getSession not processed because States database not connected`);
|
|
480
|
-
return import_js_controller_common.tools.
|
|
541
|
+
return import_js_controller_common.tools.maybeCallback(options.callback, null);
|
|
481
542
|
}
|
|
482
|
-
this.#states.getSession(options.id, options.callback);
|
|
543
|
+
this.#states.getSession(options.id, (err, session) => import_js_controller_common.tools.maybeCallback(options.callback, session || null));
|
|
483
544
|
}
|
|
484
545
|
// unknown implementation guards
|
|
546
|
+
/**
|
|
547
|
+
* Store a session in the states DB
|
|
548
|
+
*
|
|
549
|
+
* @param id the session id
|
|
550
|
+
* @param ttl time to live in seconds
|
|
551
|
+
* @param data the session data to store
|
|
552
|
+
* @param callback return result
|
|
553
|
+
*/
|
|
485
554
|
setSession(id, ttl, data, callback) {
|
|
486
555
|
import_validator.Validator.assertString(id, "id");
|
|
487
556
|
import_validator.Validator.assertOptionalCallback(callback, "callback");
|
|
@@ -495,8 +564,14 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
495
564
|
this._logger.info(`${this.namespaceLog} setSession not processed because States database not connected`);
|
|
496
565
|
return import_js_controller_common.tools.maybeCallbackWithError(options.callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
497
566
|
}
|
|
498
|
-
this.#states.setSession(options.id, options.ttl, options.data, options.callback);
|
|
567
|
+
return options.callback ? this.#states.setSession(options.id, options.ttl, options.data, options.callback) : this.#states.setSession(options.id, options.ttl, options.data);
|
|
499
568
|
}
|
|
569
|
+
/**
|
|
570
|
+
* Destroy a session in the states DB
|
|
571
|
+
*
|
|
572
|
+
* @param id the session id
|
|
573
|
+
* @param callback return result
|
|
574
|
+
*/
|
|
500
575
|
destroySession(id, callback) {
|
|
501
576
|
import_validator.Validator.assertString(id, "id");
|
|
502
577
|
import_validator.Validator.assertOptionalCallback(callback, "callback");
|
|
@@ -507,12 +582,11 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
507
582
|
this._logger.info(`${this.namespaceLog} destroySession not processed because States database not connected`);
|
|
508
583
|
return import_js_controller_common.tools.maybeCallbackWithError(options.callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
509
584
|
}
|
|
510
|
-
this.#states.destroySession(options.id, options.callback);
|
|
585
|
+
return options.callback ? this.#states.destroySession(options.id, options.callback) : this.#states.destroySession(options.id);
|
|
511
586
|
}
|
|
512
587
|
async _getObjectsByArray(keys, options) {
|
|
513
588
|
try {
|
|
514
|
-
|
|
515
|
-
return res;
|
|
589
|
+
return await this.#objects.getObjects(keys, options);
|
|
516
590
|
} catch (e) {
|
|
517
591
|
this._logger.error(`Could not get objects by array: ${e.message}`);
|
|
518
592
|
return [];
|
|
@@ -532,7 +606,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
532
606
|
}
|
|
533
607
|
this.terminated = true;
|
|
534
608
|
let shutdownStarted = false;
|
|
535
|
-
const shutdownLogic = () => {
|
|
609
|
+
const shutdownLogic = /* @__PURE__ */ __name(() => {
|
|
536
610
|
if (shutdownStarted) {
|
|
537
611
|
return;
|
|
538
612
|
}
|
|
@@ -586,7 +660,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
586
660
|
process.exit(_exitCode);
|
|
587
661
|
}
|
|
588
662
|
}, 500);
|
|
589
|
-
};
|
|
663
|
+
}, "shutdownLogic");
|
|
590
664
|
if (this.pluginHandler) {
|
|
591
665
|
this.pluginHandler.destroyAll().then(() => shutdownLogic()).catch(() => shutdownLogic());
|
|
592
666
|
} else {
|
|
@@ -818,7 +892,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
818
892
|
options.user = this.usernames[options.user].id;
|
|
819
893
|
}
|
|
820
894
|
}
|
|
821
|
-
this.getForeignObject(options.user, options, (err, obj) => {
|
|
895
|
+
this.getForeignObject(options.user, options.options, (err, obj) => {
|
|
822
896
|
if (err || !obj) {
|
|
823
897
|
return import_js_controller_common.tools.maybeCallbackWithError(options.callback, "User does not exist");
|
|
824
898
|
}
|
|
@@ -895,11 +969,11 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
895
969
|
if (options.group && !options.group.startsWith("system.group.")) {
|
|
896
970
|
options.group = `system.group.${options.group}`;
|
|
897
971
|
}
|
|
898
|
-
this.getForeignObject(options.user, options, (err, obj) => {
|
|
972
|
+
this.getForeignObject(options.user, options.options, (err, obj) => {
|
|
899
973
|
if (err || !obj) {
|
|
900
974
|
return import_js_controller_common.tools.maybeCallback(options.callback, false);
|
|
901
975
|
}
|
|
902
|
-
this.getForeignObject(options.group, options, (err2, obj2) => {
|
|
976
|
+
return this.getForeignObject(options.group, options.options, (err2, obj2) => {
|
|
903
977
|
if (err2 || !obj2) {
|
|
904
978
|
return import_js_controller_common.tools.maybeCallback(options.callback, false);
|
|
905
979
|
}
|
|
@@ -1004,7 +1078,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1004
1078
|
* ```
|
|
1005
1079
|
*/
|
|
1006
1080
|
calculatePermissions(user, commandsPermissions, options, callback) {
|
|
1007
|
-
user
|
|
1081
|
+
user ||= "";
|
|
1008
1082
|
if (typeof options === "function") {
|
|
1009
1083
|
callback = options;
|
|
1010
1084
|
options = null;
|
|
@@ -1017,7 +1091,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1017
1091
|
import_validator.Validator.assertObject(options, "options");
|
|
1018
1092
|
}
|
|
1019
1093
|
import_validator.Validator.assertOptionalCallback(callback, "callback");
|
|
1020
|
-
return this._calculatePermissions({
|
|
1094
|
+
return this._calculatePermissions({
|
|
1095
|
+
user,
|
|
1096
|
+
commandsPermissions,
|
|
1097
|
+
options,
|
|
1098
|
+
callback
|
|
1099
|
+
});
|
|
1021
1100
|
}
|
|
1022
1101
|
async _calculatePermissions(options) {
|
|
1023
1102
|
const { user } = options;
|
|
@@ -1102,15 +1181,15 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1102
1181
|
try {
|
|
1103
1182
|
for (const type of Object.keys(gAcl)) {
|
|
1104
1183
|
if (type === "user") {
|
|
1105
|
-
acl.users
|
|
1184
|
+
acl.users ||= {};
|
|
1106
1185
|
} else {
|
|
1107
|
-
acl[type]
|
|
1186
|
+
acl[type] ||= {};
|
|
1108
1187
|
}
|
|
1109
1188
|
for (const op of Object.keys(gAcl[type])) {
|
|
1110
1189
|
if (type === "user") {
|
|
1111
|
-
acl.users[op]
|
|
1190
|
+
acl.users[op] ||= gAcl.user[op];
|
|
1112
1191
|
} else {
|
|
1113
|
-
acl[type][op]
|
|
1192
|
+
acl[type][op] ||= gAcl[type][op];
|
|
1114
1193
|
}
|
|
1115
1194
|
}
|
|
1116
1195
|
}
|
|
@@ -1142,7 +1221,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1142
1221
|
this._reportInterval && clearInterval(this._reportInterval);
|
|
1143
1222
|
this._reportInterval = null;
|
|
1144
1223
|
const id = `system.adapter.${this.namespace}`;
|
|
1145
|
-
const finishUnload = async () => {
|
|
1224
|
+
const finishUnload = /* @__PURE__ */ __name(async () => {
|
|
1146
1225
|
if (this._timers.size) {
|
|
1147
1226
|
this._timers.forEach((timer) => clearTimeout(timer));
|
|
1148
1227
|
this._timers.clear();
|
|
@@ -1155,10 +1234,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1155
1234
|
this._delays.forEach((timer) => clearTimeout(timer));
|
|
1156
1235
|
this._delays.clear();
|
|
1157
1236
|
}
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
this.messageCallbacks.clear();
|
|
1161
|
-
}
|
|
1237
|
+
this.#async.clearPending();
|
|
1238
|
+
await this.stopWatchingCertificates();
|
|
1162
1239
|
if (this.#states && updateAliveState) {
|
|
1163
1240
|
this.outputCount++;
|
|
1164
1241
|
try {
|
|
@@ -1171,14 +1248,17 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1171
1248
|
this._logger.info(`${this.namespaceLog} terminating`);
|
|
1172
1249
|
}
|
|
1173
1250
|
this.terminate(reason, exitCode);
|
|
1174
|
-
};
|
|
1251
|
+
}, "finishUnload");
|
|
1175
1252
|
if (this.adapterReady) {
|
|
1176
1253
|
if (typeof this._options.unload === "function") {
|
|
1177
1254
|
if (this._options.unload.length >= 1) {
|
|
1178
1255
|
try {
|
|
1179
|
-
this._options.unload(finishUnload);
|
|
1256
|
+
const unloadResult = this._options.unload(finishUnload);
|
|
1257
|
+
if (unloadResult instanceof Promise) {
|
|
1258
|
+
unloadResult.catch((e) => this._logger.error(`${this.namespaceLog} Error in unload: ${e.message}`));
|
|
1259
|
+
}
|
|
1180
1260
|
} catch {
|
|
1181
|
-
finishUnload();
|
|
1261
|
+
finishUnload().catch((e) => this._logger.error(`${this.namespaceLog} Error in finishUnload: ${e.message}`));
|
|
1182
1262
|
}
|
|
1183
1263
|
} else {
|
|
1184
1264
|
const unloadPromise = this._options.unload();
|
|
@@ -1186,7 +1266,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1186
1266
|
try {
|
|
1187
1267
|
await unloadPromise;
|
|
1188
1268
|
} finally {
|
|
1189
|
-
finishUnload();
|
|
1269
|
+
finishUnload().catch((e) => this._logger.error(`${this.namespaceLog} Error in finishUnload: ${e.message}`));
|
|
1190
1270
|
}
|
|
1191
1271
|
} else {
|
|
1192
1272
|
this._logger.error(`${this.namespaceLog} Error in ${id}: The unload method must return a Promise if it does not accept a callback!`);
|
|
@@ -1200,38 +1280,109 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1200
1280
|
if (!this.#states) {
|
|
1201
1281
|
updateAliveState = false;
|
|
1202
1282
|
}
|
|
1203
|
-
const terminate = () => {
|
|
1283
|
+
const terminate = /* @__PURE__ */ __name(() => {
|
|
1204
1284
|
if (!isPause) {
|
|
1205
1285
|
this._logger.info(`${this.namespaceLog} terminating`);
|
|
1206
1286
|
}
|
|
1207
1287
|
this.terminate(exitCode);
|
|
1208
|
-
};
|
|
1288
|
+
}, "terminate");
|
|
1209
1289
|
finishUnload().then(terminate, terminate);
|
|
1210
1290
|
}, this.common?.stopTimeout || 500);
|
|
1211
1291
|
}
|
|
1212
1292
|
}
|
|
1213
1293
|
/**
|
|
1214
|
-
*
|
|
1215
|
-
*
|
|
1294
|
+
* Installs a restart-on-change watcher for each file-backed certificate path, deduped by path.
|
|
1295
|
+
* A change schedules a graceful restart so the adapter reloads the new certificate.
|
|
1216
1296
|
*
|
|
1217
|
-
* @param
|
|
1297
|
+
* @param paths file-backed certificate paths returned by the certificate manager
|
|
1218
1298
|
*/
|
|
1219
|
-
|
|
1220
|
-
|
|
1299
|
+
#watchCertFiles(paths) {
|
|
1300
|
+
for (const certFile of paths) {
|
|
1301
|
+
if (this.#certWatchers.has(certFile)) {
|
|
1302
|
+
continue;
|
|
1303
|
+
}
|
|
1221
1304
|
try {
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
this._logger.warn(`${this.namespaceLog} New certificate "${filename}" detected. Restart adapter`);
|
|
1227
|
-
setTimeout(() => this._stop({ isPause: false, isScheduled: true }), 2e3);
|
|
1228
|
-
});
|
|
1229
|
-
}
|
|
1305
|
+
const watcher = import_fs_extra.default.watch(certFile, (_eventType, filename) => {
|
|
1306
|
+
this.#scheduleCertificateRestart(`New certificate "${filename}" detected`);
|
|
1307
|
+
});
|
|
1308
|
+
this.#certWatchers.set(certFile, watcher);
|
|
1230
1309
|
} catch (e) {
|
|
1231
|
-
this._logger.error(`${this.namespaceLog}
|
|
1310
|
+
this._logger.error(`${this.namespaceLog} Cannot watch certificate file ${certFile}: ${e.message}`);
|
|
1311
|
+
}
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* Schedules a graceful restart, so the adapter reloads its certificates. Called by both the
|
|
1316
|
+
* file watchers and the `system.certificates` subscription; the first caller wins, so a change
|
|
1317
|
+
* seen through both channels restarts the adapter only once.
|
|
1318
|
+
*
|
|
1319
|
+
* @param reason human-readable cause, logged as a warning
|
|
1320
|
+
*/
|
|
1321
|
+
#scheduleCertificateRestart(reason) {
|
|
1322
|
+
if (this.#certRestartScheduled) {
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
this.#certRestartScheduled = true;
|
|
1326
|
+
this._logger.warn(`${this.namespaceLog} ${reason}. Restart adapter`);
|
|
1327
|
+
setTimeout(() => this._stop({ isPause: false, isScheduled: true }), 2e3);
|
|
1328
|
+
}
|
|
1329
|
+
/**
|
|
1330
|
+
* Subscribes to the `system.certificates` object, so inline (text) certificates are watched the
|
|
1331
|
+
* same way file-backed ones are watched on disk. Subscribing on the system level channel keeps
|
|
1332
|
+
* these events out of the adapter's own `objectChange` handler.
|
|
1333
|
+
*
|
|
1334
|
+
* Called after certificates have been requested, so only adapters actually using certificates
|
|
1335
|
+
* pay for the subscription.
|
|
1336
|
+
*/
|
|
1337
|
+
async #subscribeCertObject() {
|
|
1338
|
+
if (this.#certObjectSubscribed || !this.#objects) {
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
this.#certObjectSubscribed = true;
|
|
1342
|
+
try {
|
|
1343
|
+
await this.#objects.subscribeAsync(import_CertificateManager.CERTIFICATES_OBJECT_ID);
|
|
1344
|
+
if (!this.#certObjectSubscribed && this.#objects) {
|
|
1345
|
+
await this.#objects.unsubscribeAsync(import_CertificateManager.CERTIFICATES_OBJECT_ID);
|
|
1346
|
+
}
|
|
1347
|
+
} catch (e) {
|
|
1348
|
+
this.#certObjectSubscribed = false;
|
|
1349
|
+
this._logger.error(`${this.namespaceLog} Cannot watch certificate object ${import_CertificateManager.CERTIFICATES_OBJECT_ID}: ${e.message}`);
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
/**
|
|
1353
|
+
* Tears down the certificate watching installed by {@link getCertificatesAsync}: closes the file
|
|
1354
|
+
* watchers, unsubscribes from `system.certificates`, and forgets the certificates handed out by the
|
|
1355
|
+
* last call, so a later change no longer schedules a restart. Called on adapter stop.
|
|
1356
|
+
*/
|
|
1357
|
+
async stopWatchingCertificates() {
|
|
1358
|
+
for (const watcher of this.#certWatchers.values()) {
|
|
1359
|
+
watcher.close();
|
|
1360
|
+
}
|
|
1361
|
+
this.#certWatchers.clear();
|
|
1362
|
+
this.#certRestartScheduled = false;
|
|
1363
|
+
this.#async.stopWatchingCertificates();
|
|
1364
|
+
if (this.#certObjectSubscribed && this.#objects) {
|
|
1365
|
+
this.#certObjectSubscribed = false;
|
|
1366
|
+
try {
|
|
1367
|
+
await this.#objects.unsubscribeAsync(import_CertificateManager.CERTIFICATES_OBJECT_ID);
|
|
1368
|
+
} catch {
|
|
1232
1369
|
}
|
|
1233
1370
|
}
|
|
1234
|
-
|
|
1371
|
+
}
|
|
1372
|
+
/**
|
|
1373
|
+
* Loads SSL certificates by name and installs restart-on-change watchers: file watchers for
|
|
1374
|
+
* file-backed certificate values, and a subscription to `system.certificates` covering inline
|
|
1375
|
+
* ones and repointed paths.
|
|
1376
|
+
*
|
|
1377
|
+
* @param publicName public certificate name (defaults to `config.certPublic`)
|
|
1378
|
+
* @param privateName private key name (defaults to `config.certPrivate`)
|
|
1379
|
+
* @param chainedName chained certificate name (defaults to `config.certChained`)
|
|
1380
|
+
*/
|
|
1381
|
+
async getCertificatesAsync(publicName, privateName, chainedName) {
|
|
1382
|
+
const { certs, useLetsEncrypt, certFilePaths } = await this.#async.getCertificates(publicName, privateName, chainedName);
|
|
1383
|
+
this.#watchCertFiles(certFilePaths);
|
|
1384
|
+
await this.#subscribeCertObject();
|
|
1385
|
+
return [certs, useLetsEncrypt];
|
|
1235
1386
|
}
|
|
1236
1387
|
/**
|
|
1237
1388
|
* returns SSL certificates by name
|
|
@@ -1265,59 +1416,16 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1265
1416
|
callback = chainedName;
|
|
1266
1417
|
chainedName = void 0;
|
|
1267
1418
|
}
|
|
1268
|
-
const config = this.config;
|
|
1269
|
-
publicName = publicName || config.certPublic;
|
|
1270
|
-
privateName = privateName || config.certPrivate;
|
|
1271
|
-
chainedName = chainedName || config.certChained;
|
|
1272
|
-
if (publicName !== void 0) {
|
|
1273
|
-
import_validator.Validator.assertString(publicName, "publicName");
|
|
1274
|
-
}
|
|
1275
|
-
if (privateName !== void 0) {
|
|
1276
|
-
import_validator.Validator.assertString(privateName, "privateName");
|
|
1277
|
-
}
|
|
1278
|
-
if (chainedName !== void 0) {
|
|
1279
|
-
import_validator.Validator.assertString(chainedName, "chainedName");
|
|
1280
|
-
}
|
|
1281
1419
|
import_validator.Validator.assertOptionalCallback(callback, "callback");
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
1290
|
-
}
|
|
1291
|
-
try {
|
|
1292
|
-
obj = await this.#objects.getObject("system.certificates");
|
|
1293
|
-
} catch {
|
|
1294
|
-
}
|
|
1295
|
-
if (!obj || !obj.native.certificates || !publicName || !privateName || !obj.native.certificates[publicName] || !obj.native.certificates[privateName] || chainedName && !obj.native.certificates[chainedName]) {
|
|
1296
|
-
this._logger.error(`${this.namespaceLog} Cannot configure secure web server, because no certificates found: ${publicName}, ${privateName}, ${chainedName}`);
|
|
1297
|
-
if (publicName === "defaultPublic" || privateName === "defaultPrivate") {
|
|
1298
|
-
this._logger.info(`${this.namespaceLog} Default certificates seem to be configured but missing. You can execute "iobroker cert create" in your shell to create these.`);
|
|
1299
|
-
}
|
|
1300
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_NOT_FOUND);
|
|
1301
|
-
}
|
|
1302
|
-
let ca;
|
|
1303
|
-
if (chainedName) {
|
|
1304
|
-
const chained = this._readFileCertificate(obj.native.certificates[chainedName]).split("-----END CERTIFICATE-----\r\n");
|
|
1305
|
-
if (chained.join("").length >= 512) {
|
|
1306
|
-
const caArr = [];
|
|
1307
|
-
for (const cert of chained) {
|
|
1308
|
-
if (cert.replace(/(\r\n|\r|\n)/g, "").trim()) {
|
|
1309
|
-
caArr.push(`${cert}-----END CERTIFICATE-----\r
|
|
1310
|
-
`);
|
|
1311
|
-
}
|
|
1312
|
-
}
|
|
1313
|
-
ca = caArr.join("");
|
|
1314
|
-
}
|
|
1420
|
+
const cb = callback;
|
|
1421
|
+
if (typeof cb === "function") {
|
|
1422
|
+
return this.getCertificatesAsync(publicName, privateName, chainedName).then(([certs, useLetsEncrypt]) => {
|
|
1423
|
+
cb(null, certs, useLetsEncrypt);
|
|
1424
|
+
}, (err) => {
|
|
1425
|
+
cb(err);
|
|
1426
|
+
});
|
|
1315
1427
|
}
|
|
1316
|
-
return
|
|
1317
|
-
key: this._readFileCertificate(obj.native.certificates[privateName]),
|
|
1318
|
-
cert: this._readFileCertificate(obj.native.certificates[publicName]),
|
|
1319
|
-
ca
|
|
1320
|
-
}, obj.native.letsEncrypt);
|
|
1428
|
+
return this.getCertificatesAsync(publicName, privateName, chainedName);
|
|
1321
1429
|
}
|
|
1322
1430
|
/**
|
|
1323
1431
|
* Restarts an instance of the adapter.
|
|
@@ -1326,7 +1434,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1326
1434
|
restart() {
|
|
1327
1435
|
if (this.stop) {
|
|
1328
1436
|
this._logger.warn(`${this.namespaceLog} Restart initiated`);
|
|
1329
|
-
this.stop();
|
|
1437
|
+
this.stop().catch((e) => this._logger.error(`${this.namespaceLog} Cannot stop adapter: ${e.message}`));
|
|
1330
1438
|
} else {
|
|
1331
1439
|
this._logger.warn(`${this.namespaceLog} Cannot initiate restart, because this.stop is not defined`);
|
|
1332
1440
|
}
|
|
@@ -1389,7 +1497,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1389
1497
|
return this.setForeignObjectAsync(configObjId, obj);
|
|
1390
1498
|
}
|
|
1391
1499
|
/**
|
|
1392
|
-
* Reads
|
|
1500
|
+
* Reads a parameter which is stored encrypted and returns its decrypted value.
|
|
1393
1501
|
*
|
|
1394
1502
|
* It returns promise if no callback is provided.
|
|
1395
1503
|
*
|
|
@@ -1404,14 +1512,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1404
1512
|
async _getEncryptedConfig(options) {
|
|
1405
1513
|
const { attribute, callback } = options;
|
|
1406
1514
|
const value = (0, import_utils.getObjectAttribute)(this.config, attribute);
|
|
1515
|
+
if ((Array.isArray(value) || typeof value === "string") && this._decryptedNativeAttributes.includes(attribute)) {
|
|
1516
|
+
return import_js_controller_common.tools.maybeCallbackWithError(callback, null, value);
|
|
1517
|
+
}
|
|
1407
1518
|
if (Array.isArray(value)) {
|
|
1408
1519
|
const secret = await this.getSystemSecret();
|
|
1409
|
-
const result =
|
|
1410
|
-
for (let i = 0; i < value.length; i++) {
|
|
1411
|
-
if (typeof value[i] === "string") {
|
|
1412
|
-
result[i] = import_js_controller_common.tools.decrypt(secret, value[i]);
|
|
1413
|
-
}
|
|
1414
|
-
}
|
|
1520
|
+
const result = value.map((item) => typeof item === "string" ? import_js_controller_common.tools.decrypt(secret, item) : item);
|
|
1415
1521
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, null, result);
|
|
1416
1522
|
} else if (typeof value === "string") {
|
|
1417
1523
|
const secret = await this.getSystemSecret();
|
|
@@ -1705,13 +1811,13 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1705
1811
|
}
|
|
1706
1812
|
async _getAdapterObjects(options) {
|
|
1707
1813
|
const ret = {};
|
|
1708
|
-
const addRows = (rows) => {
|
|
1814
|
+
const addRows = /* @__PURE__ */ __name((rows) => {
|
|
1709
1815
|
if (rows) {
|
|
1710
1816
|
for (const { id, value } of rows) {
|
|
1711
1817
|
ret[id] = value;
|
|
1712
1818
|
}
|
|
1713
1819
|
}
|
|
1714
|
-
};
|
|
1820
|
+
}, "addRows");
|
|
1715
1821
|
if (!this.#objects) {
|
|
1716
1822
|
return import_js_controller_common.tools.maybeCallback(options.callback, ret);
|
|
1717
1823
|
}
|
|
@@ -1767,7 +1873,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1767
1873
|
* }
|
|
1768
1874
|
* ```
|
|
1769
1875
|
*
|
|
1770
|
-
* If following object will be passed as argument
|
|
1876
|
+
* If the following object will be passed as an argument
|
|
1771
1877
|
*
|
|
1772
1878
|
* ```js
|
|
1773
1879
|
* {
|
|
@@ -1868,28 +1974,28 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1868
1974
|
this._logger.error(`${this.namespaceLog} Object ${options.id} not exist!`);
|
|
1869
1975
|
oldObj = {};
|
|
1870
1976
|
}
|
|
1871
|
-
if (options.obj.native && "repositories" in options.obj.native && oldObj.native
|
|
1872
|
-
oldObj.native.repositories =
|
|
1977
|
+
if (options.obj.native && "repositories" in options.obj.native && oldObj.native?.repositories) {
|
|
1978
|
+
oldObj.native.repositories = {};
|
|
1873
1979
|
}
|
|
1874
|
-
if (options.obj.common && "members" in options.obj.common && oldObj.common
|
|
1980
|
+
if (options.obj.common && "members" in options.obj.common && oldObj.common?.members) {
|
|
1875
1981
|
oldObj.common.members = [];
|
|
1876
1982
|
}
|
|
1877
|
-
if (options.obj.native && "certificates" in options.obj.native && oldObj.native
|
|
1878
|
-
oldObj.native.certificates =
|
|
1983
|
+
if (options.obj.native && "certificates" in options.obj.native && oldObj.native?.certificates) {
|
|
1984
|
+
oldObj.native.certificates = {};
|
|
1879
1985
|
}
|
|
1880
|
-
if (options.obj.native && "devices" in options.obj.native && oldObj.native
|
|
1986
|
+
if (options.obj.native && "devices" in options.obj.native && oldObj.native?.devices) {
|
|
1881
1987
|
oldObj.native.devices = [];
|
|
1882
1988
|
}
|
|
1883
|
-
options.obj.from
|
|
1884
|
-
options.obj.user
|
|
1885
|
-
options.obj.ts
|
|
1989
|
+
options.obj.from ||= `system.adapter.${this.namespace}`;
|
|
1990
|
+
options.obj.user ||= (options.options ? options.options.user : "") || import_constants.SYSTEM_ADMIN_USER;
|
|
1991
|
+
options.obj.ts ||= Date.now();
|
|
1886
1992
|
options.obj = (0, import_node.default)(true, oldObj, options.obj);
|
|
1887
1993
|
return this.#objects.setObject(options.id, options.obj, options.options, options.callback);
|
|
1888
1994
|
}
|
|
1889
|
-
options.obj.from
|
|
1890
|
-
options.obj.user
|
|
1891
|
-
options.obj.ts
|
|
1892
|
-
if (options.obj
|
|
1995
|
+
options.obj.from ||= `system.adapter.${this.namespace}`;
|
|
1996
|
+
options.obj.user ||= (options.options ? options.options.user : "") || import_constants.SYSTEM_ADMIN_USER;
|
|
1997
|
+
options.obj.ts ||= Date.now();
|
|
1998
|
+
if (options.obj?.type === "state" || !options.obj.type && oldObj?.type === "state") {
|
|
1893
1999
|
if (options.obj.common && "custom" in options.obj.common && options.obj.common.custom !== null && !import_js_controller_common.tools.isObject(options.obj.common.custom)) {
|
|
1894
2000
|
this._logger.error(`${this.namespaceLog} extendObject ${options.id} (type=${options.obj.type}) property common.custom is of type ${typeof options.obj.common.custom}, expected object.`);
|
|
1895
2001
|
return import_js_controller_common.tools.maybeCallbackWithError(options.callback, "common.custom needs to be an object");
|
|
@@ -1904,12 +2010,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1904
2010
|
return this.setForeignObject(options.id, options.obj, options.options, options.callback);
|
|
1905
2011
|
}
|
|
1906
2012
|
try {
|
|
1907
|
-
const cbObj = await this.#objects.
|
|
2013
|
+
const cbObj = await this.#objects.extendObject(options.id, options.obj, options.options);
|
|
1908
2014
|
let defState;
|
|
1909
2015
|
if (options.obj.type === "state" || oldObj.type === "state") {
|
|
1910
2016
|
if (options.obj.common && "def" in options.obj.common && options.obj.common.def !== void 0) {
|
|
1911
2017
|
defState = options.obj.common.def;
|
|
1912
|
-
} else if (oldObj.common
|
|
2018
|
+
} else if (oldObj.common?.def !== void 0) {
|
|
1913
2019
|
defState = oldObj.common.def;
|
|
1914
2020
|
}
|
|
1915
2021
|
}
|
|
@@ -2068,28 +2174,28 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2068
2174
|
this._logger.error(`${this.namespaceLog} Object ${id} not exist!`);
|
|
2069
2175
|
oldObj = {};
|
|
2070
2176
|
}
|
|
2071
|
-
if (obj.native && "repositories" in obj.native && oldObj.native
|
|
2072
|
-
oldObj.native.repositories =
|
|
2177
|
+
if (obj.native && "repositories" in obj.native && oldObj.native?.repositories) {
|
|
2178
|
+
oldObj.native.repositories = {};
|
|
2073
2179
|
}
|
|
2074
|
-
if (obj.common && "members" in obj.common && oldObj.common
|
|
2180
|
+
if (obj.common && "members" in obj.common && oldObj.common?.members) {
|
|
2075
2181
|
oldObj.common.members = [];
|
|
2076
2182
|
}
|
|
2077
|
-
if (obj.native && "certificates" in obj.native && oldObj.native
|
|
2078
|
-
oldObj.native.certificates =
|
|
2183
|
+
if (obj.native && "certificates" in obj.native && oldObj.native?.certificates) {
|
|
2184
|
+
oldObj.native.certificates = {};
|
|
2079
2185
|
}
|
|
2080
|
-
if (obj.native && "devices" in obj.native && oldObj.native
|
|
2186
|
+
if (obj.native && "devices" in obj.native && oldObj.native?.devices) {
|
|
2081
2187
|
oldObj.native.devices = [];
|
|
2082
2188
|
}
|
|
2083
|
-
obj.from
|
|
2084
|
-
obj.user
|
|
2085
|
-
obj.ts
|
|
2189
|
+
obj.from ||= `system.adapter.${this.namespace}`;
|
|
2190
|
+
obj.user ||= options?.user || import_constants.SYSTEM_ADMIN_USER;
|
|
2191
|
+
obj.ts ||= Date.now();
|
|
2086
2192
|
obj = (0, import_node.default)(true, oldObj, obj);
|
|
2087
|
-
return this.#objects.setObject(id, obj, options, callback);
|
|
2193
|
+
return callback ? this.#objects.setObject(id, obj, options, callback) : this.#objects.setObject(id, obj, options);
|
|
2088
2194
|
}
|
|
2089
|
-
obj.from
|
|
2090
|
-
obj.user
|
|
2091
|
-
obj.ts
|
|
2092
|
-
if (obj.type && obj.type === "state" || !obj.type && oldObj
|
|
2195
|
+
obj.from ||= `system.adapter.${this.namespace}`;
|
|
2196
|
+
obj.user ||= options?.user || import_constants.SYSTEM_ADMIN_USER;
|
|
2197
|
+
obj.ts ||= Date.now();
|
|
2198
|
+
if (obj.type && obj.type === "state" || !obj.type && oldObj?.type === "state") {
|
|
2093
2199
|
if (obj.common && "custom" in obj.common && obj.common.custom !== null && !import_js_controller_common.tools.isObject(obj.common.custom)) {
|
|
2094
2200
|
this._logger.error(`${this.namespaceLog} extendObject ${id} (type=${obj.type}) property common.custom is of type ${typeof obj.common.custom}, expected object.`);
|
|
2095
2201
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, "common.custom needs to be an object");
|
|
@@ -2104,12 +2210,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2104
2210
|
return this.setForeignObject(id, obj, options, callback);
|
|
2105
2211
|
}
|
|
2106
2212
|
try {
|
|
2107
|
-
const cbObj = await this.#objects.
|
|
2213
|
+
const cbObj = await this.#objects.extendObject(id, obj, options);
|
|
2108
2214
|
if (cbObj?.value.type === "state") {
|
|
2109
2215
|
let defState;
|
|
2110
|
-
if (obj.common && "def" in obj.common && obj.common
|
|
2216
|
+
if (obj.common && "def" in obj.common && obj.common?.def !== void 0) {
|
|
2111
2217
|
defState = obj.common.def;
|
|
2112
|
-
} else if (oldObj.common
|
|
2218
|
+
} else if (oldObj.common?.def !== void 0) {
|
|
2113
2219
|
defState = oldObj.common.def;
|
|
2114
2220
|
}
|
|
2115
2221
|
if (defState !== void 0) {
|
|
@@ -2242,7 +2348,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2242
2348
|
import_validator.Validator.assertString(design, "design");
|
|
2243
2349
|
import_validator.Validator.assertString(search, "search");
|
|
2244
2350
|
import_validator.Validator.assertOptionalCallback(callback, "callback");
|
|
2245
|
-
params
|
|
2351
|
+
params ||= {};
|
|
2246
2352
|
import_validator.Validator.assertObject(params, "params");
|
|
2247
2353
|
if (options !== null && options !== void 0) {
|
|
2248
2354
|
import_validator.Validator.assertObject(options, "options");
|
|
@@ -2503,9 +2609,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2503
2609
|
if (!parts[2]) {
|
|
2504
2610
|
continue;
|
|
2505
2611
|
}
|
|
2506
|
-
|
|
2507
|
-
result[`${parts[0]}.${parts[1]}`] = {};
|
|
2508
|
-
}
|
|
2612
|
+
result[`${parts[0]}.${parts[1]}`] ||= {};
|
|
2509
2613
|
result[`${parts[0]}.${parts[1]}`][row.id] = row.value;
|
|
2510
2614
|
}
|
|
2511
2615
|
}
|
|
@@ -2712,7 +2816,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2712
2816
|
* @param options optional user context with language
|
|
2713
2817
|
* @param options.user current user
|
|
2714
2818
|
* @param options.language language in which the search must be done for multi-language names
|
|
2715
|
-
* @
|
|
2819
|
+
* @returns if the object was found by ID it will return id and may be the multi-language name it exists. If the object was found by name it will return id and the multi-language name. If the object was not found, it will return only name that was searched for.
|
|
2716
2820
|
*/
|
|
2717
2821
|
findForeignObjectAsync(id, type, options) {
|
|
2718
2822
|
return new Promise((resolve, reject) => this.findForeignObject(id, type, options || {}, (err, id2, name) => {
|
|
@@ -2759,8 +2863,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2759
2863
|
return import_js_controller_common.tools.maybeCallbackWithError(options.callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
2760
2864
|
}
|
|
2761
2865
|
try {
|
|
2762
|
-
const obj = await this.#objects.getObjectAsync(options.id, options);
|
|
2763
|
-
if (obj && "protectedNative" in obj && Array.isArray(obj.protectedNative) && obj._id
|
|
2866
|
+
const obj = await this.#objects.getObjectAsync(options.id, options.options);
|
|
2867
|
+
if (obj?.native && "protectedNative" in obj && Array.isArray(obj.protectedNative) && obj._id?.startsWith("system.adapter.") && !import_constants.NO_PROTECT_ADAPTERS.includes(this.name) && this.name !== obj._id.split(".")[2]) {
|
|
2764
2868
|
for (const attr of obj.protectedNative) {
|
|
2765
2869
|
(0, import_utils.deleteObjectAttribute)(obj.native, attr);
|
|
2766
2870
|
}
|
|
@@ -2792,29 +2896,32 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2792
2896
|
id = this._utils.fixId(id);
|
|
2793
2897
|
this.delForeignObject(id, options, callback);
|
|
2794
2898
|
}
|
|
2795
|
-
_deleteObjects(tasks, options, cb) {
|
|
2796
|
-
if (!tasks
|
|
2899
|
+
async _deleteObjects(tasks, options, cb) {
|
|
2900
|
+
if (!tasks?.length) {
|
|
2797
2901
|
return import_js_controller_common.tools.maybeCallback(cb);
|
|
2798
2902
|
}
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2903
|
+
try {
|
|
2904
|
+
for (const task of tasks) {
|
|
2905
|
+
await new Promise((resolve, reject) => this.#objects.delObject(task.id, options, (err) => {
|
|
2906
|
+
err ? reject(err) : resolve();
|
|
2907
|
+
}));
|
|
2908
|
+
if (task.state) {
|
|
2909
|
+
try {
|
|
2910
|
+
await this.delForeignStateAsync(task.id, options);
|
|
2911
|
+
} catch (e) {
|
|
2912
|
+
this._logger.warn(`${this.namespaceLog} Could not remove state of ${task.id}: ${e.message}`);
|
|
2913
|
+
}
|
|
2914
|
+
}
|
|
2805
2915
|
try {
|
|
2806
|
-
await
|
|
2916
|
+
await import_js_controller_common.tools.removeIdFromAllEnums(this.#objects, task.id, this.enums);
|
|
2807
2917
|
} catch (e) {
|
|
2808
|
-
this._logger.warn(`${this.namespaceLog} Could not remove
|
|
2918
|
+
this._logger.warn(`${this.namespaceLog} Could not remove ${task.id} from enums: ${e.message}`);
|
|
2809
2919
|
}
|
|
2810
2920
|
}
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
}
|
|
2816
|
-
setImmediate(() => this._deleteObjects(tasks, options, cb));
|
|
2817
|
-
});
|
|
2921
|
+
} catch (err) {
|
|
2922
|
+
return import_js_controller_common.tools.maybeCallbackWithError(cb, err);
|
|
2923
|
+
}
|
|
2924
|
+
return import_js_controller_common.tools.maybeCallback(cb);
|
|
2818
2925
|
}
|
|
2819
2926
|
/**
|
|
2820
2927
|
* Delete any object.
|
|
@@ -2862,16 +2969,17 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2862
2969
|
const tasks = obj && (!obj.common || !obj.common.dontDelete) ? [{ id, state: obj.type === "state" }] : [];
|
|
2863
2970
|
const selector = { startkey: `${id}.`, endkey: `${id}.\u9999` };
|
|
2864
2971
|
this.#objects.getObjectList(selector, options, (err2, res) => {
|
|
2865
|
-
res
|
|
2866
|
-
tasks.push({ id: item.id, state: item.value
|
|
2867
|
-
this._deleteObjects(tasks, options, callback);
|
|
2972
|
+
res?.rows.forEach((item) => !tasks.find((task) => task.id === item.id) && !item.value?.common?.dontDelete && // exclude objects with dontDelete flag
|
|
2973
|
+
tasks.push({ id: item.id, state: item.value?.type === "state" }));
|
|
2974
|
+
return this._deleteObjects(tasks, options, callback);
|
|
2868
2975
|
});
|
|
2869
2976
|
});
|
|
2870
2977
|
} else {
|
|
2871
2978
|
this.#objects.getObject(id, options, async (err, obj) => {
|
|
2872
2979
|
if (err) {
|
|
2873
2980
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, err);
|
|
2874
|
-
}
|
|
2981
|
+
}
|
|
2982
|
+
if (obj) {
|
|
2875
2983
|
if (obj.common?.dontDelete) {
|
|
2876
2984
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, new Error("not deletable"));
|
|
2877
2985
|
}
|
|
@@ -2918,16 +3026,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2918
3026
|
if (options !== null && options !== void 0) {
|
|
2919
3027
|
import_validator.Validator.assertObject(options, "options");
|
|
2920
3028
|
}
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
2924
|
-
}
|
|
2925
|
-
if (pattern === "*") {
|
|
2926
|
-
this.#objects.subscribeUser(`${this.namespace}.*`, options, callback);
|
|
2927
|
-
} else {
|
|
2928
|
-
const fixedPattern = Array.isArray(pattern) ? pattern : this._utils.fixId(pattern, true);
|
|
2929
|
-
this.#objects.subscribeUser(fixedPattern, options, callback);
|
|
2930
|
-
}
|
|
3029
|
+
const cb = callback;
|
|
3030
|
+
this.#subscriptions.subscribeObjects(pattern, options).then(() => cb?.(), (err) => cb?.(err));
|
|
2931
3031
|
}
|
|
2932
3032
|
/**
|
|
2933
3033
|
* Unsubscribe on the changes of objects in this instance.
|
|
@@ -2951,16 +3051,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2951
3051
|
if (options !== null && options !== void 0) {
|
|
2952
3052
|
import_validator.Validator.assertObject(options, "options");
|
|
2953
3053
|
}
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
2957
|
-
}
|
|
2958
|
-
if (pattern === "*") {
|
|
2959
|
-
this.#objects.unsubscribeUser(`${this.namespace}.*`, options, callback);
|
|
2960
|
-
} else {
|
|
2961
|
-
const fixedPattern = Array.isArray(pattern) ? pattern : this._utils.fixId(pattern, true);
|
|
2962
|
-
this.#objects.unsubscribeUser(fixedPattern, options, callback);
|
|
2963
|
-
}
|
|
3054
|
+
const cb = callback;
|
|
3055
|
+
this.#subscriptions.unsubscribeObjects(pattern, options).then(() => cb?.(), (err) => cb?.(err));
|
|
2964
3056
|
}
|
|
2965
3057
|
/**
|
|
2966
3058
|
* Subscribe for the changes of objects in any instance.
|
|
@@ -2984,11 +3076,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2984
3076
|
if (options !== null && options !== void 0) {
|
|
2985
3077
|
import_validator.Validator.assertObject(options, "options");
|
|
2986
3078
|
}
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
2990
|
-
}
|
|
2991
|
-
this.#objects.subscribeUser(pattern, options, callback);
|
|
3079
|
+
const cb = callback;
|
|
3080
|
+
this.#subscriptions.subscribeForeignObjects(pattern, options).then(() => cb?.(), (err) => cb?.(err));
|
|
2992
3081
|
}
|
|
2993
3082
|
/**
|
|
2994
3083
|
* Unsubscribe for the patterns on all objects.
|
|
@@ -3015,11 +3104,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3015
3104
|
if (options !== null && options !== void 0) {
|
|
3016
3105
|
import_validator.Validator.assertObject(options, "options");
|
|
3017
3106
|
}
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
3021
|
-
}
|
|
3022
|
-
this.#objects.unsubscribeUser(pattern, options, callback);
|
|
3107
|
+
const cb = callback;
|
|
3108
|
+
this.#subscriptions.unsubscribeForeignObjects(pattern, options).then(() => cb?.(), (err) => cb?.(err));
|
|
3023
3109
|
}
|
|
3024
3110
|
/**
|
|
3025
3111
|
* Subscribe for the changes of files in specific instance.
|
|
@@ -3029,16 +3115,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3029
3115
|
* @param options optional user context
|
|
3030
3116
|
*/
|
|
3031
3117
|
subscribeForeignFiles(id, pattern, options) {
|
|
3032
|
-
if (!this.#objects) {
|
|
3033
|
-
this._logger.info(`${this.namespaceLog} subscribeForeignFiles not processed because Objects database not connected`);
|
|
3034
|
-
throw new Error(import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
3035
|
-
}
|
|
3036
3118
|
import_validator.Validator.assertString(id, "id");
|
|
3037
3119
|
import_validator.Validator.assertPattern(pattern, "pattern");
|
|
3038
3120
|
if (options !== null && options !== void 0) {
|
|
3039
3121
|
import_validator.Validator.assertObject(options, "options");
|
|
3040
3122
|
}
|
|
3041
|
-
return this.#
|
|
3123
|
+
return this.#subscriptions.subscribeForeignFiles(id, pattern, options);
|
|
3042
3124
|
}
|
|
3043
3125
|
/**
|
|
3044
3126
|
* Unsubscribe for the changes of files on specific instance.
|
|
@@ -3051,16 +3133,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3051
3133
|
if (!pattern) {
|
|
3052
3134
|
pattern = "*";
|
|
3053
3135
|
}
|
|
3054
|
-
if (!this.#objects) {
|
|
3055
|
-
this._logger.info(`${this.namespaceLog} unsubscribeForeignFiles not processed because Objects database not connected`);
|
|
3056
|
-
throw new Error(import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
3057
|
-
}
|
|
3058
3136
|
import_validator.Validator.assertString(id, "id");
|
|
3059
3137
|
import_validator.Validator.assertPattern(pattern, "pattern");
|
|
3060
3138
|
if (options !== null && options !== void 0) {
|
|
3061
3139
|
import_validator.Validator.assertObject(options, "options");
|
|
3062
3140
|
}
|
|
3063
|
-
return this.#
|
|
3141
|
+
return this.#subscriptions.unsubscribeForeignFiles(id, pattern, options);
|
|
3064
3142
|
}
|
|
3065
3143
|
/**
|
|
3066
3144
|
* Same as {@link AdapterClass.setObject}, but with check if the object exists.
|
|
@@ -3208,11 +3286,11 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3208
3286
|
return id;
|
|
3209
3287
|
}
|
|
3210
3288
|
/**
|
|
3211
|
-
* @param deviceName
|
|
3212
|
-
* @param common
|
|
3213
|
-
* @param _native
|
|
3214
|
-
* @param options
|
|
3215
|
-
* @param callback
|
|
3289
|
+
* @param deviceName the name of the device
|
|
3290
|
+
* @param common the common section of the device object
|
|
3291
|
+
* @param _native the native section of the device object
|
|
3292
|
+
* @param options optional user context
|
|
3293
|
+
* @param callback return result
|
|
3216
3294
|
* @deprecated use `this.extendObject` instead
|
|
3217
3295
|
*/
|
|
3218
3296
|
createDevice(deviceName, common, _native, options, callback) {
|
|
@@ -3249,25 +3327,28 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3249
3327
|
_createDevice(_options) {
|
|
3250
3328
|
let { common, deviceName, _native } = _options;
|
|
3251
3329
|
const { callback, options } = _options;
|
|
3252
|
-
common
|
|
3253
|
-
common.name
|
|
3330
|
+
common ||= {};
|
|
3331
|
+
common.name ||= deviceName;
|
|
3254
3332
|
deviceName = deviceName.replace(FORBIDDEN_CHARS, "_").replace(/\./g, "_");
|
|
3255
3333
|
_native = _native || {};
|
|
3256
|
-
this.setObjectNotExists(deviceName, {
|
|
3334
|
+
const createResult = this.setObjectNotExists(deviceName, {
|
|
3257
3335
|
type: "device",
|
|
3258
3336
|
common,
|
|
3259
3337
|
native: _native
|
|
3260
3338
|
}, options, callback);
|
|
3339
|
+
if (createResult instanceof Promise) {
|
|
3340
|
+
createResult.catch((e) => this._logger.error(`${this.namespaceLog} Cannot create device: ${e.message}`));
|
|
3341
|
+
}
|
|
3261
3342
|
}
|
|
3262
3343
|
/**
|
|
3263
3344
|
* Name of channel must be in format "channel"
|
|
3264
3345
|
*
|
|
3265
|
-
* @param parentDevice
|
|
3266
|
-
* @param channelName
|
|
3267
|
-
* @param roleOrCommon
|
|
3268
|
-
* @param _native
|
|
3269
|
-
* @param options
|
|
3270
|
-
* @param callback
|
|
3346
|
+
* @param parentDevice the parent device name
|
|
3347
|
+
* @param channelName the name of the channel
|
|
3348
|
+
* @param roleOrCommon role string or the common section of the channel object
|
|
3349
|
+
* @param _native the native section of the channel object
|
|
3350
|
+
* @param options optional user context
|
|
3351
|
+
* @param callback return result
|
|
3271
3352
|
* @deprecated use `this.extendObject` instead
|
|
3272
3353
|
*/
|
|
3273
3354
|
createChannel(parentDevice, channelName, roleOrCommon, _native, options, callback) {
|
|
@@ -3300,28 +3381,29 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3300
3381
|
import_validator.Validator.assertString(channelName, "channelName");
|
|
3301
3382
|
import_validator.Validator.assertString(parentDevice, "parentDevice");
|
|
3302
3383
|
import_validator.Validator.assertOptionalCallback(callback, "callback");
|
|
3303
|
-
common.name
|
|
3384
|
+
common.name ||= channelName;
|
|
3304
3385
|
if (parentDevice) {
|
|
3305
3386
|
parentDevice = parentDevice.replace(FORBIDDEN_CHARS, "_").replace(/\./g, "_");
|
|
3306
3387
|
}
|
|
3307
3388
|
channelName = channelName.replace(FORBIDDEN_CHARS, "_").replace(/\./g, "_");
|
|
3308
3389
|
channelName = this._DCS2ID(parentDevice, channelName);
|
|
3309
|
-
_native
|
|
3390
|
+
_native ||= {};
|
|
3310
3391
|
const obj = {
|
|
3392
|
+
_id: channelName,
|
|
3311
3393
|
type: "channel",
|
|
3312
3394
|
common,
|
|
3313
3395
|
native: _native
|
|
3314
3396
|
};
|
|
3315
|
-
this.setObjectNotExists(channelName, obj, options, callback);
|
|
3397
|
+
return this.setObjectNotExists(channelName, obj, options, callback);
|
|
3316
3398
|
}
|
|
3317
3399
|
/**
|
|
3318
|
-
* @param parentDevice
|
|
3319
|
-
* @param parentChannel
|
|
3320
|
-
* @param stateName
|
|
3321
|
-
* @param roleOrCommon
|
|
3322
|
-
* @param _native
|
|
3323
|
-
* @param options
|
|
3324
|
-
* @param callback
|
|
3400
|
+
* @param parentDevice the parent device name
|
|
3401
|
+
* @param parentChannel the parent channel name
|
|
3402
|
+
* @param stateName the name of the state
|
|
3403
|
+
* @param roleOrCommon role string or the common section of the state object
|
|
3404
|
+
* @param _native the native section of the state object
|
|
3405
|
+
* @param options optional user context
|
|
3406
|
+
* @param callback return result
|
|
3325
3407
|
* @deprecated use `this.extendObject` instead
|
|
3326
3408
|
*/
|
|
3327
3409
|
createState(parentDevice, parentChannel, stateName, roleOrCommon, _native, options, callback) {
|
|
@@ -3347,12 +3429,13 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3347
3429
|
read: true,
|
|
3348
3430
|
write: false,
|
|
3349
3431
|
name: "",
|
|
3350
|
-
role: roleOrCommon
|
|
3432
|
+
role: roleOrCommon,
|
|
3433
|
+
type: "mixed"
|
|
3351
3434
|
};
|
|
3352
3435
|
} else if (import_js_controller_common.tools.isObject(roleOrCommon)) {
|
|
3353
3436
|
common = roleOrCommon;
|
|
3354
3437
|
}
|
|
3355
|
-
_native
|
|
3438
|
+
_native ||= {};
|
|
3356
3439
|
import_validator.Validator.assertObject(common, "common");
|
|
3357
3440
|
import_validator.Validator.assertString(stateName, "stateName");
|
|
3358
3441
|
import_validator.Validator.assertString(parentDevice, "parentDevice");
|
|
@@ -3367,9 +3450,9 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3367
3450
|
_createState(_options) {
|
|
3368
3451
|
const { _native, common, callback, options } = _options;
|
|
3369
3452
|
let { parentChannel, parentDevice, stateName } = _options;
|
|
3370
|
-
common.name
|
|
3371
|
-
common.read
|
|
3372
|
-
common.write
|
|
3453
|
+
common.name ||= stateName;
|
|
3454
|
+
common.read ??= true;
|
|
3455
|
+
common.write ??= false;
|
|
3373
3456
|
if (!common.role) {
|
|
3374
3457
|
this._logger.error(`${this.namespaceLog} Try to create state ${parentDevice ? `${parentDevice}.` : ""}${parentChannel}.${stateName} without role`);
|
|
3375
3458
|
return;
|
|
@@ -3438,35 +3521,36 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3438
3521
|
common.def = max;
|
|
3439
3522
|
}
|
|
3440
3523
|
}
|
|
3441
|
-
this.setObjectNotExists(id, {
|
|
3524
|
+
const stateResult = this.setObjectNotExists(id, {
|
|
3442
3525
|
type: "state",
|
|
3443
3526
|
common,
|
|
3444
3527
|
native: _native
|
|
3445
3528
|
}, options, (err) => {
|
|
3446
3529
|
if (err) {
|
|
3447
3530
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, err);
|
|
3448
|
-
}
|
|
3531
|
+
}
|
|
3532
|
+
if (common.def !== void 0) {
|
|
3449
3533
|
this.getState(id, null, (err2, state) => {
|
|
3450
3534
|
if (!state) {
|
|
3451
3535
|
if (common.defAck !== void 0) {
|
|
3452
|
-
this.setState(id, common.def, common.defAck, options, callback);
|
|
3453
|
-
} else {
|
|
3454
|
-
this.setState(id, common.def, options, callback);
|
|
3536
|
+
return this.setState(id, common.def, common.defAck, options, callback);
|
|
3455
3537
|
}
|
|
3456
|
-
|
|
3457
|
-
return import_js_controller_common.tools.maybeCallback(callback);
|
|
3538
|
+
return this.setState(id, common.def, options, callback);
|
|
3458
3539
|
}
|
|
3540
|
+
return import_js_controller_common.tools.maybeCallback(callback);
|
|
3459
3541
|
});
|
|
3460
3542
|
} else {
|
|
3461
3543
|
this.getState(id, null, (err2, state) => {
|
|
3462
3544
|
if (!state) {
|
|
3463
|
-
this.setState(id, null, true, options, callback);
|
|
3464
|
-
} else {
|
|
3465
|
-
return import_js_controller_common.tools.maybeCallback(callback);
|
|
3545
|
+
return this.setState(id, null, true, options, callback);
|
|
3466
3546
|
}
|
|
3547
|
+
return import_js_controller_common.tools.maybeCallback(callback);
|
|
3467
3548
|
});
|
|
3468
3549
|
}
|
|
3469
3550
|
});
|
|
3551
|
+
if (stateResult instanceof Promise) {
|
|
3552
|
+
stateResult.catch((e) => this._logger.error(`${this.namespaceLog} Cannot create state object: ${e.message}`));
|
|
3553
|
+
}
|
|
3470
3554
|
}
|
|
3471
3555
|
/**
|
|
3472
3556
|
* Delete device with all its channels and states.
|
|
@@ -3518,6 +3602,16 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3518
3602
|
}
|
|
3519
3603
|
return import_js_controller_common.tools.maybeCallback(callback);
|
|
3520
3604
|
}
|
|
3605
|
+
/**
|
|
3606
|
+
* Add a channel to an enum.
|
|
3607
|
+
*
|
|
3608
|
+
* @param enumName the enum category (e.g. rooms, functions)
|
|
3609
|
+
* @param addTo the enum id to add the channel to
|
|
3610
|
+
* @param parentDevice the parent device name
|
|
3611
|
+
* @param channelName the name of the channel
|
|
3612
|
+
* @param options optional user context
|
|
3613
|
+
* @param callback return result
|
|
3614
|
+
*/
|
|
3521
3615
|
addChannelToEnum(enumName, addTo, parentDevice, channelName, options, callback) {
|
|
3522
3616
|
if (typeof options === "function") {
|
|
3523
3617
|
callback = options;
|
|
@@ -3564,10 +3658,9 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3564
3658
|
obj.from = `system.adapter.${this.namespace}`;
|
|
3565
3659
|
obj.user = options?.user || import_constants.SYSTEM_ADMIN_USER;
|
|
3566
3660
|
obj.ts = Date.now();
|
|
3567
|
-
this.#objects.setObject(obj._id, obj, options, callback);
|
|
3568
|
-
} else {
|
|
3569
|
-
return import_js_controller_common.tools.maybeCallback(callback);
|
|
3661
|
+
return callback ? this.#objects.setObject(obj._id, obj, options, callback) : this.#objects.setObject(obj._id, obj, options);
|
|
3570
3662
|
}
|
|
3663
|
+
return import_js_controller_common.tools.maybeCallback(callback);
|
|
3571
3664
|
}
|
|
3572
3665
|
});
|
|
3573
3666
|
} else {
|
|
@@ -3584,25 +3677,35 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3584
3677
|
obj.from = `system.adapter.${this.namespace}`;
|
|
3585
3678
|
obj.user = options?.user || import_constants.SYSTEM_ADMIN_USER;
|
|
3586
3679
|
obj.ts = Date.now();
|
|
3587
|
-
this.#objects.setObject(obj._id, obj, options, callback);
|
|
3588
|
-
} else {
|
|
3589
|
-
return import_js_controller_common.tools.maybeCallback(callback);
|
|
3680
|
+
return callback ? this.#objects.setObject(obj._id, obj, options, callback) : this.#objects.setObject(obj._id, obj, options);
|
|
3590
3681
|
}
|
|
3591
|
-
|
|
3592
|
-
this.#objects.setObject(`enum.${enumName}.${addTo}`, {
|
|
3593
|
-
common: {
|
|
3594
|
-
name: addTo,
|
|
3595
|
-
members: [objId]
|
|
3596
|
-
},
|
|
3597
|
-
from: `system.adapter.${this.namespace}`,
|
|
3598
|
-
ts: Date.now(),
|
|
3599
|
-
type: "enum",
|
|
3600
|
-
native: {}
|
|
3601
|
-
}, options, callback);
|
|
3682
|
+
return import_js_controller_common.tools.maybeCallback(callback);
|
|
3602
3683
|
}
|
|
3684
|
+
return callback ? this.#objects.setObject(`enum.${enumName}.${addTo}`, {
|
|
3685
|
+
common: { name: addTo, members: [objId] },
|
|
3686
|
+
from: `system.adapter.${this.namespace}`,
|
|
3687
|
+
ts: Date.now(),
|
|
3688
|
+
type: "enum",
|
|
3689
|
+
native: {}
|
|
3690
|
+
}, options, callback) : this.#objects.setObject(`enum.${enumName}.${addTo}`, {
|
|
3691
|
+
common: { name: addTo, members: [objId] },
|
|
3692
|
+
from: `system.adapter.${this.namespace}`,
|
|
3693
|
+
ts: Date.now(),
|
|
3694
|
+
type: "enum",
|
|
3695
|
+
native: {}
|
|
3696
|
+
}, options);
|
|
3603
3697
|
});
|
|
3604
3698
|
}
|
|
3605
3699
|
}
|
|
3700
|
+
/**
|
|
3701
|
+
* Remove a channel from an enum.
|
|
3702
|
+
*
|
|
3703
|
+
* @param enumName the enum category (e.g. rooms, functions)
|
|
3704
|
+
* @param parentDevice the parent device name
|
|
3705
|
+
* @param channelName the name of the channel
|
|
3706
|
+
* @param options optional user context
|
|
3707
|
+
* @param callback return result
|
|
3708
|
+
*/
|
|
3606
3709
|
deleteChannelFromEnum(enumName, parentDevice, channelName, options, callback) {
|
|
3607
3710
|
if (typeof options === "function") {
|
|
3608
3711
|
callback = options;
|
|
@@ -3755,11 +3858,11 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3755
3858
|
return import_js_controller_common.tools.maybeCallback(callback);
|
|
3756
3859
|
}
|
|
3757
3860
|
/**
|
|
3758
|
-
* @param parentDevice
|
|
3759
|
-
* @param parentChannel
|
|
3760
|
-
* @param stateName
|
|
3761
|
-
* @param options
|
|
3762
|
-
* @param callback
|
|
3861
|
+
* @param parentDevice the parent device name
|
|
3862
|
+
* @param parentChannel the parent channel name
|
|
3863
|
+
* @param stateName the name of the state
|
|
3864
|
+
* @param options optional user context
|
|
3865
|
+
* @param callback return result
|
|
3763
3866
|
* @deprecated use `this.delObject` instead
|
|
3764
3867
|
*/
|
|
3765
3868
|
deleteState(parentDevice, parentChannel, stateName, options, callback) {
|
|
@@ -3841,6 +3944,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3841
3944
|
const _name = this._DCS2ID(parentDevice, parentChannel, stateName);
|
|
3842
3945
|
this.delObject(_name, options, callback);
|
|
3843
3946
|
}
|
|
3947
|
+
/**
|
|
3948
|
+
* Get all devices of this adapter.
|
|
3949
|
+
*
|
|
3950
|
+
* @param options optional user context, or the callback
|
|
3951
|
+
* @param callback return result
|
|
3952
|
+
*/
|
|
3844
3953
|
getDevices(options, callback) {
|
|
3845
3954
|
if (typeof options === "function" && typeof callback === "object") {
|
|
3846
3955
|
const tmp = callback;
|
|
@@ -3879,6 +3988,13 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3879
3988
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, null, res);
|
|
3880
3989
|
});
|
|
3881
3990
|
}
|
|
3991
|
+
/**
|
|
3992
|
+
* Get all channels of this adapter or of the given device.
|
|
3993
|
+
*
|
|
3994
|
+
* @param parentDevice the parent device name, or the callback
|
|
3995
|
+
* @param options optional user context, or the callback
|
|
3996
|
+
* @param callback return result
|
|
3997
|
+
*/
|
|
3882
3998
|
getChannelsOf(parentDevice, options, callback) {
|
|
3883
3999
|
if (typeof options === "function") {
|
|
3884
4000
|
callback = options;
|
|
@@ -3926,6 +4042,14 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3926
4042
|
return import_js_controller_common.tools.maybeCallbackWithError(options.callback, null, res);
|
|
3927
4043
|
});
|
|
3928
4044
|
}
|
|
4045
|
+
/**
|
|
4046
|
+
* Get all states of this adapter or of the given device/channel.
|
|
4047
|
+
*
|
|
4048
|
+
* @param parentDevice the parent device name, or the callback
|
|
4049
|
+
* @param parentChannel the parent channel name, or the callback
|
|
4050
|
+
* @param options optional user context, or the callback
|
|
4051
|
+
* @param callback return result
|
|
4052
|
+
*/
|
|
3929
4053
|
getStatesOf(parentDevice, parentChannel, options, callback) {
|
|
3930
4054
|
if (typeof options === "function") {
|
|
3931
4055
|
callback = options;
|
|
@@ -4002,6 +4126,17 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4002
4126
|
}
|
|
4003
4127
|
});
|
|
4004
4128
|
}
|
|
4129
|
+
/**
|
|
4130
|
+
* Add a state to an enum.
|
|
4131
|
+
*
|
|
4132
|
+
* @param enumName the enum category (e.g. rooms, functions)
|
|
4133
|
+
* @param addTo the enum id to add the state to
|
|
4134
|
+
* @param parentDevice the parent device name
|
|
4135
|
+
* @param parentChannel the parent channel name
|
|
4136
|
+
* @param stateName the name of the state
|
|
4137
|
+
* @param options optional user context
|
|
4138
|
+
* @param callback return result
|
|
4139
|
+
*/
|
|
4005
4140
|
addStateToEnum(enumName, addTo, parentDevice, parentChannel, stateName, options, callback) {
|
|
4006
4141
|
if (typeof options === "function") {
|
|
4007
4142
|
callback = options;
|
|
@@ -4061,10 +4196,9 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4061
4196
|
obj.from = `system.adapter.${this.namespace}`;
|
|
4062
4197
|
obj.user = options?.user || import_constants.SYSTEM_ADMIN_USER;
|
|
4063
4198
|
obj.ts = Date.now();
|
|
4064
|
-
this.#objects.setObject(obj._id, obj, options, callback);
|
|
4065
|
-
} else {
|
|
4066
|
-
return import_js_controller_common.tools.maybeCallback(callback);
|
|
4199
|
+
return callback ? this.#objects.setObject(obj._id, obj, options, callback) : this.#objects.setObject(obj._id, obj, options);
|
|
4067
4200
|
}
|
|
4201
|
+
return import_js_controller_common.tools.maybeCallback(callback);
|
|
4068
4202
|
});
|
|
4069
4203
|
} else {
|
|
4070
4204
|
if (enumName.startsWith("enum.")) {
|
|
@@ -4077,28 +4211,39 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4077
4211
|
obj.from = `system.adapter.${this.namespace}`;
|
|
4078
4212
|
obj.user = options?.user || import_constants.SYSTEM_ADMIN_USER;
|
|
4079
4213
|
obj.ts = Date.now();
|
|
4080
|
-
this.#objects.setObject(obj._id, obj, callback);
|
|
4081
|
-
} else {
|
|
4082
|
-
return import_js_controller_common.tools.maybeCallback(callback);
|
|
4083
|
-
}
|
|
4084
|
-
} else {
|
|
4085
|
-
if (err) {
|
|
4086
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, err);
|
|
4214
|
+
return callback ? this.#objects.setObject(obj._id, obj, callback) : this.#objects.setObject(obj._id, obj);
|
|
4087
4215
|
}
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
},
|
|
4093
|
-
from: `system.adapter.${this.namespace}`,
|
|
4094
|
-
ts: Date.now(),
|
|
4095
|
-
type: "enum",
|
|
4096
|
-
native: {}
|
|
4097
|
-
}, options, callback);
|
|
4216
|
+
return import_js_controller_common.tools.maybeCallback(callback);
|
|
4217
|
+
}
|
|
4218
|
+
if (err) {
|
|
4219
|
+
return import_js_controller_common.tools.maybeCallbackWithError(callback, err);
|
|
4098
4220
|
}
|
|
4221
|
+
return callback ? this.#objects.setObject(`enum.${enumName}.${addTo}`, {
|
|
4222
|
+
common: { name: addTo, members: [objId] },
|
|
4223
|
+
from: `system.adapter.${this.namespace}`,
|
|
4224
|
+
ts: Date.now(),
|
|
4225
|
+
type: "enum",
|
|
4226
|
+
native: {}
|
|
4227
|
+
}, options, callback) : this.#objects.setObject(`enum.${enumName}.${addTo}`, {
|
|
4228
|
+
common: { name: addTo, members: [objId] },
|
|
4229
|
+
from: `system.adapter.${this.namespace}`,
|
|
4230
|
+
ts: Date.now(),
|
|
4231
|
+
type: "enum",
|
|
4232
|
+
native: {}
|
|
4233
|
+
}, options);
|
|
4099
4234
|
});
|
|
4100
4235
|
}
|
|
4101
4236
|
}
|
|
4237
|
+
/**
|
|
4238
|
+
* Remove a state from an enum.
|
|
4239
|
+
*
|
|
4240
|
+
* @param enumName the enum category (e.g. rooms, functions)
|
|
4241
|
+
* @param parentDevice the parent device name
|
|
4242
|
+
* @param parentChannel the parent channel name
|
|
4243
|
+
* @param stateName the name of the state
|
|
4244
|
+
* @param options optional user context
|
|
4245
|
+
* @param callback return result
|
|
4246
|
+
*/
|
|
4102
4247
|
deleteStateFromEnum(enumName, parentDevice, parentChannel, stateName, options, callback) {
|
|
4103
4248
|
if (typeof options === "function") {
|
|
4104
4249
|
callback = options;
|
|
@@ -4312,6 +4457,14 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4312
4457
|
}
|
|
4313
4458
|
this.#objects.readDir(_adapter, path, options, callback);
|
|
4314
4459
|
}
|
|
4460
|
+
/**
|
|
4461
|
+
* Deletes a file in the DB.
|
|
4462
|
+
*
|
|
4463
|
+
* @param _adapter adapter name, or null for the current adapter
|
|
4464
|
+
* @param name path to the file
|
|
4465
|
+
* @param options optional user context
|
|
4466
|
+
* @param callback return result
|
|
4467
|
+
*/
|
|
4315
4468
|
unlink(_adapter, name, options, callback) {
|
|
4316
4469
|
if (_adapter === null) {
|
|
4317
4470
|
_adapter = this.name;
|
|
@@ -4332,6 +4485,15 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4332
4485
|
}
|
|
4333
4486
|
this.#objects.unlink(_adapter, name, options, callback);
|
|
4334
4487
|
}
|
|
4488
|
+
/**
|
|
4489
|
+
* Renames a file in the DB.
|
|
4490
|
+
*
|
|
4491
|
+
* @param _adapter adapter name, or null for the current adapter
|
|
4492
|
+
* @param oldName current path to the file
|
|
4493
|
+
* @param newName new path to the file
|
|
4494
|
+
* @param options optional user context
|
|
4495
|
+
* @param callback return result
|
|
4496
|
+
*/
|
|
4335
4497
|
rename(_adapter, oldName, newName, options, callback) {
|
|
4336
4498
|
if (_adapter === null) {
|
|
4337
4499
|
_adapter = this.name;
|
|
@@ -4351,8 +4513,16 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4351
4513
|
this._logger.info(`${this.namespaceLog} rename not processed because Objects database not connected`);
|
|
4352
4514
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
4353
4515
|
}
|
|
4354
|
-
this.#objects.rename(_adapter, oldName, newName, options, callback);
|
|
4516
|
+
return this.#objects.rename(_adapter, oldName, newName, options, callback);
|
|
4355
4517
|
}
|
|
4518
|
+
/**
|
|
4519
|
+
* Creates a directory in the DB.
|
|
4520
|
+
*
|
|
4521
|
+
* @param _adapter adapter name, or null for the current adapter
|
|
4522
|
+
* @param dirname path to the directory
|
|
4523
|
+
* @param options optional user context
|
|
4524
|
+
* @param callback return result
|
|
4525
|
+
*/
|
|
4356
4526
|
mkdir(_adapter, dirname, options, callback) {
|
|
4357
4527
|
if (_adapter === null) {
|
|
4358
4528
|
_adapter = this.name;
|
|
@@ -4489,6 +4659,13 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4489
4659
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, e);
|
|
4490
4660
|
}
|
|
4491
4661
|
}
|
|
4662
|
+
/**
|
|
4663
|
+
* Formats a numeric value using the given format string.
|
|
4664
|
+
*
|
|
4665
|
+
* @param value the value to format
|
|
4666
|
+
* @param decimals number of decimals to keep, or the format string
|
|
4667
|
+
* @param _format optional format string for the decimal and thousands separator
|
|
4668
|
+
*/
|
|
4492
4669
|
formatValue(value, decimals, _format) {
|
|
4493
4670
|
if (typeof decimals !== "number") {
|
|
4494
4671
|
_format = decimals;
|
|
@@ -4506,6 +4683,13 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4506
4683
|
value.toFixed(decimals).replace(format[0], format[1]).replace(/\B(?=(\d{3})+(?!\d))/g, format[0])
|
|
4507
4684
|
);
|
|
4508
4685
|
}
|
|
4686
|
+
/**
|
|
4687
|
+
* Formats a date or duration according to the given format string.
|
|
4688
|
+
*
|
|
4689
|
+
* @param dateObj the date to format
|
|
4690
|
+
* @param isDuration whether the value represents a duration, or the format string
|
|
4691
|
+
* @param _format optional format string
|
|
4692
|
+
*/
|
|
4509
4693
|
formatDate(dateObj, isDuration, _format) {
|
|
4510
4694
|
if (typeof isDuration === "string" && isDuration.toLowerCase() === "duration" || isDuration === true) {
|
|
4511
4695
|
isDuration = true;
|
|
@@ -4552,7 +4736,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4552
4736
|
const validFormatChars = "YJ\u0413M\u041CDT\u0414hS\u0447m\u043Cs\u0441";
|
|
4553
4737
|
let s = "";
|
|
4554
4738
|
let result = "";
|
|
4555
|
-
const put = (s2) => {
|
|
4739
|
+
const put = /* @__PURE__ */ __name((s2) => {
|
|
4556
4740
|
let v = "";
|
|
4557
4741
|
switch (s2) {
|
|
4558
4742
|
case "YYYY":
|
|
@@ -4630,7 +4814,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4630
4814
|
v = v.toString();
|
|
4631
4815
|
}
|
|
4632
4816
|
return result += v;
|
|
4633
|
-
};
|
|
4817
|
+
}, "put");
|
|
4634
4818
|
for (let i = 0; i < format.length; i++) {
|
|
4635
4819
|
if (validFormatChars.includes(format[i])) {
|
|
4636
4820
|
s += format[i];
|
|
@@ -4678,13 +4862,42 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4678
4862
|
if (options !== void 0) {
|
|
4679
4863
|
import_validator.Validator.assertObject(options, "options");
|
|
4680
4864
|
}
|
|
4681
|
-
|
|
4682
|
-
instanceName,
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4865
|
+
if (import_js_controller_common.tools.isObject(callback)) {
|
|
4866
|
+
this.#fireAndForget(this.#async.sendTo(instanceName, command, message, this.#withSendFlags(options, { callback })), "Error in sendTo");
|
|
4867
|
+
return;
|
|
4868
|
+
}
|
|
4869
|
+
const cb = callback;
|
|
4870
|
+
if (typeof cb === "function") {
|
|
4871
|
+
this.sendToAsync(instanceName, command, message, options).then((reply) => cb(reply), (err) => cb(err));
|
|
4872
|
+
return;
|
|
4873
|
+
}
|
|
4874
|
+
this.#fireAndForget(this.#async.sendTo(instanceName, command, message, this.#withSendFlags(options, { expectReply: false })), "Error in sendTo");
|
|
4875
|
+
}
|
|
4876
|
+
/**
|
|
4877
|
+
* Merges send-control flags into the caller-supplied options for delegation to the async facade.
|
|
4878
|
+
* A non-object `options` is forwarded unchanged so the facade's validation surfaces it.
|
|
4879
|
+
*
|
|
4880
|
+
* @param options caller-supplied send options (unvalidated)
|
|
4881
|
+
* @param flags control flags to apply
|
|
4882
|
+
* @param flags.expectReply when false, the facade sends fire-and-forget
|
|
4883
|
+
* @param flags.callback legacy callback-info header to attach to the message
|
|
4884
|
+
*/
|
|
4885
|
+
#withSendFlags(options, flags) {
|
|
4886
|
+
if (options !== void 0 && !import_js_controller_common.tools.isObject(options)) {
|
|
4887
|
+
return options;
|
|
4888
|
+
}
|
|
4889
|
+
return { ...options, ...flags };
|
|
4890
|
+
}
|
|
4891
|
+
/**
|
|
4892
|
+
* Observes a fire-and-forget promise from the callback-compat layer, logging any rejection without
|
|
4893
|
+
* rethrowing. Used only where the legacy callback API had no channel to surface the error; async
|
|
4894
|
+
* callers on {@link AsyncAdapter} instead await and catch.
|
|
4895
|
+
*
|
|
4896
|
+
* @param promise the promise to observe
|
|
4897
|
+
* @param errorMessage log prefix describing the failed action
|
|
4898
|
+
*/
|
|
4899
|
+
#fireAndForget(promise, errorMessage) {
|
|
4900
|
+
promise.catch((e) => this._logger.error(`${this.namespaceLog} ${errorMessage}: ${e instanceof Error ? e.message : String(e)}`));
|
|
4688
4901
|
}
|
|
4689
4902
|
/**
|
|
4690
4903
|
* Async version of sendTo
|
|
@@ -4696,105 +4909,15 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4696
4909
|
* @param options optional options to define a timeout. This allows to get an error callback if no answer received in time (only if target is specific instance)
|
|
4697
4910
|
*/
|
|
4698
4911
|
sendToAsync(instanceName, command, message, options) {
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
this.sendTo(instanceName, command, message, callback, options);
|
|
4707
|
-
});
|
|
4708
|
-
}
|
|
4709
|
-
async _sendTo(_options) {
|
|
4710
|
-
const { command, message, callback, options } = _options;
|
|
4711
|
-
let { instanceName } = _options;
|
|
4712
|
-
const obj = {
|
|
4713
|
-
command,
|
|
4714
|
-
message,
|
|
4715
|
-
from: `system.adapter.${this.namespace}`
|
|
4716
|
-
};
|
|
4717
|
-
if (!instanceName) {
|
|
4718
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, "No instanceName provided or not a string");
|
|
4719
|
-
}
|
|
4720
|
-
if (!instanceName.startsWith("system.adapter.")) {
|
|
4721
|
-
instanceName = `system.adapter.${instanceName}`;
|
|
4722
|
-
}
|
|
4723
|
-
if (!this.#states) {
|
|
4724
|
-
this._logger.info(`${this.namespaceLog} sendTo not processed because States database not connected`);
|
|
4725
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
4726
|
-
}
|
|
4727
|
-
if (typeof message !== "object") {
|
|
4728
|
-
this._logger.silly(`${this.namespaceLog} sendTo "${command}" to ${instanceName} from system.adapter.${this.namespace}: ${message}`);
|
|
4729
|
-
} else {
|
|
4730
|
-
this._logger.silly(`${this.namespaceLog} sendTo "${command}" to ${instanceName} from system.adapter.${this.namespace}`);
|
|
4731
|
-
}
|
|
4732
|
-
if (!instanceName.match(/\.[0-9]+$/)) {
|
|
4733
|
-
if (!this.#objects) {
|
|
4734
|
-
this._logger.info(`${this.namespaceLog} sendTo not processed because Objects database not connected`);
|
|
4735
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
4736
|
-
}
|
|
4737
|
-
try {
|
|
4738
|
-
const res = await this.#objects.getObjectView("system", "instance", {
|
|
4739
|
-
startkey: `${instanceName}.`,
|
|
4740
|
-
endkey: `${instanceName}.\u9999`
|
|
4741
|
-
});
|
|
4742
|
-
if (res) {
|
|
4743
|
-
for (const row of res.rows) {
|
|
4744
|
-
try {
|
|
4745
|
-
await this.#states.pushMessage(row.id, obj);
|
|
4746
|
-
} catch (e) {
|
|
4747
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, e);
|
|
4748
|
-
}
|
|
4749
|
-
}
|
|
4750
|
-
}
|
|
4751
|
-
} catch {
|
|
4752
|
-
}
|
|
4753
|
-
} else {
|
|
4754
|
-
if (callback) {
|
|
4755
|
-
if (typeof callback === "function") {
|
|
4756
|
-
if (!(0, import_utils.isMessageboxSupported)(this.common) && !this.mboxSubscribed) {
|
|
4757
|
-
this.mboxSubscribed = true;
|
|
4758
|
-
this.#states.subscribeMessage(`system.adapter.${this.namespace}`);
|
|
4759
|
-
}
|
|
4760
|
-
obj.callback = {
|
|
4761
|
-
message,
|
|
4762
|
-
id: this._callbackId++,
|
|
4763
|
-
ack: false,
|
|
4764
|
-
time: Date.now()
|
|
4765
|
-
};
|
|
4766
|
-
if (this._callbackId >= 4294967295) {
|
|
4767
|
-
this._callbackId = 1;
|
|
4768
|
-
}
|
|
4769
|
-
const callbackId = obj.callback.id;
|
|
4770
|
-
let timer;
|
|
4771
|
-
if (options?.timeout) {
|
|
4772
|
-
timer = setTimeout(() => {
|
|
4773
|
-
const callbackObj = this.messageCallbacks.get(callbackId);
|
|
4774
|
-
if (callbackObj) {
|
|
4775
|
-
callbackObj.cb(new Error("Timeout exceeded"));
|
|
4776
|
-
this.messageCallbacks.delete(callbackId);
|
|
4777
|
-
}
|
|
4778
|
-
}, options.timeout);
|
|
4779
|
-
}
|
|
4780
|
-
this.messageCallbacks.set(callbackId, { cb: callback, time: Date.now(), timer });
|
|
4781
|
-
const now = Date.now();
|
|
4782
|
-
for (const [_id, cb] of this.messageCallbacks) {
|
|
4783
|
-
if (now - cb.time > 36e5) {
|
|
4784
|
-
this.messageCallbacks.delete(_id);
|
|
4785
|
-
}
|
|
4786
|
-
}
|
|
4787
|
-
} else {
|
|
4788
|
-
obj.callback = callback;
|
|
4789
|
-
obj.callback.ack = true;
|
|
4790
|
-
}
|
|
4791
|
-
}
|
|
4792
|
-
try {
|
|
4793
|
-
await this.#states.pushMessage(instanceName, obj);
|
|
4794
|
-
} catch (e) {
|
|
4795
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, e);
|
|
4796
|
-
}
|
|
4912
|
+
if (typeof message === "function") {
|
|
4913
|
+
options = void 0;
|
|
4914
|
+
message = command;
|
|
4915
|
+
command = "send";
|
|
4916
|
+
} else if (typeof message === "undefined") {
|
|
4917
|
+
message = command;
|
|
4918
|
+
command = "send";
|
|
4797
4919
|
}
|
|
4920
|
+
return this.#async.sendTo(instanceName, command, message, this.#withSendFlags(options, { expectReply: true }));
|
|
4798
4921
|
}
|
|
4799
4922
|
/**
|
|
4800
4923
|
* Send message to specific host or to all hosts.
|
|
@@ -4814,6 +4937,10 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4814
4937
|
* ```
|
|
4815
4938
|
*/
|
|
4816
4939
|
sendToHost(hostName, command, message, callback) {
|
|
4940
|
+
if (typeof message === "function" && typeof callback === "undefined") {
|
|
4941
|
+
callback = message;
|
|
4942
|
+
message = void 0;
|
|
4943
|
+
}
|
|
4817
4944
|
if (typeof message === "undefined") {
|
|
4818
4945
|
message = command;
|
|
4819
4946
|
command = "send";
|
|
@@ -4825,77 +4952,32 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4825
4952
|
if (!import_js_controller_common.tools.isObject(callback)) {
|
|
4826
4953
|
import_validator.Validator.assertOptionalCallback(callback, "callback");
|
|
4827
4954
|
}
|
|
4828
|
-
|
|
4829
|
-
hostName,
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
});
|
|
4834
|
-
}
|
|
4835
|
-
async _sendToHost(_options) {
|
|
4836
|
-
const { command, message, callback } = _options;
|
|
4837
|
-
let { hostName } = _options;
|
|
4838
|
-
const obj = { command, message, from: `system.adapter.${this.namespace}` };
|
|
4839
|
-
if (!this.#states) {
|
|
4840
|
-
this._logger.info(`${this.namespaceLog} sendToHost not processed because States database not connected`);
|
|
4841
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
4955
|
+
if (import_js_controller_common.tools.isObject(callback)) {
|
|
4956
|
+
this.#fireAndForget(this.#async.sendToHost(hostName, command, message, {
|
|
4957
|
+
callback
|
|
4958
|
+
}), "Error in sendToHost");
|
|
4959
|
+
return;
|
|
4842
4960
|
}
|
|
4843
|
-
|
|
4844
|
-
|
|
4961
|
+
const cb = callback;
|
|
4962
|
+
if (typeof cb === "function" && hostName !== null) {
|
|
4963
|
+
this.sendToHostAsync(hostName, command, message).then((reply) => cb(reply), (err) => cb(err));
|
|
4964
|
+
return;
|
|
4845
4965
|
}
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
for (const row of res.rows) {
|
|
4860
|
-
const parts = row.id.split(".");
|
|
4861
|
-
if (parts.length === 3) {
|
|
4862
|
-
try {
|
|
4863
|
-
await this.#states.pushMessage(row.id, obj);
|
|
4864
|
-
} catch (e) {
|
|
4865
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, e);
|
|
4866
|
-
}
|
|
4867
|
-
}
|
|
4868
|
-
}
|
|
4869
|
-
}
|
|
4870
|
-
});
|
|
4871
|
-
} else {
|
|
4872
|
-
if (callback) {
|
|
4873
|
-
if (typeof callback === "function") {
|
|
4874
|
-
if (!(0, import_utils.isMessageboxSupported)(this.common) && !this.mboxSubscribed) {
|
|
4875
|
-
this.mboxSubscribed = true;
|
|
4876
|
-
this.#states.subscribeMessage(`system.adapter.${this.namespace}`);
|
|
4877
|
-
}
|
|
4878
|
-
obj.callback = {
|
|
4879
|
-
message,
|
|
4880
|
-
id: this._callbackId++,
|
|
4881
|
-
ack: false,
|
|
4882
|
-
time: Date.now()
|
|
4883
|
-
};
|
|
4884
|
-
if (this._callbackId >= 4294967295) {
|
|
4885
|
-
this._callbackId = 1;
|
|
4886
|
-
}
|
|
4887
|
-
this.messageCallbacks.set(obj.callback.id, { cb: callback, time: Date.now() });
|
|
4888
|
-
} else {
|
|
4889
|
-
obj.callback = callback;
|
|
4890
|
-
obj.callback.ack = true;
|
|
4891
|
-
}
|
|
4892
|
-
}
|
|
4893
|
-
try {
|
|
4894
|
-
await this.#states.pushMessage(hostName, obj);
|
|
4895
|
-
} catch (e) {
|
|
4896
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, e);
|
|
4897
|
-
}
|
|
4966
|
+
this.#fireAndForget(this.#async.sendToHost(hostName, command, message, { expectReply: false }), "Error in sendToHost");
|
|
4967
|
+
}
|
|
4968
|
+
/**
|
|
4969
|
+
* Async version of sendToHost
|
|
4970
|
+
*
|
|
4971
|
+
* @param hostName name of the host where the message must be sent to. E.g. "myPC" or "system.host.myPC". If argument is null, the message will be sent to all hosts.
|
|
4972
|
+
* @param command command name. One of: "cmdExec", "getRepository", "getInstalled", "getVersion", "getDiagData", "getLocationOnDisk", "getDevList", "getLogs", "delLogs", "readDirAsZip", "writeDirAsZip", "readObjectsAsZip", "writeObjectsAsZip", "checkLogging". Commands can be checked in controller.js (function processMessage)
|
|
4973
|
+
* @param message object that will be given as argument for request
|
|
4974
|
+
*/
|
|
4975
|
+
sendToHostAsync(hostName, command, message) {
|
|
4976
|
+
if (typeof message === "undefined") {
|
|
4977
|
+
message = command;
|
|
4978
|
+
command = "send";
|
|
4898
4979
|
}
|
|
4980
|
+
return this.#async.sendToHost(hostName, command, message, { expectReply: hostName !== null });
|
|
4899
4981
|
}
|
|
4900
4982
|
/**
|
|
4901
4983
|
* Send a message to an active UI Client
|
|
@@ -4903,22 +4985,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4903
4985
|
* @param options clientId and data options
|
|
4904
4986
|
*/
|
|
4905
4987
|
sendToUI(options) {
|
|
4906
|
-
|
|
4907
|
-
throw new Error(import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
4908
|
-
}
|
|
4909
|
-
const { clientId, data } = options;
|
|
4910
|
-
if (clientId === void 0) {
|
|
4911
|
-
return this.uiMessagingController.sendToAllClients({
|
|
4912
|
-
data,
|
|
4913
|
-
states: this.#states
|
|
4914
|
-
});
|
|
4915
|
-
}
|
|
4916
|
-
import_validator.Validator.assertString(clientId, "clientId");
|
|
4917
|
-
return this.uiMessagingController.sendToClient({
|
|
4918
|
-
clientId,
|
|
4919
|
-
data,
|
|
4920
|
-
states: this.#states
|
|
4921
|
-
});
|
|
4988
|
+
return this.#async.sendToUI(options);
|
|
4922
4989
|
}
|
|
4923
4990
|
/**
|
|
4924
4991
|
* Send notification with given scope and category to host of this adapter
|
|
@@ -4929,30 +4996,80 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4929
4996
|
* @param options - Additional options for the notification, currently `contextData` is supported
|
|
4930
4997
|
*/
|
|
4931
4998
|
async registerNotification(scope, category, message, options) {
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4999
|
+
return this.#async.registerNotification(scope, category, message, options);
|
|
5000
|
+
}
|
|
5001
|
+
/**
|
|
5002
|
+
* Register an exclusive resource (serial port, TCP/UDP port, USB device, ...) as used by this instance.
|
|
5003
|
+
*
|
|
5004
|
+
* Exclusive resources are the ones that cannot be occupied by more than one instance at the same time.
|
|
5005
|
+
* The information is forwarded to the host this instance runs on and stored under
|
|
5006
|
+
* `system.host.<hostname>.usedResources.<type>`, so the user gets an overview of the occupied resources
|
|
5007
|
+
* and can pick a free one when configuring a new instance.
|
|
5008
|
+
*
|
|
5009
|
+
* Registering is **additive**: call it once per occupied resource, in any order and from any number of
|
|
5010
|
+
* async init paths. The host drops what this instance registered before whenever the instance starts, so
|
|
5011
|
+
* a stale registration from a previous configuration cannot survive a restart.
|
|
5012
|
+
*
|
|
5013
|
+
* @param type the kind of resource, e.g. "serialPort" or "tcpPort"
|
|
5014
|
+
* @param data the strictly typed payload describing the resource, e.g. `{ port: '/dev/ttyUSB0' }`
|
|
5015
|
+
* @throws {Error} when the host refuses the registration - e.g. because `common.declareUsedResources` is not `true` - or does not answer
|
|
5016
|
+
*/
|
|
5017
|
+
async registerUsedResource(type, data) {
|
|
5018
|
+
return this.#async.registerUsedResource(type, data);
|
|
5019
|
+
}
|
|
5020
|
+
/**
|
|
5021
|
+
* Ask whether another instance on this host currently holds an exclusive resource, without
|
|
5022
|
+
* registering anything.
|
|
5023
|
+
*
|
|
5024
|
+
* Call this **before** opening the port or the device - afterwards the operating system has
|
|
5025
|
+
* already decided the conflict and this can only improve the error message.
|
|
5026
|
+
*
|
|
5027
|
+
* The answer is a hint, not a permission: the registry knows what adapters declare, so an empty
|
|
5028
|
+
* result does not promise the resource is free.
|
|
5029
|
+
*
|
|
5030
|
+
* @param type the kind of resource, e.g. "serialPort" or "tcpPort"
|
|
5031
|
+
* @param data description of the resource that is about to be used, e.g. `{ port: 1883 }`
|
|
5032
|
+
* @returns the entries of other instances that currently hold it, newest registration first
|
|
5033
|
+
* @throws {Error} when the host refuses the request or does not answer
|
|
5034
|
+
*/
|
|
5035
|
+
async checkUsedResource(type, data) {
|
|
5036
|
+
return this.#async.checkUsedResource(type, data);
|
|
5037
|
+
}
|
|
5038
|
+
/**
|
|
5039
|
+
* Free all exclusive resources this instance registered, across all types.
|
|
5040
|
+
*
|
|
5041
|
+
* This is not needed on start-up (the host already resets the registrations of a starting instance) nor
|
|
5042
|
+
* on shutdown (the host marks them as no longer held). Use it when the instance drops everything it
|
|
5043
|
+
* occupied while it keeps running, e.g. on a reconfiguration.
|
|
5044
|
+
*
|
|
5045
|
+
* @throws {Error} when the host refuses the command or does not answer
|
|
5046
|
+
*/
|
|
5047
|
+
async clearUsedResources() {
|
|
5048
|
+
return this.#async.clearUsedResources();
|
|
5049
|
+
}
|
|
5050
|
+
/**
|
|
5051
|
+
* Free previously registered exclusive resources of this instance.
|
|
5052
|
+
*
|
|
5053
|
+
* `data` is a **filter, not the exact payload**: every field it names must match, fields it does not name
|
|
5054
|
+
* are ignored. `freeUsedResource('tcpPort', { port: 8080 })` therefore also frees an entry registered as
|
|
5055
|
+
* `{ port: 8080, bind: '0.0.0.0' }`, and if `data` is omitted, all registered resources of the given
|
|
5056
|
+
* `type` for this instance are freed. The change is forwarded to the host this instance runs on and
|
|
5057
|
+
* reflected in `system.host.<hostname>.usedResources.<type>`; a filter that matches nothing is logged by
|
|
5058
|
+
* the host.
|
|
5059
|
+
*
|
|
5060
|
+
* @param type the kind of resource, e.g. "serialPort" or "tcpPort"
|
|
5061
|
+
* @param data the fields identifying the resources to free; if omitted, all resources of `type` are freed
|
|
5062
|
+
* @throws {Error} when the host refuses the command or does not answer
|
|
5063
|
+
*/
|
|
5064
|
+
async freeUsedResource(type, data) {
|
|
5065
|
+
return this.#async.freeUsedResource(type, data);
|
|
5066
|
+
}
|
|
5067
|
+
/**
|
|
5068
|
+
* @param type resource type to read; if omitted, the resources of every type are returned
|
|
5069
|
+
* @returns the list of registered resources (across all instances of this host)
|
|
5070
|
+
*/
|
|
5071
|
+
async getHostUsedResources(type) {
|
|
5072
|
+
return type === void 0 ? this.#async.getHostUsedResources() : this.#async.getHostUsedResources(type);
|
|
4956
5073
|
}
|
|
4957
5074
|
/**
|
|
4958
5075
|
* Writes value into states DB.
|
|
@@ -5155,8 +5272,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5155
5272
|
}
|
|
5156
5273
|
this.users[options.user] = {
|
|
5157
5274
|
groups: options.groups,
|
|
5158
|
-
|
|
5159
|
-
acl: userAcl.common?.acl || {}
|
|
5275
|
+
acl: {}
|
|
5160
5276
|
};
|
|
5161
5277
|
await this._getGroups(options.groups);
|
|
5162
5278
|
const user = this.users[options.user];
|
|
@@ -5166,71 +5282,71 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5166
5282
|
}
|
|
5167
5283
|
const group = this.groups[gName];
|
|
5168
5284
|
if (group.common?.acl?.file) {
|
|
5169
|
-
if (!user.acl
|
|
5170
|
-
user.acl
|
|
5171
|
-
user.acl.file
|
|
5285
|
+
if (!user.acl?.file) {
|
|
5286
|
+
user.acl ||= {};
|
|
5287
|
+
user.acl.file ||= {};
|
|
5172
5288
|
user.acl.file.create = group.common.acl.file.create;
|
|
5173
5289
|
user.acl.file.read = group.common.acl.file.read;
|
|
5174
5290
|
user.acl.file.write = group.common.acl.file.write;
|
|
5175
5291
|
user.acl.file.delete = group.common.acl.file.delete;
|
|
5176
5292
|
user.acl.file.list = group.common.acl.file.list;
|
|
5177
5293
|
} else {
|
|
5178
|
-
user.acl.file.create
|
|
5179
|
-
user.acl.file.read
|
|
5180
|
-
user.acl.file.write
|
|
5181
|
-
user.acl.file.delete
|
|
5182
|
-
user.acl.file.list
|
|
5294
|
+
user.acl.file.create ||= group.common.acl.file.create;
|
|
5295
|
+
user.acl.file.read ||= group.common.acl.file.read;
|
|
5296
|
+
user.acl.file.write ||= group.common.acl.file.write;
|
|
5297
|
+
user.acl.file.delete ||= group.common.acl.file.delete;
|
|
5298
|
+
user.acl.file.list ||= group.common.acl.file.list;
|
|
5183
5299
|
}
|
|
5184
5300
|
}
|
|
5185
5301
|
if (group.common?.acl?.object) {
|
|
5186
5302
|
if (!user.acl || !user.acl.object) {
|
|
5187
|
-
user.acl
|
|
5188
|
-
user.acl.object
|
|
5303
|
+
user.acl ||= {};
|
|
5304
|
+
user.acl.object ||= {};
|
|
5189
5305
|
user.acl.object.create = group.common.acl.object.create;
|
|
5190
5306
|
user.acl.object.read = group.common.acl.object.read;
|
|
5191
5307
|
user.acl.object.write = group.common.acl.object.write;
|
|
5192
5308
|
user.acl.object.delete = group.common.acl.object.delete;
|
|
5193
5309
|
user.acl.object.list = group.common.acl.object.list;
|
|
5194
5310
|
} else {
|
|
5195
|
-
user.acl.object.create
|
|
5196
|
-
user.acl.object.read
|
|
5197
|
-
user.acl.object.write
|
|
5198
|
-
user.acl.object.delete
|
|
5199
|
-
user.acl.object.list
|
|
5311
|
+
user.acl.object.create ||= group.common.acl.object.create;
|
|
5312
|
+
user.acl.object.read ||= group.common.acl.object.read;
|
|
5313
|
+
user.acl.object.write ||= group.common.acl.object.write;
|
|
5314
|
+
user.acl.object.delete ||= group.common.acl.object.delete;
|
|
5315
|
+
user.acl.object.list ||= group.common.acl.object.list;
|
|
5200
5316
|
}
|
|
5201
5317
|
}
|
|
5202
5318
|
if (group.common?.acl?.users) {
|
|
5203
5319
|
if (!user.acl || !user.acl.users) {
|
|
5204
|
-
user.acl
|
|
5205
|
-
user.acl.users
|
|
5320
|
+
user.acl ||= {};
|
|
5321
|
+
user.acl.users ||= {};
|
|
5206
5322
|
user.acl.users.create = group.common.acl.users.create;
|
|
5207
5323
|
user.acl.users.read = group.common.acl.users.read;
|
|
5208
5324
|
user.acl.users.write = group.common.acl.users.write;
|
|
5209
5325
|
user.acl.users.delete = group.common.acl.users.delete;
|
|
5210
5326
|
user.acl.users.list = group.common.acl.users.list;
|
|
5211
5327
|
} else {
|
|
5212
|
-
user.acl.users.create
|
|
5213
|
-
user.acl.users.read
|
|
5214
|
-
user.acl.users.write
|
|
5215
|
-
user.acl.users.delete
|
|
5216
|
-
user.acl.users.list
|
|
5328
|
+
user.acl.users.create ||= group.common.acl.users.create;
|
|
5329
|
+
user.acl.users.read ||= group.common.acl.users.read;
|
|
5330
|
+
user.acl.users.write ||= group.common.acl.users.write;
|
|
5331
|
+
user.acl.users.delete ||= group.common.acl.users.delete;
|
|
5332
|
+
user.acl.users.list ||= group.common.acl.users.list;
|
|
5217
5333
|
}
|
|
5218
5334
|
}
|
|
5219
5335
|
if (group.common?.acl?.state) {
|
|
5220
5336
|
if (!user.acl || !user.acl.state) {
|
|
5221
|
-
user.acl
|
|
5222
|
-
user.acl.state
|
|
5337
|
+
user.acl ||= {};
|
|
5338
|
+
user.acl.state ||= {};
|
|
5223
5339
|
user.acl.state.create = group.common.acl.state.create;
|
|
5224
5340
|
user.acl.state.read = group.common.acl.state.read;
|
|
5225
5341
|
user.acl.state.write = group.common.acl.state.write;
|
|
5226
5342
|
user.acl.state.delete = group.common.acl.state.delete;
|
|
5227
5343
|
user.acl.state.list = group.common.acl.state.list;
|
|
5228
5344
|
} else {
|
|
5229
|
-
user.acl.state.create
|
|
5230
|
-
user.acl.state.read
|
|
5231
|
-
user.acl.state.write
|
|
5232
|
-
user.acl.state.delete
|
|
5233
|
-
user.acl.state.list
|
|
5345
|
+
user.acl.state.create ||= group.common.acl.state.create;
|
|
5346
|
+
user.acl.state.read ||= group.common.acl.state.read;
|
|
5347
|
+
user.acl.state.write ||= group.common.acl.state.write;
|
|
5348
|
+
user.acl.state.delete ||= group.common.acl.state.delete;
|
|
5349
|
+
user.acl.state.list ||= group.common.acl.state.list;
|
|
5234
5350
|
}
|
|
5235
5351
|
}
|
|
5236
5352
|
}
|
|
@@ -5238,10 +5354,17 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5238
5354
|
return options;
|
|
5239
5355
|
}
|
|
5240
5356
|
_checkState(obj, options, command) {
|
|
5357
|
+
if (options.groups?.includes(import_constants.SYSTEM_ADMIN_GROUP)) {
|
|
5358
|
+
return true;
|
|
5359
|
+
}
|
|
5241
5360
|
const limitToOwnerRights = options.limitToOwnerRights === true;
|
|
5242
5361
|
if (obj?.acl) {
|
|
5243
|
-
obj.acl.state
|
|
5362
|
+
obj.acl.state ||= obj.acl.object;
|
|
5244
5363
|
if (obj.acl.state) {
|
|
5364
|
+
if (!options.acl) {
|
|
5365
|
+
this._logger.warn(`${this.namespaceLog} Permission error for user "${options.user} on "${obj._id}": ${command}`);
|
|
5366
|
+
return false;
|
|
5367
|
+
}
|
|
5245
5368
|
if (options.user === obj.acl.owner) {
|
|
5246
5369
|
if (command === "setState" || command === "delState") {
|
|
5247
5370
|
if (command === "delState" && !options.acl.state.delete) {
|
|
@@ -5262,7 +5385,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5262
5385
|
} else {
|
|
5263
5386
|
this._logger.warn(`${this.namespaceLog} Called unknown command on "${obj._id}": ${command}`);
|
|
5264
5387
|
}
|
|
5265
|
-
} else if (options.groups
|
|
5388
|
+
} else if (options.groups?.includes(obj.acl.ownerGroup) && !limitToOwnerRights) {
|
|
5266
5389
|
if (command === "setState" || command === "delState") {
|
|
5267
5390
|
if (command === "delState" && !options.acl.state.delete) {
|
|
5268
5391
|
this._logger.warn(`${this.namespaceLog} Permission error for user "${options.user} on "${obj._id}": ${command}`);
|
|
@@ -5630,7 +5753,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5630
5753
|
this.outputCount++;
|
|
5631
5754
|
this.#states.setState(aliasId, import_js_controller_common.tools.formatAliasValue({
|
|
5632
5755
|
sourceCommon: obj?.common,
|
|
5633
|
-
targetCommon: targetObj
|
|
5756
|
+
targetCommon: targetObj?.common,
|
|
5634
5757
|
state,
|
|
5635
5758
|
logger: this._logger,
|
|
5636
5759
|
logNamespace: this.namespaceLog,
|
|
@@ -5805,7 +5928,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5805
5928
|
* }
|
|
5806
5929
|
* ```
|
|
5807
5930
|
*
|
|
5808
|
-
* See possible attributes of the state in
|
|
5931
|
+
* See possible attributes of the state in `setState` explanation
|
|
5809
5932
|
*/
|
|
5810
5933
|
getState(id, options, callback) {
|
|
5811
5934
|
if (!import_js_controller_common.tools.isObject(id)) {
|
|
@@ -5828,7 +5951,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5828
5951
|
* }
|
|
5829
5952
|
* ```
|
|
5830
5953
|
*
|
|
5831
|
-
* See possible attributes of the state in
|
|
5954
|
+
* See possible attributes of the state in `setState` explanation
|
|
5832
5955
|
*/
|
|
5833
5956
|
getForeignState(id, options, callback) {
|
|
5834
5957
|
if (typeof options === "function") {
|
|
@@ -5918,7 +6041,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5918
6041
|
if (this.oStates && this.oStates[id]) {
|
|
5919
6042
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, null, this.oStates[id]);
|
|
5920
6043
|
}
|
|
5921
|
-
return this.#states.getState(id, callback);
|
|
6044
|
+
return callback ? this.#states.getState(id, callback) : this.#states.getState(id);
|
|
5922
6045
|
}
|
|
5923
6046
|
}
|
|
5924
6047
|
// find out default history instance
|
|
@@ -5996,7 +6119,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5996
6119
|
* }
|
|
5997
6120
|
* ```
|
|
5998
6121
|
*
|
|
5999
|
-
* See possible attributes of the state in
|
|
6122
|
+
* See possible attributes of the state in `setState` explanation
|
|
6000
6123
|
*/
|
|
6001
6124
|
getHistory(id, options, callback) {
|
|
6002
6125
|
if (typeof options === "function") {
|
|
@@ -6019,10 +6142,10 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6019
6142
|
} catch (e) {
|
|
6020
6143
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, e);
|
|
6021
6144
|
}
|
|
6022
|
-
options
|
|
6023
|
-
options.end
|
|
6145
|
+
options ||= {};
|
|
6146
|
+
options.end ||= Date.now() + 5e6;
|
|
6024
6147
|
if (!options.count && !options.start) {
|
|
6025
|
-
options.start
|
|
6148
|
+
options.start ||= Date.now() - 6048e5;
|
|
6026
6149
|
}
|
|
6027
6150
|
if (!options.instance) {
|
|
6028
6151
|
if (!this.defaultHistory) {
|
|
@@ -6065,7 +6188,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6065
6188
|
}
|
|
6066
6189
|
/**
|
|
6067
6190
|
* Deletes a state of this instance.
|
|
6068
|
-
* The object will NOT be deleted. If you want to delete it too, use
|
|
6191
|
+
* The object will NOT be deleted. If you want to delete it too, use `delObject` instead.
|
|
6069
6192
|
*
|
|
6070
6193
|
* It is not required to provice the adapter namespace, because it will automatically be added.
|
|
6071
6194
|
* E.g. to delete "adapterName.X.myObject", only "myObject" is required as ID.
|
|
@@ -6106,7 +6229,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6106
6229
|
}
|
|
6107
6230
|
/**
|
|
6108
6231
|
* Deletes a state of any adapter.
|
|
6109
|
-
* The object is NOT deleted. If you want to delete it too, use
|
|
6232
|
+
* The object is NOT deleted. If you want to delete it too, use `delForeignObject` instead.
|
|
6110
6233
|
*
|
|
6111
6234
|
* No error is returned if state does not exist.
|
|
6112
6235
|
*
|
|
@@ -6147,7 +6270,11 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6147
6270
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, e);
|
|
6148
6271
|
}
|
|
6149
6272
|
}
|
|
6150
|
-
|
|
6273
|
+
if (callback) {
|
|
6274
|
+
this.#states.delState(id, callback);
|
|
6275
|
+
} else {
|
|
6276
|
+
await this.#states.delState(id);
|
|
6277
|
+
}
|
|
6151
6278
|
}
|
|
6152
6279
|
/**
|
|
6153
6280
|
* Read all states of this adapter, that pass the pattern
|
|
@@ -6181,7 +6308,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6181
6308
|
const arr = await this.#states.getStates(keys);
|
|
6182
6309
|
const result = {};
|
|
6183
6310
|
for (let i = 0; i < keys.length; i++) {
|
|
6184
|
-
const obj = targetObjs
|
|
6311
|
+
const obj = targetObjs?.[i];
|
|
6185
6312
|
if (obj?.common?.alias && srcObjs) {
|
|
6186
6313
|
const srcObj = srcObjs[i];
|
|
6187
6314
|
if (srcObj) {
|
|
@@ -6295,7 +6422,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6295
6422
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, e);
|
|
6296
6423
|
}
|
|
6297
6424
|
} else {
|
|
6298
|
-
const res = await this._processStates(pattern, options
|
|
6425
|
+
const res = await this._processStates(pattern, options._objects);
|
|
6299
6426
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, null, res);
|
|
6300
6427
|
}
|
|
6301
6428
|
} else {
|
|
@@ -6354,76 +6481,6 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6354
6481
|
}
|
|
6355
6482
|
}
|
|
6356
6483
|
}
|
|
6357
|
-
/**
|
|
6358
|
-
* Add subscription for given alias, if it is not a state it will be ignored
|
|
6359
|
-
*
|
|
6360
|
-
* @param aliasObj the alias object
|
|
6361
|
-
* @param pattern pattern to subscribe for
|
|
6362
|
-
*/
|
|
6363
|
-
async _addAliasSubscribe(aliasObj, pattern) {
|
|
6364
|
-
if (aliasObj.type !== "state") {
|
|
6365
|
-
return;
|
|
6366
|
-
}
|
|
6367
|
-
if (!aliasObj.common?.alias?.id) {
|
|
6368
|
-
this._logger.warn(`${this.namespaceLog} Alias ${aliasObj._id} has no target 5`);
|
|
6369
|
-
throw new Error(`Alias ${aliasObj._id} has no target`);
|
|
6370
|
-
}
|
|
6371
|
-
const sourceId = import_js_controller_common.tools.isObject(aliasObj.common.alias.id) ? aliasObj.common.alias.id.read : aliasObj.common.alias.id;
|
|
6372
|
-
try {
|
|
6373
|
-
this._utils.validateId(sourceId, true, null);
|
|
6374
|
-
} catch (e) {
|
|
6375
|
-
throw new Error(`Error validating alias id of ${aliasObj._id}: ${e.message}`);
|
|
6376
|
-
}
|
|
6377
|
-
const targetEntry = {
|
|
6378
|
-
alias: (0, import_deep_clone.default)(aliasObj.common.alias),
|
|
6379
|
-
id: aliasObj._id,
|
|
6380
|
-
pattern,
|
|
6381
|
-
type: aliasObj.common.type,
|
|
6382
|
-
max: aliasObj.common.max,
|
|
6383
|
-
min: aliasObj.common.min,
|
|
6384
|
-
unit: aliasObj.common.unit
|
|
6385
|
-
};
|
|
6386
|
-
let aliasDetails;
|
|
6387
|
-
if (!this.aliases.has(sourceId)) {
|
|
6388
|
-
aliasDetails = { targets: [] };
|
|
6389
|
-
this.aliases.set(sourceId, aliasDetails);
|
|
6390
|
-
} else {
|
|
6391
|
-
aliasDetails = this.aliases.get(sourceId);
|
|
6392
|
-
}
|
|
6393
|
-
if (!aliasDetails.source) {
|
|
6394
|
-
await this.#states.subscribe(sourceId);
|
|
6395
|
-
const sourceObj = await this.#objects.getObject(sourceId, { user: import_constants.SYSTEM_ADMIN_USER });
|
|
6396
|
-
if (sourceObj?.common && this.aliases.has(sourceObj._id)) {
|
|
6397
|
-
aliasDetails.source = {
|
|
6398
|
-
min: sourceObj.common.min,
|
|
6399
|
-
max: sourceObj.common.max,
|
|
6400
|
-
type: sourceObj.common.type,
|
|
6401
|
-
unit: sourceObj.common.unit
|
|
6402
|
-
};
|
|
6403
|
-
}
|
|
6404
|
-
}
|
|
6405
|
-
aliasDetails.targets.push(targetEntry);
|
|
6406
|
-
}
|
|
6407
|
-
/**
|
|
6408
|
-
* Remove an alias subscribe
|
|
6409
|
-
*
|
|
6410
|
-
* @param sourceId id of the source object
|
|
6411
|
-
* @param aliasObjOrIdx the alias target or the index of the targets array
|
|
6412
|
-
*/
|
|
6413
|
-
async _removeAliasSubscribe(sourceId, aliasObjOrIdx) {
|
|
6414
|
-
if (!this.aliases.has(sourceId)) {
|
|
6415
|
-
return;
|
|
6416
|
-
}
|
|
6417
|
-
const alias = this.aliases.get(sourceId);
|
|
6418
|
-
const pos = typeof aliasObjOrIdx === "number" ? aliasObjOrIdx : alias.targets.indexOf(aliasObjOrIdx);
|
|
6419
|
-
if (pos !== -1) {
|
|
6420
|
-
alias.targets.splice(pos, 1);
|
|
6421
|
-
if (!alias.targets.length) {
|
|
6422
|
-
this.aliases.delete(sourceId);
|
|
6423
|
-
await this.#states.unsubscribe(sourceId);
|
|
6424
|
-
}
|
|
6425
|
-
}
|
|
6426
|
-
}
|
|
6427
6484
|
/**
|
|
6428
6485
|
* Subscribe for changes on all states of all adapters (and system states), that pass the pattern
|
|
6429
6486
|
*
|
|
@@ -6450,136 +6507,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6450
6507
|
import_validator.Validator.assertObject(options, "options");
|
|
6451
6508
|
}
|
|
6452
6509
|
import_validator.Validator.assertPattern(pattern, "pattern");
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
async _subscribeForeignStates(_options) {
|
|
6456
|
-
const { pattern, options, callback } = _options;
|
|
6457
|
-
await this._autoSubscribeOn();
|
|
6458
|
-
if (!this.#states) {
|
|
6459
|
-
this._logger.info(`${this.namespaceLog} subscribeForeignStates not processed because States database not connected`);
|
|
6460
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
6461
|
-
}
|
|
6462
|
-
if (!this.#objects) {
|
|
6463
|
-
this._logger.info(`${this.namespaceLog} subscribeForeignStates not processed because Objects database not connected`);
|
|
6464
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
6465
|
-
}
|
|
6466
|
-
for (const autoSubEntry of this.autoSubscribe) {
|
|
6467
|
-
if (typeof pattern === "string" && (pattern === "*" || pattern.startsWith(`${autoSubEntry}.`))) {
|
|
6468
|
-
let state;
|
|
6469
|
-
try {
|
|
6470
|
-
state = await this.#states.getState(`system.adapter.${autoSubEntry}.subscribes`);
|
|
6471
|
-
} catch {
|
|
6472
|
-
}
|
|
6473
|
-
state = state || { val: "{}" };
|
|
6474
|
-
state.val = state.val || "{}";
|
|
6475
|
-
let subs;
|
|
6476
|
-
try {
|
|
6477
|
-
subs = JSON.parse(state.val);
|
|
6478
|
-
} catch {
|
|
6479
|
-
this._logger.error(`${this.namespaceLog} Cannot parse subscribes for "${autoSubEntry}.subscribes"`);
|
|
6480
|
-
}
|
|
6481
|
-
if (!import_js_controller_common.tools.isObject(subs)) {
|
|
6482
|
-
subs = {};
|
|
6483
|
-
}
|
|
6484
|
-
if (!import_js_controller_common.tools.isObject(subs[pattern])) {
|
|
6485
|
-
subs[pattern] = {};
|
|
6486
|
-
}
|
|
6487
|
-
if (typeof subs[pattern][this.namespace] !== "number") {
|
|
6488
|
-
subs[pattern][this.namespace] = 0;
|
|
6489
|
-
}
|
|
6490
|
-
subs[pattern][this.namespace]++;
|
|
6491
|
-
this.outputCount++;
|
|
6492
|
-
await this.#states.setState(`system.adapter.${autoSubEntry}.subscribes`, JSON.stringify(subs));
|
|
6493
|
-
}
|
|
6494
|
-
}
|
|
6495
|
-
if (Array.isArray(pattern)) {
|
|
6496
|
-
const aliasesIds = pattern.map((id) => id.startsWith(import_constants.ALIAS_STARTS_WITH) ? id : null).filter((id) => id);
|
|
6497
|
-
const nonAliasesIds = pattern.map((id) => !id.startsWith(import_constants.ALIAS_STARTS_WITH) ? id : null).filter((id) => id);
|
|
6498
|
-
for (const aliasPattern of pattern) {
|
|
6499
|
-
if ((aliasPattern.startsWith(import_constants.ALIAS_STARTS_WITH) || aliasPattern.includes("*")) && !this.aliasPatterns.has(aliasPattern)) {
|
|
6500
|
-
this.aliasPatterns.add(aliasPattern);
|
|
6501
|
-
}
|
|
6502
|
-
}
|
|
6503
|
-
const promises = [];
|
|
6504
|
-
if (aliasesIds.length) {
|
|
6505
|
-
if (!this._aliasObjectsSubscribed) {
|
|
6506
|
-
this._aliasObjectsSubscribed = true;
|
|
6507
|
-
this.#objects.subscribe(`${import_constants.ALIAS_STARTS_WITH}*`);
|
|
6508
|
-
}
|
|
6509
|
-
const aliasObjs = await this._getObjectsByArray(aliasesIds, options);
|
|
6510
|
-
for (const aliasObj of aliasObjs) {
|
|
6511
|
-
if (aliasObj) {
|
|
6512
|
-
promises.push(this._addAliasSubscribe(aliasObj, aliasObj._id));
|
|
6513
|
-
}
|
|
6514
|
-
}
|
|
6515
|
-
}
|
|
6516
|
-
if (nonAliasesIds.length) {
|
|
6517
|
-
for (const id of nonAliasesIds) {
|
|
6518
|
-
promises.push(new Promise((resolve) => this.#states.subscribeUser(id, resolve)));
|
|
6519
|
-
}
|
|
6520
|
-
}
|
|
6521
|
-
try {
|
|
6522
|
-
await Promise.all(promises);
|
|
6523
|
-
} catch (e) {
|
|
6524
|
-
this._logger.error(`${this.namespaceLog} Error on "subscribeForeignStates": ${e.message}`);
|
|
6525
|
-
}
|
|
6526
|
-
return import_js_controller_common.tools.maybeCallback(callback);
|
|
6527
|
-
} else if (pattern.includes("*")) {
|
|
6528
|
-
if (pattern === "*" || pattern.startsWith(import_constants.ALIAS_STARTS_WITH)) {
|
|
6529
|
-
if (!this._aliasObjectsSubscribed) {
|
|
6530
|
-
this._aliasObjectsSubscribed = true;
|
|
6531
|
-
this.#objects.subscribe(`${import_constants.ALIAS_STARTS_WITH}*`);
|
|
6532
|
-
}
|
|
6533
|
-
try {
|
|
6534
|
-
const objs = await this.getForeignObjectsAsync(pattern, null, null, options);
|
|
6535
|
-
const promises = [];
|
|
6536
|
-
if (!this.aliasPatterns.has(pattern)) {
|
|
6537
|
-
this.aliasPatterns.add(pattern);
|
|
6538
|
-
}
|
|
6539
|
-
for (const id of Object.keys(objs)) {
|
|
6540
|
-
if (id.startsWith(import_constants.ALIAS_STARTS_WITH)) {
|
|
6541
|
-
const aliasObj = objs[id];
|
|
6542
|
-
promises.push(this._addAliasSubscribe(aliasObj, pattern));
|
|
6543
|
-
}
|
|
6544
|
-
}
|
|
6545
|
-
try {
|
|
6546
|
-
await Promise.all(promises);
|
|
6547
|
-
} catch (e) {
|
|
6548
|
-
this._logger.error(`${this.namespaceLog} Error on "subscribeForeignStates": ${e.message}`);
|
|
6549
|
-
}
|
|
6550
|
-
if (!this.#states) {
|
|
6551
|
-
this._logger.info(`${this.namespaceLog} subscribeForeignStates not processed because States database not connected`);
|
|
6552
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
6553
|
-
}
|
|
6554
|
-
if (promises.length && pattern !== "*") {
|
|
6555
|
-
return import_js_controller_common.tools.maybeCallback(callback);
|
|
6556
|
-
}
|
|
6557
|
-
this.#states.subscribeUser(pattern, callback);
|
|
6558
|
-
} catch (e) {
|
|
6559
|
-
this._logger.warn(`${this.namespaceLog} Cannot subscribe to ${pattern}: ${e.message}`);
|
|
6560
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, e);
|
|
6561
|
-
}
|
|
6562
|
-
} else {
|
|
6563
|
-
this.#states.subscribeUser(pattern, callback);
|
|
6564
|
-
}
|
|
6565
|
-
} else if (pattern.startsWith(import_constants.ALIAS_STARTS_WITH)) {
|
|
6566
|
-
if (!this._aliasObjectsSubscribed) {
|
|
6567
|
-
this._aliasObjectsSubscribed = true;
|
|
6568
|
-
this.#objects.subscribe(`${import_constants.ALIAS_STARTS_WITH}*`);
|
|
6569
|
-
}
|
|
6570
|
-
try {
|
|
6571
|
-
const aliasObj = await this.#objects.getObject(pattern, options);
|
|
6572
|
-
if (aliasObj) {
|
|
6573
|
-
await this._addAliasSubscribe(aliasObj, pattern);
|
|
6574
|
-
return import_js_controller_common.tools.maybeCallback(callback);
|
|
6575
|
-
}
|
|
6576
|
-
return import_js_controller_common.tools.maybeCallback(callback);
|
|
6577
|
-
} catch (e) {
|
|
6578
|
-
this._logger.warn(`${this.namespaceLog} cannot subscribe on alias "${pattern}": ${e.message}`);
|
|
6579
|
-
}
|
|
6580
|
-
} else {
|
|
6581
|
-
this.#states.subscribeUser(pattern, callback);
|
|
6582
|
-
}
|
|
6510
|
+
const cb = callback;
|
|
6511
|
+
this.#subscriptions.subscribeForeignStates(pattern, options).then(() => cb?.(), (err) => cb?.(err));
|
|
6583
6512
|
}
|
|
6584
6513
|
/**
|
|
6585
6514
|
* Unsubscribe for changes for given pattern
|
|
@@ -6612,85 +6541,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6612
6541
|
if (options !== null && options !== void 0) {
|
|
6613
6542
|
import_validator.Validator.assertObject(options, "options");
|
|
6614
6543
|
}
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
async _unsubscribeForeignStates(_options) {
|
|
6618
|
-
const { pattern, callback } = _options;
|
|
6619
|
-
if (!this.#states) {
|
|
6620
|
-
this._logger.info(`${this.namespaceLog} unsubscrubeForeignStates not processed because States database not connected`);
|
|
6621
|
-
return import_js_controller_common.tools.maybeCallbackWithError(callback, import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
6622
|
-
}
|
|
6623
|
-
if (this.autoSubscribe && typeof pattern === "string") {
|
|
6624
|
-
for (const autoSub of this.autoSubscribe) {
|
|
6625
|
-
if (pattern === "*" || pattern.substring(0, autoSub.length + 1) === `${autoSub}.`) {
|
|
6626
|
-
let state;
|
|
6627
|
-
try {
|
|
6628
|
-
state = await this.#states.getState(`system.adapter.${autoSub}.subscribes`);
|
|
6629
|
-
} catch {
|
|
6630
|
-
}
|
|
6631
|
-
if (!state || !state.val) {
|
|
6632
|
-
continue;
|
|
6633
|
-
}
|
|
6634
|
-
let subs;
|
|
6635
|
-
try {
|
|
6636
|
-
subs = JSON.parse(state.val);
|
|
6637
|
-
} catch {
|
|
6638
|
-
this._logger.error(`${this.namespaceLog} Cannot parse subscribes for "${autoSub}.subscribes"`);
|
|
6639
|
-
continue;
|
|
6640
|
-
}
|
|
6641
|
-
if (!import_js_controller_common.tools.isObject(subs) || !import_js_controller_common.tools.isObject(subs[pattern]) || subs[pattern][this.namespace] === void 0) {
|
|
6642
|
-
continue;
|
|
6643
|
-
}
|
|
6644
|
-
if (typeof subs[pattern][this.namespace] === "number") {
|
|
6645
|
-
subs[pattern][this.namespace]--;
|
|
6646
|
-
if (subs[pattern][this.namespace] <= 0) {
|
|
6647
|
-
delete subs[pattern][this.namespace];
|
|
6648
|
-
}
|
|
6649
|
-
} else {
|
|
6650
|
-
delete subs[pattern][this.namespace];
|
|
6651
|
-
}
|
|
6652
|
-
if (!Object.keys(subs[pattern]).length) {
|
|
6653
|
-
delete subs[pattern];
|
|
6654
|
-
}
|
|
6655
|
-
this.outputCount++;
|
|
6656
|
-
await this.#states.setState(`system.adapter.${autoSub}.subscribes`, JSON.stringify(subs));
|
|
6657
|
-
}
|
|
6658
|
-
}
|
|
6659
|
-
}
|
|
6660
|
-
let aliasPattern;
|
|
6661
|
-
const promises = [];
|
|
6662
|
-
if (Array.isArray(pattern)) {
|
|
6663
|
-
for (const _pattern of pattern) {
|
|
6664
|
-
promises.push(this.unsubscribeForeignStatesAsync(_pattern));
|
|
6665
|
-
}
|
|
6666
|
-
} else if (pattern.includes("*") || pattern.startsWith(import_constants.ALIAS_STARTS_WITH)) {
|
|
6667
|
-
if (pattern === "*" || pattern.startsWith(import_constants.ALIAS_STARTS_WITH)) {
|
|
6668
|
-
aliasPattern = pattern;
|
|
6669
|
-
if (pattern === "*") {
|
|
6670
|
-
promises.push(this.#states.unsubscribeUser(pattern));
|
|
6671
|
-
}
|
|
6672
|
-
} else {
|
|
6673
|
-
promises.push(this.#states.unsubscribeUser(pattern));
|
|
6674
|
-
}
|
|
6675
|
-
} else {
|
|
6676
|
-
promises.push(this.#states.unsubscribeUser(pattern));
|
|
6677
|
-
}
|
|
6678
|
-
if (aliasPattern) {
|
|
6679
|
-
this.aliasPatterns.delete(aliasPattern);
|
|
6680
|
-
for (const [sourceId, alias] of this.aliases) {
|
|
6681
|
-
for (let i = alias.targets.length - 1; i >= 0; i--) {
|
|
6682
|
-
if (alias.targets[i].pattern === aliasPattern) {
|
|
6683
|
-
promises.push(this._removeAliasSubscribe(sourceId, i));
|
|
6684
|
-
}
|
|
6685
|
-
}
|
|
6686
|
-
}
|
|
6687
|
-
}
|
|
6688
|
-
await Promise.all(promises);
|
|
6689
|
-
if (!this.aliases.size && this._aliasObjectsSubscribed) {
|
|
6690
|
-
this._aliasObjectsSubscribed = false;
|
|
6691
|
-
this.#objects.unsubscribe(`${import_constants.ALIAS_STARTS_WITH}*`);
|
|
6692
|
-
}
|
|
6693
|
-
return import_js_controller_common.tools.maybeCallback(callback);
|
|
6544
|
+
const cb = callback;
|
|
6545
|
+
this.#subscriptions.unsubscribeForeignStates(pattern, options).then(() => cb?.(), (err) => cb?.(err));
|
|
6694
6546
|
}
|
|
6695
6547
|
/**
|
|
6696
6548
|
* Subscribe for changes on all states of this instance, that pass the pattern
|
|
@@ -6714,11 +6566,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6714
6566
|
if (options !== null && options !== void 0) {
|
|
6715
6567
|
import_validator.Validator.assertObject(options, "options");
|
|
6716
6568
|
}
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
options,
|
|
6720
|
-
callback
|
|
6721
|
-
});
|
|
6569
|
+
const cb = callback;
|
|
6570
|
+
this.#subscriptions.subscribeForeignStates(Array.isArray(pattern) ? pattern : this._utils.fixId(pattern, true), options).then(() => cb?.(), (err) => cb?.(err));
|
|
6722
6571
|
}
|
|
6723
6572
|
/**
|
|
6724
6573
|
* Unsubscribe for changes for given pattern for own states.
|
|
@@ -6744,11 +6593,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6744
6593
|
if (options !== null && options !== void 0) {
|
|
6745
6594
|
import_validator.Validator.assertObject(options, "options");
|
|
6746
6595
|
}
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
options,
|
|
6750
|
-
callback
|
|
6751
|
-
});
|
|
6596
|
+
const cb = callback;
|
|
6597
|
+
this.#subscriptions.unsubscribeForeignStates(Array.isArray(pattern) ? pattern : this._utils.fixId(pattern, true), options).then(() => cb?.(), (err) => cb?.(err));
|
|
6752
6598
|
}
|
|
6753
6599
|
/**
|
|
6754
6600
|
* Return plugin instance
|
|
@@ -6776,27 +6622,6 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6776
6622
|
import_validator.Validator.assertString(name, "name");
|
|
6777
6623
|
return this.pluginHandler.getPluginConfig(name);
|
|
6778
6624
|
}
|
|
6779
|
-
async _autoSubscribeOn() {
|
|
6780
|
-
if (!this.autoSubscribe && this.#objects) {
|
|
6781
|
-
try {
|
|
6782
|
-
const res = await this.#objects.getObjectViewAsync("system", "instance", {
|
|
6783
|
-
startkey: "system.adapter.",
|
|
6784
|
-
endkey: "system.adapter.\u9999"
|
|
6785
|
-
});
|
|
6786
|
-
this.autoSubscribe = [];
|
|
6787
|
-
for (const row of res.rows) {
|
|
6788
|
-
if (row.value?.common.subscribable) {
|
|
6789
|
-
const _id = row.id.substring(15);
|
|
6790
|
-
if (!this.autoSubscribe.includes(_id)) {
|
|
6791
|
-
this.autoSubscribe.push(_id);
|
|
6792
|
-
}
|
|
6793
|
-
}
|
|
6794
|
-
}
|
|
6795
|
-
await this.#objects.subscribeAsync("system.adapter.*");
|
|
6796
|
-
} catch {
|
|
6797
|
-
}
|
|
6798
|
-
}
|
|
6799
|
-
}
|
|
6800
6625
|
/**
|
|
6801
6626
|
* This method returns the list of license that can be used by this adapter
|
|
6802
6627
|
*
|
|
@@ -6902,7 +6727,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6902
6727
|
ack: true,
|
|
6903
6728
|
expire: reportStatusExpirySec,
|
|
6904
6729
|
from: id
|
|
6905
|
-
});
|
|
6730
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set alive state: ${e.message}`));
|
|
6906
6731
|
this.outputCount++;
|
|
6907
6732
|
if (this.connected) {
|
|
6908
6733
|
this.#states.setState(`${id}.connected`, {
|
|
@@ -6910,24 +6735,24 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6910
6735
|
ack: true,
|
|
6911
6736
|
expire: reportStatusExpirySec,
|
|
6912
6737
|
from: id
|
|
6913
|
-
});
|
|
6738
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set connected state: ${e.message}`));
|
|
6914
6739
|
this.outputCount++;
|
|
6915
6740
|
}
|
|
6916
6741
|
if (!this.startedInCompactMode) {
|
|
6917
6742
|
(0, import_pidusage.default)(process.pid, (err, stats) => {
|
|
6918
|
-
if (!err && this && this.#states && this.#states.setState && stats) {
|
|
6743
|
+
if (!err && this && this.#states && this.#states.setState && stats && !this.terminated) {
|
|
6919
6744
|
this.#states.setState(`${id}.cpu`, {
|
|
6920
6745
|
ack: true,
|
|
6921
6746
|
from: id,
|
|
6922
6747
|
val: Math.round(100 * stats.cpu) / 100,
|
|
6923
6748
|
expire: reportStatusExpirySec
|
|
6924
|
-
});
|
|
6749
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set cpu state: ${e.message}`));
|
|
6925
6750
|
this.#states.setState(`${id}.cputime`, {
|
|
6926
6751
|
ack: true,
|
|
6927
6752
|
from: id,
|
|
6928
6753
|
val: stats.ctime / 1e3,
|
|
6929
6754
|
expire: reportStatusExpirySec
|
|
6930
|
-
});
|
|
6755
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set cputime state: ${e.message}`));
|
|
6931
6756
|
this.outputCount += 2;
|
|
6932
6757
|
}
|
|
6933
6758
|
});
|
|
@@ -6938,19 +6763,19 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6938
6763
|
ack: true,
|
|
6939
6764
|
from: id,
|
|
6940
6765
|
expire: reportStatusExpirySec
|
|
6941
|
-
});
|
|
6766
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set memRss state: ${e.message}`));
|
|
6942
6767
|
this.#states.setState(`${id}.memHeapTotal`, {
|
|
6943
6768
|
val: parseFloat((mem.heapTotal / 1048576).toFixed(2)),
|
|
6944
6769
|
ack: true,
|
|
6945
6770
|
from: id,
|
|
6946
6771
|
expire: reportStatusExpirySec
|
|
6947
|
-
});
|
|
6772
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set memHeapTotal state: ${e.message}`));
|
|
6948
6773
|
this.#states.setState(`${id}.memHeapUsed`, {
|
|
6949
6774
|
val: parseFloat((mem.heapUsed / 1048576).toFixed(2)),
|
|
6950
6775
|
ack: true,
|
|
6951
6776
|
from: id,
|
|
6952
6777
|
expire: reportStatusExpirySec
|
|
6953
|
-
});
|
|
6778
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set memHeapUsed state: ${e.message}`));
|
|
6954
6779
|
} catch (e) {
|
|
6955
6780
|
this._logger.warn(`${this.namespaceLog} Could not query used process memory: ${e.message}`);
|
|
6956
6781
|
}
|
|
@@ -6962,7 +6787,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6962
6787
|
ack: true,
|
|
6963
6788
|
from: id,
|
|
6964
6789
|
expire: reportStatusExpirySec
|
|
6965
|
-
});
|
|
6790
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set eventLoopLag state: ${e.message}`));
|
|
6966
6791
|
this.eventLoopLags = [];
|
|
6967
6792
|
this.outputCount++;
|
|
6968
6793
|
}
|
|
@@ -6973,19 +6798,19 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6973
6798
|
ack: true,
|
|
6974
6799
|
from: id,
|
|
6975
6800
|
expire: reportStatusExpirySec
|
|
6976
|
-
});
|
|
6801
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set uptime state: ${e.message}`));
|
|
6977
6802
|
this.#states.setState(`${id}.inputCount`, {
|
|
6978
6803
|
val: this.inputCount,
|
|
6979
6804
|
ack: true,
|
|
6980
6805
|
from: id,
|
|
6981
6806
|
expire: reportStatusExpirySec
|
|
6982
|
-
});
|
|
6807
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set inputCount state: ${e.message}`));
|
|
6983
6808
|
this.#states.setState(`${id}.outputCount`, {
|
|
6984
6809
|
val: this.outputCount,
|
|
6985
6810
|
ack: true,
|
|
6986
6811
|
from: id,
|
|
6987
6812
|
expire: reportStatusExpirySec
|
|
6988
|
-
});
|
|
6813
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set outputCount state: ${e.message}`));
|
|
6989
6814
|
this.inputCount = 0;
|
|
6990
6815
|
this.outputCount = 0;
|
|
6991
6816
|
}
|
|
@@ -7053,7 +6878,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7053
6878
|
}
|
|
7054
6879
|
} else if (this.#states?.pushLog) {
|
|
7055
6880
|
for (const instanceId of this.logList) {
|
|
7056
|
-
this.#states.pushLog(instanceId, info);
|
|
6881
|
+
this.#states.pushLog(instanceId, info).catch((e) => this._logger.error(`${this.namespaceLog} Cannot push log: ${e.message}`));
|
|
7057
6882
|
}
|
|
7058
6883
|
}
|
|
7059
6884
|
});
|
|
@@ -7077,7 +6902,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7077
6902
|
if (this.logList.size && messages?.length && this.#states) {
|
|
7078
6903
|
for (const message of messages) {
|
|
7079
6904
|
for (const instanceId of this.logList) {
|
|
7080
|
-
this.#states.pushLog(instanceId, message);
|
|
6905
|
+
this.#states.pushLog(instanceId, message).catch((e) => this._logger.error(`${this.namespaceLog} Cannot push log: ${e.message}`));
|
|
7081
6906
|
}
|
|
7082
6907
|
}
|
|
7083
6908
|
}
|
|
@@ -7139,7 +6964,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7139
6964
|
this.emit("log", msg);
|
|
7140
6965
|
}
|
|
7141
6966
|
};
|
|
7142
|
-
this.#states.subscribeLog(`system.adapter.${this.namespace}`);
|
|
6967
|
+
this.#states.subscribeLog(`system.adapter.${this.namespace}`).catch((e) => this._logger.error(`${this.namespaceLog} Cannot subscribe to log: ${e.message}`));
|
|
7143
6968
|
} else {
|
|
7144
6969
|
this.requireLog = (isActive) => {
|
|
7145
6970
|
if (isActive) {
|
|
@@ -7168,7 +6993,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7168
6993
|
this.#states = new this.States({
|
|
7169
6994
|
namespace: this.namespaceLog,
|
|
7170
6995
|
connection: this._config.states,
|
|
7171
|
-
connected: async () => {
|
|
6996
|
+
connected: /* @__PURE__ */ __name(async () => {
|
|
7172
6997
|
if (!this.#states) {
|
|
7173
6998
|
return;
|
|
7174
6999
|
}
|
|
@@ -7179,11 +7004,11 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7179
7004
|
this._initializeTimeout = null;
|
|
7180
7005
|
}
|
|
7181
7006
|
if (!this._config.isInstall) {
|
|
7182
|
-
this.#states.subscribe(`system.adapter.${this.namespace}.sigKill`);
|
|
7183
|
-
this.#states.subscribe(`system.adapter.${this.namespace}.logLevel`);
|
|
7007
|
+
this.#states.subscribe(`system.adapter.${this.namespace}.sigKill`).catch((e) => this._logger.error(`${this.namespaceLog} Cannot subscribe to sigKill: ${e.message}`));
|
|
7008
|
+
this.#states.subscribe(`system.adapter.${this.namespace}.logLevel`).catch((e) => this._logger.error(`${this.namespaceLog} Cannot subscribe to logLevel: ${e.message}`));
|
|
7184
7009
|
}
|
|
7185
7010
|
if (this._options.subscribable) {
|
|
7186
|
-
this.#states.subscribe(`system.adapter.${this.namespace}.subscribes`);
|
|
7011
|
+
this.#states.subscribe(`system.adapter.${this.namespace}.subscribes`).catch((e) => this._logger.error(`${this.namespaceLog} Cannot subscribe to subscribes: ${e.message}`));
|
|
7187
7012
|
let state;
|
|
7188
7013
|
try {
|
|
7189
7014
|
state = await this.#states.getStateAsync(`system.adapter.${this.namespace}.subscribes`);
|
|
@@ -7202,9 +7027,9 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7202
7027
|
return import_js_controller_common.tools.maybeCallback(cb);
|
|
7203
7028
|
}
|
|
7204
7029
|
return import_js_controller_common.tools.maybeCallback(cb);
|
|
7205
|
-
},
|
|
7030
|
+
}, "connected"),
|
|
7206
7031
|
logger: this._logger,
|
|
7207
|
-
change: async (id, stateOrMessage) => {
|
|
7032
|
+
change: /* @__PURE__ */ __name(async (id, stateOrMessage) => {
|
|
7208
7033
|
this.inputCount++;
|
|
7209
7034
|
const state = stateOrMessage;
|
|
7210
7035
|
if (!id || typeof id !== "string") {
|
|
@@ -7225,7 +7050,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7225
7050
|
isScheduled: false,
|
|
7226
7051
|
exitCode: import_js_controller_common.EXIT_CODES.ADAPTER_REQUESTED_TERMINATION,
|
|
7227
7052
|
updateAliveState: false
|
|
7228
|
-
});
|
|
7053
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot stop adapter: ${e.message}`));
|
|
7229
7054
|
}
|
|
7230
7055
|
}
|
|
7231
7056
|
}
|
|
@@ -7236,12 +7061,9 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7236
7061
|
if (state.val && state.val !== currentLevel && (0, import_tools.isLogLevel)(newLogLevel)) {
|
|
7237
7062
|
this.overwriteLogLevel = true;
|
|
7238
7063
|
this._config.log.level = newLogLevel;
|
|
7239
|
-
for (const transport
|
|
7240
|
-
if (!
|
|
7241
|
-
|
|
7242
|
-
}
|
|
7243
|
-
if (!this._logger.transports[transport]._defaultConfigLoglevel) {
|
|
7244
|
-
this._logger.transports[transport].level = newLogLevel;
|
|
7064
|
+
for (const transport of this._logger.transports) {
|
|
7065
|
+
if (!transport._defaultConfigLoglevel) {
|
|
7066
|
+
transport.level = newLogLevel;
|
|
7245
7067
|
}
|
|
7246
7068
|
}
|
|
7247
7069
|
this._logger.info(`${this.namespaceLog} Loglevel changed from "${currentLevel}" to "${state.val}"`);
|
|
@@ -7254,7 +7076,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7254
7076
|
val: currentLevel,
|
|
7255
7077
|
ack: true,
|
|
7256
7078
|
from: `system.adapter.${this.namespace}`
|
|
7257
|
-
});
|
|
7079
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set logLevel state: ${e.message}`));
|
|
7258
7080
|
}
|
|
7259
7081
|
}
|
|
7260
7082
|
if (id === `system.adapter.${this.namespace}.checkLogging`) {
|
|
@@ -7286,25 +7108,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7286
7108
|
} else if (id === `messagebox.system.adapter.${this.namespace}` && state) {
|
|
7287
7109
|
const obj = state;
|
|
7288
7110
|
if (obj) {
|
|
7289
|
-
|
|
7290
|
-
if (obj.callback?.id) {
|
|
7291
|
-
callbackObj = this.messageCallbacks.get(obj.callback.id);
|
|
7292
|
-
}
|
|
7293
|
-
if (obj.callback?.ack && obj.callback.id && callbackObj) {
|
|
7294
|
-
if (typeof callbackObj.cb === "function") {
|
|
7295
|
-
callbackObj.cb(obj.message);
|
|
7296
|
-
if (callbackObj.timer) {
|
|
7297
|
-
clearTimeout(callbackObj.timer);
|
|
7298
|
-
}
|
|
7299
|
-
this.messageCallbacks.delete(obj.callback.id);
|
|
7300
|
-
}
|
|
7301
|
-
const now = Date.now();
|
|
7302
|
-
for (const [_id, callback] of this.messageCallbacks) {
|
|
7303
|
-
if (now - callback.time > 36e5) {
|
|
7304
|
-
this.messageCallbacks.delete(_id);
|
|
7305
|
-
}
|
|
7306
|
-
}
|
|
7307
|
-
} else if (!this._stopInProgress) {
|
|
7111
|
+
if (!this.#async.resolveReply(obj) && !this._stopInProgress) {
|
|
7308
7112
|
if (obj.command === "clientSubscribe") {
|
|
7309
7113
|
const res = await this.uiMessagingController.registerClientSubscribeByMessage(obj);
|
|
7310
7114
|
this.sendTo(obj.from, obj.command, res, obj.callback);
|
|
@@ -7314,7 +7118,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7314
7118
|
return this.uiMessagingController.removeClientSubscribeByMessage(obj);
|
|
7315
7119
|
}
|
|
7316
7120
|
if (this._options.message) {
|
|
7317
|
-
this._options.message(obj);
|
|
7121
|
+
Promise.resolve(this._options.message(obj)).catch((e) => this._logger.error(`${this.namespaceLog} Error in message handler: ${e.message}`));
|
|
7318
7122
|
}
|
|
7319
7123
|
this.emit("message", obj);
|
|
7320
7124
|
}
|
|
@@ -7345,36 +7149,17 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7345
7149
|
}
|
|
7346
7150
|
}
|
|
7347
7151
|
}
|
|
7348
|
-
} else if (!this._stopInProgress && this.adapterReady && this.
|
|
7349
|
-
const
|
|
7350
|
-
|
|
7351
|
-
|
|
7352
|
-
|
|
7353
|
-
|
|
7354
|
-
continue;
|
|
7355
|
-
}
|
|
7356
|
-
uniqueTargets.add(targetId);
|
|
7357
|
-
const source = alias.source;
|
|
7358
|
-
const aState = state ? import_js_controller_common.tools.formatAliasValue({
|
|
7359
|
-
sourceCommon: source,
|
|
7360
|
-
targetCommon: target,
|
|
7361
|
-
state: (0, import_deep_clone.default)(state),
|
|
7362
|
-
logger: this._logger,
|
|
7363
|
-
logNamespace: this.namespaceLog,
|
|
7364
|
-
sourceId: id,
|
|
7365
|
-
targetId
|
|
7366
|
-
}) : null;
|
|
7367
|
-
if (aState || !state) {
|
|
7368
|
-
if (typeof this._options.stateChange === "function") {
|
|
7369
|
-
this._options.stateChange(targetId, aState);
|
|
7370
|
-
} else {
|
|
7371
|
-
setImmediate(() => this.emit("stateChange", targetId, aState));
|
|
7372
|
-
}
|
|
7152
|
+
} else if (!this._stopInProgress && this.adapterReady && this.#alias.hasSource(id)) {
|
|
7153
|
+
for (const { targetId, state: aState } of this.#alias.resolveSourceChange(id, state)) {
|
|
7154
|
+
if (typeof this._options.stateChange === "function") {
|
|
7155
|
+
Promise.resolve(this._options.stateChange(targetId, aState)).catch((e) => this._logger.error(`${this.namespaceLog} Error in stateChange handler: ${e.message}`));
|
|
7156
|
+
} else {
|
|
7157
|
+
setImmediate(() => this.emit("stateChange", targetId, aState));
|
|
7373
7158
|
}
|
|
7374
7159
|
}
|
|
7375
7160
|
}
|
|
7376
|
-
},
|
|
7377
|
-
changeUser: (id, state) => {
|
|
7161
|
+
}, "change"),
|
|
7162
|
+
changeUser: /* @__PURE__ */ __name((id, state) => {
|
|
7378
7163
|
this.inputCount++;
|
|
7379
7164
|
if (!id || typeof id !== "string") {
|
|
7380
7165
|
this._logger.warn(`${this.namespaceLog} Invalid id on state change: ${JSON.stringify(id)}`);
|
|
@@ -7396,17 +7181,17 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7396
7181
|
}
|
|
7397
7182
|
}
|
|
7398
7183
|
}
|
|
7399
|
-
},
|
|
7400
|
-
disconnected: () => {
|
|
7184
|
+
}, "changeUser"),
|
|
7185
|
+
disconnected: /* @__PURE__ */ __name(() => {
|
|
7401
7186
|
this.connected = false;
|
|
7402
7187
|
!this.terminated && setTimeout(() => {
|
|
7403
7188
|
if (this.connected) {
|
|
7404
7189
|
return;
|
|
7405
7190
|
}
|
|
7406
7191
|
this._logger.warn(`${this.namespaceLog} Cannot connect/reconnect to states DB. Stopping adapter.`);
|
|
7407
|
-
this._stop({ exitCode: import_js_controller_common.EXIT_CODES.NO_ERROR, updateAliveState: false });
|
|
7192
|
+
this._stop({ exitCode: import_js_controller_common.EXIT_CODES.NO_ERROR, updateAliveState: false }).catch((e) => this._logger.error(`${this.namespaceLog} Cannot stop adapter: ${e.message}`));
|
|
7408
7193
|
}, 5e3);
|
|
7409
|
-
}
|
|
7194
|
+
}, "disconnected")
|
|
7410
7195
|
});
|
|
7411
7196
|
}
|
|
7412
7197
|
_initObjects(cb) {
|
|
@@ -7427,7 +7212,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7427
7212
|
namespace: this.namespaceLog,
|
|
7428
7213
|
connection: this._config.objects,
|
|
7429
7214
|
logger: this._logger,
|
|
7430
|
-
connected: async () => {
|
|
7215
|
+
connected: /* @__PURE__ */ __name(async () => {
|
|
7431
7216
|
this.connected = true;
|
|
7432
7217
|
if (this._initializeTimeout) {
|
|
7433
7218
|
clearTimeout(this._initializeTimeout);
|
|
@@ -7457,25 +7242,31 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7457
7242
|
} else {
|
|
7458
7243
|
return import_js_controller_common.tools.maybeCallback(cb);
|
|
7459
7244
|
}
|
|
7460
|
-
},
|
|
7461
|
-
disconnected: () => {
|
|
7245
|
+
}, "connected"),
|
|
7246
|
+
disconnected: /* @__PURE__ */ __name(() => {
|
|
7462
7247
|
this.connected = false;
|
|
7463
7248
|
!this.terminated && setTimeout(() => {
|
|
7464
7249
|
if (this.connected) {
|
|
7465
7250
|
return;
|
|
7466
7251
|
}
|
|
7467
7252
|
this._logger.warn(`${this.namespaceLog} Cannot connect/reconnect to objects DB. Stopping adapter.`);
|
|
7468
|
-
this._stop({ exitCode: import_js_controller_common.EXIT_CODES.NO_ERROR, updateAliveState: false });
|
|
7253
|
+
this._stop({ exitCode: import_js_controller_common.EXIT_CODES.NO_ERROR, updateAliveState: false }).catch((e) => this._logger.error(`${this.namespaceLog} Cannot stop adapter: ${e.message}`));
|
|
7469
7254
|
}, 4e3);
|
|
7470
|
-
},
|
|
7471
|
-
change: async (id, obj) => {
|
|
7255
|
+
}, "disconnected"),
|
|
7256
|
+
change: /* @__PURE__ */ __name(async (id, obj) => {
|
|
7472
7257
|
if (!id) {
|
|
7473
7258
|
this._logger.error(`${this.namespaceLog} change ID is empty: ${JSON.stringify(obj)}`);
|
|
7474
7259
|
return;
|
|
7475
7260
|
}
|
|
7476
7261
|
if (id === `system.adapter.${this.namespace}` && obj?.common?.enabled === false) {
|
|
7477
7262
|
this._logger.info(`${this.namespaceLog} Adapter is disabled => stop`);
|
|
7478
|
-
this._stop();
|
|
7263
|
+
this._stop().catch((e) => this._logger.error(`${this.namespaceLog} Cannot stop adapter: ${e.message}`));
|
|
7264
|
+
return;
|
|
7265
|
+
}
|
|
7266
|
+
if (id === import_CertificateManager.CERTIFICATES_OBJECT_ID) {
|
|
7267
|
+
if (this.#async.hasRelevantCertificateChange(obj)) {
|
|
7268
|
+
this.#scheduleCertificateRestart("Changed certificate detected");
|
|
7269
|
+
}
|
|
7479
7270
|
return;
|
|
7480
7271
|
}
|
|
7481
7272
|
if (id === "system.config" && obj?.common && (this._options.useFormatDate || this.defaultHistory !== void 0)) {
|
|
@@ -7487,57 +7278,15 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7487
7278
|
this.defaultHistory = obj.common.defaultHistory;
|
|
7488
7279
|
}
|
|
7489
7280
|
if (id.startsWith(import_constants.ALIAS_STARTS_WITH)) {
|
|
7490
|
-
|
|
7491
|
-
for (const [sourceId, alias] of this.aliases) {
|
|
7492
|
-
const targetAlias = alias.targets.find((entry) => entry.id === id);
|
|
7493
|
-
if (targetAlias) {
|
|
7494
|
-
isNewAlias = false;
|
|
7495
|
-
if (obj?.common?.alias?.id) {
|
|
7496
|
-
const newSourceId = typeof obj.common.alias.id.read === "string" ? obj.common.alias.id.read : obj.common.alias.id;
|
|
7497
|
-
if (newSourceId !== sourceId) {
|
|
7498
|
-
await this._removeAliasSubscribe(sourceId, targetAlias);
|
|
7499
|
-
try {
|
|
7500
|
-
await this._addAliasSubscribe(obj, targetAlias.pattern);
|
|
7501
|
-
} catch (e) {
|
|
7502
|
-
this._logger.error(`${this.namespaceLog} Could not add alias subscription: ${e.message}`);
|
|
7503
|
-
}
|
|
7504
|
-
} else {
|
|
7505
|
-
targetAlias.min = obj.common.min;
|
|
7506
|
-
targetAlias.max = obj.common.max;
|
|
7507
|
-
targetAlias.type = obj.common.type;
|
|
7508
|
-
targetAlias.alias = (0, import_deep_clone.default)(obj.common.alias);
|
|
7509
|
-
}
|
|
7510
|
-
} else {
|
|
7511
|
-
await this._removeAliasSubscribe(sourceId, targetAlias);
|
|
7512
|
-
}
|
|
7513
|
-
}
|
|
7514
|
-
}
|
|
7515
|
-
if (isNewAlias && obj) {
|
|
7516
|
-
for (const aliasPattern of this.aliasPatterns) {
|
|
7517
|
-
const testPattern = aliasPattern.slice(-1) === "*" ? new RegExp(import_js_controller_common.tools.pattern2RegEx(aliasPattern)) : aliasPattern;
|
|
7518
|
-
if (typeof testPattern === "string" && aliasPattern === id || testPattern instanceof RegExp && testPattern.test(id)) {
|
|
7519
|
-
try {
|
|
7520
|
-
await this._addAliasSubscribe(obj, id);
|
|
7521
|
-
} catch (e) {
|
|
7522
|
-
this._logger.warn(`${this.namespaceLog} Could not add alias subscription: ${e.message}`);
|
|
7523
|
-
}
|
|
7524
|
-
break;
|
|
7525
|
-
}
|
|
7526
|
-
}
|
|
7527
|
-
}
|
|
7281
|
+
await this.#alias.handleAliasObjectChange(id, obj);
|
|
7528
7282
|
}
|
|
7529
7283
|
if (id.startsWith("system.adapter.")) {
|
|
7530
7284
|
if (obj?.common?.subscribable) {
|
|
7531
7285
|
const _id = id.substring(15);
|
|
7532
7286
|
if (obj.common.enabled) {
|
|
7533
|
-
|
|
7534
|
-
this.autoSubscribe.push(_id);
|
|
7535
|
-
}
|
|
7287
|
+
this.#subscriptions.addSubscribableInstance(_id);
|
|
7536
7288
|
} else {
|
|
7537
|
-
|
|
7538
|
-
if (pos !== -1) {
|
|
7539
|
-
this.autoSubscribe.splice(pos, 1);
|
|
7540
|
-
}
|
|
7289
|
+
this.#subscriptions.removeSubscribableInstance(_id);
|
|
7541
7290
|
}
|
|
7542
7291
|
}
|
|
7543
7292
|
}
|
|
@@ -7553,8 +7302,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7553
7302
|
this.enums[id] = obj;
|
|
7554
7303
|
}
|
|
7555
7304
|
}
|
|
7556
|
-
},
|
|
7557
|
-
changeUser: (id, obj) => {
|
|
7305
|
+
}, "change"),
|
|
7306
|
+
changeUser: /* @__PURE__ */ __name((id, obj) => {
|
|
7558
7307
|
if (!id) {
|
|
7559
7308
|
this._logger.error(`${this.namespaceLog} change ID is empty: ${JSON.stringify(obj)}`);
|
|
7560
7309
|
return;
|
|
@@ -7578,8 +7327,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7578
7327
|
setImmediate(() => this.emit("objectChange", id, obj));
|
|
7579
7328
|
}
|
|
7580
7329
|
}
|
|
7581
|
-
},
|
|
7582
|
-
changeFileUser: (id, fileName, size) => {
|
|
7330
|
+
}, "changeUser"),
|
|
7331
|
+
changeFileUser: /* @__PURE__ */ __name((id, fileName, size) => {
|
|
7583
7332
|
if (!id) {
|
|
7584
7333
|
this._logger.error(`${this.namespaceLog} change file name is empty`);
|
|
7585
7334
|
return;
|
|
@@ -7588,7 +7337,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7588
7337
|
typeof this._options.fileChange === "function" && setImmediate(() => this._options.fileChange(id, fileName, size));
|
|
7589
7338
|
setImmediate(() => this.emit("fileChange", id, fileName, size));
|
|
7590
7339
|
}
|
|
7591
|
-
}
|
|
7340
|
+
}, "changeFileUser")
|
|
7592
7341
|
});
|
|
7593
7342
|
}
|
|
7594
7343
|
/**
|
|
@@ -7645,7 +7394,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7645
7394
|
if (!this.#states || !this.#objects || this.terminated) {
|
|
7646
7395
|
return;
|
|
7647
7396
|
}
|
|
7648
|
-
this.#states.subscribe(`system.adapter.${this.namespace}.plugins.*`);
|
|
7397
|
+
this.#states.subscribe(`system.adapter.${this.namespace}.plugins.*`).catch((e) => this._logger.error(`${this.namespaceLog} Cannot subscribe to plugins: ${e.message}`));
|
|
7649
7398
|
if (this._options.instance === void 0) {
|
|
7650
7399
|
if (!adapterConfig || !("common" in adapterConfig) || !adapterConfig.common.enabled) {
|
|
7651
7400
|
if (adapterConfig && "common" in adapterConfig && adapterConfig.common.enabled !== void 0) {
|
|
@@ -7721,13 +7470,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7721
7470
|
} else {
|
|
7722
7471
|
this.stop = (params) => this._stop({ ...params, isPause: false });
|
|
7723
7472
|
}
|
|
7724
|
-
this.#states.subscribe(`${import_constants2.SYSTEM_ADAPTER_PREFIX}*.logging`);
|
|
7473
|
+
this.#states.subscribe(`${import_constants2.SYSTEM_ADAPTER_PREFIX}*.logging`).catch((e) => this._logger.error(`${this.namespaceLog} Cannot subscribe to logging: ${e.message}`));
|
|
7725
7474
|
if (typeof this._options.message === "function" && // @ts-expect-error, we should infer correctly that this is an InstanceObject in this case
|
|
7726
7475
|
!(0, import_utils.isMessageboxSupported)(adapterConfig.common)) {
|
|
7727
7476
|
this._logger.error(`${this.namespaceLog} : message handler implemented, but messagebox not enabled. Define common.messagebox in io-package.json for adapter or delete message handler.`);
|
|
7728
7477
|
} else if ((0, import_utils.isMessageboxSupported)(adapterConfig.common)) {
|
|
7729
|
-
this.
|
|
7730
|
-
this.#states.subscribeMessage(`system.adapter.${this.namespace}`);
|
|
7478
|
+
this.#states.subscribeMessage(`system.adapter.${this.namespace}`).catch((e) => this._logger.error(`${this.namespaceLog} Cannot subscribe to messages: ${e.message}`));
|
|
7731
7479
|
}
|
|
7732
7480
|
} else {
|
|
7733
7481
|
this.name = adapterConfig.name || this.name;
|
|
@@ -7739,19 +7487,22 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7739
7487
|
this.host = this.common?.host || import_js_controller_common.tools.getHostName();
|
|
7740
7488
|
}
|
|
7741
7489
|
this.adapterConfig = adapterConfig;
|
|
7742
|
-
this._utils = new import_validator.Validator(this.#objects, this
|
|
7490
|
+
this._utils = new import_validator.Validator(this.#objects, this.namespaceLog, this._logger, this.namespace, this._namespaceRegExp);
|
|
7743
7491
|
this.log = new import_log.Log(this.namespaceLog, this._config.log.level, this._logger);
|
|
7744
7492
|
await this._createInstancesObjects(adapterConfig);
|
|
7745
7493
|
if (this._options.objects) {
|
|
7746
7494
|
this.oObjects = await this.getAdapterObjectsAsync();
|
|
7747
7495
|
await this.subscribeObjectsAsync("*");
|
|
7748
7496
|
}
|
|
7749
|
-
await this.getSystemSecret();
|
|
7750
|
-
const promises = [];
|
|
7497
|
+
const secret = await this.getSystemSecret();
|
|
7751
7498
|
if (Array.isArray(adapterConfig.encryptedNative)) {
|
|
7499
|
+
this._decryptedNativeAttributes = new Array();
|
|
7752
7500
|
for (const attr of adapterConfig.encryptedNative) {
|
|
7753
|
-
|
|
7754
|
-
|
|
7501
|
+
try {
|
|
7502
|
+
(0, import_utils.decryptArray)({ obj: this.config, secret, keys: [attr] });
|
|
7503
|
+
this._decryptedNativeAttributes.push(attr);
|
|
7504
|
+
} catch (e) {
|
|
7505
|
+
this._logger.error(`${this.namespaceLog} Can not decrypt attribute ${attr}: ${e.message}`);
|
|
7755
7506
|
}
|
|
7756
7507
|
}
|
|
7757
7508
|
} else {
|
|
@@ -7760,7 +7511,6 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7760
7511
|
this.SUPPORTED_FEATURES.splice(idx, 1);
|
|
7761
7512
|
}
|
|
7762
7513
|
}
|
|
7763
|
-
await Promise.all(promises);
|
|
7764
7514
|
if (!this.#states) {
|
|
7765
7515
|
return;
|
|
7766
7516
|
}
|
|
@@ -7769,7 +7519,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7769
7519
|
val: this._config.log.level,
|
|
7770
7520
|
ack: true,
|
|
7771
7521
|
from: `system.adapter.${this.namespace}`
|
|
7772
|
-
});
|
|
7522
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set logLevel state: ${e.message}`));
|
|
7773
7523
|
try {
|
|
7774
7524
|
await this.#checkObjectsWarnLimit();
|
|
7775
7525
|
} catch (e) {
|
|
@@ -7792,15 +7542,18 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7792
7542
|
ack: true,
|
|
7793
7543
|
from: id,
|
|
7794
7544
|
val: !!this.startedInCompactMode
|
|
7795
|
-
});
|
|
7545
|
+
}).catch((e) => this._logger.error(`${this.namespaceLog} Cannot set compactMode state: ${e.message}`));
|
|
7796
7546
|
this.outputCount++;
|
|
7797
7547
|
if (this.startedInCompactMode) {
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
this.#states.setState(`${id}.
|
|
7802
|
-
this.#states.setState(`${id}.
|
|
7803
|
-
this.#states.setState(`${id}.
|
|
7548
|
+
const onErr = /* @__PURE__ */ __name((e) => {
|
|
7549
|
+
this._logger.error(`${this.namespaceLog} Cannot reset compact metric: ${e.message}`);
|
|
7550
|
+
}, "onErr");
|
|
7551
|
+
this.#states.setState(`${id}.cpu`, { ack: true, from: id, val: 0 }).catch(onErr);
|
|
7552
|
+
this.#states.setState(`${id}.cputime`, { ack: true, from: id, val: 0 }).catch(onErr);
|
|
7553
|
+
this.#states.setState(`${id}.memRss`, { val: 0, ack: true, from: id }).catch(onErr);
|
|
7554
|
+
this.#states.setState(`${id}.memHeapTotal`, { val: 0, ack: true, from: id }).catch(onErr);
|
|
7555
|
+
this.#states.setState(`${id}.memHeapUsed`, { val: 0, ack: true, from: id }).catch(onErr);
|
|
7556
|
+
this.#states.setState(`${id}.eventLoopLag`, { val: 0, ack: true, from: id }).catch(onErr);
|
|
7804
7557
|
this.outputCount += 6;
|
|
7805
7558
|
} else {
|
|
7806
7559
|
import_js_controller_common.tools.measureEventLoopLag(1e3, (lag) => {
|
|
@@ -7821,7 +7574,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7821
7574
|
this._logger.debug(`${this.namespaceLog} Schedule restart: ${adapterConfig.common.restartSchedule}`);
|
|
7822
7575
|
this._restartScheduleJob = this._schedule.scheduleJob(adapterConfig.common.restartSchedule, () => {
|
|
7823
7576
|
this._logger.info(`${this.namespaceLog} Scheduled restart.`);
|
|
7824
|
-
this._stop({ isPause: false, isScheduled: true });
|
|
7577
|
+
this._stop({ isPause: false, isScheduled: true }).catch((e) => this._logger.error(`${this.namespaceLog} Cannot stop adapter: ${e.message}`));
|
|
7825
7578
|
});
|
|
7826
7579
|
}
|
|
7827
7580
|
}
|
|
@@ -7849,12 +7602,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7849
7602
|
_callReadyHandler() {
|
|
7850
7603
|
if (this._config.isInstall && (typeof this._options.install === "function" || this.listeners("install").length)) {
|
|
7851
7604
|
if (typeof this._options.install === "function") {
|
|
7852
|
-
this._options.install();
|
|
7605
|
+
Promise.resolve(this._options.install()).catch((e) => this._logger.error(`${this.namespaceLog} Error in install handler: ${e.message}`));
|
|
7853
7606
|
}
|
|
7854
7607
|
this.emit("install");
|
|
7855
7608
|
} else {
|
|
7856
7609
|
if (typeof this._options.ready === "function") {
|
|
7857
|
-
this._options.ready();
|
|
7610
|
+
Promise.resolve(this._options.ready()).catch((e) => this._logger.error(`${this.namespaceLog} Error in ready handler: ${e.message}`));
|
|
7858
7611
|
}
|
|
7859
7612
|
this.emit("ready");
|
|
7860
7613
|
}
|
|
@@ -7900,7 +7653,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7900
7653
|
isScheduled: false,
|
|
7901
7654
|
exitCode: import_js_controller_common.EXIT_CODES.UNCAUGHT_EXCEPTION,
|
|
7902
7655
|
updateAliveState: false
|
|
7903
|
-
});
|
|
7656
|
+
}).catch((err2) => this._logger.error(`${this.namespaceLog} Cannot stop adapter: ${err2.message}`));
|
|
7904
7657
|
} catch (e) {
|
|
7905
7658
|
this._logger.error(`${this.namespaceLog} exception by stop: ${e ? e.message : e}`);
|
|
7906
7659
|
}
|
|
@@ -7973,7 +7726,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
7973
7726
|
});
|
|
7974
7727
|
}
|
|
7975
7728
|
return new Promise((resolve) => {
|
|
7976
|
-
this._extendObjects(objs, resolve);
|
|
7729
|
+
return this._extendObjects(objs, resolve);
|
|
7977
7730
|
});
|
|
7978
7731
|
}
|
|
7979
7732
|
/**
|
|
@@ -8023,7 +7776,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
8023
7776
|
return this.#states.setState(id, state);
|
|
8024
7777
|
}
|
|
8025
7778
|
async _extendObjects(tasks, callback) {
|
|
8026
|
-
if (!tasks
|
|
7779
|
+
if (!tasks?.length) {
|
|
8027
7780
|
return import_js_controller_common.tools.maybeCallback(callback);
|
|
8028
7781
|
}
|
|
8029
7782
|
const task = tasks.shift();
|
|
@@ -8130,7 +7883,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
8130
7883
|
* Initializes the adapter
|
|
8131
7884
|
*/
|
|
8132
7885
|
async _init() {
|
|
8133
|
-
const _initDBs = () => {
|
|
7886
|
+
const _initDBs = /* @__PURE__ */ __name(() => {
|
|
8134
7887
|
this._initObjects(() => {
|
|
8135
7888
|
if (this.inited) {
|
|
8136
7889
|
this._logger.warn(`${this.namespaceLog} Reconnection to DB.`);
|
|
@@ -8139,7 +7892,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
8139
7892
|
this.inited = true;
|
|
8140
7893
|
this._initStates(() => this._prepareInitAdapter());
|
|
8141
7894
|
});
|
|
8142
|
-
};
|
|
7895
|
+
}, "_initDBs");
|
|
8143
7896
|
if (import_fs_extra.default.existsSync(`${this.adapterDir}/package.json`)) {
|
|
8144
7897
|
this.pack = import_fs_extra.default.readJSONSync(`${this.adapterDir}/package.json`);
|
|
8145
7898
|
} else {
|