homebridge-aeg-robot
Version:
AEG RX9 / Electrolux Pure i9 robot vacuum plugin for Homebridge
67 lines • 2.27 kB
JavaScript
// Homebridge plugin for AEG RX 9 / Electrolux Pure i9 robot vacuum
// Copyright © 2022-2023 Alexander Thoukydides
import { setTimeout } from 'node:timers/promises';
import { MS, logError } from './utils.js';
// Multiple of interval to treat as a failure
const TIMEOUT_MULTIPLE = 3;
const TIMEOUT_OFFSET = 10 * MS;
// Perform an action periodically with error reporting and timeout
export class Heartbeat {
log;
name;
interval;
action;
failure;
// Abort signal used to stop a watchdog
abortController;
// The result of the last action
lastError;
// Create a new periodic action
constructor(log, name, interval, action, failure) {
this.log = log;
this.name = name;
this.interval = interval;
this.action = action;
this.failure = failure;
void this.doAction();
void this.resetWatchdog();
}
// Perform the action periodically indefinitely
async doAction() {
for (;;) {
try {
await this.action();
void this.resetWatchdog();
}
catch (err) {
logError(this.log, this.name, err);
this.lastError = err;
}
await setTimeout(this.interval);
}
}
// Reset the timeout
async resetWatchdog() {
try {
// Kill any previous watchdog, indicating any previous timeout as cleared
this.abortController?.abort();
if (this.lastError) {
this.lastError = undefined;
this.failure();
}
// Start a new watchdog
this.abortController = new AbortController();
const { signal } = this.abortController;
await setTimeout(this.interval * TIMEOUT_MULTIPLE + TIMEOUT_OFFSET, undefined, { signal });
// The timeout has occurred, so report the failure
this.lastError ??= new Error(`${this.name} watchdog timeout`);
this.failure(this.lastError);
}
catch (cause) {
if (cause instanceof Error && cause.name === 'AbortError')
return;
logError(this.log, this.name, cause);
}
}
}
//# sourceMappingURL=heartbeat.js.map