UNPKG

homebridge-keyble

Version:
195 lines (194 loc) 9.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.KeybleAccessory = void 0; const keyble_1 = require("keyble"); var Position; (function (Position) { Position[Position["Lock"] = 0] = "Lock"; Position[Position["Unlock"] = 2] = "Unlock"; Position[Position["Open"] = 3] = "Open"; Position[Position["Unlock_MinStep"] = 1] = "Unlock_MinStep"; })(Position || (Position = {})); /** * Platform Accessory * An instance of this class is created for each accessory your platform registers * Each accessory may expose multiple services of different service types. */ class KeybleAccessory { constructor(platform, accessory) { this.platform = platform; this.accessory = accessory; /** * These are just used to create a working example * You should implement your own code to track the state of your accessory */ this.state = { currentPosition: Position.Lock, movement: this.platform.Characteristic.PositionState.STOPPED, targetPosition: Position.Lock }; this.lock = new keyble_1.Key_Ble({ address: accessory.context.config.address, user_id: accessory.context.config.user, user_key: accessory.context.config.key, auto_disconnect_time: 15, status_update_time: 600 }); // set accessory information const accessoryService = this.accessory.getService(this.platform.Service.AccessoryInformation); if (accessoryService) { accessoryService.setCharacteristic(this.platform.Characteristic.Manufacturer, 'eqiva') .setCharacteristic(this.platform.Characteristic.Model, 'eq3') .setCharacteristic(this.platform.Characteristic.SerialNumber, 'Default-Serial'); } // get the Door service if it exists, otherwise create a new Door service // you can create multiple services for each accessory this.service = this.accessory.getService(this.platform.Service.Door) || this.accessory.addService(this.platform.Service.Door); // set the service name, this is what is displayed as the default name on the Home app // in this example we are using the name we stored in the `accessory.context` in the `discoverDevices` method. this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.config.name); // each service must implement at-minimum the "required characteristics" for the given service type // see https://developers.homebridge.io/#/service/Door this.service.getCharacteristic(this.platform.Characteristic.CurrentPosition) .setProps({ minValue: Position.Lock, minStep: Position.Unlock_MinStep, maxValue: Position.Unlock }); this.service.getCharacteristic(this.platform.Characteristic.TargetPosition) .setProps({ minValue: Position.Lock, minStep: Position.Unlock_MinStep, maxValue: Position.Open }); // register handlers for the CurrentPosition Characteristic this.service.getCharacteristic(this.platform.Characteristic.CurrentPosition) .on('get', this.getCurrentPosition.bind(this)); // register handlers for the State Characteristic this.service.getCharacteristic(this.platform.Characteristic.PositionState) .on('get', this.getState.bind(this)); // register handlers for the TargetPosition Characteristic this.service.getCharacteristic(this.platform.Characteristic.TargetPosition) .on('get', this.getTargetPosition.bind(this)) .on('set', this.setTargetPosition.bind(this)); // register handler for status changes from lock this.lock .on('status_change', this.handleStatusChange.bind(this)); this.lock.request_status(); } /** * Handle the "GET" requests from HomeKit * These are sent when HomeKit wants to know the current state of the accessory, for example, checking if a Light bulb is on. * * GET requests should return as fast as possbile. A long delay here will result in * HomeKit being unresponsive and a bad user experience in general. * * If your device takes time to respond you should update the status of your device * asynchronously instead using the `updateCharacteristic` method instead. * @example * this.service.updateCharacteristic(this.platform.Characteristic.On, true) */ getCurrentPosition(callback) { const currentPosition = this.state.currentPosition; this.platform.log.debug('Get Characteristic Current Position ->', currentPosition); callback(null, currentPosition); } getState(callback) { const movement = this.state.movement; this.platform.log.debug('Get Characteristic State ->', movement); callback(null, movement); } getTargetPosition(callback) { const targetPosition = this.state.targetPosition; this.platform.log.debug('Get Characteristic Target Position ->', targetPosition); callback(null, targetPosition); } /** * Handle "SET" requests from HomeKit * These are sent when the user changes the state of an accessory, for example, changing the Brightness */ setTargetPosition(value, callback) { if (this.state.targetPosition != value) { this.state.targetPosition = value; this.lock.ensure_connected(); this.platform.log.info('Set Characteristic Target Position -> ', value); switch (value) { case Position.Open: this.platform.log.debug('Open'); this.state.movement = this.platform.Characteristic.PositionState.INCREASING; this.lock.open() .then(() => { this.updateCurrentPosition(value); }) .catch((error) => { this.handleLockError(error); }); break; case Position.Unlock: case Position.Unlock_MinStep: this.platform.log.debug('Unlock'); this.state.movement = this.platform.Characteristic.PositionState.INCREASING; this.lock.unlock() .then(() => { this.updateCurrentPosition(value); }) .catch((error) => { this.handleLockError(error); }); break; case Position.Lock: this.platform.log.debug('Lock'); this.state.movement = this.platform.Characteristic.PositionState.DECREASING; this.lock.lock() .then(() => { this.updateCurrentPosition(value); }) .catch((error) => { this.handleLockError(error); }); } } callback(null); } /* Meant to be called with then after operating the lock * This probably can be replaced by handleStatusChange */ updateCurrentPosition(position) { this.platform.log.debug('updateCurrentPosition -> ', position); this.service.getCharacteristic(this.platform.Characteristic.CurrentPosition) .setValue(Math.min(position, Position.Unlock)); this.service.getCharacteristic(this.platform.Characteristic.PositionState) .setValue(this.platform.Characteristic.PositionState.STOPPED); } handleLockError(error) { this.lock.request_status(); this.platform.log.error(error); } handleStatusChange(newStatus) { this.platform.log.debug('Status update: ', newStatus.lock_status); switch (newStatus.lock_status_id) { case 3: // LOCKED this.state.targetPosition = Position.Lock; this.state.currentPosition = Position.Lock; this.state.movement = this.platform.Characteristic.PositionState.STOPPED; break; case 2: // UNLOCKED case 4: // OPENED this.state.targetPosition = Position.Unlock; this.state.currentPosition = Position.Unlock; this.state.movement = this.platform.Characteristic.PositionState.STOPPED; break; case 1: // MOVING if (this.state.targetPosition > Position.Lock) { this.state.movement = this.platform.Characteristic.PositionState.INCREASING; } else { this.state.movement = this.platform.Characteristic.PositionState.DECREASING; } break; case 0: // UNKNOWN this.platform.log.info("Lock reports state unknown"); break; default: this.platform.log.error("Received unkown state: ", newStatus); break; } // Update homebridge values this.service.getCharacteristic(this.platform.Characteristic.CurrentPosition) .updateValue(this.state.currentPosition); this.service.getCharacteristic(this.platform.Characteristic.TargetPosition) .updateValue(this.state.targetPosition); this.service.getCharacteristic(this.platform.Characteristic.PositionState) .updateValue(this.state.movement); } } exports.KeybleAccessory = KeybleAccessory; //# sourceMappingURL=keybleAccessory.js.map