homebridge-flume
Version:
Homebridge plugin to integrate Flume devices into HomeKit.
103 lines • 4.64 kB
JavaScript
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { FlumeAccessory } from './accessory.js';
import strings from '../lang/en.js';
import { FlumeAPI } from '../model/api.js';
import { STORAGE_FILE_NAME } from '../tools/storage.js';
import { VolumeUnits } from '../model/types.js';
export const PLATFORM_ALIAS = 'Flume';
const PLUGIN_NAME = 'homebridge-flume';
export class FlumePlatform {
log;
config;
api;
storagePath;
flumeAPI = null;
accessories = new Map();
constructor(log, config, api) {
this.log = log;
this.config = config;
this.api = api;
this.storagePath = path.join(api.user.storagePath(), STORAGE_FILE_NAME);
const packageVersion = this.packageVersion;
this.log.info('v%s | System %s | Node %s | HB v%s | HAPNodeJS v%s', packageVersion, process.platform, process.version, api.serverVersion, api.hap.HAPLibraryVersion());
this.api.on('didFinishLaunching', () => this.didFinishLaunching());
this.api.on('shutdown', () => this.shutdown());
}
get packageVersion() {
try {
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const packageJSONPath = path.join(__dirname, '../../package.json');
const packageJSON = JSON.parse(fs.readFileSync(packageJSONPath, { encoding: 'utf8' }));
return packageJSON.version;
}
catch (error) {
return '0.0.0';
}
}
async didFinishLaunching() {
if (!this.config.username ||
!this.config.password ||
!this.config.clientId ||
!this.config.clientSecret ||
!this.config.refreshInterval) {
this.log.error(strings.badConfig);
return;
}
this.flumeAPI = await FlumeAPI.connect(this.config.username, this.config.password, this.config.clientId, this.config.clientSecret, this.config.refreshInterval, this.config.units ?? VolumeUnits.GALLONS, this.storagePath, this.log, this.config.verbose);
const keepDevices = new Set();
const excludeDevices = new Set(this.config.excludeDevices ?? []);
const devices = this.flumeAPI.devices.filter((device) => !excludeDevices.has(device.id));
if (devices.length === 0) {
this.accessories.forEach((accessory) => this.removeAccessory(accessory));
this.log.warn(strings.noDevices);
this.shutdown();
return;
}
devices.forEach((device) => {
keepDevices.add(device.id);
this.initializeAccessory(device);
});
// Remove any stale accessories that don't appear in the device list
this.accessories.forEach((accessory) => {
if (!keepDevices.has(accessory.context.deviceId)) {
this.removeAccessory(accessory);
}
});
const randIndex = Math.floor(Math.random() * strings.welcomeMessages.length);
this.log.info(strings.complete, strings.welcomeMessages[randIndex]);
}
shutdown() {
this.flumeAPI?.teardown();
}
initializeAccessory(device) {
const uuid = this.api.hap.uuid.generate(device.id);
const name = this.flumeAPI?.locationNames.get(device.locationId);
let accessory = this.accessories.get(uuid);
if (!accessory) {
this.log.info(strings.newDevice, name ?? device.id);
accessory = new this.api.platformAccessory(strings.brand, uuid);
accessory.context.deviceId = device.id;
accessory.context.deviceName = name;
this.api.registerPlatformAccessories(PLUGIN_NAME, PLATFORM_ALIAS, [accessory]);
this.accessories.set(uuid, accessory);
}
else if (!accessory.context.deviceName) {
accessory.context.deviceName = name;
this.api.updatePlatformAccessories([accessory]);
}
const units = this.config.units ?? VolumeUnits.GALLONS;
new FlumeAccessory(this, accessory, device, name, units, this.config.disableDeviceLogging);
}
configureAccessory(accessory) {
this.log.info(strings.restoringDevice, accessory.context.deviceName ?? accessory.context.deviceId);
this.accessories.set(accessory.UUID, accessory);
}
removeAccessory(accessory) {
this.log.info(strings.removeDevice, accessory.context.deviceName ?? accessory.context.deviceId);
this.api.unregisterPlatformAccessories(PLUGIN_NAME, PLATFORM_ALIAS, [accessory]);
this.accessories.delete(accessory.UUID);
}
}
//# sourceMappingURL=platform.js.map