mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2026-07-21 02:51:11 +00:00
Fix race condition when configuring devices
This commit is contained in:
@@ -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';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user