UNPKG

homebridge-broadlink-rm-pro

Version:

Broadlink RM plugin (including the mini and pro) for homebridge with AC Pro and TV features

469 lines (343 loc) 17.7 kB
const { expect } = require('chai'); const { log, setup } = require('./helpers/setup') const ping = require('./helpers/fakePing') const FakeServiceManager = require('./helpers/fakeServiceManager') const { getDevice } = require('../helpers/getDevice') const delayForDuration = require('../helpers/delayForDuration') const { GarageDoorOpener } = require('../accessories') const data = { open: 'OPEN_HEX', close: 'CLOSE_HEX', lock: 'LOCK_HEX', unlock: 'UNLOCK_HEX' } const defaultConfig = { data, isUnitTest: true, persistState: false }; describe('doorAccessory', () => { // Closing -> Closed it('"closeDuration": 0.2, closing -> closed', async () => { const { device } = setup(); const config = { ...defaultConfig, host: device.host.address, closeDuration: 0.2 } const doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') doorAccessory.serviceManager.setCharacteristic(Characteristic.TargetDoorState, Characteristic.TargetDoorState.CLOSED) // Closing expect(doorAccessory.state.doorCurrentState).to.equal(undefined); expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); await delayForDuration(0.3) // Closed expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.CLOSED); expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); }); // Closing -> Closed -> Opening -> Opened it('"openDuration": 0.2, closing -> closed -> opening -> opened', async () => { const { device } = setup(); const config = { ...defaultConfig, host: device.host.address, closeDuration: 0.2, openDuration: 0.2 } const doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') doorAccessory.serviceManager.setCharacteristic(Characteristic.TargetDoorState, Characteristic.TargetDoorState.CLOSED) let sentHexCodeCount // Check hex code was sent const hasSentCloseCode = device.hasSentCode('CLOSE_HEX') expect(hasSentCloseCode).to.equal(true); // Check that only one code has been sent sentHexCodeCount = device.getSentHexCodeCount() expect(sentHexCodeCount).to.equal(1); // Closing expect(doorAccessory.state.doorCurrentState).to.equal(undefined); expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); // Delay to allow for `closeDuration` await delayForDuration(0.3) // Closed expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.CLOSED); expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); // Arbitrary Delay await delayForDuration(0.3) // Opening doorAccessory.serviceManager.setCharacteristic(Characteristic.TargetDoorState, Characteristic.TargetDoorState.OPEN) // Check hex sent const hasSentOpenCode = device.hasSentCode('OPEN_HEX') expect(hasSentOpenCode).to.equal(true); // Check that only one code has been sent sentHexCodeCount = device.getSentHexCodeCount() expect(sentHexCodeCount).to.equal(2); expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.CLOSED); expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.OPEN); // Delay to allow for `openDuration` await delayForDuration(0.3) // Opened expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.OPEN); expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.OPEN); }); // Closing -> Closed -> Opening -> Opened -> Auto-closing -> Closed it('"autoCloseDelay" : true, closing -> closed -> opening -> opened -> auto-closing -> closed', async () => { const { device } = setup(); const config = { ...defaultConfig, host: device.host.address, closeDuration: 0.2, openDuration: 0.2, autoCloseDelay: 0.2 } const doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') doorAccessory.serviceManager.setCharacteristic(Characteristic.TargetDoorState, Characteristic.TargetDoorState.CLOSED) // Closing expect(doorAccessory.state.doorCurrentState).to.equal(undefined); expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); // Delay to allow for `closeDuration` await delayForDuration(0.3) // Closed expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.CLOSED); expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); // Arbitrary Delay await delayForDuration(0.3) // Opening doorAccessory.serviceManager.setCharacteristic(Characteristic.TargetDoorState, Characteristic.TargetDoorState.OPEN) expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.CLOSED); expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.OPEN); // Delay to allow for `openDuration` await delayForDuration(0.3) // Opened expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.OPEN); expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.OPEN); // Delay to allow for `autoCloseDelay` await delayForDuration(0.3) expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); // Delay to allow for `closeDuration` await delayForDuration(0.3) // Closed expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.CLOSED); expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); }); // Persist State it('"persistState": true', async () => { const { device } = setup(); const config = { ...defaultConfig, name: 'Unit Test Door', host: device.host.address, persistState: true, closeDuration: 0.2, openDuration: 0.2 } let doorAccessory // Close doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') doorAccessory.serviceManager.setCharacteristic(Characteristic.TargetDoorState, Characteristic.TargetDoorState.CLOSED) expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); // Delay to allow for `closeDuration` await delayForDuration(0.3) expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.CLOSED); // Should still be closed when loading within a new instance doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.CLOSED); // Open doorAccessory.serviceManager.setCharacteristic(Characteristic.TargetDoorState, Characteristic.TargetDoorState.OPEN) expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.OPEN); // Delay to allow for `openDuration` await delayForDuration(0.3) expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.OPEN); // Should still be opened when loading within a new instance doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.OPEN); expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.OPEN); }); it('"persistState": false', async () => { const { device } = setup(); const config = { ...defaultConfig, name: 'Unit Test Door', host: device.host.address, closeDuration: 0.2, openDuration: 0.2 } let doorAccessory // Close doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') doorAccessory.serviceManager.setCharacteristic(Characteristic.TargetDoorState, Characteristic.TargetDoorState.CLOSED) expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); // Delay to allow for `closeDuration` await delayForDuration(0.3) // Should be opened again with a new instance doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') expect(doorAccessory.state.doorTargetState).to.equal(undefined); }); // Ensure the hex is resent after reload it('"resendHexAfterReload": true, "persistState": true', async () => { const { device } = setup(); const config = { ...defaultConfig, persistState: true, host: device.host.address, resendHexAfterReload: true, resendDataAfterReloadDelay: 0.1, closeDuration: 0.2, openDuration: 0.2 } let doorAccessory // Close doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') doorAccessory.serviceManager.setCharacteristic(Characteristic.TargetDoorState, Characteristic.TargetDoorState.CLOSED) expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); // Wait for resendDataAfterReloadDelay await delayForDuration(0.3) // Delay to allow for `closeDuration` await delayForDuration(0.3) expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.CLOSED); device.resetSentHexCodes(); // Should be closed with a new instance doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.CLOSED); // We should find that setCharacteristic has been called after a duration of resendHexAfterReloadDelay await delayForDuration(0.3); expect(doorAccessory.serviceManager.hasRecordedSetCharacteristic).to.equal(true); // Check ON hex code was sent const hasSentOnCode = device.hasSentCode('CLOSE_HEX'); expect(hasSentOnCode).to.equal(true); // Check that the code was sent const sentHexCodeCount = device.getSentHexCodeCount(); expect(sentHexCodeCount).to.equal(1); }); // Ensure the hex is not resent after reload it('"resendHexAfterReload": false, "persistState": true', async () => { const { device } = setup(); const config = { ...defaultConfig, persistState: true, host: device.host.address, resendHexAfterReload: false, resendDataAfterReloadDelay: 0.1, closeDuration: 0.2, openDuration: 0.2 } let doorAccessory // Close doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') doorAccessory.serviceManager.setCharacteristic(Characteristic.TargetDoorState, Characteristic.TargetDoorState.CLOSED) expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); // Wait for resendDataAfterReloadDelay await delayForDuration(0.3) // Delay to allow for `closeDuration` await delayForDuration(0.3) expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.CLOSED); device.resetSentHexCodes(); // Should be closed with a new instance doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.CLOSED); // We should find that setCharacteristic has not been called after a duration of resendHexAfterReloadDelay await delayForDuration(0.3) expect(doorAccessory.serviceManager.hasRecordedSetCharacteristic).to.equal(false); // Check ON hex code was not sent const hasSentOnCode = device.hasSentCode('CLOSE_HEX'); expect(hasSentOnCode).to.equal(false); // Check that no code was sent const sentHexCodeCount = device.getSentHexCodeCount(); expect(sentHexCodeCount).to.equal(0); }); // Ensure correctReloadedState is working correctly it('correctReloadedState for interupted open - "persistState": true', async () => { const { device } = setup(); const config = { data, host: device.host.address, persistState: true, resendHexAfterReload: false, isUnitTest: true } let doorAccessory // Close doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') doorAccessory.serviceManager.setCharacteristic(Characteristic.TargetDoorState, Characteristic.TargetDoorState.CLOSED) doorAccessory.serviceManager.setCharacteristic(Characteristic.CurrentDoorState, Characteristic.CurrentDoorState.OPEN) doorAccessory.serviceManager.setCharacteristic(Characteristic.LockTargetState, Characteristic.LockTargetState.SECURED) doorAccessory.serviceManager.setCharacteristic(Characteristic.LockCurrentState, Characteristic.LockCurrentState.UNSECURED) expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); expect(doorAccessory.state.lockTargetState).to.equal(Characteristic.LockTargetState.SECURED); // Cancel all timers doorAccessory.reset(); expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.CLOSED); expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.OPEN); expect(doorAccessory.state.lockTargetState).to.equal(Characteristic.LockTargetState.SECURED); expect(doorAccessory.state.lockCurrentState).to.equal(Characteristic.LockCurrentState.UNSECURED); // Should be closed with a new instance doorAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') expect(doorAccessory.state.doorTargetState).to.equal(Characteristic.TargetDoorState.OPEN); expect(doorAccessory.state.doorCurrentState).to.equal(Characteristic.CurrentDoorState.OPEN); expect(doorAccessory.state.lockTargetState).to.equal(Characteristic.LockTargetState.UNSECURED); expect(doorAccessory.state.lockCurrentState).to.equal(Characteristic.LockCurrentState.UNSECURED); // Cancel all timers doorAccessory.reset(); }); // Lock it('lock', async () => { const { device } = setup(); const config = { data, host: device.host.address, persistState: false } const lockAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') lockAccessory.serviceManager.setCharacteristic(Characteristic.LockTargetState, Characteristic.LockTargetState.SECURED) await delayForDuration(.1); // Locked expect(lockAccessory.state.lockCurrentState).to.equal(Characteristic.LockCurrentState.SECURED); expect(lockAccessory.state.lockTargetState).to.equal(Characteristic.LockTargetState.SECURED); // Check hex code was sent const hasSentLockCode = device.hasSentCode('LOCK_HEX') expect(hasSentLockCode).to.equal(true); // Check that only one code has been sent const sentHexCodeCount = device.getSentHexCodeCount() expect(sentHexCodeCount).to.equal(1); }); // Unlock it('unlock', async () => { const { device } = setup(); const config = { data, host: device.host.address, persistState: false } const lockAccessory = new GarageDoorOpener(null, config, 'FakeServiceManager') // Lock lockAccessory.serviceManager.setCharacteristic(Characteristic.LockTargetState, Characteristic.LockTargetState.SECURED) await delayForDuration(.1); let sentHexCodeCount // Check hex code was sent const hasSentLockCode = device.hasSentCode('LOCK_HEX') expect(hasSentLockCode).to.equal(true); // Check that only one code has been sent sentHexCodeCount = device.getSentHexCodeCount() expect(sentHexCodeCount).to.equal(1); // Locked expect(lockAccessory.state.lockCurrentState).to.equal(Characteristic.LockCurrentState.SECURED); expect(lockAccessory.state.lockTargetState).to.equal(Characteristic.LockTargetState.SECURED); // Arbitrary Delay await delayForDuration(0.3) // Unlock lockAccessory.serviceManager.setCharacteristic(Characteristic.LockTargetState, Characteristic.LockTargetState.UNSECURED) await delayForDuration(.1); // Check hex sent const hasSentUnlockCode = device.hasSentCode('UNLOCK_HEX') expect(hasSentUnlockCode).to.equal(true); // Check that only one code has been sent sentHexCodeCount = device.getSentHexCodeCount() expect(sentHexCodeCount).to.equal(2); // Unlocked expect(lockAccessory.state.lockCurrentState).to.equal(Characteristic.LockCurrentState.UNSECURED); expect(lockAccessory.state.lockTargetState).to.equal(Characteristic.LockTargetState.UNSECURED); }) })