homebridge-flume
Version:
Homebridge plugin to integrate Flume devices into HomeKit.
148 lines • 7.13 kB
JavaScript
import { strings } from '../i18n/i18n.js';
import { VolumeUnits } from '../model/types.js';
import getVersion from '../tools/version.js';
class CustomCharacteristic {
uuid;
name;
constructor(uuid, name) {
this.uuid = uuid;
this.name = name;
}
}
const TODAY_USAGE = new CustomCharacteristic('f25cc272-83cb-46a7-915a-259fa17364ed', strings.customChar.todayUsage);
const MONTH_USAGE = new CustomCharacteristic('580e224d-edf2-4c23-af79-cdbebfc509c5', strings.customChar.monthUsage);
const LAST_MONTH_USAGE = new CustomCharacteristic('69129d54-bdb8-46a1-a93b-f7e8d16d32a8', strings.customChar.lastMonth);
export class FlumeAccessory {
platform;
accessory;
device;
name;
units;
disableLogging;
HAP;
Characteristic;
Service;
leakService;
isLeakDetected = false;
isBatteryLow = false;
isDisconnected = true;
charLeakDetected;
charStatusLowBattery;
charStatusFault;
todayUsageChar;
monthUsageChar;
lastMonthUsageChar;
constructor(platform, accessory, device, name, units, disableLogging) {
this.platform = platform;
this.accessory = accessory;
this.device = device;
this.name = name;
this.units = units;
this.disableLogging = disableLogging;
this.HAP = platform.api.hap;
this.Characteristic = this.HAP.Characteristic;
this.Service = this.HAP.Service;
accessory.getService(this.Service.AccessoryInformation)
.setCharacteristic(this.Characteristic.Name, name)
.setCharacteristic(this.Characteristic.ConfiguredName, name)
.setCharacteristic(this.Characteristic.Manufacturer, strings.general.brand)
.setCharacteristic(this.Characteristic.SerialNumber, device.id)
.setCharacteristic(this.Characteristic.Model, device.productName)
.setCharacteristic(this.Characteristic.FirmwareRevision, getVersion());
this.charLeakDetected = this.Characteristic.LeakDetected;
this.charStatusLowBattery = this.Characteristic.StatusLowBattery;
this.charStatusFault = this.Characteristic.StatusFault;
this.leakService = this.accessory.getService(this.HAP.Service.LeakSensor)
|| this.accessory.addService(this.HAP.Service.LeakSensor);
this.isLeakDetected = this.leakService.getCharacteristic(this.charLeakDetected).value === this.charLeakDetected.LEAK_DETECTED;
this.isBatteryLow = this.leakService.getCharacteristic(this.charStatusLowBattery).value === this.charStatusLowBattery.BATTERY_LEVEL_LOW;
this.isDisconnected = this.leakService.getCharacteristic(this.charStatusFault).value === this.charStatusFault.GENERAL_FAULT;
this.clearCustomCharacteristics();
this.todayUsageChar = this.attachCustomCharacteristic(TODAY_USAGE);
this.monthUsageChar = this.attachCustomCharacteristic(MONTH_USAGE);
this.lastMonthUsageChar = this.attachCustomCharacteristic(LAST_MONTH_USAGE);
device.setOnUpdateCallback(this.handleUpdate.bind(this));
this.updateCharacteristics();
}
handleUpdate(id) {
if (id === this.device.id) {
this.updateCharacteristics();
}
}
updateCharacteristics() {
if (this.device.isLeakDetected !== this.isLeakDetected) {
this.isLeakDetected = this.device.isLeakDetected;
const value = this.isLeakDetected ? this.charLeakDetected.LEAK_DETECTED : this.charLeakDetected.LEAK_NOT_DETECTED;
this.leakService.updateCharacteristic(this.charLeakDetected, value);
this.logState(this.isLeakDetected ? "error" /* LogLevel.ERROR */ : "info" /* LogLevel.INFO */, this.isLeakDetected ? strings.status.leakDetected : strings.status.leakNotDetected);
}
if (this.device.isBatteryLow !== this.isBatteryLow) {
this.isBatteryLow = this.device.isBatteryLow;
const value = this.isBatteryLow ? this.charStatusLowBattery.BATTERY_LEVEL_LOW : this.charStatusLowBattery.BATTERY_LEVEL_NORMAL;
this.leakService.updateCharacteristic(this.charStatusLowBattery, value);
this.logState(this.isBatteryLow ? "warn" /* LogLevel.WARN */ : "info" /* LogLevel.INFO */, this.isBatteryLow ? strings.status.batteryLow : strings.status.batteryNormal);
}
if (this.device.isDisconnected !== this.isDisconnected) {
this.isDisconnected = this.device.isDisconnected;
const value = this.isDisconnected ? this.charStatusFault.GENERAL_FAULT : this.charStatusFault.NO_FAULT;
this.leakService.updateCharacteristic(this.charStatusFault, value);
this.logState(this.isDisconnected ? "warn" /* LogLevel.WARN */ : "info" /* LogLevel.INFO */, this.isDisconnected ? strings.status.connectionFault : strings.status.connectionNormal);
}
this.todayUsageChar.updateValue(this.device.usageToday);
this.monthUsageChar.updateValue(this.device.usageMonth);
this.lastMonthUsageChar.updateValue(this.device.usageLastMonth);
}
stringForUnits() {
switch (this.units) {
case VolumeUnits.GALLONS: return strings.config.enumNames.gallons;
case VolumeUnits.LITERS: return strings.config.enumNames.liters;
case VolumeUnits.CUBIC_FEET: return strings.config.enumNames.cubicFeet;
case VolumeUnits.CUBIC_METERS: return strings.config.enumNames.cubicMeters;
}
}
clearCustomCharacteristics() {
const allowedUUIDs = new Set([
this.charLeakDetected.UUID,
this.charStatusLowBattery.UUID,
this.charStatusFault.UUID,
]);
const charsToRemove = this.leakService.characteristics.filter(char => !allowedUUIDs.has(char.UUID));
charsToRemove.forEach(char => {
this.leakService.removeCharacteristic(char);
});
}
attachCustomCharacteristic(char) {
let result;
if (this.leakService.testCharacteristic(char.name)) {
result = this.leakService.getCharacteristic(char.name);
}
else {
const unitsString = this.stringForUnits();
const customCharacteristic = class TodayUsage extends this.Characteristic {
constructor() {
super(char.name, char.uuid, {
format: "uint32" /* Formats.UINT32 */,
perms: ["pr" /* Perms.PAIRED_READ */, "ev" /* Perms.NOTIFY */],
unit: unitsString,
});
this.value = this.getDefaultValue();
}
};
result = this.leakService.addCharacteristic(customCharacteristic);
result.UUID = char.uuid;
}
return result;
}
logState(level, message) {
if (this.disableLogging) {
return;
}
if (this.name) {
this.platform.log.log(level, '[%s] %s', this.name, message);
}
else {
this.platform.log.log(level, message);
}
}
}
//# sourceMappingURL=accessory.js.map