UNPKG

homebridge-pura

Version:

Homebridge plugin for Pura smart fragrance diffusers

157 lines 6.99 kB
/** * Pura Platform Accessory * An instance of this class is created for each bay of each Pura device * Each accessory exposes a Fan service to represent the fragrance diffuser */ export class PuraPlatformAccessory { platform; accessory; puraApi; service; device; bayNumber; /** * Track the current state of the diffuser */ currentState = { On: false, RotationSpeed: 0, }; constructor(platform, accessory, puraApi) { this.platform = platform; this.accessory = accessory; this.puraApi = puraApi; this.device = accessory.context.device; this.bayNumber = accessory.context.bayNumber; // Set accessory information this.accessory.getService(this.platform.Service.AccessoryInformation) .setCharacteristic(this.platform.Characteristic.Manufacturer, 'Pura') .setCharacteristic(this.platform.Characteristic.Model, this.device.type || 'Pura Diffuser') .setCharacteristic(this.platform.Characteristic.SerialNumber, this.device.id) .setCharacteristic(this.platform.Characteristic.FirmwareRevision, this.device.state?.firmwareVersion || '1.0.0'); // Get the Fan service if it exists, otherwise create a new Fan service this.service = this.accessory.getService(this.platform.Service.Fan) || this.accessory.addService(this.platform.Service.Fan); // Set the service name this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.displayName); // Register handlers for the On/Off Characteristic this.service.getCharacteristic(this.platform.Characteristic.On) .onSet(this.setOn.bind(this)) .onGet(this.getOn.bind(this)); // Register handlers for the RotationSpeed Characteristic (represents intensity) this.service.getCharacteristic(this.platform.Characteristic.RotationSpeed) .onSet(this.setRotationSpeed.bind(this)) .onGet(this.getRotationSpeed.bind(this)); // Initialize current state from device this.updateCurrentState(); } /** * Update current state from device data */ updateCurrentState() { const bay = this.getBay(); if (bay) { this.currentState.On = bay.active; this.currentState.RotationSpeed = bay.intensity; // Update HomeKit with current state this.service.updateCharacteristic(this.platform.Characteristic.On, this.currentState.On); this.service.updateCharacteristic(this.platform.Characteristic.RotationSpeed, this.currentState.RotationSpeed); } } /** * Get the bay data for this accessory */ getBay() { return this.bayNumber === 1 ? this.device.bay1 : this.device.bay2; } /** * Handle "SET" requests from HomeKit for On/Off */ async setOn(value) { const isOn = value; this.platform.log.debug(`Set Characteristic On for ${this.accessory.displayName} ->`, value); try { if (isOn) { // Turn on with current intensity or default to 50% const intensity = this.currentState.RotationSpeed || 50; const success = await this.puraApi.setIntensity(this.device.id, this.bayNumber, intensity); if (success) { this.currentState.On = true; this.currentState.RotationSpeed = intensity; this.platform.log.debug(`Successfully turned on ${this.accessory.displayName} with intensity ${intensity}`); } else { this.platform.log.error(`Failed to turn on ${this.accessory.displayName}`); throw new Error('Failed to turn on device'); } } else { // Turn off by setting intensity to 0 const success = await this.puraApi.setIntensity(this.device.id, this.bayNumber, 0); if (success) { this.currentState.On = false; this.currentState.RotationSpeed = 0; this.platform.log.debug(`Successfully turned off ${this.accessory.displayName}`); } else { this.platform.log.error(`Failed to turn off ${this.accessory.displayName}`); throw new Error('Failed to turn off device'); } } } catch (error) { this.platform.log.error(`Error setting On state for ${this.accessory.displayName}:`, error); throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */); } } /** * Handle the "GET" requests from HomeKit for On/Off */ async getOn() { const isOn = this.currentState.On; this.platform.log.debug(`Get Characteristic On for ${this.accessory.displayName} ->`, isOn); return isOn; } /** * Handle "SET" requests from HomeKit for RotationSpeed (intensity) */ async setRotationSpeed(value) { const intensity = value; this.platform.log.debug(`Set Characteristic RotationSpeed for ${this.accessory.displayName} ->`, intensity); try { const success = await this.puraApi.setIntensity(this.device.id, this.bayNumber, intensity); if (success) { this.currentState.RotationSpeed = intensity; this.currentState.On = intensity > 0; // Update the On characteristic to reflect the new state this.service.updateCharacteristic(this.platform.Characteristic.On, this.currentState.On); this.platform.log.debug(`Successfully set intensity for ${this.accessory.displayName} to ${intensity}`); } else { this.platform.log.error(`Failed to set intensity for ${this.accessory.displayName}`); throw new Error('Failed to set intensity'); } } catch (error) { this.platform.log.error(`Error setting RotationSpeed for ${this.accessory.displayName}:`, error); throw new this.platform.api.hap.HapStatusError(-70402 /* this.platform.api.hap.HAPStatus.SERVICE_COMMUNICATION_FAILURE */); } } /** * Handle the "GET" requests from HomeKit for RotationSpeed (intensity) */ async getRotationSpeed() { const intensity = this.currentState.RotationSpeed; this.platform.log.debug(`Get Characteristic RotationSpeed for ${this.accessory.displayName} ->`, intensity); return intensity; } /** * Update device data and refresh state */ updateDevice(device) { this.device = device; this.accessory.context.device = device; this.updateCurrentState(); } } //# sourceMappingURL=platformAccessory.js.map