iobroker.zigbee 1.5.5 → 1.6.6
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/.github/FUNDING.yml +1 -1
- package/.github/workflows/test-and-release.yml +10 -10
- package/LICENSE +1 -1
- package/README.md +40 -8
- package/admin/adapter-settings.js +39 -3
- package/admin/admin.js +23 -33
- package/admin/img/tuya_rb280.png +0 -0
- package/admin/index_m.html +84 -37
- package/admin/tab_m.html +95 -35
- package/admin/words.js +24 -24
- package/docs/tutorial/adm5_1.PNG +0 -0
- package/docs/tutorial/adm5_2.PNG +0 -0
- package/docs/tutorial/zigbee.png +0 -0
- package/io-package.json +27 -3
- package/lib/commands.js +2 -1
- package/lib/devices.js +10 -14
- package/lib/exposes.js +263 -104
- package/lib/states.js +86 -27
- package/lib/statescontroller.js +10 -2
- package/lib/utils.js +19 -0
- package/lib/zbBaseExtension.js +4 -0
- package/lib/zbDelayedAction.js +5 -0
- package/lib/zbDeviceAvailability.js +2 -0
- package/lib/zbDeviceConfigure.js +8 -5
- package/lib/zigbeecontroller.js +79 -31
- package/main.js +118 -43
- package/package.json +7 -6
package/lib/states.js
CHANGED
|
@@ -80,7 +80,7 @@ const states = {
|
|
|
80
80
|
read: true,
|
|
81
81
|
type: 'number',
|
|
82
82
|
min: 0,
|
|
83
|
-
max:
|
|
83
|
+
max: 255
|
|
84
84
|
},
|
|
85
85
|
available: {
|
|
86
86
|
id: 'available',
|
|
@@ -103,6 +103,15 @@ const states = {
|
|
|
103
103
|
type: 'boolean',
|
|
104
104
|
isOption: true,
|
|
105
105
|
},
|
|
106
|
+
from_zigbee: {
|
|
107
|
+
id: 'msg_from_zigbee',
|
|
108
|
+
name: 'Message from Zigbee',
|
|
109
|
+
icon: undefined,
|
|
110
|
+
role: 'state',
|
|
111
|
+
write: false,
|
|
112
|
+
read: true,
|
|
113
|
+
type: 'string',
|
|
114
|
+
},
|
|
106
115
|
checking: { // press button for checking
|
|
107
116
|
id: 'checking',
|
|
108
117
|
name: 'Start checking process',
|
|
@@ -287,7 +296,7 @@ const states = {
|
|
|
287
296
|
prop: 'battery',
|
|
288
297
|
name: 'Battery percent',
|
|
289
298
|
icon: 'img/battery_p.png',
|
|
290
|
-
role: 'battery
|
|
299
|
+
role: 'value.battery',
|
|
291
300
|
write: false,
|
|
292
301
|
read: true,
|
|
293
302
|
type: 'number',
|
|
@@ -738,7 +747,7 @@ const states = {
|
|
|
738
747
|
prop: 'battery_low',
|
|
739
748
|
name: 'Battery Status Low',
|
|
740
749
|
icon: undefined,
|
|
741
|
-
role: '
|
|
750
|
+
role: 'indicator.lowbat',
|
|
742
751
|
write: false,
|
|
743
752
|
read: true,
|
|
744
753
|
type: 'boolean'
|
|
@@ -2130,7 +2139,7 @@ const states = {
|
|
|
2130
2139
|
prop: 'local_temperature_calibration',
|
|
2131
2140
|
name: 'Temperature Calibration',
|
|
2132
2141
|
icon: undefined,
|
|
2133
|
-
role: '
|
|
2142
|
+
role: 'level',
|
|
2134
2143
|
write: true,
|
|
2135
2144
|
read: true,
|
|
2136
2145
|
type: 'number',
|
|
@@ -2343,7 +2352,7 @@ const states = {
|
|
|
2343
2352
|
prop: 'pi_heating_demand',
|
|
2344
2353
|
name: 'Auto Valve position',
|
|
2345
2354
|
icon: undefined,
|
|
2346
|
-
role: '
|
|
2355
|
+
role: 'value.valve',
|
|
2347
2356
|
write: false,
|
|
2348
2357
|
read: true,
|
|
2349
2358
|
type: 'number',
|
|
@@ -2355,7 +2364,7 @@ const states = {
|
|
|
2355
2364
|
prop: 'eurotronic_valve_position',
|
|
2356
2365
|
name: 'Manual Valve position',
|
|
2357
2366
|
icon: undefined,
|
|
2358
|
-
role: '
|
|
2367
|
+
role: 'level.valve',
|
|
2359
2368
|
write: true,
|
|
2360
2369
|
read: true,
|
|
2361
2370
|
type: 'number',
|
|
@@ -2370,7 +2379,7 @@ const states = {
|
|
|
2370
2379
|
prop: 'current_heating_setpoint',
|
|
2371
2380
|
name: 'Current Target Temperature',
|
|
2372
2381
|
icon: undefined,
|
|
2373
|
-
role: '
|
|
2382
|
+
role: 'level.temperature',
|
|
2374
2383
|
write: true,
|
|
2375
2384
|
read: true,
|
|
2376
2385
|
type: 'number',
|
|
@@ -2382,10 +2391,10 @@ const states = {
|
|
|
2382
2391
|
// 1 = manual valve control
|
|
2383
2392
|
// 2 = auto (default)
|
|
2384
2393
|
id: 'spz_trv_mode',
|
|
2385
|
-
name: 'TRV Mode',
|
|
2394
|
+
name: 'TRV Mode (1 = manual | 2 = auto)',
|
|
2386
2395
|
prop: 'eurotronic_trv_mode',
|
|
2387
2396
|
icon: undefined,
|
|
2388
|
-
role: '
|
|
2397
|
+
role: 'level',
|
|
2389
2398
|
write: true,
|
|
2390
2399
|
read: true,
|
|
2391
2400
|
type: 'number',
|
|
@@ -2402,7 +2411,7 @@ const states = {
|
|
|
2402
2411
|
name: 'Thermostat Mode',
|
|
2403
2412
|
prop: 'eurotronic_system_mode',
|
|
2404
2413
|
icon: undefined,
|
|
2405
|
-
role: '
|
|
2414
|
+
role: 'level',
|
|
2406
2415
|
write: true,
|
|
2407
2416
|
read: true,
|
|
2408
2417
|
type: 'number',
|
|
@@ -2412,7 +2421,7 @@ const states = {
|
|
|
2412
2421
|
name: 'Thermostat Error',
|
|
2413
2422
|
prop: 'eurotronic_error_status',
|
|
2414
2423
|
icon: undefined,
|
|
2415
|
-
role: '
|
|
2424
|
+
role: 'value',
|
|
2416
2425
|
write: false,
|
|
2417
2426
|
read: true,
|
|
2418
2427
|
type: 'number',
|
|
@@ -2422,7 +2431,7 @@ const states = {
|
|
|
2422
2431
|
name: 'Window Open / Off',
|
|
2423
2432
|
prop: 'eurotronic_host_flags',
|
|
2424
2433
|
icon: undefined,
|
|
2425
|
-
role: '
|
|
2434
|
+
role: 'switch',
|
|
2426
2435
|
write: true,
|
|
2427
2436
|
read: true,
|
|
2428
2437
|
type: 'boolean',
|
|
@@ -2441,7 +2450,7 @@ const states = {
|
|
|
2441
2450
|
name: 'Boost Mode',
|
|
2442
2451
|
prop: 'eurotronic_host_flags',
|
|
2443
2452
|
icon: undefined,
|
|
2444
|
-
role: '
|
|
2453
|
+
role: 'switch.mode.boost',
|
|
2445
2454
|
write: true,
|
|
2446
2455
|
read: true,
|
|
2447
2456
|
type: 'boolean',
|
|
@@ -2460,7 +2469,7 @@ const states = {
|
|
|
2460
2469
|
name: 'Child Protection',
|
|
2461
2470
|
prop: 'eurotronic_host_flags',
|
|
2462
2471
|
icon: undefined,
|
|
2463
|
-
role: '
|
|
2472
|
+
role: 'switch.lock',
|
|
2464
2473
|
write: true,
|
|
2465
2474
|
read: true,
|
|
2466
2475
|
type: 'boolean',
|
|
@@ -2479,7 +2488,7 @@ const states = {
|
|
|
2479
2488
|
name: 'Mirror Display',
|
|
2480
2489
|
prop: 'eurotronic_host_flags',
|
|
2481
2490
|
icon: undefined,
|
|
2482
|
-
role: '
|
|
2491
|
+
role: 'switch',
|
|
2483
2492
|
write: true,
|
|
2484
2493
|
read: true,
|
|
2485
2494
|
type: 'boolean',
|
|
@@ -2932,6 +2941,56 @@ const states = {
|
|
|
2932
2941
|
return {...options, reverse_direction: value};
|
|
2933
2942
|
},
|
|
2934
2943
|
},
|
|
2944
|
+
curtain_xiaomi_reverse_direction: {
|
|
2945
|
+
id: 'reverse_direction',
|
|
2946
|
+
prop: 'options',
|
|
2947
|
+
name: 'Reverse direction',
|
|
2948
|
+
icon: undefined,
|
|
2949
|
+
role: 'state',
|
|
2950
|
+
write: true,
|
|
2951
|
+
read: true,
|
|
2952
|
+
type: 'boolean',
|
|
2953
|
+
inOptions: true,
|
|
2954
|
+
getter: payload => (payload.options !== null) && payload.options.hasOwnProperty('reverse_direction') && !isNaN(payload.options.reverse_direction) ? payload.options.reverse_direction : undefined,
|
|
2955
|
+
setterOpt: (value, options) => {
|
|
2956
|
+
return {...options, reverse_direction: value};
|
|
2957
|
+
},
|
|
2958
|
+
setter: (value, options) => {
|
|
2959
|
+
return {...options, reverse_direction: value};
|
|
2960
|
+
},
|
|
2961
|
+
},
|
|
2962
|
+
curtain_xiaomi_hand_open: {
|
|
2963
|
+
id: 'hand_open',
|
|
2964
|
+
prop: 'options',
|
|
2965
|
+
name: 'Hand open',
|
|
2966
|
+
icon: undefined,
|
|
2967
|
+
role: 'state',
|
|
2968
|
+
write: true,
|
|
2969
|
+
read: true,
|
|
2970
|
+
type: 'boolean',
|
|
2971
|
+
inOptions: true,
|
|
2972
|
+
getter: payload => (payload.options !== null) && payload.options.hasOwnProperty('hand_open') && !isNaN(payload.options.hand_open) ? payload.options.hand_open : undefined,
|
|
2973
|
+
setterOpt: (value, options) => {
|
|
2974
|
+
return {...options, hand_open: value};
|
|
2975
|
+
},
|
|
2976
|
+
setter: (value, options) => {
|
|
2977
|
+
return {...options, hand_open: value};
|
|
2978
|
+
},
|
|
2979
|
+
},
|
|
2980
|
+
curtain_xiaomi_reset_limits: {
|
|
2981
|
+
id: 'reset_limits',
|
|
2982
|
+
prop: 'options',
|
|
2983
|
+
name: 'Reset limits',
|
|
2984
|
+
icon: undefined,
|
|
2985
|
+
write: true,
|
|
2986
|
+
read: true,
|
|
2987
|
+
type: 'boolean',
|
|
2988
|
+
getter: payload => (undefined),
|
|
2989
|
+
inOptions: true,
|
|
2990
|
+
setter: (value, options) => {
|
|
2991
|
+
return {...options, reset_limits: value};
|
|
2992
|
+
},
|
|
2993
|
+
},
|
|
2935
2994
|
blind_position: {
|
|
2936
2995
|
id: 'position',
|
|
2937
2996
|
prop: 'position',
|
|
@@ -4011,7 +4070,7 @@ const states = {
|
|
|
4011
4070
|
prop: 'current_heating_setpoint',
|
|
4012
4071
|
name: 'Current Target Temperature',
|
|
4013
4072
|
icon: undefined,
|
|
4014
|
-
role: '
|
|
4073
|
+
role: 'level.temperature',
|
|
4015
4074
|
write: true,
|
|
4016
4075
|
read: true,
|
|
4017
4076
|
type: 'number',
|
|
@@ -4024,7 +4083,7 @@ const states = {
|
|
|
4024
4083
|
name: 'Locked',
|
|
4025
4084
|
prop: 'child_lock',
|
|
4026
4085
|
icon: undefined,
|
|
4027
|
-
role: '
|
|
4086
|
+
role: 'switch.lock',
|
|
4028
4087
|
write: true,
|
|
4029
4088
|
read: true,
|
|
4030
4089
|
type: 'boolean',
|
|
@@ -4036,7 +4095,7 @@ const states = {
|
|
|
4036
4095
|
name: 'Window detected',
|
|
4037
4096
|
prop: 'window_detection',
|
|
4038
4097
|
icon: undefined,
|
|
4039
|
-
role: '
|
|
4098
|
+
role: 'value',
|
|
4040
4099
|
write: false,
|
|
4041
4100
|
read: true,
|
|
4042
4101
|
type: 'boolean',
|
|
@@ -4047,7 +4106,7 @@ const states = {
|
|
|
4047
4106
|
name: 'Valve detected',
|
|
4048
4107
|
prop: 'valve_detection',
|
|
4049
4108
|
icon: undefined,
|
|
4050
|
-
role: '
|
|
4109
|
+
role: 'value',
|
|
4051
4110
|
write: false,
|
|
4052
4111
|
read: true,
|
|
4053
4112
|
type: 'boolean',
|
|
@@ -4058,7 +4117,7 @@ const states = {
|
|
|
4058
4117
|
name: 'Auto lock',
|
|
4059
4118
|
prop: 'auto_lock',
|
|
4060
4119
|
icon: undefined,
|
|
4061
|
-
role: '
|
|
4120
|
+
role: 'value',
|
|
4062
4121
|
write: false,
|
|
4063
4122
|
read: true,
|
|
4064
4123
|
type: 'boolean',
|
|
@@ -4069,7 +4128,7 @@ const states = {
|
|
|
4069
4128
|
prop: 'min_temperature',
|
|
4070
4129
|
name: 'Minimal Temperature',
|
|
4071
4130
|
icon: undefined,
|
|
4072
|
-
role: '
|
|
4131
|
+
role: 'level',
|
|
4073
4132
|
write: true,
|
|
4074
4133
|
read: true,
|
|
4075
4134
|
type: 'number',
|
|
@@ -4082,7 +4141,7 @@ const states = {
|
|
|
4082
4141
|
prop: 'max_temperature',
|
|
4083
4142
|
name: 'Maximal Temperature',
|
|
4084
4143
|
icon: undefined,
|
|
4085
|
-
role: '
|
|
4144
|
+
role: 'level',
|
|
4086
4145
|
write: true,
|
|
4087
4146
|
read: true,
|
|
4088
4147
|
type: 'number',
|
|
@@ -4095,7 +4154,7 @@ const states = {
|
|
|
4095
4154
|
prop: 'boost_time',
|
|
4096
4155
|
name: 'Boost time',
|
|
4097
4156
|
icon: undefined,
|
|
4098
|
-
role: '
|
|
4157
|
+
role: 'level',
|
|
4099
4158
|
write: true,
|
|
4100
4159
|
read: true,
|
|
4101
4160
|
type: 'number',
|
|
@@ -4108,7 +4167,7 @@ const states = {
|
|
|
4108
4167
|
prop: 'comfort_temperature',
|
|
4109
4168
|
name: 'Comfort Temperature',
|
|
4110
4169
|
icon: undefined,
|
|
4111
|
-
role: '
|
|
4170
|
+
role: 'level',
|
|
4112
4171
|
write: true,
|
|
4113
4172
|
read: true,
|
|
4114
4173
|
type: 'number',
|
|
@@ -4121,7 +4180,7 @@ const states = {
|
|
|
4121
4180
|
prop: 'eco_temperature',
|
|
4122
4181
|
name: 'ECO Temperature',
|
|
4123
4182
|
icon: undefined,
|
|
4124
|
-
role: '
|
|
4183
|
+
role: 'level',
|
|
4125
4184
|
write: true,
|
|
4126
4185
|
read: true,
|
|
4127
4186
|
type: 'number',
|
|
@@ -4134,7 +4193,7 @@ const states = {
|
|
|
4134
4193
|
name: 'Mode',
|
|
4135
4194
|
prop: 'system_mode',
|
|
4136
4195
|
icon: undefined,
|
|
4137
|
-
role: '
|
|
4196
|
+
role: 'level.mode.thermostat',
|
|
4138
4197
|
write: true,
|
|
4139
4198
|
read: true,
|
|
4140
4199
|
type: 'string', // valid: low, medium, high
|
|
@@ -4201,7 +4260,7 @@ const states = {
|
|
|
4201
4260
|
prop: 'position',
|
|
4202
4261
|
name: 'Valve position',
|
|
4203
4262
|
icon: undefined,
|
|
4204
|
-
role: '
|
|
4263
|
+
role: 'value.valve',
|
|
4205
4264
|
write: false,
|
|
4206
4265
|
read: true,
|
|
4207
4266
|
type: 'number',
|
package/lib/statescontroller.js
CHANGED
|
@@ -31,6 +31,10 @@ class StatesController extends EventEmitter {
|
|
|
31
31
|
this.emit('log', 'warn', message, data);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
sendError(error, message) {
|
|
35
|
+
this.adapter.sendError(error, message);
|
|
36
|
+
}
|
|
37
|
+
|
|
34
38
|
getDebugDevices() {
|
|
35
39
|
this.debugDevices = [];
|
|
36
40
|
this.adapter.getState(this.adapter.namespace + '.info.debugmessages', (err, state) => {
|
|
@@ -54,6 +58,7 @@ class StatesController extends EventEmitter {
|
|
|
54
58
|
|
|
55
59
|
}
|
|
56
60
|
onStateChange(id, state){
|
|
61
|
+
if (!this.adapter.zbController || !this.adapter.zbController.connected()) return;
|
|
57
62
|
if (this.debugDevices === undefined) this.getDebugDevices();
|
|
58
63
|
if (state && !state.ack) {
|
|
59
64
|
if (id.endsWith('pairingCountdown') || id.endsWith('pairingMessage') || id.endsWith('connection')) return;
|
|
@@ -137,9 +142,10 @@ class StatesController extends EventEmitter {
|
|
|
137
142
|
stateModel = statesMapping.findModel(model);
|
|
138
143
|
if (!stateModel) {
|
|
139
144
|
this.error('Device ' + deviceId + ' "' + model + '" not described in statesMapping.');
|
|
140
|
-
|
|
145
|
+
states = statesMapping.commonStates;
|
|
146
|
+
} else {
|
|
147
|
+
states = stateModel.states;
|
|
141
148
|
}
|
|
142
|
-
states = stateModel.states;
|
|
143
149
|
if (typeof states === 'function' && !states.prototype) {
|
|
144
150
|
const entity = await this.adapter.zbController.resolveEntity(deviceId);
|
|
145
151
|
if (entity)
|
|
@@ -148,6 +154,7 @@ class StatesController extends EventEmitter {
|
|
|
148
154
|
}
|
|
149
155
|
return {states: states, stateModel: stateModel};
|
|
150
156
|
} catch (error) {
|
|
157
|
+
this.sendError(error);
|
|
151
158
|
this.error(`Error getDevStates for ${deviceId}. Error: ${error.stack}`);
|
|
152
159
|
}
|
|
153
160
|
}
|
|
@@ -191,6 +198,7 @@ class StatesController extends EventEmitter {
|
|
|
191
198
|
this.warn('publish from State - LinkedState is not a function ' + JSON.stringify(linkedFunct));
|
|
192
199
|
}
|
|
193
200
|
} catch (e) {
|
|
201
|
+
this.sendError(e);
|
|
194
202
|
this.error('Exception caught in publishfromstate');
|
|
195
203
|
}
|
|
196
204
|
|
package/lib/utils.js
CHANGED
|
@@ -114,6 +114,24 @@ const forceEndDevice = flatten(
|
|
|
114
114
|
const xiaomiManufacturerID = [4151, 4447];
|
|
115
115
|
const ikeaTradfriManufacturerID = [4476];
|
|
116
116
|
|
|
117
|
+
function sanitizeImageParameter(parameter) {
|
|
118
|
+
const replaceByDash = [/\?/g, /&/g, /[^a-z\d\-_./:]/gi, /[/]/gi];
|
|
119
|
+
let sanitized = parameter;
|
|
120
|
+
replaceByDash.forEach((r) => sanitized = sanitized.replace(r, '-'));
|
|
121
|
+
return sanitized;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function getDeviceIcon(definition) {
|
|
125
|
+
let icon = definition.icon;
|
|
126
|
+
if (icon) {
|
|
127
|
+
icon = icon.replace('${model}', sanitizeImageParameter(definition.model));
|
|
128
|
+
}
|
|
129
|
+
if (!icon) {
|
|
130
|
+
icon = `https://www.zigbee2mqtt.io/images/devices/${sanitizeImageParameter(definition.model)}.jpg`;
|
|
131
|
+
}
|
|
132
|
+
return icon;
|
|
133
|
+
}
|
|
134
|
+
|
|
117
135
|
exports.secondsToMilliseconds = (seconds) => seconds * 1000;
|
|
118
136
|
exports.bulbLevelToAdapterLevel = bulbLevelToAdapterLevel;
|
|
119
137
|
exports.adapterLevelToBulbLevel = adapterLevelToBulbLevel;
|
|
@@ -130,3 +148,4 @@ exports.isXiaomiDevice = (device) => {
|
|
|
130
148
|
(!device.manufacturerName || !device.manufacturerName.startsWith('Trust'));
|
|
131
149
|
};
|
|
132
150
|
exports.isIkeaTradfriDevice = (device) => ikeaTradfriManufacturerID.includes(device.manufacturerID);
|
|
151
|
+
exports.getDeviceIcon = getDeviceIcon;
|
package/lib/zbBaseExtension.js
CHANGED
package/lib/zbDelayedAction.js
CHANGED
|
@@ -49,6 +49,7 @@ class DelayedAction extends BaseExtension {
|
|
|
49
49
|
// }
|
|
50
50
|
// }
|
|
51
51
|
} catch (error) {
|
|
52
|
+
this.sendError(error);
|
|
52
53
|
this.error(
|
|
53
54
|
`Failed to DelayedAction.onZigbeeStarted (${error.stack})`,
|
|
54
55
|
);
|
|
@@ -62,6 +63,7 @@ class DelayedAction extends BaseExtension {
|
|
|
62
63
|
this.doActions(device);
|
|
63
64
|
// }
|
|
64
65
|
} catch (error) {
|
|
66
|
+
this.sendError(error);
|
|
65
67
|
this.error(
|
|
66
68
|
`Failed to DelayedAction.onZigbeeEvent (${error.stack})`,
|
|
67
69
|
);
|
|
@@ -80,6 +82,7 @@ class DelayedAction extends BaseExtension {
|
|
|
80
82
|
this.debug(`Succesfully delay action for ${device.ieeeAddr} ${device.modelID}`);
|
|
81
83
|
this.doActions(device);
|
|
82
84
|
} catch (error) {
|
|
85
|
+
this.sendError(error);
|
|
83
86
|
this.error(
|
|
84
87
|
`Failed to DelayedAction.delayAction ${device.ieeeAddr} ${device.modelID} (${error.stack})`,
|
|
85
88
|
);
|
|
@@ -119,6 +122,7 @@ class DelayedAction extends BaseExtension {
|
|
|
119
122
|
this.info(`Do action succesfully ${device.ieeeAddr} ${device.modelID}`);
|
|
120
123
|
toDelete.push(actionDef);
|
|
121
124
|
} catch (error) {
|
|
125
|
+
this.sendError(error);
|
|
122
126
|
this.error(
|
|
123
127
|
`Failed to do action ${device.ieeeAddr} ${device.modelID}, ` +
|
|
124
128
|
`attempt ${actionDef.attempts + 1} (${error.stack})`,
|
|
@@ -136,6 +140,7 @@ class DelayedAction extends BaseExtension {
|
|
|
136
140
|
delete this.actions[device.ieeeAddr];
|
|
137
141
|
}
|
|
138
142
|
} catch (error) {
|
|
143
|
+
this.sendError(error);
|
|
139
144
|
this.error(
|
|
140
145
|
`Failed to DelayedAction.doAction ${device.ieeeAddr} ${device.modelID} (${error.stack})`,
|
|
141
146
|
);
|
|
@@ -159,6 +159,7 @@ class DeviceAvailability extends BaseExtension {
|
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
catch (error) {
|
|
162
|
+
this.sendError(error);
|
|
162
163
|
this.debug(`Exception in readState of '${device.ieeeAddr}' - error : '${error}'`);
|
|
163
164
|
// intentionally empty: Just present to ensure we cause no harm
|
|
164
165
|
// when reading the state fails. => fall back on standard Ping function
|
|
@@ -236,6 +237,7 @@ class DeviceAvailability extends BaseExtension {
|
|
|
236
237
|
}
|
|
237
238
|
}
|
|
238
239
|
} catch (error) {
|
|
240
|
+
this.sendError(error);
|
|
239
241
|
this.debug(`Failed to read state of '${entity.device.ieeeAddr}' after reconnect`);
|
|
240
242
|
}
|
|
241
243
|
}
|
package/lib/zbDeviceConfigure.js
CHANGED
|
@@ -29,15 +29,13 @@ class DeviceConfigure extends BaseExtension {
|
|
|
29
29
|
if (!device || !mappedDevice) {
|
|
30
30
|
return false;
|
|
31
31
|
}
|
|
32
|
-
if (
|
|
33
|
-
zigbeeHerdsmanConverters.getConfigureKey(mappedDevice)) {
|
|
32
|
+
if (!mappedDevice || !mappedDevice.configure) {
|
|
34
33
|
return false;
|
|
35
34
|
}
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
if (device.meta.hasOwnProperty('configured') &&
|
|
36
|
+
zigbeeHerdsmanConverters.getConfigureKey(mappedDevice)) {
|
|
38
37
|
return false;
|
|
39
38
|
}
|
|
40
|
-
|
|
41
39
|
if (device.interviewing === true) {
|
|
42
40
|
return false;
|
|
43
41
|
}
|
|
@@ -64,6 +62,7 @@ class DeviceConfigure extends BaseExtension {
|
|
|
64
62
|
}
|
|
65
63
|
}
|
|
66
64
|
} catch (error) {
|
|
65
|
+
this.sendError(error);
|
|
67
66
|
this.error(
|
|
68
67
|
`Failed to DeviceConfigure.onZigbeeStarted (${error.stack})`,
|
|
69
68
|
);
|
|
@@ -77,6 +76,7 @@ class DeviceConfigure extends BaseExtension {
|
|
|
77
76
|
this.configure(device, mappedDevice);
|
|
78
77
|
}
|
|
79
78
|
} catch (error) {
|
|
79
|
+
this.sendError(error);
|
|
80
80
|
this.error(
|
|
81
81
|
`Failed to DeviceConfigure.onZigbeeEvent (${error.stack})`,
|
|
82
82
|
);
|
|
@@ -93,6 +93,7 @@ class DeviceConfigure extends BaseExtension {
|
|
|
93
93
|
delete this.attempts[device.ieeeAddr];
|
|
94
94
|
}
|
|
95
95
|
} catch (error) {
|
|
96
|
+
this.sendError(error);
|
|
96
97
|
this.error(
|
|
97
98
|
`Failed to DeviceConfigure.onDeviceRemove (${error.stack})`,
|
|
98
99
|
);
|
|
@@ -126,6 +127,7 @@ class DeviceConfigure extends BaseExtension {
|
|
|
126
127
|
device.meta.configured = zigbeeHerdsmanConverters.getConfigureKey(mappedDevice);
|
|
127
128
|
device.save();
|
|
128
129
|
} catch (error) {
|
|
130
|
+
this.sendError(error);
|
|
129
131
|
this.warn(
|
|
130
132
|
`DeviceConfigure failed ${device.ieeeAddr} ${device.modelID}, ` +
|
|
131
133
|
`attempt ${this.attempts[device.ieeeAddr] + 1} (${error.stack})`,
|
|
@@ -135,6 +137,7 @@ class DeviceConfigure extends BaseExtension {
|
|
|
135
137
|
|
|
136
138
|
this.configuring.delete(device.ieeeAddr);
|
|
137
139
|
} catch (error) {
|
|
140
|
+
this.sendError(error);
|
|
138
141
|
this.error(
|
|
139
142
|
`Failed to DeviceConfigure.configure ${device.ieeeAddr} ${device.modelID} (${error.stack})`,
|
|
140
143
|
);
|