UNPKG

homebridge-flume

Version:

Homebridge plugin to integrate Flume devices into HomeKit.

148 lines 7.13 kB
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