homebridge-econet-rheem
Version:
Homebridge plugin for control of Rheem and Ruud thermostats and water heaters
123 lines • 4.77 kB
JavaScript
import { F_OK } from 'constants';
import fakegato from 'fakegato-history/fakegato-history.cjs';
import { access, unlink } from 'fs/promises';
import path from 'path';
import { EveCharacteristicKey } from './enums.js';
import { EveCharacteristic } from '../accessory/characteristic/eve.js';
import { strings } from '../i18n/i18n.js';
import { SECOND } from '../tools/time.js';
export var HistoryType;
(function (HistoryType) {
HistoryType["CUSTOM"] = "custom";
HistoryType["WEATHER"] = "weather";
})(HistoryType || (HistoryType = {}));
let ServiceProvider;
const HISTORY_UUID = 'd08afca9-1791-4d50-a580-7b343f5a22b3';
function HistoryService(type, accessory, options) {
if (!ServiceProvider) {
throw new Error('HistoryServiceProvider not initialized');
}
return new ServiceProvider(type, accessory, options);
}
export class History {
api;
log;
enabled;
historyServices = new Map();
persistPath;
cleanedUp = new Set();
constructor(api, log, enabled) {
this.api = api;
this.log = log;
this.enabled = enabled;
if (ServiceProvider) {
throw new Error('HistoryServiceProvider already initialized');
}
ServiceProvider = fakegato(api);
this.persistPath = api.user.persistPath();
}
record(accessory, type, entry, updateLastActivation = false) {
if (!this.enabled) {
this.cleanup(accessory);
return;
}
const historyService = this.historyServices.get(accessory.identifier)
?? this.createHistoryService(accessory, type);
const time = Math.floor(Date.now() / 1000);
entry = {
time: time,
...entry,
};
this.log.ifDebug(strings.history.entry, accessory.name, JSON.stringify(entry));
historyService.addEntry(entry);
if (updateLastActivation && !isNaN(historyService.getInitialTime())) {
const lastActivation = time - historyService.getInitialTime();
accessory.setProperty(EveCharacteristicKey.LastActivation, lastActivation);
accessory.service.updateCharacteristic(EveCharacteristic(EveCharacteristicKey.LastActivation), lastActivation);
}
return;
}
createHistoryService(accessory, type) {
const options = {
size: 4032,
storage: 'fs',
path: this.persistPath,
filename: this.getFilename(accessory),
};
const historyService = HistoryService(type, accessory.platformAccessory, options);
this.historyServices.set(accessory.identifier, historyService);
setTimeout(() => {
if (historyService.lastEntry === undefined || historyService.memorySize === undefined) {
return;
}
const entry = historyService.history[historyService.lastEntry % historyService.memorySize];
if (entry === undefined || entry.time === undefined) {
return;
}
const lastActivation = entry.time - historyService.getInitialTime();
accessory.setProperty(EveCharacteristicKey.LastActivation, lastActivation);
accessory.service.addOptionalCharacteristic(EveCharacteristic(EveCharacteristicKey.LastActivation));
const characteristic = accessory.service.getCharacteristic(EveCharacteristic(EveCharacteristicKey.LastActivation));
characteristic.updateValue(lastActivation);
characteristic.onGet(async () => {
return accessory.getProperty(EveCharacteristicKey.LastActivation) ?? lastActivation;
});
}, 1 * SECOND);
return historyService;
}
getFilename(accessory) {
return this.api.hap.uuid.generate(accessory.identifier + HISTORY_UUID);
}
async cleanup(accessory) {
if (this.cleanedUp.has(accessory.identifier)) {
return;
}
this.cleanedUp.add(accessory.identifier);
const filename = this.getFilename(accessory);
const filePath = path.join(this.persistPath, filename);
const fileExists = await this.fileExists(filePath);
if (!fileExists) {
return;
}
this.log.ifDebug(strings.history.cleanup, accessory.name);
try {
await unlink(filePath);
}
catch (error) {
if (error.code !== 'ENOENT') {
return;
}
this.log.error(strings.history.cleanupFailed, accessory.name, filename);
}
}
async fileExists(filePath) {
try {
await access(filePath, F_OK);
return true;
}
catch {
return false;
}
}
}
//# sourceMappingURL=history.js.map