UNPKG

@zswuwing/homebridge-wyze-smart-home

Version:
128 lines (101 loc) 5.36 kB
const {Service,Characteristic,} = require('../types') const WyzeAccessory = require('./WyzeAccessory') const HOMEBRIDGE_LOCK_MECHANISM_SERVICE = Service.LockMechanism const HOMEBRIDGE_LOCK_MECHANISM_CURRENT_STATE_CHARACTERISTIC = Characteristic.LockCurrentState const HOMEBRIDGE_LOCK_MECHANISM_TARGET_STATE_CHARACTERISTIC = Characteristic.LockTargetState const HOMEBRIDGE_BATTERY_SERVICE = Service.Battery const HOMEBRIDGE_BATTERY_CHARACTERISTIC = Characteristic.BatteryLevel const HOMEBRIDGE_CONTACT_SENSOR_SERVICE = Service.ContactSensor const HOMEBRIDGE_CONTACT_SENSOR_CHARACTERISTIC = Characteristic.ContactSensorState.CurrentDoorState const noResponse = new Error('No Response') noResponse.toString = () => { return noResponse.message } module.exports = class WyzeLock extends WyzeAccessory { constructor (plugin, homeKitAccessory) { super(plugin, homeKitAccessory) this.lockService = this.homeKitAccessory.getService(HOMEBRIDGE_LOCK_MECHANISM_SERVICE) this.contactService = this.homeKitAccessory.getService(HOMEBRIDGE_CONTACT_SENSOR_SERVICE) this.batteryService = this.homeKitAccessory.getService(HOMEBRIDGE_BATTERY_SERVICE) if (!this.lockService) { this.lockService = this.homeKitAccessory.addService(HOMEBRIDGE_LOCK_MECHANISM_SERVICE) } if (!this.contactService) { this.contactService = this.homeKitAccessory.addService(HOMEBRIDGE_CONTACT_SENSOR_SERVICE) } if (!this.batteryService) { this.batteryService = this.homeKitAccessory.addService(HOMEBRIDGE_BATTERY_SERVICE) } this.batteryService.getCharacteristic(HOMEBRIDGE_BATTERY_CHARACTERISTIC) .onGet(this.getBatteryStatus.bind(this)) this.contactService.getCharacteristic(HOMEBRIDGE_CONTACT_SENSOR_CHARACTERISTIC) .onGet(this.getDoorStatus.bind(this)) this.lockService.getCharacteristic(HOMEBRIDGE_LOCK_MECHANISM_CURRENT_STATE_CHARACTERISTIC) .onGet(this.getLockCurrentState.bind(this)) this.lockService.getCharacteristic(HOMEBRIDGE_LOCK_MECHANISM_TARGET_STATE_CHARACTERISTIC) .onGet(this.getLockTargetState.bind(this)) .onSet(this.setLockTargetState.bind(this)) this.lockGetProperty() } async updateCharacteristics () { this.lockGetProperty() if (this.lockOnoffLine === 0) { this.getLockCurrentState().updateValue(noResponse) } else { this.getLockCurrentState() this.getDoorStatus() this.getBatteryStatus() } } async getLockCurrentState () { if(this.plugin.config.logging == "debug") this.plugin.log(`[Lock] getLockCurrentState "${this.display_name}"`) if (this.lockLockerStatusHardlock === 2) { return HOMEBRIDGE_LOCK_MECHANISM_CURRENT_STATE_CHARACTERISTIC.UNSECURED } else { return HOMEBRIDGE_LOCK_MECHANISM_CURRENT_STATE_CHARACTERISTIC.SECURED } } async getLockTargetState () { if(this.plugin.config.logging == "debug") this.plugin.log(`[Lock] getLockTargetState "${this.display_name}"`) if (this.lockLockerStatusHardlock === 2) { return HOMEBRIDGE_LOCK_MECHANISM_TARGET_STATE_CHARACTERISTIC.UNSECURED } else { return HOMEBRIDGE_LOCK_MECHANISM_TARGET_STATE_CHARACTERISTIC.SECURED } } async getDoorStatus () { if(this.plugin.config.logging == "debug") this.plugin.log(`[Lock] LockDoorStatus "${this.display_name}"`) if (this.lockDoorOpenStatus === 2) { return HOMEBRIDGE_CONTACT_SENSOR_CHARACTERISTIC.CLOSED } else { return HOMEBRIDGE_CONTACT_SENSOR_CHARACTERISTIC.OPEN } } async getBatteryStatus () { if(this.plugin.config.logging == "debug") this.plugin.log(`[Lock] LockBattery "${this.display_name}"`) return this.checkBatteryVoltage(this.lockPower) } async setLockTargetState (targetState) { if(this.plugin.config.logging == "debug") this.plugin.log(`[Lock] setLockTargetSate "${targetState}"`) // this is zero or 1 await this.plugin.client.controlLock(this.mac, this.product_model, (targetState === HOMEBRIDGE_LOCK_MECHANISM_CURRENT_STATE_CHARACTERISTIC.SECURED ? 'remoteLock' : 'remoteUnlock')) // Takes a few seconds for the lock command to actually update lock state property // Poll every second to see if the lock state has changed to what we expect, or time out after 30 attempts // await this.poll(async () => await this.getLockCurrentState(), this.locker_status ? 1 : 0 , this.locker_status ? 1 : 0 === targetState, 1000, 10) this.lockService.setCharacteristic(Characteristic.LockCurrentState, targetState === HOMEBRIDGE_LOCK_MECHANISM_TARGET_STATE_CHARACTERISTIC.SECURED ? HOMEBRIDGE_LOCK_MECHANISM_CURRENT_STATE_CHARACTERISTIC.SECURED : HOMEBRIDGE_LOCK_MECHANISM_CURRENT_STATE_CHARACTERISTIC.UNSECURED) } async poll (fn, validate, interval, maxAttempts) { let attempts = 0 const executePoll = async (resolve, reject) => { const result = await fn() attempts++ if (validate(result)) { return resolve(result) } else if (maxAttempts && maxAttempts === attempts) { return reject(new Error('Exceeded maximum attempts')) } else { setTimeout(executePoll, interval, resolve, reject) } } return new Promise(executePoll) } checkBatteryVoltage (deviceVoltage) { if (deviceVoltage >= 100) { return 100 } else if ( deviceVoltage == "undefined") { return 100 } else { return deviceVoltage }} }