UNPKG

homebridge-velux-active

Version:

Homebridge plugin for controlling velux blinds and windows

133 lines (116 loc) 5.78 kB
import {PlatformAccessory, Service} from 'homebridge' import {VeluxActivePlatform} from './platform' import {VeluxDevice} from './VeluxDevice' import fetch from 'node-fetch' export class VeluxAccessory { private service: Service | undefined constructor ( private readonly platform: VeluxActivePlatform, private readonly accessory: PlatformAccessory, private readonly device: VeluxDevice ) { this.platform.log.info(`Initializing Velux ${device.velux_type}`) this.accessory.getService(this.platform.Service.AccessoryInformation)! .setCharacteristic(this.platform.Characteristic.Manufacturer, device.manufacturer) .setCharacteristic(this.platform.Characteristic.Model, device.velux_type) .setCharacteristic(this.platform.Characteristic.SerialNumber, device.id) // create a new Window Covering service if (device.velux_type === 'window') { this.service = this.accessory.getService(this.platform.Service.Window) || this.accessory.addService(this.platform.Service.Window, `Window ${device.id}`, 'cl9gre9tm0000rj664gpx42pf') } else if (device.velux_type === 'shutter') { this.service = this.accessory.getService(this.platform.Service.WindowCovering) || this.accessory.addService(this.platform.Service.WindowCovering, `Shutter ${device.id}`, 'cl9grh82v0001rj66tq1fgtta') } else { this.platform.log.error('Not supported device type discovered') return } this.service.setCharacteristic(this.platform.Characteristic.Name, (`Velux ${device.velux_type === 'window' ? 'Window' : 'Shutter'} ${device.id}`)) // create handlers for required characteristics this.service.getCharacteristic(this.platform.Characteristic.CurrentPosition) .onGet(this.handleCurrentPositionGet.bind(this)) this.service.getCharacteristic(this.platform.Characteristic.PositionState) .onGet(this.handlePositionStateGet.bind(this)) this.service.getCharacteristic(this.platform.Characteristic.TargetPosition) .onGet(this.handleTargetPositionGet.bind(this)) .onSet(this.handleTargetPositionSet.bind(this)) } async getUpdatedState (id: string, delayTime = 2000) { await this.platform.retrieveDevicesStatus(delayTime) const state = this.platform.devices.find(f => f.id === id) return state ?? this.device } /** * Handle requests to get the current value of the "Current Position" characteristic */ async handleCurrentPositionGet () { this.platform.log.debug('Triggered GET CurrentPosition') const veluxDevice = await this.getUpdatedState(this.device.id) return veluxDevice.current_position } /** * Handle requests to get the current value of the "Position State" characteristic */ async handlePositionStateGet () { this.platform.log.debug('Triggered GET PositionState') const veluxDevice = await this.getUpdatedState(this.device.id) if (veluxDevice.current_position < veluxDevice.target_position) { return this.platform.Characteristic.PositionState.INCREASING } else if (veluxDevice.current_position > veluxDevice.target_position) { return this.platform.Characteristic.PositionState.DECREASING } return this.platform.Characteristic.PositionState.STOPPED } /** * Handle requests to get the current value of the "Target Position" characteristic */ async handleTargetPositionGet () { this.platform.log.debug('Triggered GET TargetPosition') const veluxDevice = await this.getUpdatedState(this.device.id) return veluxDevice.target_position } /** * Handle requests to set the "Target Position" characteristic */ handleTargetPositionSet (value) { if (value > 100 || value < 0) { this.platform.log.error('Invalid value for target position') return } this.platform.log.debug('Triggered SET TargetPosition:', value) try { this.platform.retrieveNewToken().then(async () => { const response = await fetch(this.platform.baseUrl + 'syncapi/v1/setstate', { method: 'POST', headers: { 'Content-Type': 'application/json; charset=utf-8', Authorization: `Bearer ${this.platform.apiToken}` }, body: JSON.stringify({ home: { id: this.platform.homeId, modules: [ { bridge: this.device.bridge, id: this.device.id, target_position: value, nonce: 0, timestamp: new Date().getTime() } ] } }) }) const result = await response.json() this.platform.log.info(`Target position set to ${value}. Success: ${result.status}`) let veluxDevice: VeluxDevice do { veluxDevice = await this.getUpdatedState(this.device.id, 500) await this.platform.delay(1000) } while (veluxDevice.current_position !== veluxDevice.target_position) }) } catch (e) { this.platform.log.error(`Could not set position for device: ${this.device.id}`, e) } } }