UNPKG

homebridge-jablotron-mqtt

Version:

Plugin for Jablotron JA-6X system communicating via mqtt and py-jablotron6x

241 lines 11.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.JbMqttAccPlg = void 0; const mqtt = __importStar(require("mqtt")); const const_1 = require("./const"); const settings_1 = require("./settings"); var JbMqttCustomConfigKeys; (function (JbMqttCustomConfigKeys) { JbMqttCustomConfigKeys["SECURITY_CODE"] = "securityCode"; JbMqttCustomConfigKeys["MQTT_USERNAME"] = "username"; JbMqttCustomConfigKeys["MQTT_PASSWORD"] = "password"; JbMqttCustomConfigKeys["MQTT_URL"] = "mqttUrl"; JbMqttCustomConfigKeys["MQTT_TOPIC_PREFIX"] = "mqttTopicPrefix"; JbMqttCustomConfigKeys["MQTT_START_CMD"] = "startCmd"; JbMqttCustomConfigKeys["MQTT_START_PARAM"] = "startParameter"; JbMqttCustomConfigKeys["MODEL"] = "MODEL"; JbMqttCustomConfigKeys["ALLOW_COMMUNICATION"] = "allowCommunication"; })(JbMqttCustomConfigKeys || (JbMqttCustomConfigKeys = {})); class JbMqttAccPlg { constructor(logger, config, api) { this.currentState = 3; //Characteristic.SecuritySystemCurrentState.DISARMED; this.client_Id = 'mqttjs_' + Math.random().toString(16).substr(2, 8); this.mqttOptions = {}; this.allowCommunication = false; this.runningChangeCallback = undefined; this.runningChangeTarget = undefined; this.changeState = async (target) => { await this.asyncPublish(const_1.AlarmTopic.KEY_PRESS, const_1.Command.CLEAR); if (target === const_1.JblMode.ARMED) { await this.asyncPublish(const_1.AlarmTopic.KEY_PRESS, const_1.Command.ARM); } else if (target === const_1.JblMode.DISARMED) { await this.asyncPublish(const_1.AlarmTopic.KEY_PRESS, this.securityCode); } }; this.log = logger; this.Service = api.hap.Service; this.Characteristic = api.hap.Characteristic; this.name = config.name; this.model = config[JbMqttCustomConfigKeys.MODEL]; this.securityCode = config[JbMqttCustomConfigKeys.SECURITY_CODE]; this.mqttOptions = { keepalive: 10, clientId: this.client_Id, protocolId: 'MQTT', protocolVersion: 4, clean: true, reconnectPeriod: 1000, connectTimeout: 30 * 1000, will: { topic: 'WillMsg', payload: 'Connection Closed abnormally..!', qos: 0, retain: false, }, username: config[JbMqttCustomConfigKeys.MQTT_USERNAME], password: config[JbMqttCustomConfigKeys.MQTT_PASSWORD], rejectUnauthorized: false, }; this.mqttUrl = config[JbMqttCustomConfigKeys.MQTT_URL]; this.mqttTopicPrefix = config[JbMqttCustomConfigKeys.MQTT_TOPIC_PREFIX] || ''; this.mqttTopics = [this.getTopic(const_1.AlarmTopic.RAW), this.getTopic(const_1.AlarmTopic.MODE)]; this.client = mqtt.connect(this.mqttUrl, this.mqttOptions); this.allowCommunication = config[JbMqttCustomConfigKeys.ALLOW_COMMUNICATION]; this.log('Subsribing to', this.mqttTopics); this.client.subscribe(this.mqttTopics); const securityStateService = new api.hap.Service.SecuritySystem(settings_1.ACCESSORY_NAME, 'MODEL TODO'); securityStateService .getCharacteristic(api.hap.Characteristic.SecuritySystemCurrentState) .on("get" /* GET */, this.getCurrentState.bind(this)); securityStateService .getCharacteristic(api.hap.Characteristic.SecuritySystemTargetState) .on("get" /* GET */, this.getTargetState.bind(this)) .on("set" /* SET */, this.setTargetState.bind(this)); this.securityStateService = securityStateService; const informationService = new api.hap.Service.AccessoryInformation(); informationService .setCharacteristic(api.hap.Characteristic.Name, this.name) .setCharacteristic(api.hap.Characteristic.Manufacturer, const_1.MANUFACTURER) .setCharacteristic(api.hap.Characteristic.Model, this.model) .setCharacteristic(api.hap.Characteristic.SerialNumber, '-'); this.informationService = informationService; this.client.on('error', () => { this.log('Error event on MQTT'); }); this.client.on('connect', () => { if (config['startCmd'] !== undefined && config['startParameter'] !== undefined) { this.client.publish(config[JbMqttCustomConfigKeys.MQTT_START_CMD], config[JbMqttCustomConfigKeys.MQTT_START_PARAM]); } }); this.client.on('message', (topic, message) => { const text = message.toString(); if (topic === this.getTopic(const_1.AlarmTopic.RAW)) { //Raw /// e0 41 11 59 29 03 3d ff /* 00 1 byte e0/e1/e2 - general status 01 1 byte mode 02 1 byte binary status of leds ??? 03 1 byte content of display ??? 04 1 byte strength of GSM signal/battery?? 05 1 byte zero one or two 06 1 byte checksum 07 1 byte 0xFF - indicates end of message */ const arrE0 = text.split(' '); if (arrE0.length === 8) { if (arrE0[0] === const_1.JablotronRecordType.STATUS) { let newState = undefined; let stateName; const jblMode = arrE0[1]; switch (jblMode) { case const_1.JblMode.ARMED: newState = this.Characteristic.SecuritySystemCurrentState.AWAY_ARM; stateName = 'AWAY_ARM'; break; case const_1.JblMode.DISARMED: newState = this.Characteristic.SecuritySystemCurrentState.DISARMED; stateName = 'DISARMED'; break; case const_1.JblMode.TAMPERED: case const_1.JblMode.TRIGGERED: newState = this.Characteristic.SecuritySystemCurrentState.ALARM_TRIGGERED; stateName = 'ALARM_TRIGGERED'; break; default: stateName = 'UNKNOWN'; //change = false; } if (newState !== undefined) { if (this.runningChangeCallback !== undefined && jblMode === this.runningChangeTarget) { try { this.runningChangeCallback(null, newState); } catch (e) { this.log('Error sending event back to callback from raw', e); this.runningChangeCallback = undefined; } } if (newState !== this.currentState) { this.log('setting new state', stateName); this.currentState = newState; this.securityStateService .getCharacteristic(api.hap.Characteristic.SecuritySystemCurrentState) .setValue(this.currentState, 'fromSetValue'); } } } } } }); } async asyncPublish(topic, message, opts = {}) { return new Promise((resolve, reject) => { this.client.publish(this.getTopic(topic), message, opts, (error, packet) => { if (error) { reject(error); } else { resolve(packet); } }); }); } getTopic(name) { return this.mqttTopicPrefix + '/' + name; } getServices() { return [this.securityStateService, this.informationService]; } getCurrentState(callback) { callback(null, this.currentState); } getTargetState(callback) { callback(null, this.currentState); } setTargetState(state, callback) { this.log('Getting current state'); if (this.runningChangeCallback !== undefined) { this.runningChangeTarget = undefined; this.runningChangeCallback(new Error('Cancelled')); this.runningChangeCallback = undefined; } if (this.currentState === state) { callback(null, state); return; } let targetState = undefined; switch (state) { case this.Characteristic.SecuritySystemTargetState.STAY_ARM: case this.Characteristic.SecuritySystemTargetState.AWAY_ARM: case this.Characteristic.SecuritySystemTargetState.NIGHT_ARM: targetState = const_1.JblMode.ARMED; break; case this.Characteristic.SecuritySystemTargetState.DISARM: targetState = const_1.JblMode.DISARMED; break; } if (!this.allowCommunication) { this.log('Communication is forbiden', 'current state:', this.currentState, 'new state:', targetState); callback(new Error('Communication is forbiden')); return; } if (!this.client.connected) { this.log('MQTT is not connected'); callback(new Error('MQTT is not connected')); return; } if (targetState !== undefined) { this.runningChangeTarget = targetState; this.runningChangeCallback = callback; this.changeState(targetState).catch(e => { this.runningChangeTarget = undefined; this.runningChangeCallback = undefined; callback(e, null); this.log('Error in invoke', e); }); } } } exports.JbMqttAccPlg = JbMqttAccPlg; //# sourceMappingURL=accessory.js.map