mirror of
https://github.com/Koenkk/zigbee2mqtt.git
synced 2024-11-17 02:48:31 -07:00
85 lines
1.9 KiB
JavaScript
85 lines
1.9 KiB
JavaScript
const maxSimultaneouslyRunning = 5;
|
|
const delay = 250;
|
|
const error17Retries = 3;
|
|
|
|
class ZigbeeQueue {
|
|
constructor() {
|
|
this.queue = [];
|
|
this.active = [];
|
|
this.timer = null;
|
|
this.running = false;
|
|
}
|
|
|
|
start() {
|
|
this.running = true;
|
|
this.resetTimer();
|
|
}
|
|
|
|
push(entityID, func) {
|
|
this.queue.push({entityID, func, attempts: 0});
|
|
}
|
|
|
|
stopTimer() {
|
|
if (this.timer) {
|
|
clearInterval(this.timer);
|
|
this.timer = null;
|
|
}
|
|
}
|
|
|
|
resetTimer() {
|
|
this.stopTimer();
|
|
|
|
this.timer = setInterval(() => {
|
|
this.executeNext();
|
|
}, delay);
|
|
}
|
|
|
|
stop() {
|
|
this.stopTimer();
|
|
this.running = false;
|
|
}
|
|
|
|
handleJobComplete(job, error) {
|
|
if (error && error.message === 'rsp error: 17' && job.attempts < error17Retries) {
|
|
// Error 17 means that the buffer of the ZNP was full,
|
|
// retry this for a maximum of 3 times.
|
|
job.attempts++;
|
|
this.active.splice(this.active.indexOf(job), 1);
|
|
} else {
|
|
this.active.splice(this.active.indexOf(job), 1);
|
|
this.queue.splice(this.queue.indexOf(job), 1);
|
|
}
|
|
}
|
|
|
|
executeNext() {
|
|
if (!this.running) {
|
|
return;
|
|
}
|
|
|
|
const next = this.getNext();
|
|
|
|
if (next) {
|
|
this.active.push(next);
|
|
next.func((error) => this.handleJobComplete(next, error));
|
|
}
|
|
}
|
|
|
|
getNext() {
|
|
if (this.active.length > (maxSimultaneouslyRunning - 1)) {
|
|
return null;
|
|
}
|
|
|
|
for (let i = 0; i < this.queue.length; i++) {
|
|
const job = this.queue[i];
|
|
const activeDeviceJob = this.active.find((j) => j.entityID === job.entityID);
|
|
if (!activeDeviceJob) {
|
|
return job;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
module.exports = ZigbeeQueue;
|