UNPKG

homebridge-virtual-accessories

Version:
215 lines 9.4 kB
import { Accessory } from './accessory.js'; import { Timer } from '../utils/timer.js'; /** * Valve - Accessory implementation */ export class Valve extends Accessory { static ACCESSORY_TYPE_NAME = 'Valve'; static GENERIC_VALVE = 0; // Characteristic.ValveType.GENERIC_VALVE static IRRIGATION = 1; // Characteristic.ValveType.IRRIGATION static SHOWER_HEAD = 2; // Characteristic.ValveType.SHOWER_HEAD static WATER_FAUCET = 3; // Characteristic.ValveType.WATER_FAUCET static INACTIVE = 0; // Characteristic.Active.INACTIVE static ACTIVE = 1; // Characteristic.Active.ACTIVE static NOT_IN_USE = 0; // Characteristic.InUse.NOT_IN_USE static IN_USE = 1; // Characteristic.InUse.IN_USE valveType; durationTimer; stateStorageKey = 'ValveActive'; // private readonly timerStartTimeStorageKey: string = 'TimerStartTime'; // private readonly timerDurationStorageKey: string = 'TimerDuration'; // private readonly timerIsRunningStorageKey: string = 'TimerIsRunning'; states = { ValveActive: Valve.INACTIVE, ValveInUse: Valve.NOT_IN_USE, }; constructor(platform, accessory, accessoryConfiguration) { super(platform, accessory, accessoryConfiguration); switch (this.accessoryConfiguration.valve.type) { case 'generic': this.valveType = Valve.GENERIC_VALVE; break; case 'irrigation': this.valveType = Valve.IRRIGATION; break; case 'showerhead': this.valveType = Valve.SHOWER_HEAD; break; case 'waterfaucet': this.valveType = Valve.WATER_FAUCET; break; // Should never drop down to here, but being defensive default: this.valveType = Valve.GENERIC_VALVE; break; } // First configure the device based on the accessory details this.states.ValveActive = Valve.INACTIVE; this.states.ValveInUse = Valve.NOT_IN_USE; // If the accessory is stateful retrieve stored state if (this.accessoryConfiguration.accessoryIsStateful) { const accessoryState = this.loadAccessoryState(this.storagePath); const cachedState = accessoryState[this.stateStorageKey]; if (cachedState !== undefined) { this.states.ValveActive = cachedState; this.states.ValveInUse = (this.states.ValveActive === Valve.ACTIVE) ? Valve.IN_USE : Valve.NOT_IN_USE; } } // Timer is not resettable const timerIsResettable = false; this.durationTimer = new Timer(this.accessoryConfiguration.accessoryName, this.log, timerIsResettable, this.accessoryConfiguration.valve.duration.toSeconds()); this.service = this.accessory.getService(this.platform.Service.Valve) || this.accessory.addService(this.platform.Service.Valve); this.service.setCharacteristic(this.platform.Characteristic.Name, this.accessoryConfiguration.accessoryName); // Update the initial state of the accessory this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Setting Valve Current State: ${Valve.getActiveName(this.states.ValveActive)}`); this.service.updateCharacteristic(this.platform.Characteristic.Active, (this.states.ValveActive)); this.service.updateCharacteristic(this.platform.Characteristic.InUse, (this.states.ValveInUse)); this.service.updateCharacteristic(this.platform.Characteristic.SetDuration, (this.accessoryConfiguration.valve.duration.toSeconds())); // register handlers this.service.getCharacteristic(this.platform.Characteristic.ValveType) .onGet(this.getValveType.bind(this)); this.service.getCharacteristic(this.platform.Characteristic.Active) .onSet(this.setActive.bind(this)) .onGet(this.getActive.bind(this)); this.service.getCharacteristic(this.platform.Characteristic.InUse) .onGet(this.getInUse.bind(this)); this.service.getCharacteristic(this.platform.Characteristic.SetDuration) .onSet(this.setSetDuration.bind(this)) .onGet(this.getSetDuration.bind(this)); this.service.getCharacteristic(this.platform.Characteristic.RemainingDuration) .onGet(this.getRemainingDuration.bind(this)); } // Handlers async getValveType() { const valveType = this.valveType; this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Valve Type: ${Valve.getValveTypeName(valveType)}`); return valveType; } async setActive(value) { this.states.ValveActive = value; this.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting Active: ${Valve.getActiveName(this.states.ValveActive)}`); this.states.ValveInUse = (this.states.ValveActive === Valve.ACTIVE) ? Valve.IN_USE : Valve.NOT_IN_USE; this.service.setCharacteristic(this.platform.Characteristic.InUse, (this.states.ValveInUse)); this.storeState(); this.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting In Use: ${Valve.getInUseName(this.states.ValveInUse)}`); // Valve was turned off: turn off timer if (this.states.ValveActive === Valve.INACTIVE) { this.durationTimer.stop(); } // Valve was turned on: try to start timer if (this.states.ValveActive === Valve.ACTIVE && this.accessoryConfiguration.valve.duration.toSeconds() > 0) { this.durationTimer.start(() => { this.service.setCharacteristic(this.platform.Characteristic.Active, Valve.INACTIVE); }); } } async getActive() { const valveActive = this.states.ValveActive; this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Active: ${Valve.getActiveName(valveActive)}`); return valveActive; } async getInUse() { const valveInUse = this.states.ValveInUse; this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting In Use: ${Valve.getInUseName(valveInUse)}`); return valveInUse; } async setSetDuration(value) { const duration = value; this.durationTimer.setDefaultDuration(duration); this.log.info(`[${this.accessoryConfiguration.accessoryName}] Setting Set Duration: ${duration} seconds`); } async getSetDuration() { const duration = this.durationTimer.getDefaultDuration(); this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Set Duration: ${duration} seconds`); return duration; } async getRemainingDuration() { const remainingDuration = this.durationTimer.getRemainingDuration(); this.log.debug(`[${this.accessoryConfiguration.accessoryName}] Getting Remaining Duration: ${remainingDuration} seconds`); return remainingDuration; } getJsonState() { const json = JSON.stringify({ [this.stateStorageKey]: this.states.ValveActive, // [this.timerStartTimeStorageKey]: this.durationTimer.getStartTime().toString(), // [this.timerDurationStorageKey]: this.durationTimer.getDuration(), // [this.timerIsRunningStorageKey]: this.durationTimer.isTimerRunning(), }); return json; } getAccessoryTypeName() { return Valve.ACCESSORY_TYPE_NAME; } static getValveTypeName(event) { let eventName; switch (event) { case undefined: { eventName = 'undefined'; break; } case Valve.GENERIC_VALVE: { eventName = 'GENERIC VALVE'; break; } case Valve.IRRIGATION: { eventName = 'IRRIGATION'; break; } case Valve.SHOWER_HEAD: { eventName = 'SHOWER HEAD'; break; } case Valve.WATER_FAUCET: { eventName = 'WATER FAUCET'; break; } default: { eventName = event.toString(); } } return eventName; } static getActiveName(event) { let eventName; switch (event) { case undefined: { eventName = 'undefined'; break; } case Valve.INACTIVE: { eventName = 'INACTIVE'; break; } case Valve.ACTIVE: { eventName = 'ACTIVE'; break; } default: { eventName = event.toString(); } } return eventName; } static getInUseName(event) { let eventName; switch (event) { case undefined: { eventName = 'undefined'; break; } case Valve.NOT_IN_USE: { eventName = 'NOT IN USE'; break; } case Valve.IN_USE: { eventName = 'IN USE'; break; } default: { eventName = event.toString(); } } return eventName; } } //# sourceMappingURL=virtualAccessoryValve.js.map