UNPKG

homebridge-dreo-db94

Version:
185 lines 9.07 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DreoPlatform = void 0; const settings_1 = require("./settings"); const FanAccessory_1 = require("./accessories/FanAccessory"); const HeaterAccessory_1 = require("./accessories/HeaterAccessory"); const DreoAPI_1 = __importDefault(require("./DreoAPI")); /** * HomebridgePlatform * This class is the main constructor for your plugin, this is where you should * parse the user config and discover/register accessories with Homebridge. */ class DreoPlatform { constructor(log, config, api) { this.log = log; this.config = config; this.api = api; this.Service = this.api.hap.Service; this.Characteristic = this.api.hap.Characteristic; this.webHelper = new DreoAPI_1.default(this); // This is used to track restored cached accessories this.accessories = []; this.log.debug('Finished initializing platform:', this.config.name); // When this event is fired it means Homebridge has restored all cached accessories from disk. // Dynamic Platform plugins should only register new accessories after this event was fired, // in order to ensure they weren't added to homebridge already. This event can also be used // to start discovery of new accessories. this.api.on('didFinishLaunching', async () => { log.debug('Executed didFinishLaunching callback'); // Run the method to discover / register your devices as accessories this.discoverDevices(); }); } /** * This function is invoked when homebridge restores cached accessories from disk at startup. * It should be used to setup event handlers for characteristics and update respective values. */ configureAccessory(accessory) { this.log.info('Loading accessory from cache:', accessory.displayName); // Add the restored accessory to the accessories cache so we can track if it has already been registered this.accessories.push(accessory); } /** * Log into Dreo services, retrieve the user's devices, and register them as accessories * Also remove accessories that are no longer present on the user's account */ async discoverDevices() { // Validate config values if (!this.config.options || !this.config.options.email || !this.config.options.password) { this.log.error('error: Invalid email and/or password'); return; } // Request access token from Dreo server let auth = await this.webHelper.authenticate(); // Check if access_token is valid if (auth === undefined) { this.log.error('Authentication error: Failed to obtain access_token'); return; } this.log.info('Country:', auth.countryCode); this.log.info('Region:', auth.region); // Re-authenticate with EU server if european account is detected if (auth.region === 'EU') { this.webHelper.server = 'eu'; auth = await this.webHelper.authenticate(); } else if (auth.region !== 'NA') { this.log.error('error, unknown region'); this.log.error('Please open a github issue and provide your Country and Region (shown above)'); return; } // Use access token to retrieve user's devices const dreoDevices = await this.webHelper.getDevices(); // Make sure devices were retrieved successfully if (dreoDevices === undefined) { return; } // Mask sensitive information and print the device list const maskedDevices = dreoDevices.map(device => ({ ...device, sn: '********', deviceId: '********', })); this.log.debug('\n\nDevices:\n', maskedDevices); // Create a set of UUIDs for the currently discovered devices const discoveredDeviceUUIDs = new Set(dreoDevices.map(device => this.api.hap.uuid.generate(device.sn))); // Unregister accessories that are no longer present const accessoriesToRemove = this.accessories.filter(accessory => !discoveredDeviceUUIDs.has(accessory.UUID)); if (accessoriesToRemove.length > 0) { this.api.unregisterPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, accessoriesToRemove); this.log.info('Removing accessories:', accessoriesToRemove.map(accessory => accessory.displayName).join(', ')); } // Open WebSocket (used to control devices later) await this.webHelper.startWebSocket(); // Loop over the discovered devices and register each one if it has not already been registered for (const device of dreoDevices) { // Print device info: this.log.debug('Control config: ', JSON.stringify(device.controlsConf, null, 2)); // Generate a unique id for the accessory this should be generated from // something globally unique, but constant, for example, the device serial // number or MAC address const uuid = this.api.hap.uuid.generate(device.sn); // See if an accessory with the same uuid has already been registered and restored from // the cached devices we stored in the `configureAccessory` method above const existingAccessory = this.accessories.find(accessory => accessory.UUID === uuid); let accessory; if (existingAccessory) { // The accessory already exists this.log.info('Restoring existing accessory from cache:', device.deviceName); accessory = existingAccessory; } else { // The accessory does not yet exist, so we need to create it this.log.info('Adding new accessory:', device.deviceName); // Create a new accessory accessory = new this.api.platformAccessory(device.deviceName, uuid); // Store a copy of the device object in the `accessory.context` accessory.context.device = device; } // Get initial device state const state = await this.webHelper.getState(device.sn); if (state === undefined) { this.log.error('error: Failed to retrieve device state'); return; } this.log.debug('Accessory state:', state); // Create the accessory handler for new/restored accessory // This is imported from `platformAccessory.ts` // List of supported model prefixes const SUPPORTED_MODEL_PREFIXES = [ 'DR-HTF', 'DR-HAF', 'DR-HPF', 'DR-HCF', 'DR-HAP', 'DR-HSH', 'WH', 'DR-HAC', 'DR-HHM', // Humidifier ]; // Find the matching prefix let modelPrefix = SUPPORTED_MODEL_PREFIXES.find(prefix => device.model.startsWith(prefix)); // Determine device type based on the matched prefix switch (modelPrefix) { case 'DR-HTF': case 'DR-HAF': case 'DR-HPF': case 'DR-HCF': case 'DR-HAP': // Tower Fan, Air Circulator, Ceiling Fan, Air Purifier accessory.category = 3 /* FAN */; new FanAccessory_1.FanAccessory(this, accessory, state); break; case 'DR-HSH': case 'WH': // Heater accessory.category = 20 /* AIR_HEATER */; new HeaterAccessory_1.HeaterAccessory(this, accessory, state); break; case 'DR-HAC': // Air Conditioner // new CoolerAccessory(this, accessory, state); this.log.info('Air Conditioner not yet supported'); modelPrefix = undefined; break; case 'DR-HHM': // Humidifier this.log.info('Humidifier not yet supported'); modelPrefix = undefined; // Unassign this so accessory isn't registered below break; default: this.log.error('Error, unknown device type:', device.productName, device.model); } if (!existingAccessory && modelPrefix) { // Link accessory to the platform if model is supported this.api.registerPlatformAccessories(settings_1.PLUGIN_NAME, settings_1.PLATFORM_NAME, [accessory]); } } } } exports.DreoPlatform = DreoPlatform; //# sourceMappingURL=platform.js.map