iobroker.zigbee 1.7.5 → 1.8.0
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/LICENSE +1 -1
- package/README.md +22 -29
- package/admin/admin.js +494 -469
- package/admin/i18n/de/translations.json +108 -0
- package/admin/i18n/en/translations.json +108 -0
- package/admin/i18n/es/translations.json +102 -0
- package/admin/i18n/fr/translations.json +108 -0
- package/admin/i18n/it/translations.json +102 -0
- package/admin/i18n/nl/translations.json +108 -0
- package/admin/i18n/pl/translations.json +108 -0
- package/admin/i18n/pt/translations.json +102 -0
- package/admin/i18n/ru/translations.json +108 -0
- package/admin/i18n/uk/translations.json +108 -0
- package/admin/i18n/zh-cn/translations.json +102 -0
- package/admin/index_m.html +1 -1
- package/admin/tab_m.html +44 -3
- package/admin/words.js +107 -108
- package/io-package.json +326 -357
- package/lib/backup.js +2 -2
- package/lib/binding.js +23 -24
- package/lib/colors.js +16 -14
- package/lib/commands.js +89 -82
- package/lib/developer.js +6 -7
- package/lib/devices.js +145 -154
- package/lib/exclude.js +30 -36
- package/lib/exposes.js +106 -111
- package/lib/groups.js +53 -54
- package/lib/json.js +3 -4
- package/lib/networkmap.js +2 -2
- package/lib/ota.js +23 -15
- package/lib/rgb.js +47 -44
- package/lib/seriallist.js +21 -10
- package/lib/states.js +488 -498
- package/lib/statescontroller.js +170 -164
- package/lib/utils.js +22 -21
- package/lib/zbBaseExtension.js +4 -4
- package/lib/zbDelayedAction.js +5 -13
- package/lib/zbDeviceAvailability.js +47 -44
- package/lib/zbDeviceConfigure.js +18 -23
- package/lib/zbDeviceEvent.js +3 -4
- package/lib/zigbeecontroller.js +97 -100
- package/main.js +149 -133
- package/package.json +33 -19
- package/.eslintignore +0 -2
- package/.eslintrc.json +0 -37
- package/.github/FUNDING.yml +0 -3
- package/.github/stale.yml +0 -13
- package/.github/workflows/test-and-release.yml +0 -151
- package/.travis/wiki.sh +0 -28
- package/admin/adapter-settings.js +0 -244
package/lib/exposes.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
|
|
4
|
-
const statesDefs = require(
|
|
5
|
-
const rgb = require(
|
|
6
|
-
const utils = require(
|
|
7
|
-
const colors = require(
|
|
4
|
+
const statesDefs = require('./states.js').states;
|
|
5
|
+
const rgb = require('./rgb.js');
|
|
6
|
+
const utils = require('./utils.js');
|
|
7
|
+
const colors = require('./colors.js');
|
|
8
8
|
const ea = zigbeeHerdsmanConverters.exposes.access;
|
|
9
9
|
|
|
10
10
|
function genState(expose, role, name, desc) {
|
|
@@ -32,7 +32,7 @@ function genState(expose, role, name, desc) {
|
|
|
32
32
|
state.getter = payload => (payload[propName] === (expose.value_on || 'ON'));
|
|
33
33
|
}
|
|
34
34
|
else {
|
|
35
|
-
state.getter = payload =>
|
|
35
|
+
state.getter = payload => undefined;
|
|
36
36
|
}
|
|
37
37
|
if (writable) {
|
|
38
38
|
state.setter = (value) => (value) ? (expose.value_on || 'ON') : ((expose.value_off != undefined) ? expose.value_off : 'OFF');
|
|
@@ -72,7 +72,7 @@ function genState(expose, role, name, desc) {
|
|
|
72
72
|
write: writable,
|
|
73
73
|
read: true,
|
|
74
74
|
type: 'string',
|
|
75
|
-
states: expose.values.map(
|
|
75
|
+
states: expose.values.map(item => `${item}:${item}`).join(';'),
|
|
76
76
|
};
|
|
77
77
|
if (expose.endpoint) {
|
|
78
78
|
state.epname = expose.endpoint;
|
|
@@ -103,8 +103,6 @@ function genState(expose, role, name, desc) {
|
|
|
103
103
|
return state;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
|
|
107
|
-
|
|
108
106
|
function createFromExposes(model, def) {
|
|
109
107
|
const states = [];
|
|
110
108
|
// make the different (set and get) part of state is updatable if different exposes is used for get and set
|
|
@@ -121,22 +119,24 @@ function createFromExposes(model, def) {
|
|
|
121
119
|
if (state === undefined) {
|
|
122
120
|
return 0;
|
|
123
121
|
}
|
|
124
|
-
if (access === undefined)
|
|
122
|
+
if (access === undefined) {
|
|
123
|
+
access = ea.ALL;
|
|
124
|
+
}
|
|
125
125
|
state.readable = (access & ea.STATE) > 0;
|
|
126
126
|
state.writable = (access & ea.SET) > 0;
|
|
127
|
-
const stateExists = states.findIndex( (element, index, array) =>
|
|
128
|
-
if (stateExists < 0
|
|
127
|
+
const stateExists = states.findIndex( (element, index, array) => element.id === state.id);
|
|
128
|
+
if (stateExists < 0) {
|
|
129
129
|
state.write = state.writable;
|
|
130
|
-
if (!
|
|
131
|
-
if (
|
|
130
|
+
if (!state.writable) {
|
|
131
|
+
if (state.hasOwnProperty('setter')) {
|
|
132
132
|
delete state.setter;
|
|
133
133
|
}
|
|
134
|
-
if (
|
|
134
|
+
if (state.hasOwnProperty('setattr')) {
|
|
135
135
|
delete state.setattr;
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
-
if (!
|
|
139
|
-
if (state.hasOwnProperty('getter')
|
|
138
|
+
if (!state.readable) {
|
|
139
|
+
if (state.hasOwnProperty('getter')) {
|
|
140
140
|
//to awid some worning on unprocessed data
|
|
141
141
|
state.getter = payload => ( undefined );
|
|
142
142
|
}
|
|
@@ -144,7 +144,7 @@ function createFromExposes(model, def) {
|
|
|
144
144
|
return states.push(state);
|
|
145
145
|
}
|
|
146
146
|
else {
|
|
147
|
-
if (
|
|
147
|
+
if ((state.readable) && (!states[stateExists].readable)) {
|
|
148
148
|
states[stateExists].read = state.read;
|
|
149
149
|
// as state is readable, it can't be button or event
|
|
150
150
|
if (states[stateExists].role === 'button') {
|
|
@@ -160,58 +160,58 @@ function createFromExposes(model, def) {
|
|
|
160
160
|
// trying to remove the `prop` property, as main key for get and set,
|
|
161
161
|
// as it can be different in new and old states, and leave only:
|
|
162
162
|
// setattr for old and id for new
|
|
163
|
-
if ((
|
|
163
|
+
if ((state.hasOwnProperty('prop')) && (state.prop === state.id)) {
|
|
164
164
|
if ( states[stateExists].hasOwnProperty('prop') ) {
|
|
165
165
|
if (states[stateExists].prop !== states[stateExists].id) {
|
|
166
|
-
if (!
|
|
166
|
+
if (!states[stateExists].hasOwnProperty('setattr')) {
|
|
167
167
|
states[stateExists].setattr = states[stateExists].prop;
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
delete states[stateExists].prop;
|
|
171
171
|
}
|
|
172
|
-
}
|
|
173
|
-
else if ( state.hasOwnProperty('prop') ) {
|
|
172
|
+
} else if ( state.hasOwnProperty('prop') ) {
|
|
174
173
|
states[stateExists].prop = state.prop;
|
|
175
174
|
}
|
|
176
175
|
states[stateExists].readable = true;
|
|
177
176
|
}
|
|
178
|
-
if (
|
|
177
|
+
if ((state.writable) && (!states[stateExists].writable)) {
|
|
179
178
|
states[stateExists].write = state.writable;
|
|
180
179
|
// use new state `setter`
|
|
181
|
-
if (
|
|
180
|
+
if (state.hasOwnProperty('setter')) {
|
|
182
181
|
states[stateExists].setter = state.setter;
|
|
183
182
|
}
|
|
184
183
|
// use new state `setterOpt`
|
|
185
|
-
if (
|
|
184
|
+
if (state.hasOwnProperty('setterOpt')) {
|
|
186
185
|
states[stateExists].setterOpt = state.setterOpt;
|
|
187
186
|
}
|
|
188
187
|
// use new state `inOptions`
|
|
189
|
-
if (
|
|
188
|
+
if (state.hasOwnProperty('inOptions')) {
|
|
190
189
|
states[stateExists].inOptions = state.inOptions;
|
|
191
190
|
}
|
|
192
191
|
// as we have new state, responsible for set, we have to use new `isOption`
|
|
193
192
|
// or remove it
|
|
194
|
-
if (((!
|
|
193
|
+
if (((!state.hasOwnProperty('isOption')) || (state.isOptions === false))
|
|
195
194
|
&& (states[stateExists].hasOwnProperty('isOption'))) {
|
|
196
195
|
delete states[stateExists].isOption;
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
196
|
+
} else {
|
|
199
197
|
states[stateExists].isOption = state.isOption;
|
|
200
198
|
}
|
|
199
|
+
|
|
201
200
|
// use new `setattr` or `prop` as `setattr`
|
|
202
|
-
if (
|
|
201
|
+
if (state.hasOwnProperty('setattr')) {
|
|
203
202
|
states[stateExists].setattr = state.setattr;
|
|
204
|
-
}
|
|
205
|
-
else if ( state.hasOwnProperty('prop') ) {
|
|
203
|
+
} else if (state.hasOwnProperty('prop')) {
|
|
206
204
|
states[stateExists].setattr = state.prop;
|
|
207
205
|
}
|
|
206
|
+
|
|
208
207
|
// remove `prop` equal to if, due to prop is uses as key in set and get
|
|
209
|
-
if (
|
|
208
|
+
if (states[stateExists].prop === states[stateExists].id) {
|
|
210
209
|
delete states[stateExists].prop;
|
|
211
210
|
}
|
|
212
|
-
if (
|
|
211
|
+
if (state.hasOwnProperty('epname')) {
|
|
213
212
|
states[stateExists].epname = state.epname;
|
|
214
213
|
}
|
|
214
|
+
|
|
215
215
|
states[stateExists].writable = true;
|
|
216
216
|
}
|
|
217
217
|
return states.length;
|
|
@@ -242,6 +242,7 @@ function createFromExposes(model, def) {
|
|
|
242
242
|
}, prop.access);
|
|
243
243
|
break;
|
|
244
244
|
}
|
|
245
|
+
|
|
245
246
|
case 'brightness': {
|
|
246
247
|
const stateNameB = expose.endpoint ? `brightness_${expose.endpoint}` : 'brightness';
|
|
247
248
|
pushToStates({
|
|
@@ -255,12 +256,8 @@ function createFromExposes(model, def) {
|
|
|
255
256
|
min: 0, // ignore expose.value_min
|
|
256
257
|
max: 100, // ignore expose.value_max
|
|
257
258
|
inOptions: true,
|
|
258
|
-
getter: payload =>
|
|
259
|
-
|
|
260
|
-
},
|
|
261
|
-
setter: (value) => {
|
|
262
|
-
return utils.adapterLevelToBulbLevel(value);
|
|
263
|
-
},
|
|
259
|
+
getter: payload => utils.bulbLevelToAdapterLevel(payload[stateNameB]),
|
|
260
|
+
setter: value => utils.adapterLevelToBulbLevel(value),
|
|
264
261
|
setterOpt: (value, options) => {
|
|
265
262
|
const hasTransitionTime = options && options.hasOwnProperty('transition_time');
|
|
266
263
|
const transitionTime = hasTransitionTime ? options.transition_time : 0;
|
|
@@ -268,7 +265,7 @@ function createFromExposes(model, def) {
|
|
|
268
265
|
preparedOptions.brightness = utils.adapterLevelToBulbLevel(value);
|
|
269
266
|
return preparedOptions;
|
|
270
267
|
},
|
|
271
|
-
readResponse:
|
|
268
|
+
readResponse: resp => {
|
|
272
269
|
const respObj = resp[0];
|
|
273
270
|
if (respObj.status === 0 && respObj.attrData != undefined) {
|
|
274
271
|
return utils.bulbLevelToAdapterLevel(respObj.attrData);
|
|
@@ -282,30 +279,30 @@ function createFromExposes(model, def) {
|
|
|
282
279
|
}
|
|
283
280
|
case 'color_temp': {
|
|
284
281
|
const stateNameT = expose.endpoint ? `colortemp_${expose.endpoint}` : 'colortemp';
|
|
285
|
-
pushToStates(
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
282
|
+
pushToStates(
|
|
283
|
+
{
|
|
284
|
+
id: stateNameT,
|
|
285
|
+
prop: expose.endpoint ? `color_temp_${expose.endpoint}` : 'color_temp',
|
|
286
|
+
name: `Color temperature ${expose.endpoint ? expose.endpoint : ''}`.trim(),
|
|
287
|
+
icon: undefined,
|
|
288
|
+
role: 'level.color.temperature',
|
|
289
|
+
write: true,
|
|
290
|
+
read: true,
|
|
291
|
+
type: 'number',
|
|
292
|
+
// Ignore min and max value, so setting mireds and Kelvin with conversion to mireds works.
|
|
293
|
+
// https://github.com/ioBroker/ioBroker.zigbee/pull/1433#issuecomment-1113837035
|
|
294
|
+
min: undefined,
|
|
295
|
+
max: undefined,
|
|
296
|
+
setter: value => utils.toMired(value),
|
|
297
|
+
setterOpt: (value, options) => {
|
|
298
|
+
const hasTransitionTime = options && options.hasOwnProperty('transition_time');
|
|
299
|
+
const transitionTime = hasTransitionTime ? options.transition_time : 0;
|
|
300
|
+
return {...options, transition: transitionTime};
|
|
301
|
+
},
|
|
302
|
+
epname: expose.endpoint,
|
|
303
|
+
setattr: 'color_temp',
|
|
305
304
|
},
|
|
306
|
-
|
|
307
|
-
setattr: 'color_temp',
|
|
308
|
-
}, prop.access);
|
|
305
|
+
prop.access);
|
|
309
306
|
pushToStates(statesDefs.colortemp_move, prop.access);
|
|
310
307
|
break;
|
|
311
308
|
}
|
|
@@ -320,7 +317,7 @@ function createFromExposes(model, def) {
|
|
|
320
317
|
write: true,
|
|
321
318
|
read: true,
|
|
322
319
|
type: 'string',
|
|
323
|
-
setter:
|
|
320
|
+
setter: value => {
|
|
324
321
|
// convert RGB to XY for set
|
|
325
322
|
/*
|
|
326
323
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(value);
|
|
@@ -342,9 +339,8 @@ function createFromExposes(model, def) {
|
|
|
342
339
|
xy = rgb.rgb_to_cie(rgbcolor.r, rgbcolor.g, rgbcolor.b);
|
|
343
340
|
return {
|
|
344
341
|
x: xy[0],
|
|
345
|
-
y: xy[1]
|
|
342
|
+
y: xy[1],
|
|
346
343
|
};
|
|
347
|
-
|
|
348
344
|
},
|
|
349
345
|
setterOpt: (value, options) => {
|
|
350
346
|
const hasTransitionTime = options && options.hasOwnProperty('transition_time');
|
|
@@ -354,7 +350,7 @@ function createFromExposes(model, def) {
|
|
|
354
350
|
getter: payload => {
|
|
355
351
|
if (payload.color && payload.color.hasOwnProperty('x') && payload.color.hasOwnProperty('y')) {
|
|
356
352
|
const colorval = rgb.cie_to_rgb(payload.color.x, payload.color.y);
|
|
357
|
-
return
|
|
353
|
+
return `#${utils.decimalToHex(colorval[0])}${utils.decimalToHex(colorval[1])}${utils.decimalToHex(colorval[2])}`;
|
|
358
354
|
} else {
|
|
359
355
|
return undefined;
|
|
360
356
|
}
|
|
@@ -375,14 +371,13 @@ function createFromExposes(model, def) {
|
|
|
375
371
|
write: true,
|
|
376
372
|
read: true,
|
|
377
373
|
type: 'string',
|
|
378
|
-
setter:
|
|
374
|
+
setter: value => {
|
|
379
375
|
const _rgb = colors.ParseColor(value);
|
|
380
376
|
const hsv = rgb.rgbToHSV(_rgb.r, _rgb.g, _rgb.b, true);
|
|
381
377
|
return {
|
|
382
378
|
hue: Math.min(Math.max(hsv.h,1),359),
|
|
383
379
|
saturation: hsv.s,
|
|
384
380
|
// brightness: Math.floor(hsv.v * 2.55),
|
|
385
|
-
|
|
386
381
|
};
|
|
387
382
|
},
|
|
388
383
|
setterOpt: (value, options) => {
|
|
@@ -396,7 +391,7 @@ function createFromExposes(model, def) {
|
|
|
396
391
|
pushToStates({
|
|
397
392
|
id: expose.endpoint ? `hue_${expose.endpoint}` : 'hue',
|
|
398
393
|
prop: expose.endpoint ? `color_${expose.endpoint}` : 'color',
|
|
399
|
-
name: `Hue ${expose.endpoint
|
|
394
|
+
name: `Hue ${expose.endpoint || ''}`.trim(),
|
|
400
395
|
icon: undefined,
|
|
401
396
|
role: 'level.color.hue',
|
|
402
397
|
write: true,
|
|
@@ -423,11 +418,12 @@ function createFromExposes(model, def) {
|
|
|
423
418
|
const hue_correction_table = [];
|
|
424
419
|
options.hue_calibration.split(',').forEach(element => {
|
|
425
420
|
const match = /([0-9]+):([0-9]+)/.exec(element);
|
|
426
|
-
if (match && match.length
|
|
427
|
-
hue_correction_table.push({
|
|
421
|
+
if (match && match.length === 3)
|
|
422
|
+
hue_correction_table.push({in: Number(match[1]), out: Number(match[2])});
|
|
428
423
|
});
|
|
429
|
-
if (hue_correction_table.length > 0)
|
|
424
|
+
if (hue_correction_table.length > 0) {
|
|
430
425
|
return {...options, transition: transitionTime, hue_correction: hue_correction_table};
|
|
426
|
+
}
|
|
431
427
|
}
|
|
432
428
|
return {...options, transition: transitionTime};
|
|
433
429
|
},
|
|
@@ -445,12 +441,10 @@ function createFromExposes(model, def) {
|
|
|
445
441
|
min: 0,
|
|
446
442
|
max: 100,
|
|
447
443
|
inOptions: true,
|
|
448
|
-
setter: (value, options) => {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
};
|
|
453
|
-
},
|
|
444
|
+
setter: (value, options) => ({
|
|
445
|
+
hue: options.hue,
|
|
446
|
+
saturation: value,
|
|
447
|
+
}),
|
|
454
448
|
setterOpt: (value, options) => {
|
|
455
449
|
const hasTransitionTime = options && options.hasOwnProperty('transition_time');
|
|
456
450
|
const transitionTime = hasTransitionTime ? options.transition_time : 0;
|
|
@@ -463,11 +457,12 @@ function createFromExposes(model, def) {
|
|
|
463
457
|
const hue_correction_table = [];
|
|
464
458
|
options.hue_calibration.split(',').forEach(element => {
|
|
465
459
|
const match = /([0-9]+):([0-9]+)/.exec(element);
|
|
466
|
-
if (match && match.length
|
|
460
|
+
if (match && match.length === 3)
|
|
467
461
|
hue_correction_table.push({ in: Number(match[1]), out: Number(match[2])});
|
|
468
462
|
});
|
|
469
|
-
if (hue_correction_table.length > 0)
|
|
463
|
+
if (hue_correction_table.length > 0) {
|
|
470
464
|
return {...options, transition: transitionTime, hue_correction: hue_correction_table};
|
|
465
|
+
}
|
|
471
466
|
}
|
|
472
467
|
return {...options, transition: transitionTime};
|
|
473
468
|
},
|
|
@@ -485,12 +480,10 @@ function createFromExposes(model, def) {
|
|
|
485
480
|
read: false,
|
|
486
481
|
type: 'string',
|
|
487
482
|
inOptions: true,
|
|
488
|
-
setter: (value, options) => {
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
};
|
|
493
|
-
},
|
|
483
|
+
setter: (value, options) => ({
|
|
484
|
+
hue: options.hue,
|
|
485
|
+
saturation: options.saturation,
|
|
486
|
+
}),
|
|
494
487
|
setterOpt: (value, options) => {
|
|
495
488
|
const hasTransitionTime = options && options.hasOwnProperty('transition_time');
|
|
496
489
|
const transitionTime = hasTransitionTime ? options.transition_time : 0;
|
|
@@ -498,20 +491,20 @@ function createFromExposes(model, def) {
|
|
|
498
491
|
if (hasHueCalibrationTable)
|
|
499
492
|
try {
|
|
500
493
|
return {...options, transition: transitionTime, hue_correction: JSON.parse(options.hue_calibration)};
|
|
501
|
-
}
|
|
502
|
-
catch {
|
|
494
|
+
} catch {
|
|
503
495
|
const hue_correction_table = [];
|
|
504
496
|
options.hue_calibration.split(',').forEach(element => {
|
|
505
497
|
const match = /([0-9]+):([0-9]+)/.exec(element);
|
|
506
|
-
if (match && match.length
|
|
498
|
+
if (match && match.length === 3) {
|
|
507
499
|
hue_correction_table.push({ in: Number(match[1]), out: Number(match[2])});
|
|
500
|
+
}
|
|
508
501
|
});
|
|
509
|
-
if (hue_correction_table.length > 0)
|
|
502
|
+
if (hue_correction_table.length > 0) {
|
|
510
503
|
return {...options, transition: transitionTime, hue_correction: hue_correction_table};
|
|
504
|
+
}
|
|
511
505
|
}
|
|
512
506
|
return {...options, transition: transitionTime};
|
|
513
507
|
},
|
|
514
|
-
|
|
515
508
|
}, prop.access);
|
|
516
509
|
break;
|
|
517
510
|
}
|
|
@@ -582,19 +575,20 @@ function createFromExposes(model, def) {
|
|
|
582
575
|
break;
|
|
583
576
|
}
|
|
584
577
|
}
|
|
585
|
-
if (state)
|
|
578
|
+
if (state) {
|
|
579
|
+
pushToStates(state, expose.access);
|
|
580
|
+
}
|
|
586
581
|
break;
|
|
587
582
|
|
|
588
583
|
case 'enum':
|
|
589
584
|
switch (expose.name) {
|
|
590
585
|
case 'action': {
|
|
591
|
-
|
|
592
586
|
// Ansatz:
|
|
593
587
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
588
|
+
// Action aufspalten in 2 Blöcke:
|
|
589
|
+
// Action (bekommt text ausser hold und release, auto reset nach 250 ms)
|
|
590
|
+
// Hold: wird gesetzt bei hold, gelöscht bei passendem Release
|
|
591
|
+
|
|
598
592
|
if (!Array.isArray(expose.values)) break;
|
|
599
593
|
const hasHold = expose.values.find((actionName) => actionName.includes('hold'));
|
|
600
594
|
const hasRelease = expose.values.find((actionName) => actionName.includes('release'));
|
|
@@ -613,7 +607,7 @@ function createFromExposes(model, def) {
|
|
|
613
607
|
write: false,
|
|
614
608
|
read: true,
|
|
615
609
|
type: 'boolean',
|
|
616
|
-
getter: payload =>
|
|
610
|
+
getter: payload => payload.action === actionName ? true : (payload.action === releaseActionName ? false : undefined),
|
|
617
611
|
};
|
|
618
612
|
} else {
|
|
619
613
|
state = {
|
|
@@ -625,7 +619,7 @@ function createFromExposes(model, def) {
|
|
|
625
619
|
write: false,
|
|
626
620
|
read: true,
|
|
627
621
|
type: 'boolean',
|
|
628
|
-
getter: payload =>
|
|
622
|
+
getter: payload => payload.action === actionName ? true : undefined,
|
|
629
623
|
isEvent: true,
|
|
630
624
|
};
|
|
631
625
|
}
|
|
@@ -676,7 +670,9 @@ function createFromExposes(model, def) {
|
|
|
676
670
|
break;
|
|
677
671
|
}
|
|
678
672
|
}
|
|
679
|
-
if (state)
|
|
673
|
+
if (state) {
|
|
674
|
+
pushToStates(state, expose.access);
|
|
675
|
+
}
|
|
680
676
|
break;
|
|
681
677
|
|
|
682
678
|
case 'text':
|
|
@@ -739,7 +735,7 @@ function createFromExposes(model, def) {
|
|
|
739
735
|
return result;
|
|
740
736
|
};
|
|
741
737
|
st.setattr = expose.property;
|
|
742
|
-
}
|
|
738
|
+
}
|
|
743
739
|
// if we have a composite expose, the payload will be an object {expose.property : {prop.property: value}}
|
|
744
740
|
if (prop.access & ea.STATE) {
|
|
745
741
|
st.getter = payload => {
|
|
@@ -750,11 +746,10 @@ function createFromExposes(model, def) {
|
|
|
750
746
|
return undefined;
|
|
751
747
|
}
|
|
752
748
|
};
|
|
749
|
+
} else {
|
|
750
|
+
st.getter = payload => undefined;
|
|
753
751
|
}
|
|
754
|
-
|
|
755
|
-
st.getter = payload => { return undefined };
|
|
756
|
-
}
|
|
757
|
-
;
|
|
752
|
+
|
|
758
753
|
pushToStates(st, prop.access);
|
|
759
754
|
}
|
|
760
755
|
break;
|
|
@@ -764,8 +759,8 @@ function createFromExposes(model, def) {
|
|
|
764
759
|
}
|
|
765
760
|
const newDev = {
|
|
766
761
|
models: [model],
|
|
767
|
-
icon
|
|
768
|
-
states
|
|
762
|
+
icon,
|
|
763
|
+
states,
|
|
769
764
|
exposed: true,
|
|
770
765
|
};
|
|
771
766
|
// make the function code printable in log
|
|
@@ -775,11 +770,11 @@ function createFromExposes(model, def) {
|
|
|
775
770
|
}
|
|
776
771
|
|
|
777
772
|
function applyExposes(mappedDevices, byModel, allExcludesObj) {
|
|
778
|
-
// for
|
|
773
|
+
// for exclude search
|
|
779
774
|
const allExcludesStr = JSON.stringify(allExcludesObj);
|
|
780
775
|
// create or update device from exposes
|
|
781
776
|
for (const deviceDef of zigbeeHerdsmanConverters.definitions) {
|
|
782
|
-
const strippedModel = (deviceDef.model) ? deviceDef.model.replace(
|
|
777
|
+
const strippedModel = (deviceDef.model) ? deviceDef.model.replace(/0.*$/g, '').trim() : '';
|
|
783
778
|
// check if device is mapped
|
|
784
779
|
const existsMap = byModel.get(strippedModel);
|
|
785
780
|
|
|
@@ -794,7 +789,7 @@ function applyExposes(mappedDevices, byModel, allExcludesObj) {
|
|
|
794
789
|
existsMap.exposed = true;
|
|
795
790
|
}
|
|
796
791
|
} catch (e) {
|
|
797
|
-
console.log(`Wrong expose devicedefinition ${deviceDef.vendor} ${deviceDef.model}`
|
|
792
|
+
console.log(`Wrong expose devicedefinition ${deviceDef.vendor} ${deviceDef.model}`);
|
|
798
793
|
}
|
|
799
794
|
}
|
|
800
795
|
}
|