UNPKG

homebridge-resideo

Version:

The Resideo plugin allows you to access your Resideo device(s) from HomeKit.

151 lines 7.07 kB
import { interval, Subject } from 'rxjs'; import { debounceTime, skipWhile, take, tap } from 'rxjs/operators'; import { DeviceURL } from '../settings.js'; import { deviceBase } from './device.js'; export class Valve extends deviceBase { platform; Valve; valveType; valveUpdateInProgress; doValveUpdate; constructor(platform, accessory, location, device) { super(platform, accessory, location, device); this.platform = platform; this.getValveConfigSettings(accessory, device); this.doValveUpdate = new Subject(); this.valveUpdateInProgress = false; accessory.context.Valve = accessory.context.Valve ?? {}; this.Valve = { Name: accessory.context.Valve.Name ?? accessory.displayName, Service: accessory.getService(this.hap.Service.Valve) ?? accessory.addService(this.hap.Service.Valve), Active: accessory.context.Active ?? this.hap.Characteristic.Active.INACTIVE, InUse: accessory.context.InUse ?? this.hap.Characteristic.InUse.NOT_IN_USE, ValveType: accessory.context.ValveType ?? this.hap.Characteristic.ValveType.GENERIC_VALVE, }; accessory.context.Valve = this.Valve; this.Valve.Service .setCharacteristic(this.hap.Characteristic.Name, this.Valve.Name) .setCharacteristic(this.hap.Characteristic.ValveType, this.valveType) .getCharacteristic(this.hap.Characteristic.Active) .onGet(() => this.Valve.Active) .onSet(this.setActive.bind(this)); this.Valve.Service .getCharacteristic(this.hap.Characteristic.InUse) .onGet(() => this.Valve.InUse); this.refreshStatus(); interval(this.deviceRefreshRate * 1000) .pipe(skipWhile(() => this.valveUpdateInProgress)) .subscribe(async () => { await this.refreshStatus(); }); this.doValveUpdate .pipe(tap(() => { this.valveUpdateInProgress = true; }), debounceTime(this.devicePushRate * 1000)) .subscribe(async () => { try { await this.pushChanges(); } catch (e) { const action = 'pushChanges'; await this.resideoAPIError(e, action); this.errorLog(`${device.deviceClass} ${accessory.displayName}: doValveUpdate pushChanges: ${JSON.stringify(e)}`); } interval(this.deviceRefreshRate * 500) .pipe(skipWhile(() => this.valveUpdateInProgress), take(1)) .subscribe(async () => { await this.refreshStatus(); }); this.valveUpdateInProgress = false; }); } async parseStatus(device) { this.Valve.Active = device.isAlive ? this.hap.Characteristic.Active.ACTIVE : this.hap.Characteristic.Active.INACTIVE; this.accessory.context.Active = this.Valve.Active; this.Valve.InUse = device.actuatorValve.valveStatus === 'Open' ? this.hap.Characteristic.InUse.IN_USE : this.hap.Characteristic.InUse.NOT_IN_USE; if (this.Valve.InUse !== this.accessory.context.InUse) { this.successLog(`${this.device.deviceClass} ${this.accessory.displayName} (refreshStatus) device: ${JSON.stringify(device)}`); this.accessory.context.InUse = this.Valve.InUse; } } async refreshStatus() { try { const device = (await this.platform.axios.get(`${DeviceURL}/waterLeakDetectors/${this.device.deviceID}`, { params: { locationId: this.location.locationID, }, })).data; this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} (refreshStatus) device: ${JSON.stringify(device)}`); this.parseStatus(device); this.updateHomeKitCharacteristics(); } catch (e) { const action = 'refreshStatus'; if (this.device.retry) { if (action === 'refreshStatus') { interval(5000) .pipe(skipWhile(() => this.valveUpdateInProgress), take(1)) .subscribe(async () => { await this.refreshStatus(); }); } } await this.resideoAPIError(e, action); this.apiError(e); } } async pushChanges() { try { const payload = { state: this.Valve.Active === this.hap.Characteristic.Active.ACTIVE ? 'open' : 'closed', }; await this.platform.axios.post(`${DeviceURL}/waterLeakDetectors/${this.device.deviceID}`, payload, { params: { locationId: this.location.locationID, }, }); this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} pushChanges: ${JSON.stringify(payload)}`); const action = 'pushChanges'; await this.statusCode(200, action); } catch (e) { const action = 'pushChanges'; await this.resideoAPIError(e, action); this.errorLog(`pushChanges: ${JSON.stringify(e)}`); this.errorLog(`${this.device.deviceClass} ${this.accessory.displayName} failed pushChanges, Error Message: ${JSON.stringify(e.message)}`); } } async updateHomeKitCharacteristics() { this.Valve.Service.updateCharacteristic(this.hap.Characteristic.Active, this.Valve.Active); this.accessory.context.Active = this.Valve.Active; this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic Active: ${this.Valve.Active}`); this.Valve.Service.updateCharacteristic(this.hap.Characteristic.InUse, this.Valve.InUse); this.accessory.context.InUse = this.Valve.InUse; this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} updateCharacteristic InUse: ${this.Valve.InUse}`); } setActive(value) { this.debugLog(`${this.device.deviceClass} ${this.accessory.displayName} Set Active: ${value}`); this.Valve.Active = value; this.doValveUpdate.next(); } async getValveConfigSettings(accessory, device) { switch (device.valve?.valveType) { case 1: this.valveType = this.hap.Characteristic.ValveType.IRRIGATION; break; case 2: this.valveType = this.hap.Characteristic.ValveType.SHOWER_HEAD; break; case 3: this.valveType = this.hap.Characteristic.ValveType.WATER_FAUCET; break; default: this.valveType = this.hap.Characteristic.ValveType.GENERIC_VALVE; } accessory.context.valveType = this.valveType; } async apiError(e) { this.Valve.Service.updateCharacteristic(this.hap.Characteristic.Active, e); } } //# sourceMappingURL=valve.js.map