iobroker.openknx 0.1.9 → 0.1.13
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/README.md +230 -81
- package/admin/i18n/de/translations.json +11 -2
- package/admin/i18n/en/translations.json +11 -2
- package/admin/i18n/es/translations.json +7 -1
- package/admin/i18n/fr/translations.json +7 -1
- package/admin/i18n/it/translations.json +7 -1
- package/admin/i18n/nl/translations.json +7 -1
- package/admin/i18n/pl/translations.json +7 -1
- package/admin/i18n/pt/translations.json +7 -1
- package/admin/i18n/ru/translations.json +7 -1
- package/admin/i18n/zh-cn/translations.json +7 -1
- package/admin/index_m.html +439 -366
- package/admin/words.js +83 -206
- package/io-package.json +9 -4
- package/lib/doubleKeyedMap.js +56 -0
- package/lib/knx/package-lock.json +675 -0
- package/lib/knx/src/dptlib/dpt11.js +1 -1
- package/lib/knx/src/dptlib/dpt14.js +1 -1
- package/lib/knx/src/dptlib/dpt18.js +1 -1
- package/lib/knx/src/dptlib/dpt2.js +5 -3
- package/lib/knx/src/dptlib/dpt21.js +4 -2
- package/lib/knx/src/dptlib/dpt232.js +1 -1
- package/lib/knx/src/dptlib/dpt237.js +1 -1
- package/lib/knx/src/dptlib/dpt3.js +1 -1
- package/lib/knx/src/dptlib/dpt4.js +1 -1
- package/lib/knx/src/dptlib/dpt7.js +8 -1
- package/lib/projectImport.js +146 -48
- package/lib/projectImport.test.js +14 -7
- package/lib/tools.js +47 -26
- package/main.js +103 -104
- package/package.json +8 -20
- package/admin/exportGA.png +0 -0
|
@@ -9,7 +9,7 @@ const util = require('util');
|
|
|
9
9
|
// DPT11.*: date
|
|
10
10
|
//
|
|
11
11
|
exports.formatAPDU = (value) => {
|
|
12
|
-
if (
|
|
12
|
+
if (value == null) return log.error('cannot write null value for DPT11');
|
|
13
13
|
switch (typeof value) {
|
|
14
14
|
case 'string':
|
|
15
15
|
case 'number':
|
|
@@ -14,7 +14,7 @@ const log = require('log-driver').logger;
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
exports.formatAPDU = (value) => {
|
|
17
|
-
if (
|
|
17
|
+
if (value == null || typeof value != 'number')
|
|
18
18
|
log.error('DPT14: Must supply a number value');
|
|
19
19
|
const apdu_data = Buffer.alloc(4);
|
|
20
20
|
apdu_data.writeFloatBE(value, 0);
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
const log = require('log-driver').logger;
|
|
26
26
|
|
|
27
27
|
exports.formatAPDU = function (value) {
|
|
28
|
-
if (
|
|
28
|
+
if (value == null) log.warn("DPT18: cannot write null value");
|
|
29
29
|
else {
|
|
30
30
|
var apdu_data = new Buffer(1);
|
|
31
31
|
if (typeof value == 'object' &&
|
|
@@ -8,18 +8,20 @@ const log = require('log-driver').logger;
|
|
|
8
8
|
// DPT2 frame description.
|
|
9
9
|
// Always 8-bit aligned.
|
|
10
10
|
exports.formatAPDU = (value) => {
|
|
11
|
-
if (
|
|
11
|
+
if (value == null) return log.error('DPT2: cannot write null value');
|
|
12
12
|
|
|
13
13
|
if (
|
|
14
14
|
typeof value === 'object' &&
|
|
15
15
|
value.hasOwnProperty('priority') &&
|
|
16
16
|
value.hasOwnProperty('data')
|
|
17
17
|
)
|
|
18
|
-
return Buffer.from([(value.priority << 1) + (value.data & 0b00000001)]);
|
|
18
|
+
return Buffer.from([((value.priority << 1) & 0b00000010) + (value.data & 0b00000001)]);
|
|
19
19
|
|
|
20
20
|
log.error('DPT2: Must supply an value {priority:<bool>, data:<bool>}');
|
|
21
21
|
// FIXME: should this return zero buffer when error? Or nothing?
|
|
22
|
-
|
|
22
|
+
//a malformed object shall not result in transmission
|
|
23
|
+
//return Buffer.from([0]);
|
|
24
|
+
return null;
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
exports.fromBuffer = (buf) => {
|
|
@@ -17,7 +17,7 @@ const log = require('log-driver').logger;
|
|
|
17
17
|
|
|
18
18
|
// FIXME: help needed
|
|
19
19
|
exports.formatAPDU = function(value) {
|
|
20
|
-
if (
|
|
20
|
+
if (value == null) return log.error('DPT21: cannot write null value');
|
|
21
21
|
log.debug('./knx/src/dpt21.js : input value = ' + value);
|
|
22
22
|
|
|
23
23
|
//var apdu_data = new Buffer(1);
|
|
@@ -31,7 +31,9 @@ exports.formatAPDU = function(value) {
|
|
|
31
31
|
|
|
32
32
|
log.error('DPT21: Must supply a value which is an object');
|
|
33
33
|
//return apdu_data;
|
|
34
|
-
|
|
34
|
+
//a malformed object shall not result in transmission
|
|
35
|
+
//return Buffer.from([0]);
|
|
36
|
+
return null;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
exports.fromBuffer = function(buf) {
|
|
@@ -10,7 +10,7 @@ const log = require('log-driver').logger;
|
|
|
10
10
|
// MSB: Red, Green, LSB: Blue
|
|
11
11
|
//
|
|
12
12
|
exports.formatAPDU = (value) => {
|
|
13
|
-
if (
|
|
13
|
+
if (value == null) return log.error('DPT232: cannot write null value');
|
|
14
14
|
|
|
15
15
|
if (typeof value === 'object') {
|
|
16
16
|
const { red, green, blue } = value;
|
|
@@ -9,7 +9,7 @@ const log = require('log-driver').logger;
|
|
|
9
9
|
// DPT237: 2-byte unsigned value
|
|
10
10
|
//
|
|
11
11
|
exports.formatAPDU = function(value) {
|
|
12
|
-
if (
|
|
12
|
+
if (value == null) return log.error('DPT237: cannot write null value');
|
|
13
13
|
|
|
14
14
|
log.trace('dpt278.js : input value = ' + value);
|
|
15
15
|
|
|
@@ -9,7 +9,7 @@ const log = require('log-driver').logger;
|
|
|
9
9
|
// DPT3.*: 4-bit dimming/blinds control
|
|
10
10
|
//
|
|
11
11
|
exports.formatAPDU = (value) => {
|
|
12
|
-
if (
|
|
12
|
+
if (value == null) return log.warn('DPT3: cannot write null value');
|
|
13
13
|
|
|
14
14
|
if (
|
|
15
15
|
typeof value == 'object' &&
|
|
@@ -9,7 +9,7 @@ const log = require('log-driver').logger;
|
|
|
9
9
|
// DPT4: 8-bit character
|
|
10
10
|
//
|
|
11
11
|
exports.formatAPDU = (value) => {
|
|
12
|
-
if (
|
|
12
|
+
if (value == null) return log.warn('DPT4: cannot write null value');
|
|
13
13
|
|
|
14
14
|
if (typeof value !== 'string')
|
|
15
15
|
return log.warn('DPT4: Must supply a character or string');
|
|
@@ -90,5 +90,12 @@ exports.subtypes = {
|
|
|
90
90
|
"name" : "DPT_Brightness",
|
|
91
91
|
"desc" : "interior brightness",
|
|
92
92
|
"unit" : "lux"
|
|
93
|
-
}
|
|
93
|
+
},
|
|
94
|
+
// 7.600
|
|
95
|
+
"600" : { "use" : "FB",
|
|
96
|
+
"name" : "DPT_Absolute_Colour_Temperature",
|
|
97
|
+
"desc" : "Absolute colour temperature",
|
|
98
|
+
"unit" : "K"
|
|
99
|
+
}
|
|
100
|
+
|
|
94
101
|
}
|
package/lib/projectImport.js
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
/* eslint-disable quotes */
|
|
2
1
|
"use strict";
|
|
3
2
|
|
|
4
3
|
const DPTLib = require(__dirname + "/knx/src/dptlib"); //todo copy for the moment
|
|
5
4
|
const select = require("xpath");
|
|
6
|
-
const _ = require("underscore");
|
|
7
5
|
const util = require("util");
|
|
8
6
|
const dom = require("xmldom").DOMParser;
|
|
9
7
|
const tools = require("./tools.js");
|
|
10
|
-
|
|
11
|
-
let groupAddresses = {};
|
|
8
|
+
const similarity = require("similarity");
|
|
12
9
|
|
|
13
10
|
module.exports = {
|
|
14
11
|
// get xml Files from index.html via adapter.on 'message' and put it into file Obj
|
|
15
12
|
parseInput: function (adapter, xml, callback) {
|
|
16
|
-
|
|
13
|
+
const fileObjectList = {};
|
|
17
14
|
|
|
18
15
|
if (xml) {
|
|
19
16
|
fileObjectList["ga.xml"] = new dom().parseFromString(xml);
|
|
@@ -27,45 +24,50 @@ module.exports = {
|
|
|
27
24
|
|
|
28
25
|
// generate the Groupaddress structure
|
|
29
26
|
generateIoBObjects: function (adapter, fileObjectList, callback) {
|
|
30
|
-
groupAddresses = {};
|
|
31
|
-
|
|
27
|
+
const groupAddresses = {};
|
|
28
|
+
const iobrokerObjects = [];
|
|
32
29
|
|
|
33
30
|
function processFile(adapter, err, objectList) {
|
|
34
31
|
//from xml export
|
|
35
32
|
const doc = objectList["ga.xml"];
|
|
36
33
|
if (doc)
|
|
37
|
-
|
|
34
|
+
select.select("//*[local-name(.)='GroupAddress' and string(@Address)]", doc).forEach(ga => {
|
|
38
35
|
const address = ga.getAttribute("Address");
|
|
39
36
|
groupAddresses[address] = ga;
|
|
40
37
|
});
|
|
41
38
|
|
|
42
39
|
//format and put each found group address into the object tree
|
|
43
|
-
|
|
40
|
+
Object.entries(groupAddresses).forEach(([key, groupAddress]) => {
|
|
44
41
|
const gaName = groupAddress.getAttribute("Name");
|
|
45
42
|
let autoread = true;
|
|
46
|
-
const dpt = tools.convertDPTtype(groupAddress.getAttribute("DatapointType") || groupAddress.getAttribute("DPTs")); //DPT or DPTs
|
|
47
43
|
let dptObj = {};
|
|
48
|
-
let fullPath = tools.
|
|
49
|
-
let range = [
|
|
44
|
+
let fullPath = tools.formatGaForIob(gaName);
|
|
45
|
+
let range = [];
|
|
50
46
|
let role = "state";
|
|
51
47
|
let type;
|
|
52
48
|
|
|
53
49
|
//add name of Mittelgruppe and Hauptgruppe to fullPath if exist
|
|
54
50
|
if (groupAddress.parentNode.nodeName === "GroupRange") {
|
|
55
|
-
fullPath = tools.
|
|
51
|
+
fullPath = tools.formatGaForIob(groupAddress.parentNode.getAttribute("Name")) + "." + fullPath;
|
|
56
52
|
if (groupAddress.parentNode.parentNode.nodeName === "GroupRange") {
|
|
57
|
-
fullPath = tools.
|
|
53
|
+
fullPath = tools.formatGaForIob(groupAddress.parentNode.parentNode.getAttribute("Name")) + "." + fullPath;
|
|
58
54
|
}
|
|
59
55
|
}
|
|
60
56
|
|
|
57
|
+
const dpt = tools.formatDpt(groupAddress.getAttribute("DatapointType") || groupAddress.getAttribute("DPTs")); //DPT or DPTs
|
|
61
58
|
if (dpt == "") {
|
|
62
|
-
const text =
|
|
59
|
+
const text = `Not adding ${fullPath} because no DPT is assigned to ${groupAddress.getAttribute("Address")}. The GA is not connected to a KO in ETS`;
|
|
63
60
|
adapter.log.warn(text);
|
|
64
61
|
if (!err) err = text;
|
|
65
|
-
else err += "
|
|
62
|
+
else err += "<br/>\n" + text;
|
|
66
63
|
return;
|
|
67
64
|
}
|
|
68
|
-
|
|
65
|
+
if (dpt.indexOf(".") === -1) {
|
|
66
|
+
const text = `${fullPath} ${groupAddress.getAttribute("Address")} has only set a base DPT in ETS. No additional information (e.g. unit) for this GA available.`;
|
|
67
|
+
adapter.log.info(text);
|
|
68
|
+
if (!err) err = text;
|
|
69
|
+
else err += "<br/>\n" + text;
|
|
70
|
+
}
|
|
69
71
|
try {
|
|
70
72
|
dptObj = DPTLib.resolve(dpt);
|
|
71
73
|
} catch (e) {
|
|
@@ -73,14 +75,14 @@ module.exports = {
|
|
|
73
75
|
}
|
|
74
76
|
|
|
75
77
|
// is there a scalar range? eg. DPT5.003 angle degrees (0=0, ff=360)
|
|
76
|
-
if (!!dptObj && dptObj.
|
|
78
|
+
if (!!dptObj && dptObj.subtype && dptObj.subtype.scalar_range) {
|
|
77
79
|
range = dptObj.subtype.scalar_range;
|
|
78
|
-
} else if (!!dptObj && dptObj.
|
|
80
|
+
} else if (!!dptObj && dptObj.scalar_range) {
|
|
79
81
|
range = dptObj.scalar_range;
|
|
80
|
-
} else if (!!dptObj && dptObj.
|
|
82
|
+
} else if (!!dptObj && dptObj.subtype && dptObj.subtype.range) {
|
|
81
83
|
// just a plain numeric value, only check if within bounds
|
|
82
84
|
range = dptObj.subtype.range;
|
|
83
|
-
} else if (!!dptObj && dptObj.basetype && dptObj.basetype.
|
|
85
|
+
} else if (!!dptObj && dptObj.basetype && dptObj.basetype.range) {
|
|
84
86
|
// just a plain numeric value, only check if within bounds
|
|
85
87
|
range = dptObj.basetype.range;
|
|
86
88
|
} else if (!!dptObj && !tools.isEmptyObject(dptObj)) {
|
|
@@ -116,79 +118,175 @@ module.exports = {
|
|
|
116
118
|
range[1] = undefined;
|
|
117
119
|
type = "number";
|
|
118
120
|
} else if (tools.isUnknownDPT(dpt)) {
|
|
121
|
+
//raw interface
|
|
119
122
|
range[0] = undefined;
|
|
120
123
|
range[1] = undefined;
|
|
121
|
-
type = "string";
|
|
124
|
+
type = "string";
|
|
122
125
|
} else {
|
|
123
126
|
type = "number";
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
//if dpt is for sure not a status, remove from autoread
|
|
127
|
-
if (tools.
|
|
130
|
+
if (tools.isTriggerDPT(dpt)) {
|
|
128
131
|
autoread = false;
|
|
129
132
|
}
|
|
130
133
|
|
|
134
|
+
//https://github.com/ioBroker/ioBroker.docs/blob/master/docs/en/dev/objectsschema.md#objects
|
|
131
135
|
const iobrokerObject = {
|
|
132
136
|
_id: fullPath,
|
|
133
137
|
type: "state",
|
|
134
138
|
common: {
|
|
135
|
-
desc:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
: dptObj.
|
|
140
|
-
(Object.prototype.hasOwnProperty.call(dptObj, "subtype") && Object.prototype.hasOwnProperty.call(dptObj, "desc") ? ", Subtype: " + dptObj.subtype.desc : "")),
|
|
139
|
+
desc: "Basetype: " +
|
|
140
|
+
(!dptObj || tools.isEmptyObject(dptObj) ?
|
|
141
|
+
"raw value" :
|
|
142
|
+
dptObj.basetype.desc +
|
|
143
|
+
(Object.prototype.hasOwnProperty.call(dptObj, "subtype") && Object.prototype.hasOwnProperty.call(dptObj, "desc") ? ", Subtype: " + dptObj.subtype.desc : "")),
|
|
141
144
|
min: range[0],
|
|
142
145
|
max: range[1],
|
|
143
146
|
name: gaName,
|
|
144
147
|
read: true,
|
|
145
148
|
role: role, //description: https://github.com/ioBroker/ioBroker/blob/master/doc/STATE_ROLES.md#state-roles
|
|
146
|
-
type: type, //
|
|
147
|
-
unit: !!dptObj &&
|
|
149
|
+
type: type, //possible values: number, string, boolean, array, object, mixed, file. It is important to note that array, object, mixed and file must be serialized using JSON.stringify().
|
|
150
|
+
unit: !!dptObj && dptObj.subtype && dptObj.subtype.unit ? dptObj.subtype.unit : undefined,
|
|
148
151
|
write: true,
|
|
152
|
+
states: undefined, //todo can be extracted from some dpts
|
|
149
153
|
},
|
|
150
154
|
native: {
|
|
151
|
-
address:
|
|
155
|
+
address: convertToGa(groupAddress.getAttribute("Address")),
|
|
152
156
|
answer_groupValueResponse: false, //overwrite manually
|
|
153
157
|
autoread: autoread,
|
|
154
158
|
bitlength: !dptObj || tools.isEmptyObject(dptObj) ? undefined : dptObj.basetype.bitlength, //informative
|
|
155
159
|
dpt: dpt,
|
|
156
160
|
encoding:
|
|
157
|
-
!!dptObj && Object.prototype.hasOwnProperty.call(dptObj, "subtype")
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
: undefined, //informative ,todo matcht zu common.states`? hat basetype enc?
|
|
161
|
+
!!dptObj && Object.prototype.hasOwnProperty.call(dptObj, "subtype") ?
|
|
162
|
+
Object.prototype.hasOwnProperty.call(dptObj, "enc") ?
|
|
163
|
+
dptObj.subtype.enc :
|
|
164
|
+
dptObj.basetype.enc : undefined, //informative
|
|
162
165
|
force_encoding:
|
|
163
|
-
!!dptObj && Object.prototype.hasOwnProperty.call(dptObj, "subtype") && Object.prototype.hasOwnProperty.call(dptObj, "subtype") && dptObj.subtype
|
|
164
|
-
|
|
165
|
-
: undefined, //DPT16
|
|
166
|
+
!!dptObj && Object.prototype.hasOwnProperty.call(dptObj, "subtype") && Object.prototype.hasOwnProperty.call(dptObj, "subtype") && dptObj.subtype ?
|
|
167
|
+
dptObj.subtype.force_encoding : undefined, //DPT16
|
|
166
168
|
signedness:
|
|
167
|
-
!!dptObj && !tools.isEmptyObject(dptObj)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
: undefined
|
|
171
|
-
: undefined, //signed or unsigned or empty
|
|
169
|
+
!!dptObj && !tools.isEmptyObject(dptObj) ?
|
|
170
|
+
Object.prototype.hasOwnProperty.call(dptObj, "signedness") && dptObj.basetype ?
|
|
171
|
+
dptObj.basetype.signedness :
|
|
172
|
+
undefined : undefined, //signed or unsigned or empty
|
|
172
173
|
valuetype: !dptObj || tools.isEmptyObject(dptObj) ? undefined : dptObj.basetype.valuetype, //informative: composite or basic
|
|
173
174
|
},
|
|
174
175
|
};
|
|
175
176
|
|
|
176
177
|
iobrokerObjects.push(iobrokerObject);
|
|
177
178
|
});
|
|
178
|
-
|
|
179
|
+
|
|
180
|
+
if (typeof callback === "function") {
|
|
181
|
+
callback(err, iobrokerObjects);
|
|
182
|
+
}
|
|
179
183
|
}
|
|
180
184
|
|
|
181
185
|
// check if fileObjectList is typeof Object
|
|
182
|
-
if (!
|
|
186
|
+
if (!Object.prototype.hasOwnProperty.call(fileObjectList, "push")) {
|
|
183
187
|
processFile(adapter, null, fileObjectList);
|
|
184
188
|
}
|
|
185
189
|
},
|
|
190
|
+
|
|
191
|
+
//find statusGAs based on regexp
|
|
192
|
+
findStatusGAs(adapter, gaList, callback) {
|
|
193
|
+
let count = 0;
|
|
194
|
+
const regex = RegExp(adapter.config.statusRegex, "gi");
|
|
195
|
+
for (const statusElement of gaList) {
|
|
196
|
+
if (regex.test(statusElement)) {
|
|
197
|
+
//for all status gas
|
|
198
|
+
const reducedStatusElement = statusElement.replace((regex), "");
|
|
199
|
+
const nonStatusElement = Array.from(gaList).reduce((previousValue, currentValue) => {
|
|
200
|
+
//compare with all others
|
|
201
|
+
if (!previousValue) {
|
|
202
|
+
return currentValue;
|
|
203
|
+
}
|
|
204
|
+
if (currentValue === statusElement) {
|
|
205
|
+
//found itself, skip
|
|
206
|
+
return previousValue;
|
|
207
|
+
}
|
|
208
|
+
if (regex.test(currentValue)) {
|
|
209
|
+
//found another status, skip
|
|
210
|
+
return previousValue;
|
|
211
|
+
}
|
|
212
|
+
//reduce the list to the best match
|
|
213
|
+
if (similarity(unify(currentValue,adapter), unify(reducedStatusElement,adapter)) > similarity(unify(previousValue,adapter), unify(reducedStatusElement, adapter))) {
|
|
214
|
+
return currentValue;
|
|
215
|
+
} else {
|
|
216
|
+
return previousValue;
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
const a = unify(reducedStatusElement, adapter);
|
|
220
|
+
const b = unify(nonStatusElement, adapter);
|
|
221
|
+
if (similarity(a, b) > adapter.config.regexSimil) {
|
|
222
|
+
//found a match that is not and status and good enough, generate alias object
|
|
223
|
+
createAlias(adapter, nonStatusElement, statusElement);
|
|
224
|
+
count++;
|
|
225
|
+
adapter.log.info("create aliases: found match " + nonStatusElement + " and " + statusElement);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
callback(count);
|
|
230
|
+
}
|
|
186
231
|
};
|
|
187
232
|
|
|
233
|
+
/* make strings comparable*/
|
|
234
|
+
function unify(element, adapter) {
|
|
235
|
+
element = element.toLowerCase().replace(/_/g,"");
|
|
236
|
+
if (!(adapter.config.aliasRange)) {
|
|
237
|
+
//exclude group names from search if user sets
|
|
238
|
+
const n = element.lastIndexOf(".");
|
|
239
|
+
element = element.substring(n + 1);
|
|
240
|
+
}
|
|
241
|
+
return element;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
|
|
188
245
|
//possibly convert 2byte value into ././. form
|
|
189
|
-
function
|
|
246
|
+
function convertToGa(adr) {
|
|
190
247
|
//check if already in good format
|
|
191
248
|
if (adr.includes("/")) return adr;
|
|
192
249
|
//Bereiche: Hauptgruppe = 0..31, Mittelgruppe = 0..7, Untergruppe = 0..255
|
|
193
250
|
return util.format("%d/%d/%d", (adr >> 11) & 0x1f, (adr >> 8) & 0x7, adr & 0xff);
|
|
194
251
|
}
|
|
252
|
+
|
|
253
|
+
function createAlias(adapter, idDst, idSrc) {
|
|
254
|
+
adapter.getObject(idDst, null, (err, obj) => {
|
|
255
|
+
if (obj != null) {
|
|
256
|
+
const dstObj = obj;
|
|
257
|
+
adapter.getObject(idSrc, null, (err, srcObj) => {
|
|
258
|
+
if (srcObj != null) {
|
|
259
|
+
const aliasId = adapter.config.aliasPath + dstObj._id.replace(adapter.namespace, "");
|
|
260
|
+
const aliasObject = {
|
|
261
|
+
"_id": aliasId,
|
|
262
|
+
"type": "state",
|
|
263
|
+
"common": {
|
|
264
|
+
"name": dstObj.common.name,
|
|
265
|
+
"desc": dstObj.common.desc,
|
|
266
|
+
"role": dstObj.common.role,
|
|
267
|
+
"type": dstObj.common.type,
|
|
268
|
+
"read": dstObj.common.read,
|
|
269
|
+
"write": dstObj.common.write,
|
|
270
|
+
"unit": dstObj.common.unit,
|
|
271
|
+
"min": dstObj.common.min,
|
|
272
|
+
"max": dstObj.common.max,
|
|
273
|
+
"def": "",
|
|
274
|
+
"alias": {
|
|
275
|
+
"id": {
|
|
276
|
+
"read": srcObj._id,
|
|
277
|
+
"write": dstObj._id
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
adapter.setForeignObject(aliasId, aliasObject, (err, obj) => {});
|
|
284
|
+
} else {
|
|
285
|
+
adapter.log.debug("createAlias: source object not found: " + idSrc);
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
} else {
|
|
289
|
+
adapter.log.debug("createAlias: destination object not found: " + idDst);
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}
|