diff --git a/lib/extension/deviceConfigure.js b/lib/extension/deviceConfigure.js index 048f9b1c..a2c3e23b 100644 --- a/lib/extension/deviceConfigure.js +++ b/lib/extension/deviceConfigure.js @@ -9,7 +9,7 @@ const Queue = require('queue'); class DeviceConfigure { constructor(zigbee, mqtt, state, publishEntityState) { this.zigbee = zigbee; - this.configured = []; + this.configured = {}; this.attempts = {}; this.queue = new Queue(); @@ -22,26 +22,29 @@ class DeviceConfigure { const mappedDevice = zigbeeShepherdConverters.findByZigbeeModel(device.modelId); if (mappedDevice) { - this.configure(device, mappedDevice); + this.configure(device, mappedDevice, device.ieeeAddr); } }); } onZigbeeMessage(message, device, mappedDevice) { if (device && mappedDevice) { - this.configure(device, mappedDevice); + const ieeeAddr = device.ieeeAddr; + if (!this.configured[ieeeAddr]) { + this.configure(device, mappedDevice, ieeeAddr); + } } } - configure(device, mappedDevice) { - const ieeeAddr = device.ieeeAddr; - + configure(device, mappedDevice, ieeeAddr) { if (!this.attempts.hasOwnProperty(ieeeAddr)) { this.attempts[ieeeAddr] = 0; } - if (!this.configured.includes(ieeeAddr) && mappedDevice.configure) { + if (mappedDevice.configure) { const friendlyName = settings.getDevice(ieeeAddr) ? settings.getDevice(ieeeAddr).friendly_name : 'unknown'; + // mark device as currently being configured to prevent race conditions + this.configured[ieeeAddr]='configuring'; this.queue.push((queueCallback) => { logger.debug(`Configuring ${friendlyName} (${ieeeAddr}) ...`); @@ -49,15 +52,18 @@ class DeviceConfigure { // Call configure function of this device. mappedDevice.configure(ieeeAddr, this.zigbee.shepherd, this.zigbee.getCoordinator(), (ok, msg) => { if (ok) { - logger.info(`Successfully configured ${friendlyName} (${ieeeAddr})`); - this.configured.push(ieeeAddr); + logger.info(`Succesfully configured ${friendlyName} (${ieeeAddr})`); + this.configured[ieeeAddr]='configured'; } else { // If a device is not joined in the network the configure command may fail // (especially, immediately after zigbee start) // also, this command may fail if the network is busy or lost data packets if (this.attempts[ieeeAddr] > 1) { // Give up after 3 attempts. - this.configured.push(ieeeAddr); + this.configured[ieeeAddr] = 'failed'; + } else { + // we're not done yet so mark not busy + delete this.configured[ieeeAddr]; } logger.warn( @@ -73,6 +79,9 @@ class DeviceConfigure { queueCallback(); }); }); + } else { + // no need to configure anyting. So just mark as done + this.configured[ieeeAddr]='configured'; } } }