iobroker.zigbee 1.8.3 → 1.8.5
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 +3 -0
- package/admin/admin.js +512 -493
- package/admin/index_m.html +1171 -1001
- package/admin/tab_m.html +44 -3
- package/docs/de/img/CC2531.png +0 -0
- package/docs/de/img/CC2538_CC2592_PA.PNG +0 -0
- package/docs/de/img/CC2591.png +0 -0
- package/docs/de/img/boards.jpg +0 -0
- package/docs/de/img/cc26x2r.PNG +0 -0
- package/docs/de/img/results.jpg +0 -0
- package/docs/de/img/sku_429478_2.png +0 -0
- package/docs/de/img/sku_429601_2.png +0 -0
- package/docs/de/readme.md +27 -0
- package/docs/en/img/CC2531.png +0 -0
- package/docs/en/img/CC2591.png +0 -0
- package/docs/en/img/deconz.png +0 -0
- package/docs/en/img/sku_429478_2.png +0 -0
- package/docs/en/img/sku_429601_2.png +0 -0
- package/docs/en/readme.md +30 -0
- package/docs/flashing_via_arduino_(en).md +110 -0
- package/docs/ru/img/CC2531.png +0 -0
- package/docs/ru/img/CC2591.png +0 -0
- package/docs/ru/img/sku_429478_2.png +0 -0
- package/docs/ru/img/sku_429601_2.png +0 -0
- package/docs/ru/readme.md +28 -0
- package/docs/tutorial/CC2530_20190425.zip +0 -0
- package/docs/tutorial/CC2530_CC2591_20190515.zip +0 -0
- package/docs/tutorial/CC2530_CC2592_20190515.zip +0 -0
- package/docs/tutorial/CC2531_20190425.zip +0 -0
- package/docs/tutorial/adm5_1.PNG +0 -0
- package/docs/tutorial/adm5_2.PNG +0 -0
- package/docs/tutorial/cat.PNG +0 -0
- package/docs/tutorial/groups-1.png +0 -0
- package/docs/tutorial/groups-2.png +0 -0
- package/docs/tutorial/inst.PNG +0 -0
- package/docs/tutorial/reflash-finish.PNG +0 -0
- package/docs/tutorial/reflash-step0.png +0 -0
- package/docs/tutorial/reflash-step1.PNG +0 -0
- package/docs/tutorial/reflash-step2.PNG +0 -0
- package/docs/tutorial/settings.png +0 -0
- package/docs/tutorial/tab-dev-1.png +0 -0
- package/docs/tutorial/zigbee.png +0 -0
- package/docs/tutorial/zigbee15.png +0 -0
- package/io-package.json +17 -25
- package/lib/backup.js +2 -2
- package/lib/binding.js +32 -37
- package/lib/colors.js +163 -158
- package/lib/commands.js +100 -91
- package/lib/developer.js +9 -12
- package/lib/devices.js +168 -178
- package/lib/exclude.js +30 -36
- package/lib/exposes.js +163 -139
- package/lib/groups.js +81 -83
- package/lib/json.js +5 -6
- package/lib/networkmap.js +2 -3
- package/lib/ota.js +34 -18
- package/lib/rgb.js +114 -72
- package/lib/seriallist.js +25 -20
- package/lib/states.js +511 -526
- package/lib/statescontroller.js +206 -183
- package/lib/utils.js +24 -23
- package/lib/zbBaseExtension.js +4 -4
- package/lib/zbDelayedAction.js +5 -13
- package/lib/zbDeviceAvailability.js +69 -65
- package/lib/zbDeviceConfigure.js +9 -21
- package/lib/zbDeviceEvent.js +3 -4
- package/lib/zigbeecontroller.js +133 -128
- package/main.js +169 -154
- package/package.json +27 -13
- package/.eslintignore +0 -2
- package/.eslintrc.json +0 -37
- package/.github/FUNDING.yml +0 -3
- package/.github/auto-merge.yml +0 -17
- package/.github/dependabot.yml +0 -24
- package/.github/stale.yml +0 -13
- package/.github/workflows/codeql.yml +0 -41
- package/.github/workflows/dependabot-automerge.yml +0 -22
- package/.github/workflows/test-and-release.yml +0 -149
- package/.releaseconfig.json +0 -3
- package/.travis/wiki.sh +0 -28
- package/.travis.yml +0 -41
- package/gulpfile.js +0 -464
- package/test/integration.js +0 -5
- package/test/mocha.custom.opts +0 -2
- package/test/mocha.setup.js +0 -14
- package/test/package.js +0 -5
- package/test/unit.js +0 -5
package/lib/groups.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const statesMapping = require('./devices');
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
class Groups {
|
|
7
6
|
constructor(adapter) {
|
|
8
7
|
this.adapter = adapter;
|
|
@@ -13,12 +12,12 @@ class Groups {
|
|
|
13
12
|
this.zbController = zbController;
|
|
14
13
|
this.stController = stController;
|
|
15
14
|
this.adapter.getStateAsync('info.groups')
|
|
16
|
-
.then(
|
|
15
|
+
.then(groupsState => {
|
|
17
16
|
const groups = (groupsState && groupsState.val) ? JSON.parse(groupsState.val) : {};
|
|
18
17
|
for (const gid in groups) {
|
|
19
18
|
stController.storeDeviceName(`group_${gid}`, groups[gid]);
|
|
20
19
|
}
|
|
21
|
-
//
|
|
20
|
+
// this.Adapter.deleteState('info.groups');
|
|
22
21
|
this.syncGroups();
|
|
23
22
|
});
|
|
24
23
|
}
|
|
@@ -77,56 +76,53 @@ class Groups {
|
|
|
77
76
|
for (const member of groupmembers) {
|
|
78
77
|
const nwk = member.deviceNetworkAddress;
|
|
79
78
|
const device = this.zbController.getDeviceByNetworkAddress(nwk);
|
|
80
|
-
if (device && device.ieeeAddr)
|
|
79
|
+
if (device && device.ieeeAddr) {
|
|
80
|
+
members.push({device: device.ieeeAddr});
|
|
81
|
+
}
|
|
81
82
|
}
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
83
|
+
} else {
|
|
84
84
|
return undefined;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
} catch (error) {
|
|
88
|
-
if (error) this.error(
|
|
88
|
+
if (error) this.error(`getGroupMembersFromController: error is ${JSON.stringify(error)} ${JSON.stringify(new Error().stack)}`);
|
|
89
89
|
else this.error('unidentifed error in getGroupMembersFromController');
|
|
90
90
|
}
|
|
91
91
|
return members;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
async getGroups(obj) {
|
|
95
|
-
const response = {
|
|
95
|
+
const response = {groups: {}};
|
|
96
96
|
try {
|
|
97
|
-
//
|
|
97
|
+
// const groupsState = await this.adapter.getStateAsync('info.groups');
|
|
98
98
|
const herdsmanGroups = await this.zbController.getGroups();
|
|
99
99
|
|
|
100
|
-
//
|
|
100
|
+
// const groups = (groupsState && groupsState.val) ? JSON.parse(groupsState.val) : {};
|
|
101
101
|
|
|
102
102
|
const groups = {};
|
|
103
103
|
if (typeof herdsmanGroups === 'object') {
|
|
104
104
|
for (const group of herdsmanGroups) {
|
|
105
105
|
const gid = group.groupID;
|
|
106
106
|
if (gid) {
|
|
107
|
-
groups[gid]=this.stController.verifyDeviceName(`group_${gid}
|
|
107
|
+
groups[gid] = this.stController.verifyDeviceName(`group_${gid}`, `Group ${gid}`);
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
this.debug(
|
|
111
|
+
this.debug(`getGroups result: ${JSON.stringify(groups)}`);
|
|
112
112
|
response.groups = groups;
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
113
|
+
} catch (error) {
|
|
115
114
|
response.error = `getGroups: caught error: ${error}`;
|
|
116
115
|
this.error(`getGroups: caught error: ${error}`);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (obj)
|
|
120
|
-
this.adapter.sendTo(obj.from, obj.command, response, obj.callback);
|
|
121
|
-
|
|
116
|
+
} finally {
|
|
117
|
+
obj && this.adapter.sendTo(obj.from, obj.command, response, obj.callback);
|
|
122
118
|
}
|
|
123
119
|
return response.groups;
|
|
124
120
|
}
|
|
125
121
|
|
|
126
122
|
async updateGroupMembership(from, command, message, callback) {
|
|
127
123
|
try {
|
|
128
|
-
const groups =
|
|
129
|
-
const devId =
|
|
124
|
+
const groups = message && message.groups ? message.groups : {};
|
|
125
|
+
const devId = message && message.id ? message.id : undefined;
|
|
130
126
|
if (devId === undefined) {
|
|
131
127
|
this.adapter.sendTo(from, command, {error: 'No device specified'}, callback);
|
|
132
128
|
}
|
|
@@ -136,33 +132,32 @@ class Groups {
|
|
|
136
132
|
// this.adapter.setState(id, JSON.stringify(groups), true);
|
|
137
133
|
|
|
138
134
|
//const current = await this.zbController.getGroupMembersFromController(sysid);
|
|
139
|
-
const errors = []
|
|
135
|
+
const errors = [];
|
|
140
136
|
for (const epid in groups) {
|
|
141
137
|
for (const gpid of groups[epid]) {
|
|
142
138
|
const gpidn = parseInt(gpid);
|
|
143
139
|
if (gpidn < 0) {
|
|
144
|
-
|
|
140
|
+
const response = await this.zbController.removeDevFromGroup(sysid, (-gpidn), epid);
|
|
145
141
|
if (response && response.error) {
|
|
146
142
|
errors.push(response.error);
|
|
147
|
-
this.error(
|
|
143
|
+
this.error(`remove dev from group Error: ${JSON.stringify(response.error)}`);
|
|
148
144
|
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
let response = await this.zbController.addDevToGroup(sysid,(gpidn), epid);
|
|
145
|
+
} else if (gpidn > 0) {
|
|
146
|
+
const response = await this.zbController.addDevToGroup(sysid, (gpidn), epid);
|
|
152
147
|
if (response && response.error) {
|
|
153
148
|
errors.push(response.error);
|
|
154
|
-
this.error(
|
|
149
|
+
this.error(`add dev to group Error: ${JSON.stringify(response.error)}`);
|
|
155
150
|
}
|
|
156
|
-
|
|
151
|
+
} else {
|
|
152
|
+
this.warn('illegal group id 0');
|
|
157
153
|
}
|
|
158
|
-
else this.warn('illegal group id 0');
|
|
159
154
|
}
|
|
160
155
|
}
|
|
161
156
|
} catch (e) {
|
|
162
157
|
this.adapter.sendTo(from, command, {error: e}, callback);
|
|
163
158
|
return;
|
|
164
159
|
}
|
|
165
|
-
this.adapter.sendTo(from, command, {
|
|
160
|
+
this.adapter.sendTo(from, command, {}, callback);
|
|
166
161
|
}
|
|
167
162
|
|
|
168
163
|
|
|
@@ -174,11 +169,13 @@ class Groups {
|
|
|
174
169
|
};
|
|
175
170
|
for (const member of members) {
|
|
176
171
|
const entity = await this.zbController.resolveEntity(member.device);
|
|
177
|
-
if (!entity)
|
|
172
|
+
if (!entity) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
178
175
|
this.debug(`entity: ${JSON.stringify(entity)}`);
|
|
179
176
|
const mappedModel = entity.mapped;
|
|
180
|
-
this.debug(
|
|
181
|
-
const converter = mappedModel.toZigbee.find(
|
|
177
|
+
this.debug(`Mapped Model: ${JSON.stringify(mappedModel)}`);
|
|
178
|
+
const converter = mappedModel.toZigbee.find(c => c && (c.key.includes(stateDesc.prop) || c.key.includes(stateDesc.setattr) || c.key.includes(stateDesc.id)));
|
|
182
179
|
if (!converter) {
|
|
183
180
|
result.unsupported.push(member.device);
|
|
184
181
|
continue;
|
|
@@ -191,63 +188,62 @@ class Groups {
|
|
|
191
188
|
}
|
|
192
189
|
}
|
|
193
190
|
}
|
|
194
|
-
if (result.unsupported.length>0) {
|
|
191
|
+
if (result.unsupported.length > 0) {
|
|
195
192
|
const error = {
|
|
196
193
|
code: 134,
|
|
197
194
|
message: `unsupported ${stateDesc.id} change for group members ${result.unsupported.join()}`
|
|
198
195
|
};
|
|
199
196
|
throw error;
|
|
200
197
|
}
|
|
201
|
-
if (result.unread.length>0) {
|
|
202
|
-
this.warn(
|
|
198
|
+
if (result.unread.length > 0) {
|
|
199
|
+
this.warn(`unread ${stateDesc.id} change for group members ${JSON.stringify(result.unread)}`);
|
|
203
200
|
}
|
|
204
201
|
}
|
|
205
202
|
|
|
206
203
|
async deleteGroup(from, command, message) {
|
|
207
|
-
/*
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
204
|
+
/*
|
|
205
|
+
const members = await this.getGroupMembersFromController(parseInt(message));
|
|
206
|
+
if (members && members.length) {
|
|
207
|
+
for (const member of members) {
|
|
208
|
+
const devName = member.device.substring(2);
|
|
209
|
+
const groupEntry = this.adapter.getStateAsync(`${devName}.groups`);
|
|
210
|
+
const memberarray = (groupEntry && groupEntry.val) ? JSON.parse(groupEntry.val) : [];
|
|
211
|
+
const index = memberarray.indexOf(message.toString());
|
|
212
|
+
if (index > -1) {
|
|
213
|
+
memberarray.splice(index, 1);
|
|
214
|
+
}
|
|
215
|
+
if (memberarray.length > 0) {
|
|
216
|
+
await this.adapter.setStateAsync(`${devName}.groups`, JSON.stringify(memberarray), true);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
await this.adapter.setStateAsync(`${devName}.groups`, '', true);
|
|
220
|
+
}
|
|
223
221
|
}
|
|
224
222
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
*/
|
|
223
|
+
const groupsEntry = await this.adapter.getStateAsync('info.groups');
|
|
224
|
+
const objGroups = (groupsEntry && groupsEntry.val ? JSON.parse(groupsEntry.val) : {});
|
|
225
|
+
delete objGroups[message.toString()];
|
|
226
|
+
await this.adapter.setStateAsync('info.groups', JSON.stringify(objGroups), true);
|
|
227
|
+
*/
|
|
231
228
|
await this.zbController.removeGroupById(message);
|
|
232
229
|
await this.stController.deleteDeviceStatesAsync(`group_${parseInt(message)}`);
|
|
233
230
|
}
|
|
234
231
|
|
|
235
232
|
async renameGroup(from, command, message) {
|
|
236
|
-
|
|
237
|
-
//
|
|
238
|
-
// const objGroups = (groupsEntry && groupsEntry.val ? JSON.parse(groupsEntry.val) : {});
|
|
233
|
+
// const groupsEntry = await this.adapter.getStateAsync('info.groups');
|
|
234
|
+
// const objGroups = (groupsEntry && groupsEntry.val ? JSON.parse(groupsEntry.val) : {});
|
|
239
235
|
const name = message.name;
|
|
240
236
|
const id = `group_${message.id}`;
|
|
241
237
|
this.stController.storeDeviceName(id, name);
|
|
242
238
|
try {
|
|
243
|
-
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
239
|
+
await this.zbController.verifyGroupExists(message.id);
|
|
240
|
+
} catch (e) {
|
|
241
|
+
if (e && e.hasOwnProperty('code')) {
|
|
242
|
+
this.warn(`renameGroup caught error ${JSON.stringify(e.code)}`);
|
|
243
|
+
}
|
|
248
244
|
}
|
|
249
|
-
//
|
|
250
|
-
//
|
|
245
|
+
// objGroups[message.id.toString()] = message.name;
|
|
246
|
+
// await this.adapter.setStateAsync('info.groups', JSON.stringify(objGroups), true);
|
|
251
247
|
|
|
252
248
|
const group = await this.adapter.getStateAsync(id);
|
|
253
249
|
if (!group) {
|
|
@@ -255,12 +251,14 @@ class Groups {
|
|
|
255
251
|
this.adapter.setObjectNotExists(id, {
|
|
256
252
|
type: 'device',
|
|
257
253
|
common: {name: name, type: 'group'},
|
|
258
|
-
native: {id
|
|
254
|
+
native: {id}
|
|
259
255
|
}, () => {
|
|
260
|
-
this.adapter.extendObject(id
|
|
256
|
+
this.adapter.extendObject(id, {common: {name, type: 'group'}});
|
|
261
257
|
// create writable states for groups from their devices
|
|
262
258
|
for (const stateInd in statesMapping.groupStates) {
|
|
263
|
-
if (!statesMapping.groupStates.hasOwnProperty(stateInd))
|
|
259
|
+
if (!statesMapping.groupStates.hasOwnProperty(stateInd)) {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
264
262
|
const statedesc = statesMapping.groupStates[stateInd];
|
|
265
263
|
const common = {
|
|
266
264
|
name: statedesc.name,
|
|
@@ -279,16 +277,15 @@ class Groups {
|
|
|
279
277
|
}
|
|
280
278
|
}
|
|
281
279
|
|
|
282
|
-
|
|
283
280
|
async syncGroups() {
|
|
284
281
|
const groups = await this.getGroups();
|
|
285
282
|
const chain = [];
|
|
286
283
|
const usedGroupsIds = [];
|
|
287
284
|
for (const j in groups) {
|
|
288
285
|
if (groups.hasOwnProperty(j)) {
|
|
289
|
-
const id = `group_${j}
|
|
290
|
-
|
|
291
|
-
chain.push(new Promise(
|
|
286
|
+
const id = `group_${j}`;
|
|
287
|
+
const name = groups[j];
|
|
288
|
+
chain.push(new Promise(resolve => {
|
|
292
289
|
this.adapter.setObjectNotExists(id, {
|
|
293
290
|
type: 'device',
|
|
294
291
|
common: {name: name, type: 'group'},
|
|
@@ -297,7 +294,9 @@ class Groups {
|
|
|
297
294
|
this.adapter.extendObject(id, {common: {type: 'group'}});
|
|
298
295
|
// create writable states for groups from their devices
|
|
299
296
|
for (const stateInd in statesMapping.groupStates) {
|
|
300
|
-
if (!statesMapping.groupStates.hasOwnProperty(stateInd))
|
|
297
|
+
if (!statesMapping.groupStates.hasOwnProperty(stateInd)) {
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
301
300
|
const statedesc = statesMapping.groupStates[stateInd];
|
|
302
301
|
const common = {
|
|
303
302
|
name: statedesc.name,
|
|
@@ -318,8 +317,8 @@ class Groups {
|
|
|
318
317
|
usedGroupsIds.push(parseInt(j));
|
|
319
318
|
}
|
|
320
319
|
}
|
|
321
|
-
chain.push(new Promise(
|
|
322
|
-
// remove unused
|
|
320
|
+
chain.push(new Promise(resolve =>
|
|
321
|
+
// remove unused adapter groups
|
|
323
322
|
this.adapter.getDevices((err, devices) => {
|
|
324
323
|
if (!err) {
|
|
325
324
|
devices.forEach((dev) => {
|
|
@@ -332,11 +331,10 @@ class Groups {
|
|
|
332
331
|
});
|
|
333
332
|
}
|
|
334
333
|
resolve();
|
|
335
|
-
});
|
|
336
|
-
}));
|
|
337
|
-
Promise.all(chain);
|
|
338
|
-
}
|
|
334
|
+
})));
|
|
339
335
|
|
|
336
|
+
await Promise.all(chain);
|
|
337
|
+
}
|
|
340
338
|
}
|
|
341
339
|
|
|
342
340
|
module.exports = Groups;
|
package/lib/json.js
CHANGED
|
@@ -3,15 +3,14 @@
|
|
|
3
3
|
const hasProp = Object.prototype.hasOwnProperty;
|
|
4
4
|
|
|
5
5
|
function throwsMessage(err) {
|
|
6
|
-
return
|
|
6
|
+
return `[Throws: ${err ? err.message : '?'}]`;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
function safeGetValueFromPropertyOnObject(obj, property) {
|
|
10
10
|
if (hasProp.call(obj, property)) {
|
|
11
11
|
try {
|
|
12
12
|
return obj[property];
|
|
13
|
-
}
|
|
14
|
-
catch (err) {
|
|
13
|
+
} catch (err) {
|
|
15
14
|
return throwsMessage(err);
|
|
16
15
|
}
|
|
17
16
|
}
|
|
@@ -20,14 +19,14 @@ function safeGetValueFromPropertyOnObject(obj, property) {
|
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
function ensureProperties(obj) {
|
|
23
|
-
const seen = [
|
|
22
|
+
const seen = []; // store references to objects we have seen before
|
|
24
23
|
|
|
25
24
|
function visit(obj) {
|
|
26
25
|
if (obj === null || typeof obj !== 'object') {
|
|
27
26
|
return obj;
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
if (seen.
|
|
29
|
+
if (seen.includes(obj)) {
|
|
31
30
|
return '[Circular]';
|
|
32
31
|
}
|
|
33
32
|
seen.push(obj);
|
|
@@ -35,7 +34,7 @@ function ensureProperties(obj) {
|
|
|
35
34
|
if (typeof obj.toJSON === 'function') {
|
|
36
35
|
try {
|
|
37
36
|
return visit(obj.toJSON());
|
|
38
|
-
} catch(err) {
|
|
37
|
+
} catch (err) {
|
|
39
38
|
return throwsMessage(err);
|
|
40
39
|
}
|
|
41
40
|
}
|
package/lib/networkmap.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
3
|
class NetworkMap {
|
|
5
4
|
constructor(adapter) {
|
|
6
5
|
this.adapter = adapter;
|
|
@@ -46,8 +45,8 @@ class NetworkMap {
|
|
|
46
45
|
|
|
47
46
|
getMap(from, command, callback) {
|
|
48
47
|
if (this.zbController) {
|
|
49
|
-
this.zbController.getMap(
|
|
50
|
-
this.adapter.log.debug(
|
|
48
|
+
this.zbController.getMap(networkmap => {
|
|
49
|
+
this.adapter.log.debug(`getMap result: ${JSON.stringify(networkmap)}`);
|
|
51
50
|
this.adapter.sendTo(from, command, networkmap, callback);
|
|
52
51
|
});
|
|
53
52
|
}
|
package/lib/ota.js
CHANGED
|
@@ -55,7 +55,11 @@ class Ota {
|
|
|
55
55
|
const device = await this.getDeviceForMessage(obj);
|
|
56
56
|
if (!device) {
|
|
57
57
|
this.debug(`Device ${obj.message.devId} is unavailable`);
|
|
58
|
-
this.adapter.sendTo(obj.from, obj.command, {
|
|
58
|
+
this.adapter.sendTo(obj.from, obj.command, {
|
|
59
|
+
status: 'fail',
|
|
60
|
+
device: getZbId(obj.message.devId),
|
|
61
|
+
msg: 'Device is unavailable'
|
|
62
|
+
}, obj.callback);
|
|
59
63
|
return;
|
|
60
64
|
}
|
|
61
65
|
if (this.inProgress.has(device.device.ieeeAddr)) {
|
|
@@ -65,16 +69,24 @@ class Ota {
|
|
|
65
69
|
// do not attempt update for a device which has been deactivated or is unavailable
|
|
66
70
|
const stateObj = await this.adapter.getObjectAsync(obj.message.devId);
|
|
67
71
|
if (stateObj && stateObj.common && stateObj.common.deactivated) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
this.warn(`Device ${obj.message.devId} is deactivated, skipping...`);
|
|
73
|
+
this.adapter.sendTo(obj.from, obj.command, {
|
|
74
|
+
status: 'fail',
|
|
75
|
+
device: getZbId(obj.message.devId),
|
|
76
|
+
msg: 'Device is deactivated'
|
|
77
|
+
}, obj.callback);
|
|
78
|
+
return;
|
|
71
79
|
}
|
|
72
|
-
const availablestate = await this.adapter.getStateAsync(obj.message.devId.replace(this.namespace + '.', '')
|
|
73
|
-
const lqi = await this.adapter.getStateAsync(obj.message.devId.replace(this.namespace + '.', '')
|
|
80
|
+
const availablestate = await this.adapter.getStateAsync(`${obj.message.devId.replace(this.namespace + '.', '')}.available`);
|
|
81
|
+
const lqi = await this.adapter.getStateAsync(`${obj.message.devId.replace(this.namespace + '.', '')}.link_quality`);
|
|
74
82
|
if ((availablestate && (!availablestate.val)) || (lqi && lqi.val < 1)) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
83
|
+
this.warn(`Device ${obj.message.devId} is marked unavailable, skipping...`);
|
|
84
|
+
this.adapter.sendTo(obj.from, obj.command, {
|
|
85
|
+
status: 'fail',
|
|
86
|
+
device: getZbId(obj.message.devId),
|
|
87
|
+
msg: 'Device is marked unavailable'
|
|
88
|
+
}, obj.callback);
|
|
89
|
+
return;
|
|
78
90
|
}
|
|
79
91
|
this.inProgress.add(device.device.ieeeAddr);
|
|
80
92
|
const result = {status: 'unknown', device: device ? device.name : null};
|
|
@@ -103,7 +115,11 @@ class Ota {
|
|
|
103
115
|
const device = await this.getDeviceForMessage(obj);
|
|
104
116
|
if (!device) {
|
|
105
117
|
this.debug(`Device ${obj.message.devId} is unavailable`);
|
|
106
|
-
this.adapter.sendTo(obj.from, obj.command, {
|
|
118
|
+
this.adapter.sendTo(obj.from, obj.command, {
|
|
119
|
+
status: 'fail',
|
|
120
|
+
device: getZbId(obj.message.devId),
|
|
121
|
+
msg: 'Device is unavailable'
|
|
122
|
+
}, obj.callback);
|
|
107
123
|
return;
|
|
108
124
|
}
|
|
109
125
|
if (this.inProgress.has(device.device.ieeeAddr)) {
|
|
@@ -113,19 +129,19 @@ class Ota {
|
|
|
113
129
|
// do not attempt update for a device which has been deactivated or is unavailable
|
|
114
130
|
const stateObj = await this.adapter.getObjectAsync(obj.message.devId);
|
|
115
131
|
if (stateObj && stateObj.common && stateObj.common.deactivated) {
|
|
116
|
-
|
|
117
|
-
|
|
132
|
+
this.warn(`Device ${obj.message.devId} is deactivated, skipping...`);
|
|
133
|
+
return;
|
|
118
134
|
}
|
|
119
|
-
const availablestate = await this.adapter.getStateAsync(obj.message.devId.replace(this.namespace + '.', '')
|
|
120
|
-
const lqi = await this.adapter.getStateAsync(obj.message.devId.replace(this.namespace + '.', '')
|
|
135
|
+
const availablestate = await this.adapter.getStateAsync(`${obj.message.devId.replace(this.namespace + '.', '')}.available`);
|
|
136
|
+
const lqi = await this.adapter.getStateAsync(`${obj.message.devId.replace(this.namespace + '.', '')}.link_quality`);
|
|
121
137
|
if ((availablestate && (!availablestate.val)) || (lqi && lqi.val < 1)) {
|
|
122
|
-
|
|
123
|
-
|
|
138
|
+
this.warn(`Device ${obj.message.devId} is marked unavailable, skipping...`);
|
|
139
|
+
return;
|
|
124
140
|
}
|
|
125
141
|
this.inProgress.add(device.device.ieeeAddr);
|
|
126
142
|
const result = {status: 'unknown', device: device ? device.name : null};
|
|
127
143
|
try {
|
|
128
|
-
this.info('Start firmware update for '+device.name);
|
|
144
|
+
this.info('Start firmware update for ' + device.name);
|
|
129
145
|
|
|
130
146
|
const onProgress = (progress, remaining) => {
|
|
131
147
|
let message = `Update of '${device.name}' at ${progress}%`;
|
|
@@ -140,7 +156,7 @@ class Ota {
|
|
|
140
156
|
const to = await this.readSoftwareBuildIDAndDateCode(device.device, true);
|
|
141
157
|
const [fromS, toS] = [JSON.stringify(from_), JSON.stringify(to)];
|
|
142
158
|
result.status = 'success';
|
|
143
|
-
result.msg = `Finished update of '${device.name}'
|
|
159
|
+
result.msg = `Finished update of '${device.name}'${to ? `, from '${fromS}' to '${toS}'` : ``}`;
|
|
144
160
|
this.info(result.msg);
|
|
145
161
|
this.adapter.sendTo(obj.from, obj.command, result, obj.callback);
|
|
146
162
|
} catch (error) {
|