@iobroker/js-controller-adapter 7.0.2 → 7.0.3
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.js +2 -1
- package/build/cjs/index.js.map +2 -2
- package/build/cjs/lib/_Types.d.ts +0 -2
- package/build/cjs/lib/adapter/adapter.d.ts +3 -6
- package/build/cjs/lib/adapter/adapter.js +1537 -14
- package/build/cjs/lib/adapter/adapter.js.map +3 -3
- package/build/cjs/lib/adapter/constants.js +17 -0
- package/build/cjs/lib/adapter/constants.js.map +1 -1
- package/build/cjs/lib/adapter/log.d.ts +0 -1
- package/build/cjs/lib/adapter/log.js +6 -0
- package/build/cjs/lib/adapter/log.js.map +1 -1
- package/build/cjs/lib/adapter/userInterfaceMessagingController.d.ts +0 -2
- package/build/cjs/lib/adapter/userInterfaceMessagingController.js +41 -0
- package/build/cjs/lib/adapter/userInterfaceMessagingController.js.map +1 -1
- package/build/cjs/lib/adapter/utils.js +4 -0
- package/build/cjs/lib/adapter/utils.js.map +1 -1
- package/build/cjs/lib/adapter/validator.d.ts +0 -2
- package/build/cjs/lib/adapter/validator.js +95 -0
- package/build/cjs/lib/adapter/validator.js.map +1 -1
- package/build/esm/index.d.ts.map +1 -1
- package/build/esm/index.js +1 -0
- package/build/esm/index.js.map +1 -1
- package/build/esm/lib/_Types.d.ts +0 -2
- package/build/esm/lib/_Types.d.ts.map +1 -1
- package/build/esm/lib/adapter/adapter.d.ts +3 -6
- package/build/esm/lib/adapter/adapter.d.ts.map +1 -1
- package/build/esm/lib/adapter/adapter.js +4 -4
- package/build/esm/lib/adapter/adapter.js.map +1 -1
- package/build/esm/lib/adapter/log.d.ts +0 -1
- package/build/esm/lib/adapter/log.d.ts.map +1 -1
- package/build/esm/lib/adapter/userInterfaceMessagingController.d.ts +0 -2
- package/build/esm/lib/adapter/userInterfaceMessagingController.d.ts.map +1 -1
- package/build/esm/lib/adapter/validator.d.ts +0 -2
- package/build/esm/lib/adapter/validator.d.ts.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +10 -10
|
@@ -18,6 +18,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
return to;
|
|
19
19
|
};
|
|
20
20
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
25
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
26
|
mod
|
|
23
27
|
));
|
|
@@ -28,6 +32,7 @@ __export(adapter_exports, {
|
|
|
28
32
|
AdapterClass: () => AdapterClass
|
|
29
33
|
});
|
|
30
34
|
module.exports = __toCommonJS(adapter_exports);
|
|
35
|
+
var __import_meta_url = typeof document === "undefined" ? new (require("url".replace("", ""))).URL("file:" + __filename).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
|
|
31
36
|
var import_node_net = __toESM(require("node:net"), 1);
|
|
32
37
|
var import_fs_extra = __toESM(require("fs-extra"), 1);
|
|
33
38
|
var import_node_os = __toESM(require("node:os"), 1);
|
|
@@ -49,20 +54,26 @@ var import_constants = require("../../lib/adapter/constants.js");
|
|
|
49
54
|
var import_userInterfaceMessagingController = require("../../lib/adapter/userInterfaceMessagingController.js");
|
|
50
55
|
var import_constants2 = require("@iobroker/js-controller-common-db/constants");
|
|
51
56
|
var url = __toESM(require("node:url"), 1);
|
|
52
|
-
const import_meta = {};
|
|
53
57
|
const controllerVersion = import_package.default.version;
|
|
54
58
|
const { FORBIDDEN_CHARS } = import_js_controller_common.tools;
|
|
55
|
-
const thisDir = url.fileURLToPath(new URL(".",
|
|
59
|
+
const thisDir = url.fileURLToPath(new URL(".", __import_meta_url || `file://${__filename}`));
|
|
56
60
|
import_js_controller_common.tools.ensureDNSOrder();
|
|
57
61
|
class AdapterClass extends import_node_events.EventEmitter {
|
|
62
|
+
/** Cache of all deprecations which have already been transmitted */
|
|
58
63
|
reportedDeprecations = /* @__PURE__ */ new Set();
|
|
64
|
+
/** Instance to access states DB */
|
|
59
65
|
#states;
|
|
66
|
+
/** Instance to access objects DB */
|
|
60
67
|
#objects;
|
|
68
|
+
/** States DB constructor */
|
|
61
69
|
States;
|
|
70
|
+
/** Objects DB constructor */
|
|
62
71
|
Objects;
|
|
72
|
+
/** Contents of iobroker.json */
|
|
63
73
|
_config;
|
|
64
74
|
_options;
|
|
65
75
|
startedInCompactMode;
|
|
76
|
+
/** List of instances which want our logs */
|
|
66
77
|
logList = /* @__PURE__ */ new Set();
|
|
67
78
|
aliases = /* @__PURE__ */ new Map();
|
|
68
79
|
aliasPatterns = /* @__PURE__ */ new Set();
|
|
@@ -70,8 +81,17 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
70
81
|
eventLoopLags = [];
|
|
71
82
|
overwriteLogLevel = false;
|
|
72
83
|
adapterReady = false;
|
|
84
|
+
/** Callbacks from sendTo */
|
|
73
85
|
messageCallbacks = /* @__PURE__ */ new Map();
|
|
86
|
+
/**
|
|
87
|
+
* Contains a live cache of the adapter's states.
|
|
88
|
+
* NOTE: This is only defined if the adapter was initialized with the option states: true.
|
|
89
|
+
*/
|
|
74
90
|
oStates;
|
|
91
|
+
/**
|
|
92
|
+
* Contains a live cache of the adapter's objects.
|
|
93
|
+
* NOTE: This is only defined if the adapter was initialized with the option objects: true.
|
|
94
|
+
*/
|
|
75
95
|
oObjects;
|
|
76
96
|
_stopInProgress = false;
|
|
77
97
|
_callbackId = 1;
|
|
@@ -79,6 +99,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
79
99
|
_timers = /* @__PURE__ */ new Set();
|
|
80
100
|
_intervals = /* @__PURE__ */ new Set();
|
|
81
101
|
_delays = /* @__PURE__ */ new Set();
|
|
102
|
+
/** For ease of use the log property is always defined, however it is only available after `ready` has been called. */
|
|
82
103
|
log;
|
|
83
104
|
performStrictObjectChecks;
|
|
84
105
|
_logger;
|
|
@@ -88,13 +109,20 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
88
109
|
namespace;
|
|
89
110
|
name;
|
|
90
111
|
_systemSecret;
|
|
112
|
+
/** Whether the adapter has already terminated */
|
|
91
113
|
terminated = false;
|
|
114
|
+
/** The cache of usernames */
|
|
92
115
|
usernames = {};
|
|
116
|
+
/** A RegExp to test for forbidden chars in object IDs */
|
|
93
117
|
FORBIDDEN_CHARS = FORBIDDEN_CHARS;
|
|
94
118
|
inputCount = 0;
|
|
95
119
|
outputCount = 0;
|
|
120
|
+
/** The cache of users */
|
|
96
121
|
users = {};
|
|
122
|
+
// todo
|
|
123
|
+
/** The cache of user groups */
|
|
97
124
|
groups = {};
|
|
125
|
+
/** An array of instances, that support auto subscribe */
|
|
98
126
|
autoSubscribe = [];
|
|
99
127
|
defaultHistory = null;
|
|
100
128
|
pluginHandler;
|
|
@@ -102,19 +130,29 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
102
130
|
getPortRunning = null;
|
|
103
131
|
_namespaceRegExp;
|
|
104
132
|
instance;
|
|
133
|
+
// @ts-expect-error decide how to handle it
|
|
105
134
|
_utils;
|
|
135
|
+
/** contents of io-package.json */
|
|
106
136
|
adapterConfig;
|
|
107
137
|
connected;
|
|
108
138
|
adapterDir;
|
|
139
|
+
/** contents of package.json */
|
|
109
140
|
pack;
|
|
141
|
+
/** contents of io-package.json */
|
|
110
142
|
ioPack;
|
|
111
143
|
_initializeTimeout;
|
|
112
144
|
inited;
|
|
145
|
+
/** contents of iobroker.json if required via AdapterOptions */
|
|
113
146
|
systemConfig;
|
|
147
|
+
/** the configured date format of system.config, only available if requested via AdapterOptions `useFormatDate` */
|
|
114
148
|
dateFormat;
|
|
149
|
+
/** if float comma instead of dot is used, only available if requested via AdapterOptions `useFormatDate` */
|
|
115
150
|
isFloatComma;
|
|
151
|
+
/** configured language of system.config, only available if requested via AdapterOptions `useFormatDate` */
|
|
116
152
|
language;
|
|
153
|
+
/** longitude configured in system.config, only available if requested via AdapterOptions `useFormatDate`*/
|
|
117
154
|
longitude;
|
|
155
|
+
/** latitude configured in system.config, only available if requested via AdapterOptions `useFormatDate`*/
|
|
118
156
|
latitude;
|
|
119
157
|
_defaultObjs;
|
|
120
158
|
_aliasObjectsSubscribed;
|
|
@@ -122,19 +160,32 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
122
160
|
host;
|
|
123
161
|
common;
|
|
124
162
|
mboxSubscribed;
|
|
163
|
+
/** Stop the adapter */
|
|
125
164
|
stop;
|
|
126
165
|
version;
|
|
166
|
+
/** Stop the adapter only defined in compact, not for external usage */
|
|
127
167
|
kill;
|
|
128
168
|
processLog;
|
|
169
|
+
/**
|
|
170
|
+
* Start or stop subscribing to log messages
|
|
171
|
+
* The method is only available if logTransporter is active via io-pack or adapter options
|
|
172
|
+
* Note, that stopping will stop after 10 seconds, not immediately
|
|
173
|
+
*
|
|
174
|
+
* @param isActive - if log subscription should be activated or deactivated
|
|
175
|
+
* @param options - options passed to setState e.g. user permissions
|
|
176
|
+
*/
|
|
129
177
|
requireLog;
|
|
130
178
|
logOffTimer;
|
|
131
179
|
logRequired;
|
|
132
180
|
patterns;
|
|
133
181
|
statesConnectedTime;
|
|
182
|
+
/** Constants for frequent use in adapters */
|
|
134
183
|
constants = {
|
|
135
184
|
STATE_QUALITY: import_constants.STATE_QUALITY
|
|
136
185
|
};
|
|
186
|
+
/** Features supported by the running instance */
|
|
137
187
|
SUPPORTED_FEATURES = (0, import_utils.getSupportedFeatures)();
|
|
188
|
+
/** Controller for messaging related functionality */
|
|
138
189
|
uiMessagingController;
|
|
139
190
|
constructor(options) {
|
|
140
191
|
super();
|
|
@@ -327,9 +378,20 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
327
378
|
this.setExecutableCapabilities = import_js_controller_common.tools.setExecutableCapabilities;
|
|
328
379
|
this._init();
|
|
329
380
|
}
|
|
381
|
+
/**
|
|
382
|
+
* Get the adapter scoped package identifier of a node module
|
|
383
|
+
*
|
|
384
|
+
* @param moduleName name of the node module
|
|
385
|
+
*/
|
|
330
386
|
getAdapterScopedPackageIdentifier(moduleName) {
|
|
331
387
|
return (0, import_utils.getAdapterScopedPackageIdentifier)({ moduleName, namespace: this.namespace });
|
|
332
388
|
}
|
|
389
|
+
/**
|
|
390
|
+
* Install specified npm module
|
|
391
|
+
*
|
|
392
|
+
* @param moduleNameOrUrl name of the node module or GitHub url which can be passed to `npm install`
|
|
393
|
+
* @param options version information
|
|
394
|
+
*/
|
|
333
395
|
installNodeModule(moduleNameOrUrl, options) {
|
|
334
396
|
import_validator.Validator.assertString(moduleNameOrUrl, "moduleNameOrUrl");
|
|
335
397
|
import_validator.Validator.assertObject(options, "options");
|
|
@@ -346,19 +408,39 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
346
408
|
const packageIdentifier = isUrl ? moduleNameOrUrl : `npm:${moduleName}@${version}`;
|
|
347
409
|
return import_js_controller_common.tools.installNodeModule(`${internalModuleName}@${packageIdentifier}`);
|
|
348
410
|
}
|
|
411
|
+
/**
|
|
412
|
+
* List all additional installed node modules from this adapter
|
|
413
|
+
*/
|
|
349
414
|
listInstalledNodeModules() {
|
|
350
415
|
return (0, import_utils.listInstalledNodeModules)(this.namespace);
|
|
351
416
|
}
|
|
417
|
+
/**
|
|
418
|
+
* Uninstall specified npm module
|
|
419
|
+
*
|
|
420
|
+
* @param moduleName name of the node module
|
|
421
|
+
*/
|
|
352
422
|
uninstallNodeModule(moduleName) {
|
|
353
423
|
import_validator.Validator.assertString(moduleName, "moduleName");
|
|
354
424
|
const internalModuleName = (0, import_utils.getAdapterScopedPackageIdentifier)({ moduleName, namespace: this.namespace });
|
|
355
425
|
return import_js_controller_common.tools.uninstallNodeModule(internalModuleName);
|
|
356
426
|
}
|
|
427
|
+
/**
|
|
428
|
+
* Import a node module which has been installed via `installNodeModule`
|
|
429
|
+
*
|
|
430
|
+
* @param moduleName name of the node module
|
|
431
|
+
* @returns the required node module
|
|
432
|
+
*/
|
|
357
433
|
importNodeModule(moduleName) {
|
|
358
434
|
import_validator.Validator.assertString(moduleName, "moduleName");
|
|
359
435
|
const internalModuleName = (0, import_utils.getAdapterScopedPackageIdentifier)({ moduleName, namespace: this.namespace });
|
|
360
436
|
return import(internalModuleName);
|
|
361
437
|
}
|
|
438
|
+
/**
|
|
439
|
+
* Decrypt the password/value with given key
|
|
440
|
+
*
|
|
441
|
+
* @param secretVal to use for decrypt (or value if only one parameter is given)
|
|
442
|
+
* @param value value to decrypt (if secret is provided)
|
|
443
|
+
*/
|
|
362
444
|
decrypt(secretVal, value) {
|
|
363
445
|
if (value === void 0) {
|
|
364
446
|
value = secretVal;
|
|
@@ -368,6 +450,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
368
450
|
import_validator.Validator.assertString(value, "value");
|
|
369
451
|
return import_js_controller_common.tools.decrypt(secretVal, value);
|
|
370
452
|
}
|
|
453
|
+
/**
|
|
454
|
+
* Encrypt the password/value with given key
|
|
455
|
+
*
|
|
456
|
+
* @param secretVal to use for encrypting (or value if only one parameter is given)
|
|
457
|
+
* @param [value] value to encrypt (if secret is provided)
|
|
458
|
+
*/
|
|
371
459
|
encrypt(secretVal, value) {
|
|
372
460
|
if (value === void 0) {
|
|
373
461
|
value = secretVal;
|
|
@@ -377,11 +465,13 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
377
465
|
import_validator.Validator.assertString(value, "value");
|
|
378
466
|
return import_js_controller_common.tools.encrypt(secretVal, value);
|
|
379
467
|
}
|
|
468
|
+
// unknown guard implementation
|
|
380
469
|
getSession(id, callback) {
|
|
381
470
|
import_validator.Validator.assertString(id, "id");
|
|
382
471
|
import_validator.Validator.assertCallback(callback, "callback");
|
|
383
472
|
return this._getSession({ id, callback });
|
|
384
473
|
}
|
|
474
|
+
// actual implementation
|
|
385
475
|
_getSession(options) {
|
|
386
476
|
if (!this.#states) {
|
|
387
477
|
this._logger.info(`${this.namespaceLog} getSession not processed because States database not connected`);
|
|
@@ -389,6 +479,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
389
479
|
}
|
|
390
480
|
this.#states.getSession(options.id, options.callback);
|
|
391
481
|
}
|
|
482
|
+
// unknown implementation guards
|
|
392
483
|
setSession(id, ttl, data, callback) {
|
|
393
484
|
import_validator.Validator.assertString(id, "id");
|
|
394
485
|
import_validator.Validator.assertOptionalCallback(callback, "callback");
|
|
@@ -396,6 +487,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
396
487
|
import_validator.Validator.assertObject(data, "data");
|
|
397
488
|
return this._setSession({ id, ttl, data, callback });
|
|
398
489
|
}
|
|
490
|
+
// actual implementation
|
|
399
491
|
_setSession(options) {
|
|
400
492
|
if (!this.#states) {
|
|
401
493
|
this._logger.info(`${this.namespaceLog} setSession not processed because States database not connected`);
|
|
@@ -424,6 +516,14 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
424
516
|
return [];
|
|
425
517
|
}
|
|
426
518
|
}
|
|
519
|
+
/**
|
|
520
|
+
* stops the execution of adapter, but not disables it.
|
|
521
|
+
*
|
|
522
|
+
* Sometimes, the adapter must be stopped if some libraries are missing.
|
|
523
|
+
*
|
|
524
|
+
* @param reason optional termination description
|
|
525
|
+
* @param exitCode optional exit code
|
|
526
|
+
*/
|
|
427
527
|
terminate(reason, exitCode) {
|
|
428
528
|
if (this.terminated) {
|
|
429
529
|
return;
|
|
@@ -480,6 +580,23 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
480
580
|
}
|
|
481
581
|
}, 500);
|
|
482
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* Helper function to find next free port
|
|
585
|
+
*
|
|
586
|
+
* Looks for first free TCP port starting with given one:
|
|
587
|
+
* ```js
|
|
588
|
+
* adapter.getPort(8081, function (port) {
|
|
589
|
+
* adapter.log.debug('Following port is free: ' + port);
|
|
590
|
+
* });
|
|
591
|
+
* ```
|
|
592
|
+
*
|
|
593
|
+
* @param port port number to start the search for free port
|
|
594
|
+
* @param [host] optional hostname for the port search
|
|
595
|
+
* @param callback return result
|
|
596
|
+
* ```js
|
|
597
|
+
* function (port) {}
|
|
598
|
+
* ```
|
|
599
|
+
*/
|
|
483
600
|
getPort(port, host, callback) {
|
|
484
601
|
if (!port) {
|
|
485
602
|
throw new Error("adapterGetPort: no port");
|
|
@@ -519,12 +636,38 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
519
636
|
setImmediate(() => this.getPort(options.port + 1, options.host, options.callback));
|
|
520
637
|
}
|
|
521
638
|
}
|
|
639
|
+
/**
|
|
640
|
+
* Method to check for available Features for adapter development
|
|
641
|
+
*
|
|
642
|
+
* Use it like ...
|
|
643
|
+
* ```js
|
|
644
|
+
* if (adapter.supportsFeature && adapter.supportsFeature('ALIAS')) {
|
|
645
|
+
* ...
|
|
646
|
+
* }
|
|
647
|
+
* ```
|
|
648
|
+
|
|
649
|
+
* @param featureName the name of the feature to check
|
|
650
|
+
* @returns true/false if the feature is in the list of supported features
|
|
651
|
+
*/
|
|
522
652
|
supportsFeature(featureName) {
|
|
523
653
|
if (typeof featureName === "string") {
|
|
524
654
|
return this.SUPPORTED_FEATURES.includes(featureName);
|
|
525
655
|
}
|
|
526
656
|
return false;
|
|
527
657
|
}
|
|
658
|
+
/**
|
|
659
|
+
* validates user and password
|
|
660
|
+
*
|
|
661
|
+
* @param user user name as text
|
|
662
|
+
* @param pw password as text
|
|
663
|
+
* @param [options] optional user context
|
|
664
|
+
* @param callback return result
|
|
665
|
+
* ```js
|
|
666
|
+
* function (result) {
|
|
667
|
+
* if (result) adapter.log.debug('User is valid');
|
|
668
|
+
* }
|
|
669
|
+
* ```
|
|
670
|
+
*/
|
|
528
671
|
checkPassword(user, pw, options, callback) {
|
|
529
672
|
if (typeof options === "function") {
|
|
530
673
|
callback = options;
|
|
@@ -569,6 +712,9 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
569
712
|
});
|
|
570
713
|
});
|
|
571
714
|
}
|
|
715
|
+
/**
|
|
716
|
+
* This method update the cached values in `this.usernames`
|
|
717
|
+
*/
|
|
572
718
|
async _updateUsernameCache() {
|
|
573
719
|
try {
|
|
574
720
|
const obj = await this.getObjectListAsync({ startkey: "system.user.", endkey: "system.user.\u9999" });
|
|
@@ -584,6 +730,11 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
584
730
|
throw new Error(`Could not update user cache: ${e.message}`);
|
|
585
731
|
}
|
|
586
732
|
}
|
|
733
|
+
/**
|
|
734
|
+
* Return ID of given username
|
|
735
|
+
*
|
|
736
|
+
* @param username - name of the user
|
|
737
|
+
*/
|
|
587
738
|
getUserID(username) {
|
|
588
739
|
import_validator.Validator.assertString(username, "username");
|
|
589
740
|
return this._getUserID({ username });
|
|
@@ -602,6 +753,19 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
602
753
|
}
|
|
603
754
|
return this.usernames[options.username].id;
|
|
604
755
|
}
|
|
756
|
+
/**
|
|
757
|
+
* sets the user's password
|
|
758
|
+
*
|
|
759
|
+
* @param user user name as text
|
|
760
|
+
* @param pw password as text
|
|
761
|
+
* @param [options] optional user context
|
|
762
|
+
* @param [callback] return result
|
|
763
|
+
* ```js
|
|
764
|
+
* function (err) {
|
|
765
|
+
* if (err) adapter.log.error('Cannot set password: ' + err);
|
|
766
|
+
* }
|
|
767
|
+
* ```
|
|
768
|
+
*/
|
|
605
769
|
setPassword(user, pw, options, callback) {
|
|
606
770
|
if (typeof options === "function") {
|
|
607
771
|
callback = options;
|
|
@@ -660,6 +824,21 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
660
824
|
}
|
|
661
825
|
});
|
|
662
826
|
}
|
|
827
|
+
/**
|
|
828
|
+
* returns if user exists and is in the group
|
|
829
|
+
*
|
|
830
|
+
* This function used mostly internally and the adapter developer do not require it.
|
|
831
|
+
*
|
|
832
|
+
* @param user user name as text
|
|
833
|
+
* @param group group name
|
|
834
|
+
* @param [options] optional user context
|
|
835
|
+
* @param callback return result
|
|
836
|
+
* ```js
|
|
837
|
+
* function (result) {
|
|
838
|
+
* if (result) adapter.log.debug('User exists and in the group');
|
|
839
|
+
* }
|
|
840
|
+
* ```
|
|
841
|
+
*/
|
|
663
842
|
checkGroup(user, group, options, callback) {
|
|
664
843
|
user = user || "";
|
|
665
844
|
if (typeof options === "function") {
|
|
@@ -709,6 +888,99 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
709
888
|
});
|
|
710
889
|
});
|
|
711
890
|
}
|
|
891
|
+
/**
|
|
892
|
+
* get the user permissions
|
|
893
|
+
*
|
|
894
|
+
* This function used mostly internally and the adapter developer do not require it.
|
|
895
|
+
* The function reads permissions of user's groups (it can be more than one) and merge permissions together
|
|
896
|
+
*
|
|
897
|
+
* @param user user name as text
|
|
898
|
+
* @param commandsPermissions object that describes the access rights like
|
|
899
|
+
* ```js
|
|
900
|
+
* // static information
|
|
901
|
+
* var commandsPermissions = {
|
|
902
|
+
* getObject: {type: 'object', operation: 'read'},
|
|
903
|
+
* getObjects: {type: 'object', operation: 'list'},
|
|
904
|
+
* getObjectView: {type: 'object', operation: 'list'},
|
|
905
|
+
* setObject: {type: 'object', operation: 'write'},
|
|
906
|
+
* subscribeObjects: {type: 'object', operation: 'read'},
|
|
907
|
+
* unsubscribeObjects: {type: 'object', operation: 'read'},
|
|
908
|
+
* subscribeFiles: {type: 'object', operation: 'read'},
|
|
909
|
+
* unsubscribeFiles: {type: 'object', operation: 'read'},
|
|
910
|
+
*
|
|
911
|
+
* getStates: {type: 'state', operation: 'list'},
|
|
912
|
+
* getState: {type: 'state', operation: 'read'},
|
|
913
|
+
* setState: {type: 'state', operation: 'write'},
|
|
914
|
+
* getStateHistory: {type: 'state', operation: 'read'},
|
|
915
|
+
* subscribe: {type: 'state', operation: 'read'},
|
|
916
|
+
* unsubscribe: {type: 'state', operation: 'read'},
|
|
917
|
+
* getVersion: {type: '', operation: ''},
|
|
918
|
+
*
|
|
919
|
+
* httpGet: {type: 'other', operation: 'http'},
|
|
920
|
+
* sendTo: {type: 'other', operation: 'sendto'},
|
|
921
|
+
* sendToHost: {type: 'other', operation: 'sendto'},
|
|
922
|
+
*
|
|
923
|
+
* readFile: {type: 'file', operation: 'read'},
|
|
924
|
+
* readFile64: {type: 'file', operation: 'read'},
|
|
925
|
+
* writeFile: {type: 'file', operation: 'write'},
|
|
926
|
+
* writeFile64: {type: 'file', operation: 'write'},
|
|
927
|
+
* unlink: {type: 'file', operation: 'delete'},
|
|
928
|
+
* rename: {type: 'file', operation: 'write'},
|
|
929
|
+
* mkdir: {type: 'file', operation: 'write'},
|
|
930
|
+
* readDir: {type: 'file', operation: 'list'},
|
|
931
|
+
* chmodFile: {type: 'file', operation: 'write'},
|
|
932
|
+
* chownFile: {type: 'file', operation: 'write'},
|
|
933
|
+
*
|
|
934
|
+
* authEnabled: {type: '', operation: ''},
|
|
935
|
+
* disconnect: {type: '', operation: ''},
|
|
936
|
+
* listPermissions: {type: '', operation: ''},
|
|
937
|
+
* getUserPermissions: {type: 'object', operation: 'read'}
|
|
938
|
+
* };
|
|
939
|
+
* ```
|
|
940
|
+
* @param [options] optional user context
|
|
941
|
+
* @param [callback] return result
|
|
942
|
+
* ```js
|
|
943
|
+
* function (acl) {
|
|
944
|
+
* // Access control object for admin looks like:
|
|
945
|
+
* // {
|
|
946
|
+
* // file: {
|
|
947
|
+
* // read: true,
|
|
948
|
+
* // write: true,
|
|
949
|
+
* // 'delete': true,
|
|
950
|
+
* // create: true,
|
|
951
|
+
* // list: true
|
|
952
|
+
* // },
|
|
953
|
+
* // object: {
|
|
954
|
+
* // read: true,
|
|
955
|
+
* // write: true,
|
|
956
|
+
* // 'delete': true,
|
|
957
|
+
* // list: true
|
|
958
|
+
* // },
|
|
959
|
+
* // state: {
|
|
960
|
+
* // read: true,
|
|
961
|
+
* // write: true,
|
|
962
|
+
* // 'delete': true,
|
|
963
|
+
* // create: true,
|
|
964
|
+
* // list: true
|
|
965
|
+
* // },
|
|
966
|
+
* // user: 'admin',
|
|
967
|
+
* // users: {
|
|
968
|
+
* // read: true,
|
|
969
|
+
* // write: true,
|
|
970
|
+
* // create: true,
|
|
971
|
+
* // 'delete': true,
|
|
972
|
+
* // list: true
|
|
973
|
+
* // },
|
|
974
|
+
* // other: {
|
|
975
|
+
* // execute: true,
|
|
976
|
+
* // http: true,
|
|
977
|
+
* // sendto: true
|
|
978
|
+
* // },
|
|
979
|
+
* // groups: ['administrator'] // can be more than one
|
|
980
|
+
* // }
|
|
981
|
+
* }
|
|
982
|
+
* ```
|
|
983
|
+
*/
|
|
712
984
|
calculatePermissions(user, commandsPermissions, options, callback) {
|
|
713
985
|
user = user || "";
|
|
714
986
|
if (typeof options === "function") {
|
|
@@ -773,6 +1045,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
773
1045
|
create: true,
|
|
774
1046
|
list: true
|
|
775
1047
|
},
|
|
1048
|
+
// @ts-expect-error create is missing
|
|
776
1049
|
object: {
|
|
777
1050
|
read: true,
|
|
778
1051
|
write: true,
|
|
@@ -830,6 +1103,11 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
830
1103
|
return import_js_controller_common.tools.maybeCallback(options.callback, acl);
|
|
831
1104
|
});
|
|
832
1105
|
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Stop an instance gracefully
|
|
1108
|
+
*
|
|
1109
|
+
* @param options information about the stoppage
|
|
1110
|
+
*/
|
|
833
1111
|
async _stop(options = {}) {
|
|
834
1112
|
const { isPause, isScheduled, reason } = options;
|
|
835
1113
|
let { exitCode, updateAliveState } = options;
|
|
@@ -911,6 +1189,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
911
1189
|
}, this.common?.stopTimeout || 500);
|
|
912
1190
|
}
|
|
913
1191
|
}
|
|
1192
|
+
/**
|
|
1193
|
+
* Reads the file certificate from a given path and adds a file watcher to restart adapter on cert changes
|
|
1194
|
+
* if a cert is passed it is returned as it is
|
|
1195
|
+
*
|
|
1196
|
+
* @param cert cert or path to cert
|
|
1197
|
+
*/
|
|
914
1198
|
_readFileCertificate(cert) {
|
|
915
1199
|
if (typeof cert === "string") {
|
|
916
1200
|
try {
|
|
@@ -928,6 +1212,25 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
928
1212
|
}
|
|
929
1213
|
return cert;
|
|
930
1214
|
}
|
|
1215
|
+
/**
|
|
1216
|
+
* returns SSL certificates by name
|
|
1217
|
+
*
|
|
1218
|
+
* This function returns SSL certificates (private key, public cert and chained certificate).
|
|
1219
|
+
* Names are defined in the system's configuration in admin, e.g. "defaultPrivate", "defaultPublic".
|
|
1220
|
+
* The result can be directly used for creation of https server.
|
|
1221
|
+
*
|
|
1222
|
+
* @param [publicName] public certificate name
|
|
1223
|
+
* @param [privateName] private certificate name
|
|
1224
|
+
* @param [chainedName] optional chained certificate name
|
|
1225
|
+
* @param callback return result
|
|
1226
|
+
* ```js
|
|
1227
|
+
* function (err, certs, letsEncrypt) {
|
|
1228
|
+
* adapter.log.debug('private key: ' + certs.key);
|
|
1229
|
+
* adapter.log.debug('public cert: ' + certs.cert);
|
|
1230
|
+
* adapter.log.debug('chained cert: ' + certs.ca);
|
|
1231
|
+
* }
|
|
1232
|
+
* ```
|
|
1233
|
+
*/
|
|
931
1234
|
getCertificates(publicName, privateName, chainedName, callback) {
|
|
932
1235
|
if (typeof publicName === "function") {
|
|
933
1236
|
callback = publicName;
|
|
@@ -995,6 +1298,10 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
995
1298
|
ca
|
|
996
1299
|
}, obj.native.letsEncrypt);
|
|
997
1300
|
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Restarts an instance of the adapter.
|
|
1303
|
+
*
|
|
1304
|
+
*/
|
|
998
1305
|
restart() {
|
|
999
1306
|
if (this.stop) {
|
|
1000
1307
|
this._logger.warn(`${this.namespaceLog} Restart initiated`);
|
|
@@ -1003,6 +1310,16 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1003
1310
|
this._logger.warn(`${this.namespaceLog} Cannot initiate restart, because this.stop is not defined`);
|
|
1004
1311
|
}
|
|
1005
1312
|
}
|
|
1313
|
+
/**
|
|
1314
|
+
* Updates the adapter config with new values. Only a subset of the configuration has to be provided,
|
|
1315
|
+
* since merging with the existing config is done automatically, e.g., like this:
|
|
1316
|
+
*
|
|
1317
|
+
* `adapter.updateConfig({prop1: "newValue1"})`
|
|
1318
|
+
*
|
|
1319
|
+
* After updating the configuration, the adapter is automatically restarted.
|
|
1320
|
+
*
|
|
1321
|
+
* @param newConfig The new config values to be stored
|
|
1322
|
+
*/
|
|
1006
1323
|
updateConfig(newConfig) {
|
|
1007
1324
|
import_validator.Validator.assertObject(newConfig, "newConfig");
|
|
1008
1325
|
return this._updateConfig({ newConfig });
|
|
@@ -1032,6 +1349,10 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1032
1349
|
obj.native = mergedConfig;
|
|
1033
1350
|
return this.setForeignObjectAsync(configObjId, obj);
|
|
1034
1351
|
}
|
|
1352
|
+
/**
|
|
1353
|
+
* Disables and stops the adapter instance.
|
|
1354
|
+
*
|
|
1355
|
+
*/
|
|
1035
1356
|
async disable() {
|
|
1036
1357
|
const configObjId = `system.adapter.${this.namespace}`;
|
|
1037
1358
|
let obj;
|
|
@@ -1046,6 +1367,14 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1046
1367
|
obj.common.enabled = false;
|
|
1047
1368
|
return this.setForeignObjectAsync(configObjId, obj);
|
|
1048
1369
|
}
|
|
1370
|
+
/**
|
|
1371
|
+
* Reads the encrypted parameter from config.
|
|
1372
|
+
*
|
|
1373
|
+
* It returns promise if no callback is provided.
|
|
1374
|
+
*
|
|
1375
|
+
* @param attribute - attribute name in native configuration part
|
|
1376
|
+
* @param [callback] - optional callback
|
|
1377
|
+
*/
|
|
1049
1378
|
getEncryptedConfig(attribute, callback) {
|
|
1050
1379
|
import_validator.Validator.assertString(attribute, "attribute");
|
|
1051
1380
|
import_validator.Validator.assertOptionalCallback(callback, "callback");
|
|
@@ -1060,6 +1389,9 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1060
1389
|
}
|
|
1061
1390
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, `Attribute "${attribute}" not found`);
|
|
1062
1391
|
}
|
|
1392
|
+
/**
|
|
1393
|
+
* Get the system secret, after retrieved once it will be read from the cache
|
|
1394
|
+
*/
|
|
1063
1395
|
async getSystemSecret() {
|
|
1064
1396
|
if (this._systemSecret !== void 0) {
|
|
1065
1397
|
return this._systemSecret;
|
|
@@ -1074,6 +1406,16 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1074
1406
|
this._systemSecret = this._systemSecret || import_constants.DEFAULT_SECRET;
|
|
1075
1407
|
return this._systemSecret;
|
|
1076
1408
|
}
|
|
1409
|
+
/**
|
|
1410
|
+
* Same as setTimeout,
|
|
1411
|
+
* but it clears the running timers during the unloading process
|
|
1412
|
+
* does not work after unload has been called
|
|
1413
|
+
*
|
|
1414
|
+
* @param cb - timer callback
|
|
1415
|
+
* @param timeout - timeout in milliseconds
|
|
1416
|
+
* @param args - as many arguments as needed, which will be passed to setTimeout
|
|
1417
|
+
* @returns timer id
|
|
1418
|
+
*/
|
|
1077
1419
|
setTimeout(cb, timeout, ...args) {
|
|
1078
1420
|
if (typeof cb !== "function") {
|
|
1079
1421
|
this._logger.warn(`${this.namespaceLog} setTimeout expected callback to be of type "function", but got "${typeof cb}"`);
|
|
@@ -1092,6 +1434,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1092
1434
|
this._timers.add(timer);
|
|
1093
1435
|
return timer;
|
|
1094
1436
|
}
|
|
1437
|
+
/**
|
|
1438
|
+
* Same as clearTimeout
|
|
1439
|
+
* but it checks the running timers on unload
|
|
1440
|
+
*
|
|
1441
|
+
* @param timer - the timer object
|
|
1442
|
+
*/
|
|
1095
1443
|
clearTimeout(timer) {
|
|
1096
1444
|
if (timer === void 0) {
|
|
1097
1445
|
return;
|
|
@@ -1099,6 +1447,13 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1099
1447
|
clearTimeout(timer);
|
|
1100
1448
|
this._timers.delete(timer);
|
|
1101
1449
|
}
|
|
1450
|
+
/**
|
|
1451
|
+
* delays the fulfillment of the promise the amount of time.
|
|
1452
|
+
* it will not fulfill during and after adapter shutdown
|
|
1453
|
+
*
|
|
1454
|
+
* @param timeout - timeout in milliseconds
|
|
1455
|
+
* @returns promise when timeout is over
|
|
1456
|
+
*/
|
|
1102
1457
|
delay(timeout) {
|
|
1103
1458
|
if (this._stopInProgress) {
|
|
1104
1459
|
this._logger.warn(`${this.namespaceLog} delay called, but adapter is shutting down`);
|
|
@@ -1114,6 +1469,16 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1114
1469
|
this._delays.add(timer);
|
|
1115
1470
|
});
|
|
1116
1471
|
}
|
|
1472
|
+
/**
|
|
1473
|
+
* Same as setInterval
|
|
1474
|
+
* but it clears the running intervals during the unload process
|
|
1475
|
+
* does not work after unload has been called
|
|
1476
|
+
*
|
|
1477
|
+
* @param cb - interval callback
|
|
1478
|
+
* @param timeout - interval in milliseconds
|
|
1479
|
+
* @param args - as many arguments as needed, which will be passed to setTimeout
|
|
1480
|
+
* @returns interval interval object
|
|
1481
|
+
*/
|
|
1117
1482
|
setInterval(cb, timeout, ...args) {
|
|
1118
1483
|
if (typeof cb !== "function") {
|
|
1119
1484
|
this._logger.error(`${this.namespaceLog} setInterval expected callback to be of type "function", but got "${typeof cb}"`);
|
|
@@ -1129,6 +1494,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1129
1494
|
this._intervals.add(id);
|
|
1130
1495
|
return id;
|
|
1131
1496
|
}
|
|
1497
|
+
/**
|
|
1498
|
+
* Same as clearInterval
|
|
1499
|
+
* but it checks the running intervals on unload
|
|
1500
|
+
*
|
|
1501
|
+
* @param interval - interval object
|
|
1502
|
+
*/
|
|
1132
1503
|
clearInterval(interval) {
|
|
1133
1504
|
if (interval === void 0) {
|
|
1134
1505
|
return;
|
|
@@ -1136,6 +1507,36 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1136
1507
|
clearInterval(interval);
|
|
1137
1508
|
this._intervals.delete(interval);
|
|
1138
1509
|
}
|
|
1510
|
+
/**
|
|
1511
|
+
* Creates or overwrites an object in objectDB.
|
|
1512
|
+
*
|
|
1513
|
+
* This function can create or overwrite objects in objectDB for this adapter.
|
|
1514
|
+
* Only Ids that belong to this adapter can be modified. So the function automatically adds "adapter.X." to ID.
|
|
1515
|
+
* <b>common</b>, <b>native</b> and <b>type</b> attributes are mandatory, and it will be checked.
|
|
1516
|
+
* Additionally, type "state" requires <b>role</b>, <b>type</b> and <b>name</b>, e.g.:
|
|
1517
|
+
* ```js
|
|
1518
|
+
* {
|
|
1519
|
+
* common: {
|
|
1520
|
+
* name: 'object name',
|
|
1521
|
+
* type: 'number', // string, boolean, object, mixed, array
|
|
1522
|
+
* role: 'value' // see https://github.com/ioBroker/ioBroker/blob/master/doc/SCHEMA.md#state-commonrole
|
|
1523
|
+
* },
|
|
1524
|
+
* native: {},
|
|
1525
|
+
* type: 'state' // channel, device
|
|
1526
|
+
* }
|
|
1527
|
+
* ```
|
|
1528
|
+
*
|
|
1529
|
+
* @param id object ID, that must be overwritten or created.
|
|
1530
|
+
* @param obj new object
|
|
1531
|
+
* @param [options] optional user context
|
|
1532
|
+
* @param [callback] return result
|
|
1533
|
+
* ```js
|
|
1534
|
+
* function (err, obj) {
|
|
1535
|
+
* // obj is {id: id}
|
|
1536
|
+
* if (err) adapter.log.error('Cannot write object: ' + err);
|
|
1537
|
+
* }
|
|
1538
|
+
* ```
|
|
1539
|
+
*/
|
|
1139
1540
|
setObject(id, obj, options, callback) {
|
|
1140
1541
|
if (typeof options === "function") {
|
|
1141
1542
|
callback = options;
|
|
@@ -1213,6 +1614,14 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1213
1614
|
return import_js_controller_common.tools.maybeCallbackWithError(options.callback, "mandatory property type missing!");
|
|
1214
1615
|
}
|
|
1215
1616
|
}
|
|
1617
|
+
/**
|
|
1618
|
+
* Helper method for `set[Foreign]Object[NotExists]` that also sets the default value if one is configured
|
|
1619
|
+
*
|
|
1620
|
+
* @param id of the object
|
|
1621
|
+
* @param obj The object to set
|
|
1622
|
+
* @param options optional user context
|
|
1623
|
+
* @param callback optional callback
|
|
1624
|
+
*/
|
|
1216
1625
|
async _setObjectWithDefaultValue(id, obj, options, callback) {
|
|
1217
1626
|
if (!this.#objects) {
|
|
1218
1627
|
this._logger.info(`${this.namespaceLog} setObject not processed because Objects database not connected`);
|
|
@@ -1248,6 +1657,18 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1248
1657
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, e);
|
|
1249
1658
|
}
|
|
1250
1659
|
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Get all states, channels and devices of this adapter.
|
|
1662
|
+
*
|
|
1663
|
+
* @param callback return result
|
|
1664
|
+
* ```js
|
|
1665
|
+
* function (objects) {
|
|
1666
|
+
* for (var id in objects) {
|
|
1667
|
+
* adapter.log.debug(id);
|
|
1668
|
+
* }
|
|
1669
|
+
* }
|
|
1670
|
+
* ```
|
|
1671
|
+
*/
|
|
1251
1672
|
getAdapterObjects(callback) {
|
|
1252
1673
|
import_validator.Validator.assertOptionalCallback(callback, "callback");
|
|
1253
1674
|
return this._getAdapterObjects({ callback });
|
|
@@ -1299,6 +1720,62 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1299
1720
|
}
|
|
1300
1721
|
return import_js_controller_common.tools.maybeCallback(options.callback, ret);
|
|
1301
1722
|
}
|
|
1723
|
+
/**
|
|
1724
|
+
* Extend some object and create it if it does not exist
|
|
1725
|
+
*
|
|
1726
|
+
* You can change or extend some object. E.g. existing object is:
|
|
1727
|
+
* ```js
|
|
1728
|
+
* {
|
|
1729
|
+
* common: {
|
|
1730
|
+
* name: 'Adapter name',
|
|
1731
|
+
* desc: 'Description'
|
|
1732
|
+
* },
|
|
1733
|
+
* type: 'state',
|
|
1734
|
+
* native: {
|
|
1735
|
+
* unused: 'text'
|
|
1736
|
+
* }
|
|
1737
|
+
* }
|
|
1738
|
+
* ```
|
|
1739
|
+
*
|
|
1740
|
+
* If following object will be passed as argument
|
|
1741
|
+
*
|
|
1742
|
+
* ```js
|
|
1743
|
+
* {
|
|
1744
|
+
* common: {
|
|
1745
|
+
* desc: 'New description',
|
|
1746
|
+
* min: 0,
|
|
1747
|
+
* max: 100
|
|
1748
|
+
* },
|
|
1749
|
+
* native: {
|
|
1750
|
+
* unused: null
|
|
1751
|
+
* }
|
|
1752
|
+
* }
|
|
1753
|
+
* ```
|
|
1754
|
+
*
|
|
1755
|
+
* We will get as output:
|
|
1756
|
+
* ```js
|
|
1757
|
+
* {
|
|
1758
|
+
* common: {
|
|
1759
|
+
* desc: 'New description',
|
|
1760
|
+
* min: 0,
|
|
1761
|
+
* max: 100
|
|
1762
|
+
* },
|
|
1763
|
+
* type: 'state',
|
|
1764
|
+
* native: {}
|
|
1765
|
+
* }
|
|
1766
|
+
* ```
|
|
1767
|
+
*
|
|
1768
|
+
* @param id object ID, that must be extended
|
|
1769
|
+
* @param obj part that must be extended
|
|
1770
|
+
* @param options optional user context
|
|
1771
|
+
* @param callback return result
|
|
1772
|
+
* ```js
|
|
1773
|
+
* function (err, obj) {
|
|
1774
|
+
* if (err) adapter.log.error(err);
|
|
1775
|
+
* // obj is {"id": id}
|
|
1776
|
+
* }
|
|
1777
|
+
* ```
|
|
1778
|
+
*/
|
|
1302
1779
|
extendObject(id, obj, options, callback) {
|
|
1303
1780
|
if (typeof options === "function") {
|
|
1304
1781
|
callback = options;
|
|
@@ -1319,6 +1796,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1319
1796
|
}
|
|
1320
1797
|
return this._extendObject({ id, obj, options, callback });
|
|
1321
1798
|
}
|
|
1799
|
+
// TODO: the public return type needs to be defined correctly, probably needs to be discussed
|
|
1322
1800
|
async _extendObject(options) {
|
|
1323
1801
|
if (!this.#objects) {
|
|
1324
1802
|
this._logger.info(`${this.namespaceLog} extendObject not processed because Objects database not connected`);
|
|
@@ -1428,6 +1906,22 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1428
1906
|
return import_js_controller_common.tools.maybeCallbackWithError(options.callback, e);
|
|
1429
1907
|
}
|
|
1430
1908
|
}
|
|
1909
|
+
/**
|
|
1910
|
+
* Same as {@link AdapterClass.setObject}, but for any object.
|
|
1911
|
+
*
|
|
1912
|
+
* ID must be specified as a full name with adapter namespace. E.g "hm-rpc.0.ABC98989.1.STATE"
|
|
1913
|
+
*
|
|
1914
|
+
* @param id object ID, that must be overwritten or created.
|
|
1915
|
+
* @param obj new object
|
|
1916
|
+
* @param options optional user context
|
|
1917
|
+
* @param callback return result
|
|
1918
|
+
* ```js
|
|
1919
|
+
* function (err, obj) {
|
|
1920
|
+
* // obj is {id: id}
|
|
1921
|
+
* if (err) adapter.log.error('Cannot write object: ' + err);
|
|
1922
|
+
* }
|
|
1923
|
+
* ```
|
|
1924
|
+
*/
|
|
1431
1925
|
setForeignObject(id, obj, options, callback) {
|
|
1432
1926
|
if (typeof options === "function") {
|
|
1433
1927
|
callback = options;
|
|
@@ -1479,6 +1973,22 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1479
1973
|
}
|
|
1480
1974
|
this._setObjectWithDefaultValue(id, obj, options, callback);
|
|
1481
1975
|
}
|
|
1976
|
+
/**
|
|
1977
|
+
* Same as {@link AdapterClass.extendObject}, but for any object.
|
|
1978
|
+
*
|
|
1979
|
+
* ID must be specified as a full name with adapter namespace. E.g "hm-rpc.0.ABC98989.1.STATE"
|
|
1980
|
+
*
|
|
1981
|
+
* @param id object ID, that must be extended
|
|
1982
|
+
* @param obj part that must be extended
|
|
1983
|
+
* @param options optional user context, or use attribute preserve e.g. `{preserve: {common: ['name']}}` to preserve common.name
|
|
1984
|
+
* @param callback return result
|
|
1985
|
+
* ```js
|
|
1986
|
+
* function (err, obj) {
|
|
1987
|
+
* // obj is {"id": id}
|
|
1988
|
+
* if (err) adapter.log.error(err);
|
|
1989
|
+
* }
|
|
1990
|
+
* ```
|
|
1991
|
+
*/
|
|
1482
1992
|
extendForeignObject(id, obj, options, callback) {
|
|
1483
1993
|
if (typeof options === "function") {
|
|
1484
1994
|
callback = options;
|
|
@@ -1596,6 +2106,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1596
2106
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, e);
|
|
1597
2107
|
}
|
|
1598
2108
|
}
|
|
2109
|
+
/**
|
|
2110
|
+
* Checks if an object exists to the given id, id will be fixed first
|
|
2111
|
+
*
|
|
2112
|
+
* @param id id of the object
|
|
2113
|
+
* @param options optional user context
|
|
2114
|
+
*/
|
|
1599
2115
|
objectExists(id, options) {
|
|
1600
2116
|
if (!this.#objects) {
|
|
1601
2117
|
this._logger.info(`${this.namespaceLog} objectExists not processed because Objects database not connected`);
|
|
@@ -1609,6 +2125,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1609
2125
|
this._utils.validateId(id, false, null);
|
|
1610
2126
|
return this.#objects.objectExists(id, options);
|
|
1611
2127
|
}
|
|
2128
|
+
/**
|
|
2129
|
+
* Checks if an object exists to the given id
|
|
2130
|
+
*
|
|
2131
|
+
* @param id id of the object
|
|
2132
|
+
* @param options optional user context
|
|
2133
|
+
*/
|
|
1612
2134
|
foreignObjectExists(id, options) {
|
|
1613
2135
|
if (!this.#objects) {
|
|
1614
2136
|
this._logger.info(`${this.namespaceLog} foreignObjectExists not processed because Objects database not connected`);
|
|
@@ -1621,6 +2143,20 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1621
2143
|
this._utils.validateId(id, true, null);
|
|
1622
2144
|
return this.#objects.objectExists(id, options);
|
|
1623
2145
|
}
|
|
2146
|
+
/**
|
|
2147
|
+
* Get object of this instance.
|
|
2148
|
+
*
|
|
2149
|
+
* It is not required, that ID consists namespace. E.g. to get object of "adapterName.X.myObject", only "myObject" is required as ID.
|
|
2150
|
+
*
|
|
2151
|
+
* @param id exactly object ID (without namespace)
|
|
2152
|
+
* @param options optional user context
|
|
2153
|
+
* @param callback return result
|
|
2154
|
+
* ```js
|
|
2155
|
+
* function (err, obj) {
|
|
2156
|
+
* if (err) adapter.log.error('Cannot get object: ' + err);
|
|
2157
|
+
* }
|
|
2158
|
+
* ```
|
|
2159
|
+
*/
|
|
1624
2160
|
getObject(id, options, callback) {
|
|
1625
2161
|
if (typeof options === "function") {
|
|
1626
2162
|
callback = options;
|
|
@@ -1642,6 +2178,32 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1642
2178
|
}
|
|
1643
2179
|
this.#objects.getObject(this._utils.fixId(id), options, callback);
|
|
1644
2180
|
}
|
|
2181
|
+
/**
|
|
2182
|
+
* Read object view from DB.
|
|
2183
|
+
*
|
|
2184
|
+
* It is required, that ID consists namespace in startkey and endkey. E.g. `{startkey: 'hm-rpc.' + adapter.instance + '.', endkey: 'hm-rpc.' + adapter.instance + '.\u9999'}`
|
|
2185
|
+
* to get all objects of the instance.
|
|
2186
|
+
*
|
|
2187
|
+
* @param design name of the design
|
|
2188
|
+
* @param search name of the view
|
|
2189
|
+
* @param params object containing startkey: first id to include in result; endkey: last id to include in result
|
|
2190
|
+
* @param options additional objects, e.g. for permissions
|
|
2191
|
+
* @param callback return result
|
|
2192
|
+
* ```js
|
|
2193
|
+
* function (err, doc) {
|
|
2194
|
+
* if (doc && doc.rows) {
|
|
2195
|
+
* for (var i = 0; i < doc.rows.length; i++) {
|
|
2196
|
+
* var id = doc.rows[i].id;
|
|
2197
|
+
* var obj = doc.rows[i].value;
|
|
2198
|
+
* adapter.log.info('Found ' + id + ': ' + JSON.stringify(obj));
|
|
2199
|
+
* }
|
|
2200
|
+
* if (!doc.rows.length) adapter.log.info('No objects found.');
|
|
2201
|
+
* } else {
|
|
2202
|
+
* adapter.log.info('No objects found: ' + err);
|
|
2203
|
+
* }
|
|
2204
|
+
* }
|
|
2205
|
+
* ```
|
|
2206
|
+
*/
|
|
1645
2207
|
getObjectView(design, search, params, options, callback) {
|
|
1646
2208
|
if (typeof options === "function") {
|
|
1647
2209
|
callback = options;
|
|
@@ -1699,6 +2261,30 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1699
2261
|
}
|
|
1700
2262
|
return this.#objects.getObjectView(design, search, params, options, callback);
|
|
1701
2263
|
}
|
|
2264
|
+
/**
|
|
2265
|
+
* Read object list from DB.
|
|
2266
|
+
*
|
|
2267
|
+
* It is required, that ID consists namespace in startkey and endkey. E.g. `{startkey: 'hm-rpc.' + adapter.instance + '.', endkey: 'hm-rpc.' + adapter.instance + '.\u9999'}`
|
|
2268
|
+
* to get all objects of the instance.
|
|
2269
|
+
*
|
|
2270
|
+
* @param params startkey and endkey information
|
|
2271
|
+
* @param options additional options, e.g. for permissions
|
|
2272
|
+
* @param callback optional callback
|
|
2273
|
+
* ```js
|
|
2274
|
+
* function (err, res) {
|
|
2275
|
+
* if (res && res.rows) {
|
|
2276
|
+
* for (var i = 0; i < res.rows.length; i++) {
|
|
2277
|
+
* var id = res.rows[i].id;
|
|
2278
|
+
* var obj = res.rows[i].value;
|
|
2279
|
+
* adapter.log.info('Found ' + id + ': ' + JSON.stringify(obj));
|
|
2280
|
+
* }
|
|
2281
|
+
* if (!res.rows.length) adapter.log.info('No objects found.');
|
|
2282
|
+
* } else {
|
|
2283
|
+
* adapter.log.info('No objects found: ' + err);
|
|
2284
|
+
* }
|
|
2285
|
+
* }
|
|
2286
|
+
* ```
|
|
2287
|
+
*/
|
|
1702
2288
|
getObjectList(params, options, callback) {
|
|
1703
2289
|
if (typeof options === "function") {
|
|
1704
2290
|
callback = options;
|
|
@@ -1715,6 +2301,34 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1715
2301
|
}
|
|
1716
2302
|
this.#objects.getObjectList(params, options, callback);
|
|
1717
2303
|
}
|
|
2304
|
+
/**
|
|
2305
|
+
* Get the enum tree.
|
|
2306
|
+
*
|
|
2307
|
+
* Get enums of specified tree or all enums if nothing specified as object with values.
|
|
2308
|
+
* If getEnum called with no enum specified, all enums will be returned:
|
|
2309
|
+
* ```js
|
|
2310
|
+
* adapter.getEnums(function (err, enums, requestEnum) {
|
|
2311
|
+
* // All enums
|
|
2312
|
+
* if (err) adapter.log.error('Cannot get object: ' + err);
|
|
2313
|
+
* for (var e in enums) {
|
|
2314
|
+
* adapter.log.debug('Enum "' + e + '" has following members: ' + enums[e].common.members.join(', '));
|
|
2315
|
+
* }
|
|
2316
|
+
* });
|
|
2317
|
+
* ```
|
|
2318
|
+
*
|
|
2319
|
+
* @param _enum enum name, e.g. 'rooms', 'function' or '' (all enums)
|
|
2320
|
+
* @param options optional user context
|
|
2321
|
+
* @param callback return result
|
|
2322
|
+
* ```js
|
|
2323
|
+
* function (err, enums, requestEnum) {
|
|
2324
|
+
* // requestEnum is _enum
|
|
2325
|
+
* if (err) adapter.log.error('Cannot get object: ' + err);
|
|
2326
|
+
* for (var e in enums) {
|
|
2327
|
+
* adapter.log.debug('Enum "' + e + '" has following members: ' + enums[e].common.members.join(', '));
|
|
2328
|
+
* }
|
|
2329
|
+
* }
|
|
2330
|
+
* ```
|
|
2331
|
+
*/
|
|
1718
2332
|
getEnum(_enum, options, callback) {
|
|
1719
2333
|
if (typeof _enum === "function") {
|
|
1720
2334
|
callback = _enum;
|
|
@@ -1758,6 +2372,48 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1758
2372
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, err, result, _enum);
|
|
1759
2373
|
});
|
|
1760
2374
|
}
|
|
2375
|
+
/**
|
|
2376
|
+
* Read the members of given enums.
|
|
2377
|
+
*
|
|
2378
|
+
* Get enums of specified tree or all enums if nothing specified as object with values.
|
|
2379
|
+
*
|
|
2380
|
+
* @param _enumList enum name or names, e.g. ['rooms', 'function']
|
|
2381
|
+
* @param options optional user context
|
|
2382
|
+
* @param callback return result
|
|
2383
|
+
* ```js
|
|
2384
|
+
* function (err, enums) {
|
|
2385
|
+
* // requestEnum is _enum
|
|
2386
|
+
* if (err) adapter.log.error('Cannot get object: ' + err);
|
|
2387
|
+
* // Result is like
|
|
2388
|
+
* // {
|
|
2389
|
+
* // "enum.rooms": {
|
|
2390
|
+
* // "enum.rooms.livingroom": {
|
|
2391
|
+
* // common: {
|
|
2392
|
+
* // members: ['ID1', 'ID2']
|
|
2393
|
+
* // }
|
|
2394
|
+
* // },
|
|
2395
|
+
* // "enum.rooms.sleepingroom": {
|
|
2396
|
+
* // common: {
|
|
2397
|
+
* // members: ['ID3', 'ID4']
|
|
2398
|
+
* // }
|
|
2399
|
+
* // }
|
|
2400
|
+
* // },
|
|
2401
|
+
* // "enum.functions": {
|
|
2402
|
+
* // "enum.rooms.light": {
|
|
2403
|
+
* // common: {
|
|
2404
|
+
* // members: ['ID1', 'ID6']
|
|
2405
|
+
* // }
|
|
2406
|
+
* // },
|
|
2407
|
+
* // "enum.rooms.weather": {
|
|
2408
|
+
* // common: {
|
|
2409
|
+
* // members: ['ID4', 'ID7']
|
|
2410
|
+
* // }
|
|
2411
|
+
* // }
|
|
2412
|
+
* // }
|
|
2413
|
+
* // }
|
|
2414
|
+
* }
|
|
2415
|
+
* ```
|
|
2416
|
+
*/
|
|
1761
2417
|
getEnums(_enumList, options, callback) {
|
|
1762
2418
|
if (typeof _enumList === "function") {
|
|
1763
2419
|
callback = _enumList;
|
|
@@ -1827,6 +2483,48 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1827
2483
|
});
|
|
1828
2484
|
}
|
|
1829
2485
|
}
|
|
2486
|
+
/**
|
|
2487
|
+
* Get objects by pattern, by specific type and resolve their enums.
|
|
2488
|
+
*
|
|
2489
|
+
* Get all objects in the system of specified type. E.g.:
|
|
2490
|
+
*
|
|
2491
|
+
* ```js
|
|
2492
|
+
* adapter.getForeignObjects('hm-rega.0.*', 'state', ['rooms', 'functions'], function (err, objs) {
|
|
2493
|
+
* if (err) adapter.log.error('Cannot get object: ' + err);
|
|
2494
|
+
* // objs look like:
|
|
2495
|
+
* // {
|
|
2496
|
+
* // "hm-rega.0.ABC0000.1.STATE": {
|
|
2497
|
+
* // common: {...},
|
|
2498
|
+
* // native: {},
|
|
2499
|
+
* // type: 'state',
|
|
2500
|
+
* // enums: {
|
|
2501
|
+
* // 'enums.rooms.livingroom': 'Living room',
|
|
2502
|
+
* // 'enums.functions.light': 'Light'
|
|
2503
|
+
* // }
|
|
2504
|
+
* // },
|
|
2505
|
+
* // "hm-rega.0.ABC0000.2.STATE": {
|
|
2506
|
+
* // common: {...},
|
|
2507
|
+
* // native: {},
|
|
2508
|
+
* // type: 'state',
|
|
2509
|
+
* // enums: {
|
|
2510
|
+
* // 'enums.rooms.sleepingroom': 'Sleeping room',
|
|
2511
|
+
* // 'enums.functions.window': 'Windows'
|
|
2512
|
+
* // }
|
|
2513
|
+
* // }
|
|
2514
|
+
* }
|
|
2515
|
+
* ```
|
|
2516
|
+
*
|
|
2517
|
+
* @param pattern object ID/wildcards
|
|
2518
|
+
* @param type type of object: 'state', 'channel' or 'device'. Default - 'state'
|
|
2519
|
+
* @param enums object ID, that must be overwritten or created.
|
|
2520
|
+
* @param options optional user context
|
|
2521
|
+
* @param callback return result
|
|
2522
|
+
* ```js
|
|
2523
|
+
* function (err, obj) {
|
|
2524
|
+
* if (err) adapter.log.error('Cannot get object: ' + err);
|
|
2525
|
+
* }
|
|
2526
|
+
* ```
|
|
2527
|
+
*/
|
|
1830
2528
|
getForeignObjects(pattern, type, enums, options, callback) {
|
|
1831
2529
|
if (typeof options === "function") {
|
|
1832
2530
|
callback = options;
|
|
@@ -1933,6 +2631,22 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1933
2631
|
}
|
|
1934
2632
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, null, list);
|
|
1935
2633
|
}
|
|
2634
|
+
/**
|
|
2635
|
+
* Find any object by name or ID.
|
|
2636
|
+
*
|
|
2637
|
+
* Find object by the exact name or ID.
|
|
2638
|
+
*
|
|
2639
|
+
* @param id exactly object ID (without namespace)
|
|
2640
|
+
* @param type optional common.type of state: 'number', 'string', 'boolean', 'file', ...
|
|
2641
|
+
* @param options optional user context
|
|
2642
|
+
* @param callback return result
|
|
2643
|
+
* ```js
|
|
2644
|
+
* adapter.findForeignObject('Some name', function (err, id, name) {
|
|
2645
|
+
* if (err) adapter.log.error('Cannot get object: ' + err);
|
|
2646
|
+
* adapter.log.debug('ID of object with name "' + name + '" is "' + id + '"');
|
|
2647
|
+
* }
|
|
2648
|
+
* ```
|
|
2649
|
+
*/
|
|
1936
2650
|
findForeignObject(id, type, options, callback) {
|
|
1937
2651
|
if (typeof options === "function") {
|
|
1938
2652
|
callback = options;
|
|
@@ -1960,6 +2674,20 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1960
2674
|
}
|
|
1961
2675
|
this.#objects.findObject(id, type, options || {}, callback);
|
|
1962
2676
|
}
|
|
2677
|
+
/**
|
|
2678
|
+
* Get any object.
|
|
2679
|
+
*
|
|
2680
|
+
* ID must be specified with namespace.
|
|
2681
|
+
*
|
|
2682
|
+
* @param id exactly object ID (with namespace)
|
|
2683
|
+
* @param options optional user context
|
|
2684
|
+
* @param callback return result
|
|
2685
|
+
* ```js
|
|
2686
|
+
* function (err, obj) {
|
|
2687
|
+
* if (err) adapter.log.error('Cannot get object: ' + err);
|
|
2688
|
+
* }
|
|
2689
|
+
* ```
|
|
2690
|
+
*/
|
|
1963
2691
|
getForeignObject(id, options, callback) {
|
|
1964
2692
|
if (typeof options === "function") {
|
|
1965
2693
|
callback = options;
|
|
@@ -1993,6 +2721,23 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
1993
2721
|
return import_js_controller_common.tools.maybeCallbackWithError(options.callback, e);
|
|
1994
2722
|
}
|
|
1995
2723
|
}
|
|
2724
|
+
/**
|
|
2725
|
+
* Delete an object of this instance.
|
|
2726
|
+
*
|
|
2727
|
+
* It is not required to provide the adapter namespace, because it will automatically be added.
|
|
2728
|
+
* E.g. to delete "adapterName.X.myObject", only "myObject" is required as ID.
|
|
2729
|
+
*
|
|
2730
|
+
* The corresponding state will be deleted too if the object has type "state".
|
|
2731
|
+
*
|
|
2732
|
+
* @param id exactly object ID (without namespace)
|
|
2733
|
+
* @param options optional user context. E.g. recursive option could be true
|
|
2734
|
+
* @param callback return result
|
|
2735
|
+
* ```js
|
|
2736
|
+
* function (err) {
|
|
2737
|
+
* if (err) adapter.log.error('Cannot delete object: ' + err);
|
|
2738
|
+
* }
|
|
2739
|
+
* ```
|
|
2740
|
+
*/
|
|
1996
2741
|
delObject(id, options, callback) {
|
|
1997
2742
|
import_validator.Validator.assertString(id, "id");
|
|
1998
2743
|
id = this._utils.fixId(id);
|
|
@@ -2022,6 +2767,20 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2022
2767
|
setImmediate(() => this._deleteObjects(tasks, options, cb));
|
|
2023
2768
|
});
|
|
2024
2769
|
}
|
|
2770
|
+
/**
|
|
2771
|
+
* Delete any object.
|
|
2772
|
+
*
|
|
2773
|
+
* The full ID with namespace must be specified. The corresponding state will be deleted too if the object has type "state".
|
|
2774
|
+
*
|
|
2775
|
+
* @param id exactly object ID (with namespace)
|
|
2776
|
+
* @param options optional user context or `{ recursive: true }` to delete all underlying objects
|
|
2777
|
+
* @param callback return result
|
|
2778
|
+
* ```js
|
|
2779
|
+
* function (err) {
|
|
2780
|
+
* if (err) adapter.log.error('Cannot delete object: ' + err);
|
|
2781
|
+
* }
|
|
2782
|
+
* ```
|
|
2783
|
+
*/
|
|
2025
2784
|
delForeignObject(id, options, callback) {
|
|
2026
2785
|
if (typeof options === "function") {
|
|
2027
2786
|
callback = options;
|
|
@@ -2054,7 +2813,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2054
2813
|
const tasks = obj && (!obj.common || !obj.common.dontDelete) ? [{ id, state: obj.type === "state" }] : [];
|
|
2055
2814
|
const selector = { startkey: `${id}.`, endkey: `${id}.\u9999` };
|
|
2056
2815
|
this.#objects.getObjectList(selector, options, (err2, res) => {
|
|
2057
|
-
res && res.rows.forEach((item) => !tasks.find((task) => task.id === item.id) && (!item.value || !item.value.common || !item.value.common.dontDelete) &&
|
|
2816
|
+
res && res.rows.forEach((item) => !tasks.find((task) => task.id === item.id) && (!item.value || !item.value.common || !item.value.common.dontDelete) && // exclude objects with dontDelete flag
|
|
2817
|
+
tasks.push({ id: item.id, state: item.value && item.value.type === "state" }));
|
|
2058
2818
|
this._deleteObjects(tasks, options, callback);
|
|
2059
2819
|
});
|
|
2060
2820
|
});
|
|
@@ -2087,6 +2847,18 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2087
2847
|
});
|
|
2088
2848
|
}
|
|
2089
2849
|
}
|
|
2850
|
+
/**
|
|
2851
|
+
* Subscribe for the changes of objects in this instance.
|
|
2852
|
+
*
|
|
2853
|
+
* @param pattern pattern like 'channel.*' or '*' (all objects of this adapter) - without namespaces
|
|
2854
|
+
* @param options optional user context
|
|
2855
|
+
* @param callback optional returns result
|
|
2856
|
+
* ```js
|
|
2857
|
+
* function (err) {
|
|
2858
|
+
* if (err) adapter.log.error('Cannot subscribe object: ' + err);
|
|
2859
|
+
* }
|
|
2860
|
+
* ```
|
|
2861
|
+
*/
|
|
2090
2862
|
subscribeObjects(pattern, options, callback) {
|
|
2091
2863
|
if (typeof options === "function") {
|
|
2092
2864
|
callback = options;
|
|
@@ -2108,6 +2880,18 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2108
2880
|
this.#objects.subscribeUser(fixedPattern, options, callback);
|
|
2109
2881
|
}
|
|
2110
2882
|
}
|
|
2883
|
+
/**
|
|
2884
|
+
* Unsubscribe on the changes of objects in this instance.
|
|
2885
|
+
*
|
|
2886
|
+
* @param pattern pattern like 'channel.*' or '*' (all objects) - without namespaces
|
|
2887
|
+
* @param options optional user context
|
|
2888
|
+
* @param callback optional returns result
|
|
2889
|
+
* ```js
|
|
2890
|
+
* function (err) {
|
|
2891
|
+
* if (err) adapter.log.error('Cannot unsubscribe object: ' + err);
|
|
2892
|
+
* }
|
|
2893
|
+
* ```
|
|
2894
|
+
*/
|
|
2111
2895
|
unsubscribeObjects(pattern, options, callback) {
|
|
2112
2896
|
if (typeof options === "function") {
|
|
2113
2897
|
callback = options;
|
|
@@ -2129,6 +2913,18 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2129
2913
|
this.#objects.unsubscribeUser(fixedPattern, options, callback);
|
|
2130
2914
|
}
|
|
2131
2915
|
}
|
|
2916
|
+
/**
|
|
2917
|
+
* Subscribe for the changes of objects in any instance.
|
|
2918
|
+
*
|
|
2919
|
+
* @param pattern pattern like 'channel.*' or '*' (all objects) - without namespaces. You can use array of patterns
|
|
2920
|
+
* @param options optional user context
|
|
2921
|
+
* @param callback optional returns result
|
|
2922
|
+
* ```js
|
|
2923
|
+
* function (err) {
|
|
2924
|
+
* if (err) adapter.log.error('Cannot subscribe object: ' + err);
|
|
2925
|
+
* }
|
|
2926
|
+
* ```
|
|
2927
|
+
*/
|
|
2132
2928
|
subscribeForeignObjects(pattern, options, callback) {
|
|
2133
2929
|
if (typeof options === "function") {
|
|
2134
2930
|
callback = options;
|
|
@@ -2145,6 +2941,18 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2145
2941
|
}
|
|
2146
2942
|
this.#objects.subscribeUser(pattern, options, callback);
|
|
2147
2943
|
}
|
|
2944
|
+
/**
|
|
2945
|
+
* Unsubscribe for the patterns on all objects.
|
|
2946
|
+
*
|
|
2947
|
+
* @param pattern pattern like 'channel.*' or '*' (all objects) - without namespaces
|
|
2948
|
+
* @param options optional user context
|
|
2949
|
+
* @param callback optional returns result
|
|
2950
|
+
* ```js
|
|
2951
|
+
* function (err) {
|
|
2952
|
+
* if (err) adapter.log.error('Cannot unsubscribe object: ' + err);
|
|
2953
|
+
* }
|
|
2954
|
+
* ```
|
|
2955
|
+
*/
|
|
2148
2956
|
unsubscribeForeignObjects(pattern, options, callback) {
|
|
2149
2957
|
if (typeof options === "function") {
|
|
2150
2958
|
callback = options;
|
|
@@ -2164,6 +2972,13 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2164
2972
|
}
|
|
2165
2973
|
this.#objects.unsubscribeUser(pattern, options, callback);
|
|
2166
2974
|
}
|
|
2975
|
+
/**
|
|
2976
|
+
* Subscribe for the changes of files in specific instance.
|
|
2977
|
+
*
|
|
2978
|
+
* @param id adapter ID like 'vis-2.0' or 'vis-2.admin'
|
|
2979
|
+
* @param pattern pattern like 'channel.*' or '*' (all files) - without namespaces. You can use array of patterns
|
|
2980
|
+
* @param options optional user context
|
|
2981
|
+
*/
|
|
2167
2982
|
subscribeForeignFiles(id, pattern, options) {
|
|
2168
2983
|
if (!this.#objects) {
|
|
2169
2984
|
this._logger.info(`${this.namespaceLog} subscribeForeignFiles not processed because Objects database not connected`);
|
|
@@ -2176,6 +2991,13 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2176
2991
|
}
|
|
2177
2992
|
return this.#objects.subscribeUserFile(id, pattern, options);
|
|
2178
2993
|
}
|
|
2994
|
+
/**
|
|
2995
|
+
* Unsubscribe for the changes of files on specific instance.
|
|
2996
|
+
*
|
|
2997
|
+
* @param id adapter ID like 'vis-2.0' or 'vis-2.admin'
|
|
2998
|
+
* @param pattern pattern like 'channel.*' or '*' (all objects) - without namespaces
|
|
2999
|
+
* @param options optional user context
|
|
3000
|
+
*/
|
|
2179
3001
|
unsubscribeForeignFiles(id, pattern, options) {
|
|
2180
3002
|
if (!pattern) {
|
|
2181
3003
|
pattern = "*";
|
|
@@ -2191,6 +3013,23 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2191
3013
|
}
|
|
2192
3014
|
return this.#objects.unsubscribeUserFile(id, pattern, options);
|
|
2193
3015
|
}
|
|
3016
|
+
/**
|
|
3017
|
+
* Same as {@link AdapterClass.setObject}, but with check if the object exists.
|
|
3018
|
+
*
|
|
3019
|
+
* Only Ids that belong to this adapter can be modified. So the function automatically adds "adapter.X." to ID.
|
|
3020
|
+
* New object will be created only if no object exists with such ID.
|
|
3021
|
+
*
|
|
3022
|
+
* @param id object ID, that must be overwritten or created.
|
|
3023
|
+
* @param obj new object
|
|
3024
|
+
* @param options optional user context
|
|
3025
|
+
* @param callback return result
|
|
3026
|
+
* ```js
|
|
3027
|
+
* function (err, obj) {
|
|
3028
|
+
* // obj is {id: id}
|
|
3029
|
+
* if (err) adapter.log.error('Cannot write object: ' + err);
|
|
3030
|
+
* }
|
|
3031
|
+
* ```
|
|
3032
|
+
*/
|
|
2194
3033
|
setObjectNotExists(id, obj, options, callback) {
|
|
2195
3034
|
if (typeof options === "function") {
|
|
2196
3035
|
callback = options;
|
|
@@ -2241,6 +3080,23 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2241
3080
|
}
|
|
2242
3081
|
return import_js_controller_common.tools.maybeCallbackWithError(options.callback, null);
|
|
2243
3082
|
}
|
|
3083
|
+
/**
|
|
3084
|
+
* Same as {@link AdapterClass.setForeignObject}, but with check if the object exists.
|
|
3085
|
+
*
|
|
3086
|
+
* ID must be specified as a full name with adapter namespace. E.g "hm-rpc.0.ABC98989.1.STATE".
|
|
3087
|
+
* New object will be created only if no object exists with such ID.
|
|
3088
|
+
*
|
|
3089
|
+
* @param id object ID, that must be overwritten or created.
|
|
3090
|
+
* @param obj new object
|
|
3091
|
+
* @param options user context
|
|
3092
|
+
* @param callback return result
|
|
3093
|
+
* ```js
|
|
3094
|
+
* function (err, obj) {
|
|
3095
|
+
* // obj is {id: id}
|
|
3096
|
+
* if (err) adapter.log.error('Cannot write object: ' + err);
|
|
3097
|
+
* }
|
|
3098
|
+
* ```
|
|
3099
|
+
*/
|
|
2244
3100
|
setForeignObjectNotExists(id, obj, options, callback) {
|
|
2245
3101
|
if (typeof options === "function") {
|
|
2246
3102
|
callback = options;
|
|
@@ -2302,6 +3158,14 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2302
3158
|
}
|
|
2303
3159
|
return id;
|
|
2304
3160
|
}
|
|
3161
|
+
/**
|
|
3162
|
+
* @param deviceName
|
|
3163
|
+
* @param common
|
|
3164
|
+
* @param _native
|
|
3165
|
+
* @param options
|
|
3166
|
+
* @param callback
|
|
3167
|
+
* @deprecated use `this.extendObject` instead
|
|
3168
|
+
*/
|
|
2305
3169
|
createDevice(deviceName, common, _native, options, callback) {
|
|
2306
3170
|
this._logger.info(`${this.namespaceLog} Method "createDevice" is deprecated and will be removed in js-controller 7.1, use "extendObject/setObjectNotExists" instead`);
|
|
2307
3171
|
if (typeof options === "function") {
|
|
@@ -2346,6 +3210,17 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2346
3210
|
native: _native
|
|
2347
3211
|
}, options, callback);
|
|
2348
3212
|
}
|
|
3213
|
+
/**
|
|
3214
|
+
* Name of channel must be in format "channel"
|
|
3215
|
+
*
|
|
3216
|
+
* @param parentDevice
|
|
3217
|
+
* @param channelName
|
|
3218
|
+
* @param roleOrCommon
|
|
3219
|
+
* @param _native
|
|
3220
|
+
* @param options
|
|
3221
|
+
* @param callback
|
|
3222
|
+
* @deprecated use `this.extendObject` instead
|
|
3223
|
+
*/
|
|
2349
3224
|
createChannel(parentDevice, channelName, roleOrCommon, _native, options, callback) {
|
|
2350
3225
|
this._logger.info(`${this.namespaceLog} Method "createChannel" is deprecated and will be removed in js-controller 7.1, use "extendObject/setObjectNotExists" instead`);
|
|
2351
3226
|
if (typeof options === "function") {
|
|
@@ -2390,6 +3265,16 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2390
3265
|
};
|
|
2391
3266
|
this.setObjectNotExists(channelName, obj, options, callback);
|
|
2392
3267
|
}
|
|
3268
|
+
/**
|
|
3269
|
+
* @param parentDevice
|
|
3270
|
+
* @param parentChannel
|
|
3271
|
+
* @param stateName
|
|
3272
|
+
* @param roleOrCommon
|
|
3273
|
+
* @param _native
|
|
3274
|
+
* @param options
|
|
3275
|
+
* @param callback
|
|
3276
|
+
* @deprecated use `this.extendObject` instead
|
|
3277
|
+
*/
|
|
2393
3278
|
createState(parentDevice, parentChannel, stateName, roleOrCommon, _native, options, callback) {
|
|
2394
3279
|
this._logger.info(`${this.namespaceLog} Method "createState" is deprecated and will be removed in js-controller 7.1, use "extendObject/setObjectNotExists" instead`);
|
|
2395
3280
|
if (typeof options === "function") {
|
|
@@ -2534,6 +3419,19 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2534
3419
|
}
|
|
2535
3420
|
});
|
|
2536
3421
|
}
|
|
3422
|
+
/**
|
|
3423
|
+
* Delete device with all its channels and states.
|
|
3424
|
+
*
|
|
3425
|
+
* @deprecated use `this.delObject` instead
|
|
3426
|
+
* @param deviceName is the part of ID like: adapter.instance.<deviceName>
|
|
3427
|
+
* @param options optional user context
|
|
3428
|
+
* @param callback return result
|
|
3429
|
+
* ```js
|
|
3430
|
+
* function (err) {
|
|
3431
|
+
* if (err) adapter.log.error('Cannot delete device: ' + err);
|
|
3432
|
+
* }
|
|
3433
|
+
* ```
|
|
3434
|
+
*/
|
|
2537
3435
|
deleteDevice(deviceName, options, callback) {
|
|
2538
3436
|
this._logger.info(`${this.namespaceLog} Method "deleteDevice" is deprecated and will be removed in js-controller 7.1, use "delObject" instead`);
|
|
2539
3437
|
if (typeof options === "function") {
|
|
@@ -2726,6 +3624,21 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2726
3624
|
return import_js_controller_common.tools.maybeCallback(callback);
|
|
2727
3625
|
});
|
|
2728
3626
|
}
|
|
3627
|
+
/**
|
|
3628
|
+
* Deletes channel and underlying structure
|
|
3629
|
+
*
|
|
3630
|
+
* @deprecated use `this.delObject` instead
|
|
3631
|
+
* @alias deleteChannel
|
|
3632
|
+
* @param parentDevice is the part of ID like: adapter.instance.<deviceName>
|
|
3633
|
+
* @param channelName is the part of ID like: adapter.instance.<deviceName>.<channelName>
|
|
3634
|
+
* @param options optional user context
|
|
3635
|
+
* @param callback return result
|
|
3636
|
+
* ```js
|
|
3637
|
+
* function (err) {
|
|
3638
|
+
* if (err) adapter.log.error('Cannot delete device: ' + err);
|
|
3639
|
+
* }
|
|
3640
|
+
* ```
|
|
3641
|
+
*/
|
|
2729
3642
|
deleteChannel(parentDevice, channelName, options, callback) {
|
|
2730
3643
|
this._logger.info(`${this.namespaceLog} Method "deleteChannel" is deprecated and will be removed in js-controller 7.1, use "delObject" instead`);
|
|
2731
3644
|
if (typeof options === "function") {
|
|
@@ -2792,6 +3705,14 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
2792
3705
|
}
|
|
2793
3706
|
return import_js_controller_common.tools.maybeCallback(callback);
|
|
2794
3707
|
}
|
|
3708
|
+
/**
|
|
3709
|
+
* @param parentDevice
|
|
3710
|
+
* @param parentChannel
|
|
3711
|
+
* @param stateName
|
|
3712
|
+
* @param options
|
|
3713
|
+
* @param callback
|
|
3714
|
+
* @deprecated use `this.delObject` instead
|
|
3715
|
+
*/
|
|
2795
3716
|
deleteState(parentDevice, parentChannel, stateName, options, callback) {
|
|
2796
3717
|
this._logger.info(`${this.namespaceLog} Method "deleteState" is deprecated and will be removed in js-controller 7.1, use "delObject" instead`);
|
|
2797
3718
|
if (typeof parentChannel === "function" && stateName === void 0) {
|
|
@@ -3176,11 +4097,15 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3176
4097
|
stateName = stateName.substring(parentChannel.length + 1);
|
|
3177
4098
|
}
|
|
3178
4099
|
stateName = stateName.replace(FORBIDDEN_CHARS, "_").replace(/\./g, "_");
|
|
3179
|
-
const objId = this._utils.fixId(
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
4100
|
+
const objId = this._utils.fixId(
|
|
4101
|
+
{
|
|
4102
|
+
device: parentDevice,
|
|
4103
|
+
channel: parentChannel,
|
|
4104
|
+
state: stateName
|
|
4105
|
+
},
|
|
4106
|
+
false
|
|
4107
|
+
/*, 'state'*/
|
|
4108
|
+
);
|
|
3184
4109
|
if (enumName) {
|
|
3185
4110
|
enumName = `enum.${enumName}.`;
|
|
3186
4111
|
} else {
|
|
@@ -3213,6 +4138,27 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3213
4138
|
return import_js_controller_common.tools.maybeCallback(callback);
|
|
3214
4139
|
});
|
|
3215
4140
|
}
|
|
4141
|
+
/**
|
|
4142
|
+
* Change file access rights
|
|
4143
|
+
*
|
|
4144
|
+
* This function updates the file access rights
|
|
4145
|
+
* ```js
|
|
4146
|
+
* adapter.chmodFile('vis-2.0', '/main/vis-views.json', {mode: 0x644}, function (err, processed) {
|
|
4147
|
+
* if (err) adapter.log.error('Cannot read file: ' + err);
|
|
4148
|
+
* adapter.log.info('New files: ' + JSON.stringify(processed));
|
|
4149
|
+
* });
|
|
4150
|
+
* ```
|
|
4151
|
+
*
|
|
4152
|
+
* @param _adapter adapter name. If the adapter name is null, so the name (not instance) of the current adapter will be taken.
|
|
4153
|
+
* @param path path to file without adapter name. E.g., If you want to update "/vis-2.0/main/*", here must be "/main/*" and _adapter must be equal to "vis-2.0".
|
|
4154
|
+
* @param options data with mode
|
|
4155
|
+
* @param callback return result
|
|
4156
|
+
* ```js
|
|
4157
|
+
* function (err, processedFiles) {
|
|
4158
|
+
* list of processed files with new groups
|
|
4159
|
+
* }
|
|
4160
|
+
* ```
|
|
4161
|
+
*/
|
|
3216
4162
|
chmodFile(_adapter, path2, options, callback) {
|
|
3217
4163
|
if (_adapter === null) {
|
|
3218
4164
|
_adapter = this.name;
|
|
@@ -3227,6 +4173,27 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3227
4173
|
}
|
|
3228
4174
|
this.#objects.chmodFile(_adapter, path2, options, callback);
|
|
3229
4175
|
}
|
|
4176
|
+
/**
|
|
4177
|
+
* Change a file owner
|
|
4178
|
+
*
|
|
4179
|
+
* This function updates the file owner and ownerGroup
|
|
4180
|
+
* ```js
|
|
4181
|
+
* adapter.chownFile('vis-2.0', '/main/vis-views.json', {owner: 'newOwner', ownerGroup: 'newgroup'}, function (err, processed) {
|
|
4182
|
+
* if (err) adapter.log.error('Cannot read file: ' + err);
|
|
4183
|
+
* adapter.log.info('New files: ' + JSON.stringify(processed));
|
|
4184
|
+
* });
|
|
4185
|
+
* ```
|
|
4186
|
+
*
|
|
4187
|
+
* @param _adapter adapter name. If the adapter name is null, so the name (not instance) of the current adapter will be taken.
|
|
4188
|
+
* @param path path to file without adapter name. E.g., If you want to update "/vis-2.0/main/*", here must be "/main/*" and _adapter must be equal to "vis-2.0".
|
|
4189
|
+
* @param options data with owner and ownerGroup
|
|
4190
|
+
* @param callback return result
|
|
4191
|
+
* ```js
|
|
4192
|
+
* function (err, processedFiles) {
|
|
4193
|
+
* list of processed files with new groups
|
|
4194
|
+
* }
|
|
4195
|
+
* ```
|
|
4196
|
+
*/
|
|
3230
4197
|
chownFile(_adapter, path2, options, callback) {
|
|
3231
4198
|
if (_adapter === null) {
|
|
3232
4199
|
_adapter = this.name;
|
|
@@ -3241,6 +4208,41 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3241
4208
|
}
|
|
3242
4209
|
this.#objects.chownFile(_adapter, path2, options, callback);
|
|
3243
4210
|
}
|
|
4211
|
+
/**
|
|
4212
|
+
* Read directory from DB.
|
|
4213
|
+
*
|
|
4214
|
+
* This function reads the content of directory from DB for given adapter and path.
|
|
4215
|
+
* If getEnum called with no enum specified, all enums will be returned:
|
|
4216
|
+
* ```js
|
|
4217
|
+
* adapter.readDir('vis-2.0', '/main/', function (err, filesOrDirs) {
|
|
4218
|
+
* // All enums
|
|
4219
|
+
* if (err) adapter.log.error('Cannot read directory: ' + err);
|
|
4220
|
+
* if (filesOrDirs) {
|
|
4221
|
+
* for (var f = 0; f < filesOrDirs.length; f++) {
|
|
4222
|
+
* adapter.log.debug('Directory main has the following files and dirs: ' + filesOrDirs[f].file + '[dir - ' + filesOrDirs[f].isDir + ']');
|
|
4223
|
+
* }
|
|
4224
|
+
* }
|
|
4225
|
+
* });
|
|
4226
|
+
* ```
|
|
4227
|
+
*
|
|
4228
|
+
* @param _adapter adapter name. If the adapter name is null, so the name (not instance) of the current adapter will be taken.
|
|
4229
|
+
* @param path path to directory without adapter name. E.g., If you want to read "/vis-2.0/main/views.json", here must be "/main/views.json" and _adapter must be equal to "vis-2.0".
|
|
4230
|
+
* @param options optional user context
|
|
4231
|
+
* @param callback return result
|
|
4232
|
+
* ```js
|
|
4233
|
+
* function (err, filesOrDirs) {
|
|
4234
|
+
* // filesOrDirs is array with elements like
|
|
4235
|
+
* // {
|
|
4236
|
+
* // file: 'views.json,
|
|
4237
|
+
* // stats: node.js stats object like https://nodejs.org/api/fs.html#fs_class_fs_stats ,
|
|
4238
|
+
* // isDir: true/false,
|
|
4239
|
+
* // acl: access control list object,
|
|
4240
|
+
* // modifiedAt: time when modified,
|
|
4241
|
+
* // createdAt: time when created
|
|
4242
|
+
* // }
|
|
4243
|
+
* }
|
|
4244
|
+
* ```
|
|
4245
|
+
*/
|
|
3244
4246
|
readDir(_adapter, path2, options, callback) {
|
|
3245
4247
|
if (_adapter === null) {
|
|
3246
4248
|
_adapter = this.name;
|
|
@@ -3322,6 +4324,28 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3322
4324
|
}
|
|
3323
4325
|
this.#objects.mkdir(_adapter, dirname, options, callback);
|
|
3324
4326
|
}
|
|
4327
|
+
/**
|
|
4328
|
+
* Read file from DB.
|
|
4329
|
+
*
|
|
4330
|
+
* This function reads the content of one file from DB for given adapter and file name.
|
|
4331
|
+
* ```js
|
|
4332
|
+
* adapter.readFile('vis-2.0', '/main/vis-views.json', function (err, data) {
|
|
4333
|
+
* // All enums
|
|
4334
|
+
* if (err) adapter.log.error('Cannot read file: ' + err);
|
|
4335
|
+
* adapter.log.info('Content of file is: ' + data);
|
|
4336
|
+
* });
|
|
4337
|
+
* ```
|
|
4338
|
+
*
|
|
4339
|
+
* @param _adapter adapter name. If the adapter name is null, so the name (not instance) of the current adapter will be taken.
|
|
4340
|
+
* @param filename path to file without adapter name. E.g., If you want to read "/vis-2.0/main/views.json", here must be "/main/views.json" and _adapter must be equal to "vis-2.0".
|
|
4341
|
+
* @param options optional user context
|
|
4342
|
+
* @param callback return result
|
|
4343
|
+
* ```js
|
|
4344
|
+
* function (err, data) {
|
|
4345
|
+
* // data is utf8 or binary Buffer depends on the file extension.
|
|
4346
|
+
* }
|
|
4347
|
+
* ```
|
|
4348
|
+
*/
|
|
3325
4349
|
readFile(_adapter, filename, options, callback) {
|
|
3326
4350
|
if (_adapter === null) {
|
|
3327
4351
|
_adapter = this.name;
|
|
@@ -3342,6 +4366,27 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3342
4366
|
}
|
|
3343
4367
|
this.#objects.readFile(_adapter, filename, options, callback);
|
|
3344
4368
|
}
|
|
4369
|
+
/**
|
|
4370
|
+
* Write file to DB.
|
|
4371
|
+
*
|
|
4372
|
+
* This function writes the content of one file into DB for given adapter and file name.
|
|
4373
|
+
* ```js
|
|
4374
|
+
* adapter.writeFile('vis-2.0', '/main/vis-views.json', data, function (err) {
|
|
4375
|
+
* err && adapter.log.error('Cannot write file: ' + err);
|
|
4376
|
+
* });
|
|
4377
|
+
* ```
|
|
4378
|
+
*
|
|
4379
|
+
* @param _adapter adapter name. If the adapter name is null, so the name (not instance) of the current adapter will be taken.
|
|
4380
|
+
* @param filename path to file without adapter name. E.g., If you want to read "/vis-2.0/main/views.json", here must be "/main/views.json" and _adapter must be equal to "vis-2.0".
|
|
4381
|
+
* @param data data as UTF8 string or buffer depends on the file extension.
|
|
4382
|
+
* @param options optional user context
|
|
4383
|
+
* @param callback return result
|
|
4384
|
+
* ```js
|
|
4385
|
+
* function (err) {
|
|
4386
|
+
*
|
|
4387
|
+
* }
|
|
4388
|
+
* ```
|
|
4389
|
+
*/
|
|
3345
4390
|
writeFile(_adapter, filename, data, options, callback) {
|
|
3346
4391
|
if (_adapter === null) {
|
|
3347
4392
|
_adapter = this.name;
|
|
@@ -3365,6 +4410,14 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3365
4410
|
}
|
|
3366
4411
|
return this.#objects.writeFile(_adapter, filename, data, options, callback);
|
|
3367
4412
|
}
|
|
4413
|
+
/**
|
|
4414
|
+
* Checks if file exists in DB.
|
|
4415
|
+
*
|
|
4416
|
+
* @param _adapter adapter name
|
|
4417
|
+
* @param filename path to file without adapter name. E.g., If you want to check "/vis-2.0/main/views.json", here must be "/main/views.json" and _adapter must be equal to "vis-2.0".
|
|
4418
|
+
* @param options optional user context
|
|
4419
|
+
* @param callback cb function if none provided, a promise is returned
|
|
4420
|
+
*/
|
|
3368
4421
|
async fileExists(_adapter, filename, options, callback) {
|
|
3369
4422
|
if (typeof options === "function") {
|
|
3370
4423
|
callback = options;
|
|
@@ -3392,11 +4445,17 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3392
4445
|
_format = decimals;
|
|
3393
4446
|
decimals = 2;
|
|
3394
4447
|
}
|
|
3395
|
-
const format =
|
|
4448
|
+
const format = (
|
|
4449
|
+
// @ts-expect-error fix later
|
|
4450
|
+
!_format || _format.length !== 2 ? this.isFloatComma === void 0 ? ".," : this.isFloatComma ? ".," : ",." : _format
|
|
4451
|
+
);
|
|
3396
4452
|
if (typeof value !== "number") {
|
|
3397
4453
|
value = parseFloat(value);
|
|
3398
4454
|
}
|
|
3399
|
-
return isNaN(value) ? "" :
|
|
4455
|
+
return isNaN(value) ? "" : (
|
|
4456
|
+
// @ts-expect-error fix later
|
|
4457
|
+
value.toFixed(decimals).replace(format[0], format[1]).replace(/\B(?=(\d{3})+(?!\d))/g, format[0])
|
|
4458
|
+
);
|
|
3400
4459
|
}
|
|
3401
4460
|
formatDate(dateObj, isDuration, _format) {
|
|
3402
4461
|
if (typeof isDuration === "string" && isDuration.toLowerCase() === "duration" || isDuration === true) {
|
|
@@ -3535,6 +4594,24 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3535
4594
|
put(s);
|
|
3536
4595
|
return result;
|
|
3537
4596
|
}
|
|
4597
|
+
/**
|
|
4598
|
+
* Send message to other adapter instance or all instances of adapter.
|
|
4599
|
+
*
|
|
4600
|
+
* This function sends a message to specific instance or all instances of some specific adapter.
|
|
4601
|
+
* If no instance given (e.g. "pushover"), the callback argument will be ignored. Because normally many responses will come.
|
|
4602
|
+
*
|
|
4603
|
+
* @param instanceName name of the instance where the message must be sent to. E.g. "pushover.0" or "system.adapter.pushover.0".
|
|
4604
|
+
* @param command command name, like "send", "browse", "list". Command is depend on target adapter implementation.
|
|
4605
|
+
* @param message object that will be given as argument for request
|
|
4606
|
+
* @param callback optional return result
|
|
4607
|
+
* ```js
|
|
4608
|
+
* function (result) {
|
|
4609
|
+
* // result is target adapter specific and can vary from adapter to adapter
|
|
4610
|
+
* if (!result) adapter.log.error('No response received');
|
|
4611
|
+
* }
|
|
4612
|
+
* ```
|
|
4613
|
+
* @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)
|
|
4614
|
+
*/
|
|
3538
4615
|
sendTo(instanceName, command, message, callback, options) {
|
|
3539
4616
|
if (typeof message === "function" && typeof callback === "undefined") {
|
|
3540
4617
|
callback = message;
|
|
@@ -3560,6 +4637,15 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3560
4637
|
callback
|
|
3561
4638
|
});
|
|
3562
4639
|
}
|
|
4640
|
+
/**
|
|
4641
|
+
* Async version of sendTo
|
|
4642
|
+
* As we have a special case (first arg can be error or result, we need to promisify manually)
|
|
4643
|
+
*
|
|
4644
|
+
* @param instanceName name of the instance where the message must be sent to. E.g. "pushover.0" or "system.adapter.pushover.0".
|
|
4645
|
+
* @param command command name, like "send", "browse", "list". Command is depend on target adapter implementation.
|
|
4646
|
+
* @param message object that will be given as argument for request
|
|
4647
|
+
* @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)
|
|
4648
|
+
*/
|
|
3563
4649
|
sendToAsync(instanceName, command, message, options) {
|
|
3564
4650
|
return new Promise((resolve, reject) => {
|
|
3565
4651
|
const callback = (resOrError) => {
|
|
@@ -3661,6 +4747,23 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3661
4747
|
}
|
|
3662
4748
|
}
|
|
3663
4749
|
}
|
|
4750
|
+
/**
|
|
4751
|
+
* Send message to specific host or to all hosts.
|
|
4752
|
+
*
|
|
4753
|
+
* This function sends a message to specific host or all hosts.
|
|
4754
|
+
* If no host name given (e.g. null), the callback argument will be ignored. Because normally many responses will come.
|
|
4755
|
+
*
|
|
4756
|
+
* @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.
|
|
4757
|
+
* @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)
|
|
4758
|
+
* @param message object that will be given as argument for request
|
|
4759
|
+
* @param callback optional return result
|
|
4760
|
+
* ```js
|
|
4761
|
+
* function (result) {
|
|
4762
|
+
* // result is target adapter specific and can vary from command to command
|
|
4763
|
+
* if (!result) adapter.log.error('No response received');
|
|
4764
|
+
* }
|
|
4765
|
+
* ```
|
|
4766
|
+
*/
|
|
3664
4767
|
sendToHost(hostName, command, message, callback) {
|
|
3665
4768
|
if (typeof message === "undefined") {
|
|
3666
4769
|
message = command;
|
|
@@ -3745,6 +4848,11 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3745
4848
|
}
|
|
3746
4849
|
}
|
|
3747
4850
|
}
|
|
4851
|
+
/**
|
|
4852
|
+
* Send a message to an active UI Client
|
|
4853
|
+
*
|
|
4854
|
+
* @param options clientId and data options
|
|
4855
|
+
*/
|
|
3748
4856
|
sendToUI(options) {
|
|
3749
4857
|
if (!this.#states) {
|
|
3750
4858
|
throw new Error(import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
@@ -3763,6 +4871,14 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3763
4871
|
states: this.#states
|
|
3764
4872
|
});
|
|
3765
4873
|
}
|
|
4874
|
+
/**
|
|
4875
|
+
* Send notification with given scope and category to host of this adapter
|
|
4876
|
+
*
|
|
4877
|
+
* @param scope - scope to be addressed
|
|
4878
|
+
* @param category - to be addressed, if a null message will be checked by regex of given scope
|
|
4879
|
+
* @param message - message to be stored/checked
|
|
4880
|
+
* @param options - Additional options for the notification, currently `contextData` is supported
|
|
4881
|
+
*/
|
|
3766
4882
|
async registerNotification(scope, category, message, options) {
|
|
3767
4883
|
if (!this.#states) {
|
|
3768
4884
|
this._logger.info(`${this.namespaceLog} registerNotification not processed because States database not connected`);
|
|
@@ -3789,6 +4905,37 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3789
4905
|
};
|
|
3790
4906
|
await this.#states.pushMessage(`system.host.${this.host}`, obj);
|
|
3791
4907
|
}
|
|
4908
|
+
/**
|
|
4909
|
+
* Writes value into states DB.
|
|
4910
|
+
*
|
|
4911
|
+
* This function can write values into states DB for this adapter.
|
|
4912
|
+
* Only Ids that belong to this adapter can be modified. So the function automatically adds "adapter.X." to ID.
|
|
4913
|
+
* ack, options and callback are optional
|
|
4914
|
+
*
|
|
4915
|
+
* @param id object ID of the state.
|
|
4916
|
+
* @param state simple value or object with attributes.
|
|
4917
|
+
* If state is object and ack exists too as function argument, function argument has priority.
|
|
4918
|
+
* ```js
|
|
4919
|
+
* {
|
|
4920
|
+
* val: value,
|
|
4921
|
+
* ack: true|false, // default - false; is command(false) or status(true)
|
|
4922
|
+
* ts: timestampMS, // default - now
|
|
4923
|
+
* q: qualityAsNumber, // default - 0 (ok)
|
|
4924
|
+
* from: origin, // default - this adapter
|
|
4925
|
+
* c: comment, // default - empty
|
|
4926
|
+
* expire: expireInSeconds // default - 0
|
|
4927
|
+
* lc: timestampMS // default - automatic calculation
|
|
4928
|
+
* }
|
|
4929
|
+
* ```
|
|
4930
|
+
* @param ack optional is command(false) or status(true)
|
|
4931
|
+
* @param options optional user context
|
|
4932
|
+
* @param callback optional return error and id
|
|
4933
|
+
* ```js
|
|
4934
|
+
* function (err, id) {
|
|
4935
|
+
* if (err) adapter.log.error('Cannot set value for "' + id + '": ' + err);
|
|
4936
|
+
* }
|
|
4937
|
+
* ```
|
|
4938
|
+
*/
|
|
3792
4939
|
setState(id, state, ack, options, callback) {
|
|
3793
4940
|
if (typeof state === "object" && typeof ack !== "boolean") {
|
|
3794
4941
|
callback = options;
|
|
@@ -3928,6 +5075,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3928
5075
|
}
|
|
3929
5076
|
}
|
|
3930
5077
|
}
|
|
5078
|
+
// Cache will be cleared if user or group changes. Important! only if subscribed.
|
|
3931
5079
|
async _getUserGroups(options) {
|
|
3932
5080
|
if (this.users[options.user]) {
|
|
3933
5081
|
options.groups = this.users[options.user].groups;
|
|
@@ -3958,6 +5106,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
3958
5106
|
}
|
|
3959
5107
|
this.users[options.user] = {
|
|
3960
5108
|
groups: options.groups,
|
|
5109
|
+
// @ts-expect-error TODO: UserCommon has no acl
|
|
3961
5110
|
acl: userAcl.common?.acl || {}
|
|
3962
5111
|
};
|
|
3963
5112
|
await this._getGroups(options.groups);
|
|
@@ -4226,6 +5375,25 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4226
5375
|
return { id, notChanged: true };
|
|
4227
5376
|
}
|
|
4228
5377
|
}
|
|
5378
|
+
/**
|
|
5379
|
+
* Writes value into states DB only if the value really changed.
|
|
5380
|
+
*
|
|
5381
|
+
* This function can write values into states DB for this adapter.
|
|
5382
|
+
* Only Ids that belong to this adapter can be modified. So the function automatically adds "adapter.X." to ID.
|
|
5383
|
+
* ack, options and callback are optional
|
|
5384
|
+
*
|
|
5385
|
+
* @param id object ID of the state.
|
|
5386
|
+
* @param state simple value or object with attribues.
|
|
5387
|
+
* @param ack optional is command(false) or status(true)
|
|
5388
|
+
* @param options optional user context
|
|
5389
|
+
* @param callback optional return error, id and notChanged
|
|
5390
|
+
* ```js
|
|
5391
|
+
* function (err, id, notChanged) {
|
|
5392
|
+
* if (err) adapter.log.error('Cannot set value for "' + id + '": ' + err);
|
|
5393
|
+
* if (!notChanged) adapter.log.debug('Value was changed');
|
|
5394
|
+
* }
|
|
5395
|
+
* ```
|
|
5396
|
+
*/
|
|
4229
5397
|
setStateChanged(id, state, ack, options, callback) {
|
|
4230
5398
|
if (typeof state === "object" && typeof ack !== "boolean") {
|
|
4231
5399
|
callback = options;
|
|
@@ -4294,6 +5462,36 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4294
5462
|
const res = await this._setStateChangedHelper(fixedId, stateObj);
|
|
4295
5463
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, null, res.id, res.notChanged);
|
|
4296
5464
|
}
|
|
5465
|
+
/**
|
|
5466
|
+
* Writes value into states DB for any instance.
|
|
5467
|
+
*
|
|
5468
|
+
* This function can write values into states DB for all instances and system states too.
|
|
5469
|
+
* ack, options and callback are optional
|
|
5470
|
+
*
|
|
5471
|
+
* @param id object ID of the state.
|
|
5472
|
+
* @param state simple value or object with attribues.
|
|
5473
|
+
* If state is object, so the ack will be ignored and must be included into object.
|
|
5474
|
+
* ```js
|
|
5475
|
+
* {
|
|
5476
|
+
* val: value,
|
|
5477
|
+
* ack: true|false, // default - false; is command(false) or status(true)
|
|
5478
|
+
* ts: timestampMS, // default - now
|
|
5479
|
+
* q: qualityAsNumber, // default - 0 (ok)
|
|
5480
|
+
* from: origin, // default - this adapter
|
|
5481
|
+
* c: comment, // default - empty
|
|
5482
|
+
* expire: expireInSeconds // default - 0
|
|
5483
|
+
* lc: timestampMS // default - automatic calculation
|
|
5484
|
+
* }
|
|
5485
|
+
* ```
|
|
5486
|
+
* @param ack optional is command(false) or status(true)
|
|
5487
|
+
* @param options optional user context
|
|
5488
|
+
* @param callback optional return error and id
|
|
5489
|
+
* ```js
|
|
5490
|
+
* function (err, id) {
|
|
5491
|
+
* if (err) adapter.log.error('Cannot set value for "' + id + '": ' + err);
|
|
5492
|
+
* }
|
|
5493
|
+
* ```
|
|
5494
|
+
*/
|
|
4297
5495
|
async setForeignState(id, state, ack, options, callback) {
|
|
4298
5496
|
if (typeof state === "object" && typeof ack !== "boolean") {
|
|
4299
5497
|
callback = options;
|
|
@@ -4460,6 +5658,36 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4460
5658
|
}
|
|
4461
5659
|
}
|
|
4462
5660
|
}
|
|
5661
|
+
/**
|
|
5662
|
+
* Writes value into states DB for any instance, but only if state changed.
|
|
5663
|
+
*
|
|
5664
|
+
* This function can write values into states DB for all instances and system states too.
|
|
5665
|
+
* ack, options and callback are optional
|
|
5666
|
+
*
|
|
5667
|
+
* @param id object ID of the state.
|
|
5668
|
+
* @param state simple value or object with attribues.
|
|
5669
|
+
* If state is object and ack exists too as function argument, function argument has priority.
|
|
5670
|
+
* ```js
|
|
5671
|
+
* {
|
|
5672
|
+
* val: value,
|
|
5673
|
+
* ack: true|false, // default - false; is command(false) or status(true)
|
|
5674
|
+
* ts: timestampMS, // default - now
|
|
5675
|
+
* q: qualityAsNumber, // default - 0 (ok)
|
|
5676
|
+
* from: origin, // default - this adapter
|
|
5677
|
+
* c: comment, // default - empty
|
|
5678
|
+
* expire: expireInSeconds // default - 0
|
|
5679
|
+
* lc: timestampMS // default - automatic calculation
|
|
5680
|
+
* }
|
|
5681
|
+
* ```
|
|
5682
|
+
* @param ack optional is command(false) or status(true)
|
|
5683
|
+
* @param options optional user context
|
|
5684
|
+
* @param callback optional return error and id
|
|
5685
|
+
* ```js
|
|
5686
|
+
* function (err, id) {
|
|
5687
|
+
* if (err) adapter.log.error('Cannot set value for "' + id + '": ' + err);
|
|
5688
|
+
* }
|
|
5689
|
+
* ```
|
|
5690
|
+
*/
|
|
4463
5691
|
async setForeignStateChanged(id, state, ack, options, callback) {
|
|
4464
5692
|
if (typeof state === "object" && typeof ack !== "boolean") {
|
|
4465
5693
|
callback = options;
|
|
@@ -4513,6 +5741,23 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4513
5741
|
const res = await this._setStateChangedHelper(id, state);
|
|
4514
5742
|
return import_js_controller_common.tools.maybeCallbackWithError(callback, null, res.id, res.notChanged);
|
|
4515
5743
|
}
|
|
5744
|
+
/**
|
|
5745
|
+
* Read value from states DB.
|
|
5746
|
+
*
|
|
5747
|
+
* This function can read values from states DB for this adapter.
|
|
5748
|
+
* Only Ids that belong to this adapter can be read. So the function automatically adds "adapter.X." to ID.
|
|
5749
|
+
*
|
|
5750
|
+
* @param id object ID of the state.
|
|
5751
|
+
* @param options optional user context
|
|
5752
|
+
* @param callback return result
|
|
5753
|
+
* ```js
|
|
5754
|
+
* function (err, state) {
|
|
5755
|
+
* if (err) adapter.log.error('Cannot read value: ' + err);
|
|
5756
|
+
* }
|
|
5757
|
+
* ```
|
|
5758
|
+
*
|
|
5759
|
+
* See possible attributes of the state in @setState explanation
|
|
5760
|
+
*/
|
|
4516
5761
|
getState(id, options, callback) {
|
|
4517
5762
|
if (!import_js_controller_common.tools.isObject(id)) {
|
|
4518
5763
|
import_validator.Validator.assertString(id, "id");
|
|
@@ -4520,6 +5765,22 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4520
5765
|
const fixedId = this._utils.fixId(id, false);
|
|
4521
5766
|
return this.getForeignState(fixedId, options, callback);
|
|
4522
5767
|
}
|
|
5768
|
+
/**
|
|
5769
|
+
* Read value from states DB for any instance and system state.
|
|
5770
|
+
*
|
|
5771
|
+
* This function can read values from states DB for all instances and adapters. It expects the full path of object ID.
|
|
5772
|
+
*
|
|
5773
|
+
* @param id object ID of the state.
|
|
5774
|
+
* @param options optional user context
|
|
5775
|
+
* @param callback return result
|
|
5776
|
+
* ```js
|
|
5777
|
+
* function (err, state) {
|
|
5778
|
+
* if (err) adapter.log.error('Cannot read value: ' + err);
|
|
5779
|
+
* }
|
|
5780
|
+
* ```
|
|
5781
|
+
*
|
|
5782
|
+
* See possible attributes of the state in @setState explanation
|
|
5783
|
+
*/
|
|
4523
5784
|
getForeignState(id, options, callback) {
|
|
4524
5785
|
if (typeof options === "function") {
|
|
4525
5786
|
callback = options;
|
|
@@ -4611,6 +5872,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4611
5872
|
return this.#states.getState(id, callback);
|
|
4612
5873
|
}
|
|
4613
5874
|
}
|
|
5875
|
+
// find out default history instance
|
|
4614
5876
|
async _getDefaultHistory() {
|
|
4615
5877
|
if (!this.defaultHistory) {
|
|
4616
5878
|
let data;
|
|
@@ -4647,6 +5909,46 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4647
5909
|
}
|
|
4648
5910
|
}
|
|
4649
5911
|
}
|
|
5912
|
+
/**
|
|
5913
|
+
* Read historian data for states of any instance or system state.
|
|
5914
|
+
*
|
|
5915
|
+
* This function can read values from history adapters like: history, sql, influxdb. It expects the full path of object ID.
|
|
5916
|
+
* Normally only foreign history has interest, so there is no getHistory and getForeignHistory
|
|
5917
|
+
*
|
|
5918
|
+
* Possible options:
|
|
5919
|
+
*
|
|
5920
|
+
* - instance - (optional) name of instance, where to read the historian data, e.g. 'history.0', 'sql.1'. By default, will be taken from system settings.
|
|
5921
|
+
* - start - (optional) time in ms - Date.now()', by default is (now - 1 week)
|
|
5922
|
+
* - end - (optional) time in ms - Date.now()', by default is (now + 5000 seconds)
|
|
5923
|
+
* - step - (optional) used in aggregate (m4, max, min, average, total) step in ms of intervals
|
|
5924
|
+
* - count - number of values if aggregate is 'onchange' or number of intervals if other aggregate method. Count will be ignored if step is set.
|
|
5925
|
+
* - from - if from field should be included in answer
|
|
5926
|
+
* - ack - if ack field should be included in answer
|
|
5927
|
+
* - q - if q field should be included in answer
|
|
5928
|
+
* - addId - if id field should be included in answer
|
|
5929
|
+
* - limit - do not return more entries than limit
|
|
5930
|
+
* - ignoreNull - if null values should be included (false), replaced by last not null value (true) or replaced with 0 (0)
|
|
5931
|
+
* - sessionId - (optional) identifier of request, will be returned back in the answer
|
|
5932
|
+
* - aggregate - aggregate method:
|
|
5933
|
+
* - minmax - used special algorithm. Splice the whole time range in small intervals and find for every interval max, min, start and end values.
|
|
5934
|
+
* - max - Splice the whole time range in small intervals and find for every interval max value and use it for this interval (nulls will be ignored).
|
|
5935
|
+
* - min - Same as max, but take minimal value.
|
|
5936
|
+
* - average - Same as max, but take average value.
|
|
5937
|
+
* - total - Same as max, but calculate total value.
|
|
5938
|
+
* - count - Same as max, but calculate number of values (nulls will be calculated).
|
|
5939
|
+
* - none - No aggregation at all. Only raw values in the given period.
|
|
5940
|
+
*
|
|
5941
|
+
* @param id object ID of the state.
|
|
5942
|
+
* @param options see function description
|
|
5943
|
+
* @param callback return result
|
|
5944
|
+
* ```js
|
|
5945
|
+
* function (error, result, step, sessionId) {
|
|
5946
|
+
* if (error) adapter.log.error('Cannot read value: ' + err);
|
|
5947
|
+
* }
|
|
5948
|
+
* ```
|
|
5949
|
+
*
|
|
5950
|
+
* See possible attributes of the state in @setState explanation
|
|
5951
|
+
*/
|
|
4650
5952
|
getHistory(id, options, callback) {
|
|
4651
5953
|
if (typeof options === "function") {
|
|
4652
5954
|
callback = options;
|
|
@@ -4659,6 +5961,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4659
5961
|
import_validator.Validator.assertCallback(callback, "callback");
|
|
4660
5962
|
return this._getHistory({ id, options, callback });
|
|
4661
5963
|
}
|
|
5964
|
+
// Checked implementation
|
|
4662
5965
|
async _getHistory(_options) {
|
|
4663
5966
|
const { id, callback } = _options;
|
|
4664
5967
|
let { options } = _options;
|
|
@@ -4683,6 +5986,15 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4683
5986
|
import_js_controller_common.tools.maybeCallbackWithError(callback, res.error, res.result, res.step, res.sessionId);
|
|
4684
5987
|
});
|
|
4685
5988
|
}
|
|
5989
|
+
/**
|
|
5990
|
+
* Convert ID into object with device's, channel's and state's name.
|
|
5991
|
+
*
|
|
5992
|
+
* Convert "adapter.instance.D.C.S" in object `{device: D, channel: C, state: S}`
|
|
5993
|
+
* Convert ID to `{device: D, channel: C, state: S}`
|
|
5994
|
+
*
|
|
5995
|
+
* @param id short or long string of ID like "stateID" or "adapterName.0.stateID".
|
|
5996
|
+
* @returns parsed ID as an object
|
|
5997
|
+
*/
|
|
4686
5998
|
idToDCS(id) {
|
|
4687
5999
|
if (!id) {
|
|
4688
6000
|
return null;
|
|
@@ -4695,6 +6007,24 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4695
6007
|
}
|
|
4696
6008
|
return { device: parts[2], channel: parts[3], state: parts[4] };
|
|
4697
6009
|
}
|
|
6010
|
+
/**
|
|
6011
|
+
* Deletes a state of this instance.
|
|
6012
|
+
* The object will NOT be deleted. If you want to delete it too, use @delObject instead.
|
|
6013
|
+
*
|
|
6014
|
+
* It is not required to provice the adapter namespace, because it will automatically be added.
|
|
6015
|
+
* E.g. to delete "adapterName.X.myObject", only "myObject" is required as ID.
|
|
6016
|
+
*
|
|
6017
|
+
* No error is returned if state does not exist.
|
|
6018
|
+
*
|
|
6019
|
+
* @param id exactly object ID (without namespace)
|
|
6020
|
+
* @param options optional user context
|
|
6021
|
+
* @param callback return result
|
|
6022
|
+
* ```js
|
|
6023
|
+
* function (err) {
|
|
6024
|
+
* if (err) adapter.log.error('Cannot delete object: ' + err);
|
|
6025
|
+
* }
|
|
6026
|
+
* ```
|
|
6027
|
+
*/
|
|
4698
6028
|
delState(id, options, callback) {
|
|
4699
6029
|
if (typeof options === "function") {
|
|
4700
6030
|
callback = options;
|
|
@@ -4718,6 +6048,19 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4718
6048
|
id = this._utils.fixId(id);
|
|
4719
6049
|
return this.delForeignState(id, options, callback);
|
|
4720
6050
|
}
|
|
6051
|
+
/**
|
|
6052
|
+
* Deletes a state of any adapter.
|
|
6053
|
+
* The object is NOT deleted. If you want to delete it too, use @delForeignObject instead.
|
|
6054
|
+
*
|
|
6055
|
+
* No error is returned if state does not exist.
|
|
6056
|
+
*
|
|
6057
|
+
* @param id long string for ID like "adapterName.0.stateID".
|
|
6058
|
+
* @param options optional argument to describe the user context
|
|
6059
|
+
* @param callback return result
|
|
6060
|
+
* ```js
|
|
6061
|
+
* function (err) {}
|
|
6062
|
+
* ```
|
|
6063
|
+
*/
|
|
4721
6064
|
delForeignState(id, options, callback) {
|
|
4722
6065
|
if (typeof options === "function") {
|
|
4723
6066
|
callback = options;
|
|
@@ -4750,6 +6093,25 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4750
6093
|
}
|
|
4751
6094
|
this.#states.delState(id, callback);
|
|
4752
6095
|
}
|
|
6096
|
+
/**
|
|
6097
|
+
* Read all states of this adapter, that pass the pattern
|
|
6098
|
+
*
|
|
6099
|
+
* Allows to read all states of current adapter according to pattern. To read all states of current adapter use:
|
|
6100
|
+
* ```js
|
|
6101
|
+
* adapter.getStates('*', function (err, states) {
|
|
6102
|
+
* for (var id in states) {
|
|
6103
|
+
* adapter.log.debug('"' + id + '" = "' + states[id].val);
|
|
6104
|
+
* }
|
|
6105
|
+
* });
|
|
6106
|
+
* ```
|
|
6107
|
+
*
|
|
6108
|
+
* @param pattern string in form 'adapter.0.*' or like this. It can be an array of IDs too.
|
|
6109
|
+
* @param options optional argument to describe the user context
|
|
6110
|
+
* @param callback return result
|
|
6111
|
+
* ```js
|
|
6112
|
+
* function (err, states) {}, where states is an object like {"ID1": {"val": 1, "ack": true}, "ID2": {"val": 2, "ack": false}, ...}
|
|
6113
|
+
* ```
|
|
6114
|
+
*/
|
|
4753
6115
|
getStates(pattern, options, callback) {
|
|
4754
6116
|
if (typeof options === "function") {
|
|
4755
6117
|
callback = options;
|
|
@@ -4785,6 +6147,13 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4785
6147
|
}
|
|
4786
6148
|
return result;
|
|
4787
6149
|
}
|
|
6150
|
+
/**
|
|
6151
|
+
* Ensures, that object information is read, and the alias id is mapped to the source id if an alias is contained in the getStates call
|
|
6152
|
+
* The adaption of the actual values is then performed in _processStatesSecondary, to apply alias conversion methods
|
|
6153
|
+
*
|
|
6154
|
+
* @param keys all ids of the getStates call
|
|
6155
|
+
* @param targetObjs the target objects (e.g. alias objects or the actual objects)
|
|
6156
|
+
*/
|
|
4788
6157
|
async _processStates(keys, targetObjs) {
|
|
4789
6158
|
const aliasIndexes = [];
|
|
4790
6159
|
const aliasIds = [];
|
|
@@ -4815,6 +6184,25 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4815
6184
|
}
|
|
4816
6185
|
return this._processStatesSecondary(keys, null, null);
|
|
4817
6186
|
}
|
|
6187
|
+
/**
|
|
6188
|
+
* Read all states of all adapters (and system states), that pass the pattern
|
|
6189
|
+
*
|
|
6190
|
+
* Allows to read all states of current adapter according to pattern. To read all states of current adapter use:
|
|
6191
|
+
* ```js
|
|
6192
|
+
* adapter.getStates('*', function (err, states) {
|
|
6193
|
+
* for (var id in states) {
|
|
6194
|
+
* adapter.log.debug('"' + id + '" = "' + states[id].val);
|
|
6195
|
+
* }
|
|
6196
|
+
* });
|
|
6197
|
+
* ```
|
|
6198
|
+
*
|
|
6199
|
+
* @param pattern string in form 'adapter.0.*' or like this. It can be an array of IDs too.
|
|
6200
|
+
* @param options optional argument to describe the user context
|
|
6201
|
+
* @param callback return result
|
|
6202
|
+
* ```js
|
|
6203
|
+
* function (err, states) {}, where states is an object like {"ID1": {"val": 1, "ack": true}, "ID2": {"val": 2, "ack": false}, ...}
|
|
6204
|
+
* ```
|
|
6205
|
+
*/
|
|
4818
6206
|
getForeignStates(pattern, options, callback) {
|
|
4819
6207
|
if (typeof options === "function") {
|
|
4820
6208
|
callback = options;
|
|
@@ -4910,6 +6298,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4910
6298
|
}
|
|
4911
6299
|
}
|
|
4912
6300
|
}
|
|
6301
|
+
/**
|
|
6302
|
+
* Add subscription for given alias, if it is not a state it will be ignored
|
|
6303
|
+
*
|
|
6304
|
+
* @param aliasObj the alias object
|
|
6305
|
+
* @param pattern pattern to subscribe for
|
|
6306
|
+
*/
|
|
4913
6307
|
async _addAliasSubscribe(aliasObj, pattern) {
|
|
4914
6308
|
if (aliasObj.type !== "state") {
|
|
4915
6309
|
return;
|
|
@@ -4954,6 +6348,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4954
6348
|
}
|
|
4955
6349
|
aliasDetails.targets.push(targetEntry);
|
|
4956
6350
|
}
|
|
6351
|
+
/**
|
|
6352
|
+
* Remove an alias subscribe
|
|
6353
|
+
*
|
|
6354
|
+
* @param sourceId id of the source object
|
|
6355
|
+
* @param aliasObjOrIdx the alias target or the index of the targets array
|
|
6356
|
+
*/
|
|
4957
6357
|
async _removeAliasSubscribe(sourceId, aliasObjOrIdx) {
|
|
4958
6358
|
if (!this.aliases.has(sourceId)) {
|
|
4959
6359
|
return;
|
|
@@ -4968,6 +6368,18 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
4968
6368
|
}
|
|
4969
6369
|
}
|
|
4970
6370
|
}
|
|
6371
|
+
/**
|
|
6372
|
+
* Subscribe for changes on all states of all adapters (and system states), that pass the pattern
|
|
6373
|
+
*
|
|
6374
|
+
* Allows to Subscribe on changes all states of all instances according to pattern. E.g. to read all states of 'adapterName.X' instance use:
|
|
6375
|
+
* ```js
|
|
6376
|
+
* adapter.subscribeForeignStates('adapterName.X.*');
|
|
6377
|
+
* ```
|
|
6378
|
+
*
|
|
6379
|
+
* @param pattern string in form 'adapter.0.*' or like this. It can be an array of IDs too.
|
|
6380
|
+
* @param options optional argument to describe the user context
|
|
6381
|
+
* @param callback return result ```function (err) {}```
|
|
6382
|
+
*/
|
|
4971
6383
|
subscribeForeignStates(pattern, options, callback) {
|
|
4972
6384
|
pattern = pattern || "*";
|
|
4973
6385
|
if (typeof options === "function") {
|
|
@@ -5113,6 +6525,23 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5113
6525
|
this.#states.subscribeUser(pattern, callback);
|
|
5114
6526
|
}
|
|
5115
6527
|
}
|
|
6528
|
+
/**
|
|
6529
|
+
* Unsubscribe for changes for given pattern
|
|
6530
|
+
*
|
|
6531
|
+
* This function allows to unsubscribe from changes. The pattern must be equal to requested one.
|
|
6532
|
+
* ```js
|
|
6533
|
+
* adapter.subscribeForeignStates('adapterName.X.*');
|
|
6534
|
+
* adapter.unsubscribeForeignStates('adapterName.X.abc*'); // This will not work
|
|
6535
|
+
* adapter.unsubscribeForeignStates('adapterName.X.*'); // Valid unsubscribe
|
|
6536
|
+
* ```
|
|
6537
|
+
*
|
|
6538
|
+
* @param pattern string in form 'adapter.0.*'. Must be the same as subscribe.
|
|
6539
|
+
* @param options optional argument to describe the user context
|
|
6540
|
+
* @param callback return result
|
|
6541
|
+
* ```js
|
|
6542
|
+
* function (err) {}
|
|
6543
|
+
* ```
|
|
6544
|
+
*/
|
|
5116
6545
|
unsubscribeForeignStates(pattern, options, callback) {
|
|
5117
6546
|
pattern = pattern || "*";
|
|
5118
6547
|
if (typeof options === "function") {
|
|
@@ -5207,6 +6636,18 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5207
6636
|
}
|
|
5208
6637
|
return import_js_controller_common.tools.maybeCallback(callback);
|
|
5209
6638
|
}
|
|
6639
|
+
/**
|
|
6640
|
+
* Subscribe for changes on all states of this instance, that pass the pattern
|
|
6641
|
+
*
|
|
6642
|
+
* Allows to Subscribe on changes all states of current adapter according to pattern. To read all states of current adapter use:
|
|
6643
|
+
* ```js
|
|
6644
|
+
* adapter.subscribeStates('*'); // subscribe for all states of this adapter
|
|
6645
|
+
* ```
|
|
6646
|
+
*
|
|
6647
|
+
* @param pattern string in form 'adapter.0.*' or like this. Only string allowed
|
|
6648
|
+
* @param options optional argument to describe the user context
|
|
6649
|
+
* @param callback optional callback
|
|
6650
|
+
*/
|
|
5210
6651
|
subscribeStates(pattern, options, callback) {
|
|
5211
6652
|
if (typeof options === "function") {
|
|
5212
6653
|
callback = options;
|
|
@@ -5223,6 +6664,20 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5223
6664
|
callback
|
|
5224
6665
|
});
|
|
5225
6666
|
}
|
|
6667
|
+
/**
|
|
6668
|
+
* Unsubscribe for changes for given pattern for own states.
|
|
6669
|
+
*
|
|
6670
|
+
* This function allows to unsubscribe from changes. The pattern must be equal to requested one.
|
|
6671
|
+
*
|
|
6672
|
+
* ```js
|
|
6673
|
+
* adapter.unsubscribeStates('abc*'); // This will not work
|
|
6674
|
+
* adapter.unsubscribeStates('*'); // Valid unsubscribe
|
|
6675
|
+
* ```
|
|
6676
|
+
*
|
|
6677
|
+
* @param pattern string in form 'adapter.0.*'. Must be the same as subscribe.
|
|
6678
|
+
* @param options optional argument to describe the user context
|
|
6679
|
+
* @param callback optional callback
|
|
6680
|
+
*/
|
|
5226
6681
|
unsubscribeStates(pattern, options, callback) {
|
|
5227
6682
|
if (typeof options === "function") {
|
|
5228
6683
|
callback = options;
|
|
@@ -5239,6 +6694,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5239
6694
|
callback
|
|
5240
6695
|
});
|
|
5241
6696
|
}
|
|
6697
|
+
/**
|
|
6698
|
+
* Return plugin instance
|
|
6699
|
+
*
|
|
6700
|
+
* @param name name of the plugin to return
|
|
6701
|
+
* @returns plugin instance or null if not existent or not isActive
|
|
6702
|
+
*/
|
|
5242
6703
|
getPluginInstance(name) {
|
|
5243
6704
|
if (!this.pluginHandler) {
|
|
5244
6705
|
return null;
|
|
@@ -5246,6 +6707,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5246
6707
|
import_validator.Validator.assertString(name, "name");
|
|
5247
6708
|
return this.pluginHandler.getPluginInstance(name);
|
|
5248
6709
|
}
|
|
6710
|
+
/**
|
|
6711
|
+
* Return plugin configuration
|
|
6712
|
+
*
|
|
6713
|
+
* @param name name of the plugin to return
|
|
6714
|
+
* @returns plugin configuration or null if not existent or not isActive
|
|
6715
|
+
*/
|
|
5249
6716
|
getPluginConfig(name) {
|
|
5250
6717
|
if (!this.pluginHandler) {
|
|
5251
6718
|
return null;
|
|
@@ -5274,6 +6741,13 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5274
6741
|
}
|
|
5275
6742
|
}
|
|
5276
6743
|
}
|
|
6744
|
+
/**
|
|
6745
|
+
* This method returns the list of license that can be used by this adapter
|
|
6746
|
+
*
|
|
6747
|
+
* @param all if return the licenses, that used by other instances (true) or only for this instance (false)
|
|
6748
|
+
* @param adapterName Return licenses for specific adapter
|
|
6749
|
+
* @returns list of suitable licenses
|
|
6750
|
+
*/
|
|
5277
6751
|
async getSuitableLicenses(all, adapterName) {
|
|
5278
6752
|
const licenses = [];
|
|
5279
6753
|
try {
|
|
@@ -5343,6 +6817,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5343
6817
|
});
|
|
5344
6818
|
return licenses;
|
|
5345
6819
|
}
|
|
6820
|
+
/**
|
|
6821
|
+
* Add given id to log redirect list
|
|
6822
|
+
*
|
|
6823
|
+
* @param isActive if id should be added or removed
|
|
6824
|
+
* @param id the id to add
|
|
6825
|
+
*/
|
|
5346
6826
|
logRedirect(isActive, id) {
|
|
5347
6827
|
if (id === `system.adapter.${this.namespace}`) {
|
|
5348
6828
|
return;
|
|
@@ -5453,6 +6933,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5453
6933
|
this.inputCount = 0;
|
|
5454
6934
|
this.outputCount = 0;
|
|
5455
6935
|
}
|
|
6936
|
+
// debug function to find error with stop logging
|
|
5456
6937
|
_checkLogging() {
|
|
5457
6938
|
let logs = [];
|
|
5458
6939
|
logs.push(`Actual Loglist - ${JSON.stringify(Array.from(this.logList))}`);
|
|
@@ -5470,7 +6951,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5470
6951
|
const objPart = obj[i];
|
|
5471
6952
|
if (objPart) {
|
|
5472
6953
|
const id = keys[i].substring(0, keys[i].length - ".logging".length);
|
|
5473
|
-
if (typeof objPart === "string" &&
|
|
6954
|
+
if (typeof objPart === "string" && // @ts-expect-error recheck code-wise this should not be possible to have a string
|
|
6955
|
+
(objPart.includes('"val":true') || objPart.includes('"val":"true"')) || typeof objPart === "object" && (objPart.val === true || objPart.val === "true")) {
|
|
5474
6956
|
logs.push(`Subscriber - ${id} ENABLED`);
|
|
5475
6957
|
} else {
|
|
5476
6958
|
if (logs) {
|
|
@@ -5492,6 +6974,9 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5492
6974
|
}
|
|
5493
6975
|
});
|
|
5494
6976
|
}
|
|
6977
|
+
/**
|
|
6978
|
+
* Initialize the logging logic
|
|
6979
|
+
*/
|
|
5495
6980
|
async _initLogging() {
|
|
5496
6981
|
if (!this.#states) {
|
|
5497
6982
|
return;
|
|
@@ -5607,6 +7092,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
5607
7092
|
};
|
|
5608
7093
|
}
|
|
5609
7094
|
}
|
|
7095
|
+
// initStates is called from initAdapter
|
|
5610
7096
|
_initStates(cb) {
|
|
5611
7097
|
this._logger.silly(`${this.namespaceLog} objectDB connected`);
|
|
5612
7098
|
this._config.states.maxQueue = this._config.states.maxQueue || 1e3;
|
|
@@ -6032,7 +7518,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6032
7518
|
}
|
|
6033
7519
|
}
|
|
6034
7520
|
if (!this._stopInProgress) {
|
|
6035
|
-
typeof this._options.objectChange === "function" &&
|
|
7521
|
+
typeof this._options.objectChange === "function" && // @ts-expect-error
|
|
7522
|
+
setImmediate(() => this._options.objectChange(id, obj));
|
|
6036
7523
|
setImmediate(() => this.emit("objectChange", id, obj));
|
|
6037
7524
|
}
|
|
6038
7525
|
}
|
|
@@ -6049,6 +7536,9 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6049
7536
|
}
|
|
6050
7537
|
});
|
|
6051
7538
|
}
|
|
7539
|
+
/**
|
|
7540
|
+
* Called if states and objects successfully initialized
|
|
7541
|
+
*/
|
|
6052
7542
|
async _prepareInitAdapter() {
|
|
6053
7543
|
if (this.terminated || !this.#objects || !this.#states) {
|
|
6054
7544
|
return;
|
|
@@ -6085,6 +7575,11 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6085
7575
|
}
|
|
6086
7576
|
}
|
|
6087
7577
|
}
|
|
7578
|
+
/**
|
|
7579
|
+
* Initialize the adapter
|
|
7580
|
+
*
|
|
7581
|
+
* @param adapterConfig the AdapterOptions or the InstanceObject, is null/undefined if it is install process
|
|
7582
|
+
*/
|
|
6088
7583
|
async _initAdapter(adapterConfig) {
|
|
6089
7584
|
await this._initLogging();
|
|
6090
7585
|
if (!this.pluginHandler) {
|
|
@@ -6148,6 +7643,7 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6148
7643
|
name = this.name;
|
|
6149
7644
|
instance = 0;
|
|
6150
7645
|
adapterConfig = adapterConfig || {
|
|
7646
|
+
// @ts-expect-error protectedNative exists on instance objects
|
|
6151
7647
|
common: { mode: "once", name, protectedNative: [] },
|
|
6152
7648
|
native: {}
|
|
6153
7649
|
};
|
|
@@ -6170,7 +7666,11 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6170
7666
|
this.config = adapterConfig.native;
|
|
6171
7667
|
this.host = adapterConfig.common.host;
|
|
6172
7668
|
this.common = adapterConfig.common;
|
|
6173
|
-
if (
|
|
7669
|
+
if (
|
|
7670
|
+
// @ts-expect-error
|
|
7671
|
+
adapterConfig.common.mode === "schedule" || // @ts-expect-error
|
|
7672
|
+
adapterConfig.common.mode === "once"
|
|
7673
|
+
) {
|
|
6174
7674
|
this.stop = (params) => this._stop({ ...params, isPause: true });
|
|
6175
7675
|
} else if (this.startedInCompactMode) {
|
|
6176
7676
|
this.stop = (params) => this._stop({ ...params, isPause: false });
|
|
@@ -6179,7 +7679,8 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6179
7679
|
this.stop = (params) => this._stop({ ...params, isPause: false });
|
|
6180
7680
|
}
|
|
6181
7681
|
this.#states.subscribe(`${import_constants2.SYSTEM_ADAPTER_PREFIX}*.logging`);
|
|
6182
|
-
if (typeof this._options.message === "function" &&
|
|
7682
|
+
if (typeof this._options.message === "function" && // @ts-expect-error, we should infer correctly that this is an InstanceObject in this case
|
|
7683
|
+
!(0, import_utils.isMessageboxSupported)(adapterConfig.common)) {
|
|
6183
7684
|
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.`);
|
|
6184
7685
|
} else if ((0, import_utils.isMessageboxSupported)(adapterConfig.common)) {
|
|
6185
7686
|
this.mboxSubscribed = true;
|
|
@@ -6294,6 +7795,9 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6294
7795
|
this.adapterReady = true;
|
|
6295
7796
|
}
|
|
6296
7797
|
}
|
|
7798
|
+
/**
|
|
7799
|
+
* Calls the ready handler, if it is an install run it calls the install handler instead
|
|
7800
|
+
*/
|
|
6297
7801
|
_callReadyHandler() {
|
|
6298
7802
|
if (this._config.isInstall && (typeof this._options.install === "function" || this.listeners("install").length)) {
|
|
6299
7803
|
if (typeof this._options.install === "function") {
|
|
@@ -6460,6 +7964,12 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6460
7964
|
setImmediate(() => this._extendObjects(tasks, callback));
|
|
6461
7965
|
}
|
|
6462
7966
|
}
|
|
7967
|
+
/**
|
|
7968
|
+
* Replaces forbidden chars in an id if present
|
|
7969
|
+
* Additionally logs a warning
|
|
7970
|
+
*
|
|
7971
|
+
* @param id the id which will be replaced
|
|
7972
|
+
*/
|
|
6463
7973
|
fixForbiddenCharsInId(id) {
|
|
6464
7974
|
const mId = id.replace(FORBIDDEN_CHARS, "_");
|
|
6465
7975
|
if (mId !== id) {
|
|
@@ -6467,6 +7977,11 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6467
7977
|
}
|
|
6468
7978
|
return mId;
|
|
6469
7979
|
}
|
|
7980
|
+
/**
|
|
7981
|
+
* This method reports deprecations via Sentry (controller own instance) and can only be used internally
|
|
7982
|
+
*
|
|
7983
|
+
* @param options information about version to remove feature and the log message
|
|
7984
|
+
*/
|
|
6470
7985
|
async reportDeprecation(options) {
|
|
6471
7986
|
if (!this.#states) {
|
|
6472
7987
|
throw new Error(import_js_controller_common.tools.ERRORS.ERROR_DB_CLOSED);
|
|
@@ -6493,13 +8008,18 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6493
8008
|
};
|
|
6494
8009
|
await this.#states.pushMessage(`system.host.${this.host}`, obj);
|
|
6495
8010
|
}
|
|
8011
|
+
/**
|
|
8012
|
+
* Initialize the plugin handler for this adapter
|
|
8013
|
+
*/
|
|
6496
8014
|
_initPluginHandler() {
|
|
6497
8015
|
const pluginSettings = {
|
|
6498
8016
|
scope: "adapter",
|
|
6499
8017
|
namespace: `system.adapter.${this.namespace}`,
|
|
6500
8018
|
logNamespace: this.namespaceLog,
|
|
8019
|
+
// @ts-expect-error
|
|
6501
8020
|
log: this._logger,
|
|
6502
8021
|
iobrokerConfig: this._config,
|
|
8022
|
+
// @ts-expect-error
|
|
6503
8023
|
parentPackage: this.pack,
|
|
6504
8024
|
controllerVersion
|
|
6505
8025
|
};
|
|
@@ -6510,6 +8030,9 @@ class AdapterClass extends import_node_events.EventEmitter {
|
|
|
6510
8030
|
this._logger.error(`Could not add plugins: ${e.message}`);
|
|
6511
8031
|
}
|
|
6512
8032
|
}
|
|
8033
|
+
/**
|
|
8034
|
+
* Initializes the adapter
|
|
8035
|
+
*/
|
|
6513
8036
|
async _init() {
|
|
6514
8037
|
const _initDBs = () => {
|
|
6515
8038
|
this._initObjects(() => {
|