iobroker.zigbee 2.0.3 → 2.0.4

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.
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- const safeJsonStringify = require('./json');
4
- const { EventEmitter } = require('events');
3
+ const EventEmitter = require('events').EventEmitter;
5
4
  const statesMapping = require('./devices');
6
- const { getAdId, getZbId } = require('./utils');
5
+ const getAdId = require('./utils').getAdId;
6
+ const getZbId = require('./utils').getZbId;
7
7
  const fs = require('fs');
8
8
  const axios = require('axios');
9
9
  const localConfig = require('./localConfig');
@@ -14,8 +14,7 @@ const localConfig = require('./localConfig');
14
14
  const { exec } = require('child_process');
15
15
  const { tmpdir } = require('os');
16
16
  const path = require('path');
17
- const { throwDeprecation } = require('process');
18
- const zigbeeHerdsmanConvertersUtils = require('zigbee-herdsman-converters/lib/utils');
17
+ const { numberWithinRange } = require('zigbee-herdsman-converters/lib/utils');
19
18
 
20
19
 
21
20
  class StatesController extends EventEmitter {
@@ -33,7 +32,6 @@ class StatesController extends EventEmitter {
33
32
  this.ImagesToDownload = [];
34
33
  this.stashedErrors = {};
35
34
  this.stashedUnknownModels = [];
36
- this.debugMessages = { nodevice:{ in:[], out: []} };
37
35
  }
38
36
 
39
37
  info(message, data) {
@@ -87,10 +85,6 @@ class StatesController extends EventEmitter {
87
85
  return rv;
88
86
  }
89
87
 
90
- debugMessagesById() {
91
- return this.debugMessages;
92
- }
93
-
94
88
  async AddModelFromHerdsman(device, model) {
95
89
  // this.warn('addModelFromHerdsman ' + JSON.stringify(model) + ' ' + JSON.stringify(this.localConfig.getOverrideWithKey(model, 'legacy', true)));
96
90
  if (this.localConfig.getOverrideWithKey(model, 'legacy', true)) {
@@ -158,7 +152,6 @@ class StatesController extends EventEmitter {
158
152
  if (!this.adapter.zbController || !this.adapter.zbController.connected()) {
159
153
  return;
160
154
  }
161
- const debugId = Date.now();
162
155
  if (state && !state.ack) {
163
156
  if (id.endsWith('pairingCountdown') || id.endsWith('pairingMessage') || id.endsWith('connection')) {
164
157
  return;
@@ -173,18 +166,16 @@ class StatesController extends EventEmitter {
173
166
  return;
174
167
  }
175
168
 
169
+ if (this.checkDebugDevice(id))
170
+ this.warn(`ELEVATED O01: User state change of state ${id} with value ${state.val} (ack: ${state.ack}) from ${state.from}`);
171
+
172
+ this.debug(`User stateChange ${id} ${JSON.stringify(state)}`);
176
173
  const devId = getAdId(this.adapter, id); // iobroker device id
177
174
  let deviceId = getZbId(id); // zigbee device id
178
-
179
- if (this.checkDebugDevice(id)) {
180
- const message = `User state change of state ${id} with value ${state.val} (ack: ${state.ack}) from ${state.from}`;
181
- this.emit('device_debug', { ID:debugId, data: { ID: deviceId, flag:'01' }, message:message});
182
- } else
183
- this.debug(`User stateChange ${id} ${JSON.stringify(state)}`);
184
175
  // const stateKey = id.split('.')[3];
185
176
  const arr = /zigbee.[0-9].[^.]+.(\S+)/gm.exec(id);
186
177
  if (arr[1] === undefined) {
187
- //this.warn(`unable to extract id from state ${id}`);
178
+ this.warn(`unable to extract id from state ${id}`);
188
179
  return;
189
180
  }
190
181
  const stateKey = arr[1];
@@ -208,7 +199,7 @@ class StatesController extends EventEmitter {
208
199
 
209
200
  }
210
201
  this.collectOptions(id.split('.')[2], model, options =>
211
- this.publishFromState(deviceId, model, stateKey, state, options, debugId));
202
+ this.publishFromState(deviceId, model, stateKey, state, options));
212
203
  }
213
204
  });
214
205
  }
@@ -314,38 +305,29 @@ class StatesController extends EventEmitter {
314
305
  }, (stateDesc.compositeTimeout ? stateDesc.compositeTimeout : 100) * factor);
315
306
  }
316
307
 
317
- async publishFromState(deviceId, model, stateKey, state, options, debugId) {
308
+ async publishFromState(deviceId, model, stateKey, state, options) {
318
309
  this.debug(`Change state '${stateKey}' at device ${deviceId} type '${model}'`);
319
310
  const elevated = this.checkDebugDevice(deviceId);
320
311
 
321
- if (elevated) {
322
- const message = (`Change state '${stateKey}' at device ${deviceId} type '${model}'`);
323
- this.emit('device_debug', { ID:debugId, data: { ID: deviceId, model: model, flag:'02', IO:false }, message:message});
324
- }
312
+ if (elevated) this.warn(`ELEVATED O02: Change state '${stateKey}' at device ${deviceId} type '${model}'`);
325
313
 
326
314
  const devStates = await this.getDevStates(deviceId, model);
327
315
  if (!devStates) {
328
- if (elevated) {
329
- const message = (`no device states for device ${deviceId} type '${model}'`);
330
- this.emit('device_debug', { ID:debugId, data: { error: 'NOSTATES' , IO:false }, message:message});
331
- }
316
+ if (elevated) this.error(`ELEVATED OE1: no device states for device ${deviceId} type '${model}'`);
332
317
  return;
333
318
  }
334
319
  const commonStates = statesMapping.commonStates.find(statedesc => stateKey === statedesc.id);
335
320
  const stateDesc = (commonStates === undefined ? devStates.states.find(statedesc => stateKey === statedesc.id) : commonStates);
336
321
  const stateModel = devStates.stateModel;
337
322
  if (!stateDesc) {
338
- const message = (`No state available for '${model}' with key '${stateKey}'`);
339
- if (elevated) this.emit('device_debug', { ID:debugId, data: { states:[{id:state.ID, value:'unknown', payload:'unknown'}], error: 'NOSTKEY' , IO:false }, message:message});
323
+ this.error(`No state available for '${model}' with key '${stateKey}'`);
340
324
  return;
341
325
  }
342
326
 
343
327
  const value = state.val;
344
328
  if (value === undefined || value === '') {
345
- if (elevated) {
346
- const message = (`no value for device ${deviceId} type '${model}'`);
347
- this.emit('device_debug', { ID:debugId, data: { states:[{id:state.ID, value:'--', payload:'error', ep:stateDesc.epname}],error: 'NOVAL' , IO:false }, message:message});
348
- }
329
+ if (elevated)
330
+ this.error(`ELEVATED OE2: no value for device ${deviceId} type '${model}'`);
349
331
  return;
350
332
  }
351
333
  let stateList = [{stateDesc: stateDesc, value: value, index: 0, timeout: 0, source:state.from}];
@@ -362,8 +344,7 @@ class StatesController extends EventEmitter {
362
344
  }
363
345
  } catch (e) {
364
346
  this.sendError(e);
365
- if (elevated) this.emit('device_debug', { ID:debugId, data: { states:[{id:state.ID, value:state.val, payload:'unknown'}], error: 'EXLINK' , IO:false }});
366
- this.error('Exception caught in publishfromstate: ' + (e && e.message ? e.message : 'no error message given'));
347
+ this.error('Exception caught in publishfromstate');
367
348
  }
368
349
 
369
350
  });
@@ -378,7 +359,7 @@ class StatesController extends EventEmitter {
378
359
  readAfterWriteStates = readAfterWriteStates.concat(readAfterWriteStateDesc.id));
379
360
  }
380
361
 
381
- this.emit('changed', deviceId, model, stateModel, stateList, options, debugId);
362
+ this.emit('changed', deviceId, model, stateModel, stateList, options);
382
363
  }
383
364
 
384
365
  async renameDevice(id, newName) {
@@ -432,7 +413,7 @@ class StatesController extends EventEmitter {
432
413
  let statename = state._id;
433
414
  const arr = /zigbee.[0-9].[^.]+.(\S+)/gm.exec(statename);
434
415
  if (arr[1] === undefined) {
435
- this.debug(`unable to extract id from state ${statename}`);
416
+ this.warn(`unable to extract id from state ${statename}`);
436
417
  const idx = statename.lastIndexOf('.');
437
418
  if (idx > -1) {
438
419
  statename = statename.slice(idx + 1);
@@ -774,7 +755,7 @@ class StatesController extends EventEmitter {
774
755
  this.adapter.fileExists(namespace, target, async (err,result) => {
775
756
  if (result) return;
776
757
  const src = `${tmpdir()}/${path.basename(target)}`;
777
- //const msg = `downloading ${url} to ${src}`;
758
+ const msg = `downloading ${url} to ${src}`;
778
759
  if (this.ImagesToDownload.indexOf(url) ==-1) {
779
760
  await this.downloadIcon(url, src)
780
761
  try {
@@ -792,6 +773,7 @@ class StatesController extends EventEmitter {
792
773
  this.info(`copied ${src} to ${target}.`)
793
774
  fs.rm(src, (err) => {
794
775
  if (err) this.warn(`error removing ${src} : ${JSON.stringify(err)}`);
776
+ else this.info(`removed ${src}`)
795
777
  });
796
778
  })
797
779
  }
@@ -879,257 +861,102 @@ class StatesController extends EventEmitter {
879
861
  this.emit('debugmessage', {id: id, message:message});
880
862
  }
881
863
 
882
- async publishToState(devId, model, payload, debugId) {
883
- try {
884
- if (!debugId) debugId = Date.now();
885
- const devStates = await this.getDevStates(`0x${devId}`, model);
886
-
887
- const has_elevated_debug = (this.checkDebugDevice(devId) && !payload.hasOwnProperty('msg_from_zigbee'));
888
-
889
- const message = `message received '${JSON.stringify(payload)}' from device ${devId} type '${model}'`;
890
- if (has_elevated_debug) this.emit('device_debug', { ID:debugId, data: { deviceID: devId, flag:'01', IO:true }, message:message});
891
- else this.debug(message);
892
- if (!devStates) {
893
- const message = `no device states for device ${devId} type '${model}'`;
894
- if (has_elevated_debug)this.emit('device_debug', { ID:debugId, data: { error:'NOSTATE',states:[{ id:'--', value:'--', payload:payload}], IO:true }, message:message});
895
- else this.debug(message);
896
- return;
897
- }
898
- // find states for payload
899
- let has_published = false;
900
- if (devStates.states !== undefined) {
901
- try {
902
- const states = statesMapping.commonStates.concat(
903
- devStates.states.filter(statedesc => payload.hasOwnProperty(statedesc.prop || statedesc.id))
904
- );
905
-
906
- for (const stateInd in states) {
907
- const statedesc = states[stateInd];
908
- let value;
909
- if (statedesc.getter) {
910
- value = statedesc.getter(payload);
911
- } else {
912
- value = payload[statedesc.prop || statedesc.id];
913
- }
914
- // checking value
915
- if (value === undefined || value === null) {
916
- continue;
917
- }
918
-
919
- let stateID = statedesc.id;
920
-
921
- const message = `value generated '${JSON.stringify(value)}' from device ${devId} for '${statedesc.name}'`;
922
- if (has_elevated_debug) this.emit('device_debug', { ID:debugId, data: { states:[{id:stateID, value:value, payload:payload }],flag:'02', IO:true }, message});
923
- else this.debug(message);
924
-
925
- const common = {
926
- name: statedesc.name,
927
- type: statedesc.type,
928
- unit: statedesc.unit,
929
- read: statedesc.read,
930
- write: statedesc.write,
931
- icon: statedesc.icon,
932
- role: statedesc.role,
933
- min: statedesc.min,
934
- max: statedesc.max,
935
- };
936
-
937
- if (typeof value === 'object' && value.hasOwnProperty('stateid')) {
938
- stateID = `${stateID}.${value.stateid}`;
939
- if (value.hasOwnProperty('unit')) {
940
- common.unit = value.unit;
941
- }
942
- common.name = value.name ? value.name : value.stateid;
943
- common.role = value.role ? `value.${value.role}` : 'number';
944
- value = value.value;
945
- }
946
-
947
- // if needs to return value to back after timeout
948
- if (statedesc.isEvent) {
949
- this.updateStateWithTimeout(devId, statedesc.id, value, common, 300, (typeof value == typeof (!value) ? !value : ''));
950
- if (has_elevated_debug) this.emit('device_debug', { ID:debugId, data: { flag:'SUCCESS', IO:true }});
951
-
952
- } else {
953
- if (statedesc.prepublish) {
954
- this.collectOptions(devId, model, options =>
955
- statedesc.prepublish(devId, value, newvalue => {
956
- this.updateState(devId, stateID, newvalue, common) }, options)
957
- );
958
- if (has_elevated_debug) this.emit('device_debug', { ID:debugId, data: { flag:'SUCCESS', IO:true }});
959
- } else {
960
- this.updateState(devId, stateID, value, common, debugId);
961
- if (has_elevated_debug) this.emit('device_debug', { ID:debugId, data: { flag:'SUCCESS', IO:true }});
962
- }
963
- }
964
- has_published = true;
965
- }
966
- } catch (e) {
967
- const message = `unable to enumerate states of ${devId} for payload ${JSON.stringify(payload)}, ${(e ? e.name : 'undefined')} (${(e ? e.message : '')}).`;
968
- if (has_elevated_debug) this.emit('device_debug', { ID:debugId, data:{ error:'ESTATE', IO:true }, message:message});
969
- else this.debug(message);
970
- }
971
- const message = `No value published for device ${devId}`;
972
- if (!has_published && has_elevated_debug) this.emit('device_debug', { ID:debugId, data:{ error:'NOVAL', IO:true }, message:message});
973
- else this.debug(message);
974
- }
975
- else {
976
- const message = `ELEVATED IE05 - NOSTATE: No states matching the payload ${JSON.stringify(payload)} for device ${devId}`;
977
- if (has_elevated_debug) this.emit('device_debug', { ID:debugId, data:{ error:'NOSTATE', IO:true }, message});
978
- else this.debug(message);
979
- }
980
- }
981
- catch (error) {
982
- this.error('Something went horribly wrong: ' + (error && error.message ? error.message : 'no reason given'));
983
- }
984
- }
985
-
986
- async processConverters(converters, devId, model, mappedModel, message, meta, debugId) {
987
- for (const converter of converters) {
988
- const publish = (payload, dID) => {
989
- if (typeof payload === 'object') {
990
- this.publishToState(devId, model, payload,dID);
991
- }
992
- };
864
+ async publishToState(devId, model, payload) {
865
+ const devStates = await this.getDevStates(`0x${devId}`, model);
993
866
 
994
- const options = await new Promise((resolve, reject) => {
995
- this.collectOptions(devId, model, (options) => {
996
- resolve(options);
997
- });
998
- });
867
+ const has_elevated_debug = (this.checkDebugDevice(devId) && !payload.hasOwnProperty('msg_from_zigbee'));
999
868
 
1000
- const payload = await new Promise((resolve, reject) => {
1001
- const payloadConv = converter.convert(mappedModel, message, publish, options, meta);
1002
- if (typeof payloadConv === 'object') {
1003
- resolve(payloadConv);
1004
- }
1005
- });
1006
869
 
1007
- publish(payload, debugId);
870
+ if (has_elevated_debug)
871
+ {
872
+ this.elevatedMessage(devId, `ELEVATED I01: message received '${JSON.stringify(payload)}' from device ${devId} type '${model}'`, false);
1008
873
  }
1009
- }
1010
-
1011
-
1012
- async onZigbeeEvent(type, entity, message) {
1013
- this.debug(`Type ${type} device ${safeJsonStringify(entity)} incoming event: ${safeJsonStringify(message)}`);
1014
-
1015
- const device = entity.device;
1016
- const mappedModel = entity.mapped;
1017
- const model = entity.mapped ? entity.mapped.model : entity.device.modelID;
1018
- const cluster = message.cluster;
1019
- const devId = device.ieeeAddr.substr(2);
1020
- const meta = {device};
1021
-
1022
- const has_elevated_debug = this.checkDebugDevice(devId);
1023
- const debugId = Date.now();
1024
-
1025
- // raw message data for logging and msg_from_zigbee
1026
- const msgForState = Object.assign({}, message);
1027
- delete msgForState['device'];
1028
- delete msgForState['endpoint'];
1029
- msgForState['endpoint_id'] = message.endpoint.ID;
1030
-
1031
- if (has_elevated_debug) {
1032
- const message = `Zigbee Event of Type ${type} from device ${device.ieeeAddr}, incoming event: ${safeJsonStringify(msgForState)}`;
1033
- this.emit('device_debug', { ID:debugId, data: { ID: device.ieeeAddr, payload:safeJsonStringify(msgForState), flag:'01', IO:true }, message:message});
1034
-
874
+ if (!devStates) {
875
+ if (has_elevated_debug)
876
+ this.elevatedMessage(devId, `ELEVATED IE02: no device states for device ${devId} type '${model}'`, true)
877
+ return;
1035
878
  }
1036
- // this assigment give possibility to use iobroker logger in code of the converters, via meta.logger
1037
- meta.logger = this;
1038
-
1039
- await this.adapter.checkIfModelUpdate(entity);
1040
-
1041
- let _voltage = 0;
1042
- let _temperature = 0;
1043
- let _humidity = 0;
1044
-
1045
- let isMessure = false;
1046
- let isBattKey = false;
879
+ // find states for payload
880
+ let has_published = false;
1047
881
 
1048
- if (mappedModel && mappedModel.meta && mappedModel.meta.battery) {
1049
- const isVoltage = mappedModel.meta.battery.hasOwnProperty('voltageToPercentage');
882
+ if (devStates.states !== undefined) {
883
+ try {
884
+ const states = statesMapping.commonStates.concat(
885
+ devStates.states.filter(statedesc => payload.hasOwnProperty(statedesc.prop || statedesc.id))
886
+ );
887
+
888
+ for (const stateInd in states) {
889
+ const statedesc = states[stateInd];
890
+ let value;
891
+ if (statedesc.getter) {
892
+ value = statedesc.getter(payload);
893
+ } else {
894
+ value = payload[statedesc.prop || statedesc.id];
895
+ }
896
+ // checking value
897
+ if (value === undefined || value === null) {
898
+ continue;
899
+ }
1050
900
 
1051
- if (isVoltage) {
1052
- const keys = Object.keys(message.data);
901
+ let stateID = statedesc.id;
1053
902
 
1054
- for (const key of keys) {
1055
- const value = message.data[key];
903
+ if (has_elevated_debug) {
904
+ this.elevatedMessage(devId, `ELEVATED I02: value generated '${JSON.stringify(value)}' from device ${devId} for '${statedesc.name}'`, false);
905
+ }
1056
906
 
1057
- if (value && value[1]) {
1058
- if (key == 65282 && value[1][1]) {
1059
- _voltage = value[1][1].elmVal;
1060
- isBattKey = true;
1061
- break;
907
+ const common = {
908
+ name: statedesc.name,
909
+ type: statedesc.type,
910
+ unit: statedesc.unit,
911
+ read: statedesc.read,
912
+ write: statedesc.write,
913
+ icon: statedesc.icon,
914
+ role: statedesc.role,
915
+ min: statedesc.min,
916
+ max: statedesc.max,
917
+ };
918
+
919
+ if (typeof value === 'object' && value.hasOwnProperty('stateid')) {
920
+ stateID = `${stateID}.${value.stateid}`;
921
+ if (value.hasOwnProperty('unit')) {
922
+ common.unit = value.unit;
1062
923
  }
1063
- if (key == 65281) {
1064
- _voltage = value[1];
1065
- isBattKey = true;
1066
- _temperature = value[100];
1067
- _temperature = _temperature /100;
1068
- _humidity = value[101];
1069
- _humidity = _humidity / 100;
1070
- isMessure = true;
1071
- break;
924
+ common.name = value.name ? value.name : value.stateid;
925
+ common.role = value.role ? `value.${value.role}` : 'number';
926
+ value = value.value;
927
+ }
928
+
929
+ // if needs to return value to back after timeout
930
+ if (statedesc.isEvent) {
931
+ this.updateStateWithTimeout(devId, statedesc.id, value, common, 300, (typeof value == typeof (!value) ? !value : ''));
932
+ } else {
933
+ if (statedesc.prepublish) {
934
+ this.collectOptions(devId, model, options =>
935
+ statedesc.prepublish(devId, value, newvalue =>
936
+ this.updateState(devId, stateID, newvalue, common), options)
937
+ );
938
+ } else {
939
+ this.updateState(devId, stateID, value, common);
1072
940
  }
1073
941
  }
942
+ has_published = true;
1074
943
  }
944
+ } catch (e) {
945
+ this.debug(`No states in device ${devId} : payload ${JSON.stringify(payload)}`);
946
+ if (has_elevated_debug)
947
+ this.elevatedMessage(devId, `ELEVATED IE03: error when enumerating states of ${devId} for payload ${JSON.stringify(payload)}, ${(e ? e.name : 'undefined')} (${(e ? e.message : '')}).`, true);
1075
948
  }
1076
- }
949
+ if (!has_published && has_elevated_debug) {
950
+ this.elevatedMessage(devId, `ELEVATED IE04: No value published for device ${devId}`, true);
1077
951
 
1078
- // always publish link_quality and battery
1079
- if (message.linkquality) { // send battery with
1080
- this.publishToState(devId, model, {linkquality: message.linkquality}, debugId);
1081
- if (isBattKey) {
1082
- this.publishToState(devId, model, {voltage: _voltage}, debugId);
1083
- const battProz = zigbeeHerdsmanConvertersUtils.batteryVoltageToPercentage(_voltage,entity.mapped.meta.battery.voltageToPercentage);
1084
- this.publishToState(devId, model, {battery: battProz}, debugId);
1085
952
  }
1086
- if (isMessure) {
1087
- this.publishToState(devId, model, {temperature: _temperature}, debugId);
1088
- this.publishToState(devId, model, {humidity: _humidity}), debugId;
1089
- }
1090
- }
1091
-
1092
- // publish raw event to "from_zigbee"
1093
- // some cleanup
1094
-
1095
- this.publishToState(devId, model, {msg_from_zigbee: safeJsonStringify(msgForState)}, -1);
1096
-
1097
- if (!entity.mapped) {
1098
- return;
1099
- }
1100
-
1101
- let converters = mappedModel.fromZigbee.filter(c => c && c.cluster === cluster && (
1102
- Array.isArray(c.type) ? c.type.includes(type) : c.type === type));
1103
-
1104
-
1105
- if (!converters.length && type === 'readResponse') {
1106
- converters = mappedModel.fromZigbee.filter(c => c.cluster === cluster && (
1107
- Array.isArray(c.type) ? c.type.includes('attributeReport') : c.type === 'attributeReport'));
1108
953
  }
1109
-
1110
- if (!converters.length) {
1111
- if (type !== 'readResponse') {
1112
- const message = `No converter available for '${mappedModel.model}' '${devId}' with cluster '${cluster}' and type '${type}'`;
1113
- if (has_elevated_debug) this.emit('device_debug', { ID:debugId, data: { error:'NOCONV', IO:true }, message:message});
1114
- else this.debug(message);
1115
- }
1116
- return;
954
+ else {
955
+ if (has_elevated_debug)
956
+ this.elevatedMessage(devId, `ELEVATED IE05: No states matching the payload ${JSON.stringify(payload)} for device ${devId}`, true);
1117
957
  }
1118
-
1119
- meta.state = { state: '' }; // for tuya
1120
-
1121
- this.processConverters(converters, devId, model, mappedModel, message, meta, debugId)
1122
- .catch((error) => {
1123
- // 'Error: Expected one of: 0, 1, got: 'undefined''
1124
- if (cluster !== '64529') {
1125
- if (has_elevated_debug) this.emit('device_debug', { ID:debugId, data: { error:'EPROC', IO:true }});
1126
- this.error(`Error while processing converters DEVICE_ID: '${devId}' cluster '${cluster}' type '${type}'`);
1127
- }
1128
- });
1129
958
  }
1130
959
 
1131
-
1132
-
1133
960
  }
1134
961
 
1135
962
  module.exports = StatesController;
@@ -178,7 +178,7 @@ class DeviceAvailability extends BaseExtension {
178
178
  this.publishAvailability(device, false);
179
179
  if (pingCount.failed++ <= this.max_ping) {
180
180
  if (pingCount.failed < 2 && pingCount.reported < this.max_ping) {
181
- this.info(`Failed to ping ${ieeeAddr} ${device.modelID}`);
181
+ this.warn(`Failed to ping ${ieeeAddr} ${device.modelID}`);
182
182
  pingCount.reported++;
183
183
  } else {
184
184
  this.debug(`Failed to ping ${ieeeAddr} ${device.modelID} on ${pingCount} consecutive attempts`);
@@ -186,7 +186,7 @@ class DeviceAvailability extends BaseExtension {
186
186
  this.setTimerPingable(device, pingCount.failed);
187
187
  this.ping_counters[device.ieeeAddr] = pingCount;
188
188
  } else {
189
- this.info(`Stopping to ping ${ieeeAddr} ${device.modelID} after ${pingCount.failed} ping attempts`);
189
+ this.warn(`Stopping to ping ${ieeeAddr} ${device.modelID} after ${pingCount.failed} ping attempts`);
190
190
  }
191
191
  }
192
192
  }
@@ -14,8 +14,6 @@ class DeviceConfigure extends BaseExtension {
14
14
  this.configuring = new Set();
15
15
  this.attempts = {};
16
16
  this.name = 'DeviceConfigure';
17
-
18
- this.configureKeys = {};
19
17
  }
20
18
 
21
19
  setOptions(options) {
@@ -29,24 +27,23 @@ class DeviceConfigure extends BaseExtension {
29
27
  if (!mappedDevice || !mappedDevice.configure) {
30
28
  return false;
31
29
  }
32
- const delayedAttempts = this.checkDelayedConfigure(device, 0);
33
- if (!this.configureKeys.hasOwnProperty(device.ieeeAddr)) this.configureKeys[device.ieeeAddr] = zigbeeHerdsmanConverters.getConfigureKey(mappedDevice);
34
- if (delayedAttempts > 0 && !device.interviewing) return true;
35
- if (device.meta.hasOwnProperty('configured') && device.meta.configured !== this.configureKeys[device.ieeeAddr]) return true;
36
- return (device.interviewing !== true && this.checkDelayedConfigure(device)>0);
30
+ if (device.meta.hasOwnProperty('configured') &&
31
+ zigbeeHerdsmanConverters.getConfigureKey(mappedDevice)) {
32
+ return false;
33
+ }
34
+
35
+ return (device.interviewing !== true && this.checkDelayedConfigure(device.ieeeAddr)>0);
37
36
  }
38
37
 
39
38
  checkDelayedConfigure(device, num) {
40
39
  if (!this.delayedConfigure.hasOwnProperty(device.ieeeAddr)) {
41
40
  if (num && num > 0) {
42
- // this.warn('adding dev ' + device.ieeeAddr + ' to delayedConfigure with ' + num + ' attempts');
43
41
  this.delayedConfigure[device.ieeeAddr] = { maxAttempts:num };
44
42
  return num;
45
43
  }
46
44
  return 0;
47
45
  }
48
46
  const dc = this.delayedConfigure[device.ieeeAddr];
49
- // this.warn('checkDelayedConfigure for ' + device.ieeeAddr + ' with ' + JSON.stringify(dc));
50
47
  dc.maxAttempts--;
51
48
  if (dc.maxAttempts > 0) return dc.maxAttempts;
52
49
  if (num && num > 0) {
@@ -93,7 +90,6 @@ class DeviceConfigure extends BaseExtension {
93
90
  try {
94
91
  const device = data.device;
95
92
  if (this.shouldConfigure(device, mappedDevice)) {
96
- this.debug('ShouldConfigure ' + device.ieeeAddr);
97
93
  this.configure(device, mappedDevice);
98
94
  }
99
95
  } catch (error) {
@@ -102,7 +98,6 @@ class DeviceConfigure extends BaseExtension {
102
98
  }
103
99
  }
104
100
 
105
-
106
101
  onDeviceRemove(device) {
107
102
  try {
108
103
  if (this.configuring.has(device.ieeeAddr)) {
@@ -146,16 +141,14 @@ class DeviceConfigure extends BaseExtension {
146
141
  const coordinatorEndpoint = await this.zigbee.getDevicesByType('Coordinator')[0].endpoints[0];
147
142
  try {
148
143
  if (mappedDevice) {
149
- if (mappedDevice.configure === undefined) return `No configure available for ${device.ieeeAddr} ${device.modelID}.`;
150
- this.info(`Configuring ${device.ieeeAddr} ${device.modelID}`);
151
- if (typeof mappedDevice.configure === 'function') await mappedDevice.configure(device, coordinatorEndpoint, this);
152
- else {
153
- const promises = [];
154
- promises.push(...mappedDevice.configure);
155
- await Promise.all(promises.map(callback => callback(device, coordinatorEndpoint, mappedDevice)))
156
- }
144
+ this.info(`-> Configuring ${device.ieeeAddr} ${device.modelID}`);
145
+ const promises = [];
146
+ promises.push(mappedDevice.configure);
147
+ await Promise.all(promises.map(callback => callback(device, coordinatorEndpoint, mappedDevice)))
148
+
149
+ //await mappedDevice.configure(device, coordinatorEndpoint, this);
150
+
157
151
  device.meta.configured = zigbeeHerdsmanConverters.getConfigureKey(mappedDevice);
158
- this.configureKeys[device.ieeeAddr] = device.meta.configured;
159
152
  device.save();
160
153
  this.info(`DeviceConfigure successful ${device.ieeeAddr} ${device.modelID}`);
161
154
  this.delayedConfigureAttempt(device, true);
@@ -169,8 +162,8 @@ class DeviceConfigure extends BaseExtension {
169
162
  if (error && error.message && error.message.match(/(\d+)ms/gm)) {
170
163
  // timeout message - we do want to start the configure chain
171
164
  const num = this.delayedConfigureAttempt(device, false);
172
- this.warn(`Timeout trying to configure ${device.ieeeAddr} ${device.modelID}: ${num} attempts remaining`)
173
- return `Configuration timed out ${device.ieeeAddr} ${device.modelID}. The device did not repond in time to the configuration request. Another attempt will be made when the device is awake.`;
165
+ this.info(`Delayed configure for ${device.ieeeAddr} ${device.modelID}: ${num} attempts remaining`)
166
+ return `Delayed configure for ${device.ieeeAddr} ${device.modelID}: ${num} attempts remaining`;
174
167
  } else {
175
168
  this.sendError(error);
176
169
  this.warn(`${device.ieeeAddr} ${device.modelID} Failed to configure. --> ${error && error.message ? error.message : ' no error message given'} `);