mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2024-11-17 19:08:28 -07:00
90 lines
3.3 KiB
JavaScript
90 lines
3.3 KiB
JavaScript
const settings = require('../util/settings');
|
|
const logger = require('../util/logger');
|
|
const zigbeeShepherdConverters = require('zigbee-shepherd-converters');
|
|
const Queue = require('queue');
|
|
|
|
/**
|
|
* This extensions handles configuration of devices.
|
|
*/
|
|
class DeviceConfigure {
|
|
constructor(zigbee, mqtt, state, publishEntityState) {
|
|
this.zigbee = zigbee;
|
|
this.configured = {};
|
|
this.attempts = {};
|
|
|
|
this.queue = new Queue();
|
|
this.queue.concurrency = 1;
|
|
this.queue.autostart = true;
|
|
}
|
|
|
|
onZigbeeStarted() {
|
|
this.zigbee.getAllClients().forEach((device) => {
|
|
const mappedDevice = zigbeeShepherdConverters.findByZigbeeModel(device.modelId);
|
|
|
|
if (mappedDevice) {
|
|
this.configure(device.ieeeAddr, mappedDevice);
|
|
}
|
|
});
|
|
}
|
|
|
|
onZigbeeMessage(message, device, mappedDevice) {
|
|
if (device && mappedDevice) {
|
|
const ieeeAddr = device.ieeeAddr;
|
|
if (!this.configured[ieeeAddr]) {
|
|
this.configure(ieeeAddr, mappedDevice);
|
|
}
|
|
}
|
|
}
|
|
|
|
configure(ieeeAddr, mappedDevice) {
|
|
if (!this.attempts.hasOwnProperty(ieeeAddr)) {
|
|
this.attempts[ieeeAddr] = 0;
|
|
}
|
|
|
|
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}) ...`);
|
|
|
|
// 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[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[ieeeAddr] = 'failed';
|
|
} else {
|
|
// we're not done yet so mark not busy
|
|
delete this.configured[ieeeAddr];
|
|
}
|
|
|
|
logger.warn(
|
|
`Failed to configure ${friendlyName} (${ieeeAddr}) ('${msg}')` +
|
|
` (attempt #${this.attempts[ieeeAddr] + 1})`
|
|
);
|
|
|
|
logger.warn(`This can be ignored if the device is working properly`);
|
|
|
|
this.attempts[ieeeAddr] += 1;
|
|
}
|
|
|
|
queueCallback();
|
|
});
|
|
});
|
|
} else {
|
|
// no need to configure anyting. So just mark as done
|
|
this.configured[ieeeAddr] = 'configured';
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = DeviceConfigure;
|