From 8f00f315bae0fcb87f610eba74ab6ba959e4d855 Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 13:50:19 +0200 Subject: [PATCH 01/15] Add current mode parameter to commands (#48) --- index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/index.js b/index.js index 3a10de8..91627e2 100644 --- a/index.js +++ b/index.js @@ -1256,6 +1256,9 @@ SecuritySystem.prototype.executeCommand = function(type, state) { return; } + // Parameters + command = command.replace('${currentMode}', this.state2Mode(this.currentState)); + exec(command, (error, stdout, stderr) => { if (error !== null) { this.log.error(`Command failed (${command})\n${error}`); From 99b51918ac52c1bf7459e6347475c39f43a9ce6e Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 13:58:46 +0200 Subject: [PATCH 02/15] Add current mode parameter to webhooks (#48) --- index.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/index.js b/index.js index 91627e2..85270ef 100644 --- a/index.js +++ b/index.js @@ -1331,6 +1331,9 @@ SecuritySystem.prototype.sendWebhookEvent = function(type, state) { return; } + // Parameters + path = path.replace('${currentMode}', this.state2Mode(this.currentState)); + // Send GET request to server fetch(this.webhookUrl + path) .then(response => { From be7bec106886866b0b9fbd8dbbfff524d5193d8a Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 14:11:21 +0200 Subject: [PATCH 03/15] Allow disabling sounds (#48) --- index.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 85270ef..434e28f 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,4 @@ +const fs = require("fs"); const path = require('path'); const { exec, spawn } = require('child_process'); const packageJson = require('./package.json'); @@ -1161,7 +1162,7 @@ SecuritySystem.prototype.startServer = async function() { }; // Audio -SecuritySystem.prototype.playSound = function(type, state) { +SecuritySystem.prototype.playSound = async function(type, state) { const mode = this.state2Mode(state); // Ignore 'Current Off' event @@ -1175,7 +1176,18 @@ SecuritySystem.prototype.playSound = function(type, state) { this.stopSound(); const filename = `${type}-${mode}.mp3`; - const options = ['-loglevel', 'error', '-nodisp', `${__dirname}/sounds/${this.audioLanguage}/${filename}`]; + const filePath = `${__dirname}/sounds/${this.audioLanguage}/${filename}`; + + // Check if file exists + try { + await fs.promises.access(filePath); + } + catch (error) { + this.log.debug(`Sound file not found (${this.audioLanguage}/${filename})`); + return; + } + + const options = ['-loglevel', 'error', '-nodisp', `${filePath}`]; if (mode === 'triggered') { options.push('-loop'); From b64e6a64acfcc4c6c4deedfd27691b5f0dafeddf Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 14:17:03 +0200 Subject: [PATCH 04/15] Fix webhook status error --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 434e28f..ac3e5cf 100644 --- a/index.js +++ b/index.js @@ -1350,7 +1350,7 @@ SecuritySystem.prototype.sendWebhookEvent = function(type, state) { fetch(this.webhookUrl + path) .then(response => { if (!response.ok) { - throw new Error(`Status code (${response.statusCode})`); + throw new Error(`Status code (${response.status})`); } this.log('Webhook event (Sent)'); From ffefd8d5074d1527a3c250fd1c4fbbb0c16783e7 Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 14:22:01 +0200 Subject: [PATCH 05/15] Add more debug messages --- index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.js b/index.js index ac3e5cf..ef1a653 100644 --- a/index.js +++ b/index.js @@ -1265,6 +1265,7 @@ SecuritySystem.prototype.executeCommand = function(type, state) { } if (isValueSet(command) === false) { + this.log.debug(`Command option for ${type} mode is not set.`); return; } @@ -1340,6 +1341,7 @@ SecuritySystem.prototype.sendWebhookEvent = function(type, state) { } if (isValueSet(path) === false) { + this.log.debug(`Webhook option for ${type} mode is not set.`); return; } From f296c5bc276668ca873d2dd3d74163779d80a94e Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 14:46:51 +0200 Subject: [PATCH 06/15] Fix cancelled alarm bug --- index.js | 64 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/index.js b/index.js index ef1a653..7b941d2 100644 --- a/index.js +++ b/index.js @@ -621,7 +621,9 @@ SecuritySystem.prototype.setCurrentState = function(state) { this.resetTimeout = null; this.log.debug('Reset timeout (Fired)'); - this.handleStateChange(); + this.resetTimers(); + this.handleStateChange(true); + this.setCurrentState(this.targetState); }, this.resetMinutes * 60 * 1000); } @@ -632,7 +634,23 @@ SecuritySystem.prototype.setCurrentState = function(state) { } }; -SecuritySystem.prototype.handleStateChange = function() { +SecuritySystem.prototype.resetTimers = function() { + // Clear trigger timeout + if (this.triggerTimeout !== null) { + clearTimeout(this.triggerTimeout); + + this.triggerTimeout = null; + this.log.debug('Trigger timeout (Cleared)'); + } + + // Clear arming timeout + if (this.armingTimeout !== null) { + clearTimeout(this.armingTimeout); + + this.armingTimeout = null; + this.log.debug('Arming timeout (Cleared)'); + } + // Stop siren triggered sensor if (this.sirenInterval !== null) { clearInterval(this.sirenInterval); @@ -648,13 +666,19 @@ SecuritySystem.prototype.handleStateChange = function() { this.resetTimeout = null; this.log.debug('Reset timeout (Cleared)'); } +}; +SecuritySystem.prototype.handleStateChange = function(external) { // Set security system to mode // selected from the user // during triggered state this.stateChanged = this.currentState === Characteristic.SecuritySystemCurrentState.ALARM_TRIGGERED; - // Update characteristics & switches + // Update characteristics + if (external) { + this.service.getCharacteristic(Characteristic.SecuritySystemTargetState).updateValue(this.targetState); + } + const sirenCharacteristic = this.service.getCharacteristic(CustomCharacteristic.SecuritySystemSiren); const sirenOnCharacteristic = this.sirenSwitchService.getCharacteristic(Characteristic.On); @@ -666,15 +690,16 @@ SecuritySystem.prototype.handleStateChange = function() { sirenOnCharacteristic.updateValue(false); } + // Update switches this.resetSirenSwitches(); this.resetModeSwitches(); - this.updateModeSwitches(); }; SecuritySystem.prototype.updateTargetState = function(state, external, delay) { // Check if state is already arming - if (state === this.targetState) { + if (this.targetState === state && + this.currentState !== Characteristic.SecuritySystemCurrentState.ALARM_TRIGGERED) { return; } @@ -683,25 +708,16 @@ SecuritySystem.prototype.updateTargetState = function(state, external, delay) { return; } - // Clear trigger timeout - if (this.triggerTimeout !== null) { - clearTimeout(this.triggerTimeout); - - this.triggerTimeout = null; - this.log.debug('Trigger timeout (Cleared)'); - } - - // Clear arming timeout - if (this.armingTimeout !== null) { - clearTimeout(this.armingTimeout); - - this.armingTimeout = null; - this.log.debug('Arming timeout (Cleared)'); - } + // Reset timers + this.resetTimers(); + // Update target state this.targetState = state; this.logMode('Target', state); + // Update characteristics & switches + this.handleStateChange(external); + // Commands this.executeCommand('target', state); @@ -709,12 +725,6 @@ SecuritySystem.prototype.updateTargetState = function(state, external, delay) { if (this.webhook) { this.sendWebhookEvent('target', state); } - - if (external) { - this.service.getCharacteristic(Characteristic.SecuritySystemTargetState).updateValue(this.targetState); - } - - this.handleStateChange(); // Check if state is currently // selected @@ -850,7 +860,7 @@ SecuritySystem.prototype.sensorTriggered = function(value, callback) { } } else { - this.updateTargetState(this.targetState, false, false); + this.resetTimers(); } } From 5f75b70d07d543cd56b51cbb45db21addbfedc58 Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 14:55:32 +0200 Subject: [PATCH 07/15] Play audio when cancelled or restored --- index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/index.js b/index.js index 7b941d2..1dc71b6 100644 --- a/index.js +++ b/index.js @@ -729,6 +729,7 @@ SecuritySystem.prototype.updateTargetState = function(state, external, delay) { // Check if state is currently // selected if (state === this.currentState) { + this.playSound('current', this.currentState); return; } @@ -861,6 +862,7 @@ SecuritySystem.prototype.sensorTriggered = function(value, callback) { } else { this.resetTimers(); + this.playSound('current', this.currentState); } } From 0ecabaafd900d0e93bddf925b2e32881dda00c94 Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 14:56:18 +0200 Subject: [PATCH 08/15] Bump version --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 18b39a8..c0545d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "homebridge-securitysystem", - "version": "3.0.2-beta.1", + "version": "3.1.0-beta.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 35ec4a9..90a7b0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homebridge-securitysystem", - "version": "3.0.2-beta.1", + "version": "3.1.0-beta.1", "description": "Homebridge plugin that creates a security system accessory that can be triggered by HomeKit accessories.", "main": "index.js", "scripts": { From 9689edb52ff7cde3b0a1a561ce1283f1307c1271 Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 17:28:37 +0200 Subject: [PATCH 09/15] Check if audio feature enabled --- index.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 1dc71b6..d6e7176 100644 --- a/index.js +++ b/index.js @@ -728,8 +728,11 @@ SecuritySystem.prototype.updateTargetState = function(state, external, delay) { // Check if state is currently // selected - if (state === this.currentState) { - this.playSound('current', this.currentState); + if (this.currentState === state) { + if (this.audio) { + this.playSound('current', this.currentState); + } + return; } @@ -862,7 +865,10 @@ SecuritySystem.prototype.sensorTriggered = function(value, callback) { } else { this.resetTimers(); - this.playSound('current', this.currentState); + + if (this.audio) { + this.playSound('current', this.currentState); + } } } From edb2d07dacd7577713b618f67138a73d1f3ad887 Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 17:38:38 +0200 Subject: [PATCH 10/15] Add condition to alert sound (#48) --- index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index d6e7176..1656e0e 100644 --- a/index.js +++ b/index.js @@ -839,6 +839,11 @@ SecuritySystem.prototype.sensorTriggered = function(value, callback) { this.setCurrentState(Characteristic.SecuritySystemCurrentState.ALARM_TRIGGERED); }, this.triggerSeconds * 1000); + // Audio + if (this.audio && this.triggerSeconds !== 0) { + this.playSound('current', 'alert'); + } + // Execute command this.executeCommand('current', 'alert'); @@ -846,11 +851,6 @@ SecuritySystem.prototype.sensorTriggered = function(value, callback) { if (this.webhook) { this.sendWebhookEvent('current', 'alert'); } - - // Audio - if (this.audio) { - this.playSound('current', 'alert'); - } } } else { From 9fd2c248efa899ba416f543366612ae044517456 Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 18:43:15 +0200 Subject: [PATCH 11/15] Add target off options (#48) --- accessories.schema.json | 92 ++++++++++++++++++++++++----------------- config.schema.json | 68 ++++++++++++++++++------------ index.js | 62 ++++++++++++++------------- 3 files changed, 128 insertions(+), 94 deletions(-) diff --git a/accessories.schema.json b/accessories.schema.json index bff07cb..e30fc1d 100644 --- a/accessories.schema.json +++ b/accessories.schema.json @@ -64,6 +64,19 @@ "required": false, "minimum": 0 }, + "siren_sensor": { + "title": "Show Siren Sensor", + "type": "boolean", + "default": false, + "required": false + }, + "siren_sensor_seconds": { + "title": "Seconds", + "type": "integer", + "default": 5, + "required": false, + "minimum": 0 + }, "trigger_seconds": { "title": "Trigger Delay Seconds", "type": "integer", @@ -84,19 +97,6 @@ "default": true, "required": false }, - "siren_sensor": { - "title": "Show Siren Sensor", - "type": "boolean", - "default": false, - "required": false - }, - "siren_sensor_seconds": { - "title": "Seconds", - "type": "integer", - "default": 5, - "required": false, - "minimum": 0 - }, "siren_mode_switches": { "title": "Show Siren Mode Switches", "type": "boolean", @@ -171,18 +171,6 @@ "format": "uri", "placeholder": "http://localhost" }, - "webhook_triggered": { - "title": "Current Mode: Triggered", - "type": "string", - "required": false, - "placeholder": "/triggered" - }, - "webhook_alert": { - "title": "Current Event: Alert", - "type": "string", - "required": false, - "placeholder": "/alert" - }, "webhook_target_home": { "title": "Target Mode: Home", "type": "string", @@ -201,6 +189,12 @@ "required": false, "placeholder": "/target/night" }, + "webhook_target_off": { + "title": "Target Mode: Off", + "type": "string", + "required": false, + "placeholder": "/target/off" + }, "webhook_current_home": { "title": "Current Mode: Home", "type": "string", @@ -219,23 +213,23 @@ "required": false, "placeholder": "/current/night" }, - "webhook_off": { + "webhook_current_off": { "title": "Current Mode: Off", "type": "string", "required": false, - "placeholder": "/off" + "placeholder": "/current/off" }, - "command_triggered": { - "title": "Current Mode: Triggered", + "webhook_alert": { + "title": "Current Event: Alert", "type": "string", "required": false, - "placeholder": "echo triggered" + "placeholder": "/event/alert" }, - "command_alert": { - "title": "Current Event: Alert", + "webhook_triggered": { + "title": "Current Mode: Triggered", "type": "string", "required": false, - "placeholder": "echo alert" + "placeholder": "/current/triggered" }, "command_target_home": { "title": "Target Mode: Home", @@ -249,6 +243,12 @@ "required": false, "placeholder": "echo target away" }, + "command_target_off": { + "title": "Target Mode: Off", + "type": "string", + "required": false, + "placeholder": "echo target off" + }, "command_target_night": { "title": "Target Mode: Night", "type": "string", @@ -273,11 +273,23 @@ "required": false, "placeholder": "echo current night" }, - "command_off": { + "command_current_off": { "title": "Current Mode: Off", "type": "string", "required": false, - "placeholder": "echo off" + "placeholder": "echo current off" + }, + "command_alert": { + "title": "Current Event: Alert", + "type": "string", + "required": false, + "placeholder": "echo event alert" + }, + "command_triggered": { + "title": "Current Mode: Triggered", + "type": "string", + "required": false, + "placeholder": "echo current triggered" } } }], @@ -377,12 +389,13 @@ "webhook_target_home", "webhook_target_away", "webhook_target_night", + "webhook_target_off", "webhook_current_home", "webhook_current_away", "webhook_current_night", - "webhook_triggered", + "webhook_current_off", "webhook_alert", - "webhook_off" + "webhook_triggered" ] }, { @@ -395,12 +408,13 @@ "command_target_home", "command_target_away", "command_target_night", + "command_target_off", "command_current_home", "command_current_away", "command_current_night", - "command_triggered", + "command_current_off", "command_alert", - "command_off" + "command_triggered" ] } ] diff --git a/config.schema.json b/config.schema.json index 373c721..f5bdef2 100644 --- a/config.schema.json +++ b/config.schema.json @@ -2,7 +2,7 @@ "pluginAlias": "security-system", "pluginType": "accessory", "headerDisplay": "Create a security system accessory that can be triggered by HomeKit accessories.", - "footerDisplay": "Need help? [Ask me anything!](https://github.com/MiguelRipoll23/homebridge-securitysystem/issues) | [Donate](https://paypal.me/miguelripoll23)", + "footerDisplay": "Need help? [Ask me anything](https://github.com/MiguelRipoll23/homebridge-securitysystem/issues) | [Donate](https://paypal.me/miguelripoll23)", "schema": { "title": "Security System", "type": "object", @@ -168,18 +168,6 @@ "format": "uri", "placeholder": "http://localhost" }, - "webhook_triggered": { - "title": "Current Mode: Triggered", - "type": "string", - "required": false, - "placeholder": "/triggered" - }, - "webhook_alert": { - "title": "Current Event: Alert", - "type": "string", - "required": false, - "placeholder": "/alert" - }, "webhook_target_home": { "title": "Target Mode: Home", "type": "string", @@ -198,6 +186,12 @@ "required": false, "placeholder": "/target/night" }, + "webhook_target_off": { + "title": "Target Mode: Off", + "type": "string", + "required": false, + "placeholder": "/target/off" + }, "webhook_current_home": { "title": "Current Mode: Home", "type": "string", @@ -216,23 +210,23 @@ "required": false, "placeholder": "/current/night" }, - "webhook_off": { + "webhook_current_off": { "title": "Current Mode: Off", "type": "string", "required": false, - "placeholder": "/off" + "placeholder": "/current/off" }, - "command_triggered": { - "title": "Current Mode: Triggered", + "webhook_alert": { + "title": "Current Event: Alert", "type": "string", "required": false, - "placeholder": "echo triggered" + "placeholder": "/event/alert" }, - "command_alert": { - "title": "Current Event: Alert", + "webhook_triggered": { + "title": "Current Mode: Triggered", "type": "string", "required": false, - "placeholder": "echo alert" + "placeholder": "/current/triggered" }, "command_target_home": { "title": "Target Mode: Home", @@ -246,6 +240,12 @@ "required": false, "placeholder": "echo target away" }, + "command_target_off": { + "title": "Target Mode: Off", + "type": "string", + "required": false, + "placeholder": "echo target off" + }, "command_target_night": { "title": "Target Mode: Night", "type": "string", @@ -270,11 +270,23 @@ "required": false, "placeholder": "echo current night" }, - "command_off": { + "command_current_off": { "title": "Current Mode: Off", "type": "string", "required": false, - "placeholder": "echo off" + "placeholder": "echo current off" + }, + "command_alert": { + "title": "Current Event: Alert", + "type": "string", + "required": false, + "placeholder": "echo event alert" + }, + "command_triggered": { + "title": "Current Mode: Triggered", + "type": "string", + "required": false, + "placeholder": "echo current triggered" } } }, @@ -374,12 +386,13 @@ "webhook_target_home", "webhook_target_away", "webhook_target_night", + "webhook_target_off", "webhook_current_home", "webhook_current_away", "webhook_current_night", - "webhook_triggered", + "webhook_current_off", "webhook_alert", - "webhook_off" + "webhook_triggered" ] }, { @@ -392,12 +405,13 @@ "command_target_home", "command_target_away", "command_target_night", + "command_target_off", "command_current_home", "command_current_away", "command_current_night", - "command_triggered", + "command_current_off", "command_alert", - "command_off" + "command_triggered" ] } ] diff --git a/index.js b/index.js index 1656e0e..77b1454 100644 --- a/index.js +++ b/index.js @@ -62,22 +62,44 @@ function SecuritySystem(log, config) { this.serverPort = config.server_port; this.serverCode = config.server_code; - // Optional: webhook - this.webhookUrl = config.webhook_url; - // Optional: commands this.commandTargetHome = config.command_target_home; this.commandTargetAway = config.command_target_away; this.commandTargetNight = config.command_target_night; + this.commandTargetOff = config.command_target_off; this.commandCurrentHome = config.command_current_home; this.commandCurrentAway = config.command_current_away; this.commandCurrentNight = config.command_current_night; - - this.commandOff = config.command_off; - this.commandTriggered = config.command_triggered; + this.commandCurrentOff = config.command_current_off || config.command_off; this.commandAlert = config.command_alert; + this.commandTriggered = config.command_triggered; + + // Optional: webhook + this.webhookUrl = config.webhook_url; + + this.webhookTargetHome = config.webhook_target_home; + this.webhookTargetAway = config.webhook_target_away; + this.webhookTargetNight = config.webhook_target_night; + this.webhookTargetOff = config.webhook_target_off; + + this.webhookCurrentHome = config.webhook_current_home; + this.webhookCurrentAway = config.webhook_current_away; + this.webhookCurrentNight = config.webhook_current_night; + this.webhookCurrentOff = config.webhook_current_off || config.webhook_off; + + this.webhookAlert = config.webhook_alert; + this.webhookTriggered = config.webhook_triggered; + + // Deprecated warnings + if (isValueSet(config.command_off)) { + this.log.error('Option comand_off has been deprecated, use command_current_off instead.'); + } + + if (isValueSet(config.webhook_off)) { + this.log.error('Option webhook_off has been deprecated, use webhook_current_off instead.'); + } // Variables this.defaultState = null; @@ -183,25 +205,7 @@ function SecuritySystem(log, config) { } } - if (isValueSet(this.webhookUrl)) { - this.webhook = true; - - this.webhookTargetHome = config.webhook_target_home; - this.webhookTargetAway = config.webhook_target_away; - this.webhookTargetNight = config.webhook_target_night; - - this.webhookCurrentHome = config.webhook_current_home; - this.webhookCurrentAway = config.webhook_current_away; - this.webhookCurrentNight = config.webhook_current_night; - - this.webhookOff = config.webhook_off; - this.webhookTriggered = config.webhook_triggered; - - this.webhookAlert = config.webhook_alert; - } - else { - this.webhook = false; - } + this.webhook = isValueSet(this.webhookUrl); // Log this.logMode('Default', this.defaultState); @@ -1268,10 +1272,11 @@ SecuritySystem.prototype.executeCommand = function(type, state) { case Characteristic.SecuritySystemCurrentState.DISARMED: if (type === 'current') { - return; + command = this.commandCurrentOff; + break; } - command = this.commandOff; + command = this.commandTargetOff; break; case 'alert': @@ -1343,10 +1348,11 @@ SecuritySystem.prototype.sendWebhookEvent = function(type, state) { case Characteristic.SecuritySystemCurrentState.DISARMED: if (type === 'current') { + path = this.webhookCurrentOff; return; } - path = this.webhookOff; + path = this.webhookTargetOff; break; case 'alert': From 839077fde0781f194f788f1ae77d4abd7be9c7a8 Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 18:43:50 +0200 Subject: [PATCH 12/15] Bump version --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index c0545d8..f6c8198 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "homebridge-securitysystem", - "version": "3.1.0-beta.1", + "version": "3.1.0-beta.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 90a7b0a..cd3b6aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homebridge-securitysystem", - "version": "3.1.0-beta.1", + "version": "3.1.0-beta.2", "description": "Homebridge plugin that creates a security system accessory that can be triggered by HomeKit accessories.", "main": "index.js", "scripts": { From 3dff8096d7cdd2c91f5ea6aa24cb01d57b0f4a21 Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 20:51:42 +0200 Subject: [PATCH 13/15] Refactor code --- index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 77b1454..41389b3 100644 --- a/index.js +++ b/index.js @@ -741,8 +741,10 @@ SecuritySystem.prototype.updateTargetState = function(state, external, delay) { } // Audio - if (this.audio && this.stateChanged === false && this.armSeconds > 0) { - this.playSound('target', state); + if (this.audio) { + if (this.stateChanged === false && this.armSeconds > 0) { + this.playSound('target', state); + } } if (delay === undefined) { From a9031213b13504df25b510af6b1fccb3ca3c081c Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 21:16:18 +0200 Subject: [PATCH 14/15] Add option for custom sounds (#48) --- README.md | 1 + accessories.schema.json | 9 ++++++++- config.schema.json | 9 ++++++++- index.js | 18 ++++++++++++++++-- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d8c412f..051a4c5 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Use Eve or a similar app to create automations like these: | show_mode_pause_switch | Shows the `Mode Pause` switch to temporarily disarm the security system. | false | true | | override_off | Allows to trigger the security system while disarmed. | false | true | | audio | Play audio sounds (requires ffmpeg installed). | false | true | +| audio_custom | Use custom sounds for all events (add `-custom` before `.mp3` in the filename). | false | true | | audio_language | Set language used for the audio warnings. | en-US | de-DE | | audio_alert_looped | Loop alert sound that plays when the security system's countdown has started. | false | true | | save_state | State persistence for shutdowns and reboots. | false | true | diff --git a/accessories.schema.json b/accessories.schema.json index e30fc1d..1605ec4 100644 --- a/accessories.schema.json +++ b/accessories.schema.json @@ -128,6 +128,12 @@ "default": false, "required": false }, + "audio_custom": { + "title": "Use Custom Sounds", + "type": "boolean", + "default": false, + "required": false + }, "audio_language": { "title": "Audio Language", "type": "string", @@ -328,9 +334,10 @@ "expandable": true, "expanded": false, "items": [ + "audio_custom", + "audio_alert_looped", "unsafe_mode_switches", "hide_mode_off_switch", - "audio_alert_looped", "siren_switch", "siren_mode_switches", "override_off", diff --git a/config.schema.json b/config.schema.json index f5bdef2..7e0eceb 100644 --- a/config.schema.json +++ b/config.schema.json @@ -125,6 +125,12 @@ "default": false, "required": false }, + "audio_custom": { + "title": "Use Custom Sounds", + "type": "boolean", + "default": false, + "required": false + }, "audio_language": { "title": "Audio Language", "type": "string", @@ -325,9 +331,10 @@ "expandable": true, "expanded": false, "items": [ + "audio_custom", + "audio_alert_looped", "unsafe_mode_switches", "hide_mode_off_switch", - "audio_alert_looped", "siren_switch", "siren_mode_switches", "override_off", diff --git a/index.js b/index.js index 41389b3..6eee3eb 100644 --- a/index.js +++ b/index.js @@ -54,6 +54,7 @@ function SecuritySystem(log, config) { this.sirenSensorSeconds = config.siren_sensor_seconds; this.overrideOff = config.override_off; this.audio = config.audio; + this.audioCustom = config.audio_custom; this.audioLanguage = config.audio_language; this.audioAlertLooped = config.audio_alert_looped; this.saveState = config.save_state; @@ -182,6 +183,10 @@ function SecuritySystem(log, config) { this.audio = false; } + if (isValueSet(this.audioCustom) === false) { + this.audioCustom = false; + } + if (isValueSet(this.audioLanguage) === false) { this.audioLanguage = 'en-US'; } @@ -1199,10 +1204,18 @@ SecuritySystem.prototype.playSound = async function(type, state) { // Close previous player this.stopSound(); - const filename = `${type}-${mode}.mp3`; - const filePath = `${__dirname}/sounds/${this.audioLanguage}/${filename}`; + // Filename + let filename = `${type}-${mode}`; + + if (this.audioCustom) { + filename += '-custom'; + } + + filename += '.mp3'; // Check if file exists + const filePath = `${__dirname}/sounds/${this.audioLanguage}/${filename}`; + try { await fs.promises.access(filePath); } @@ -1211,6 +1224,7 @@ SecuritySystem.prototype.playSound = async function(type, state) { return; } + // Spawn process const options = ['-loglevel', 'error', '-nodisp', `${filePath}`]; if (mode === 'triggered') { From 6133856dbf70b32cc4e21ebdcaf49965f75ee829 Mon Sep 17 00:00:00 2001 From: Miguel Ripoll Date: Sat, 4 Jul 2020 21:17:05 +0200 Subject: [PATCH 15/15] Bump version --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index f6c8198..8c27eb2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "homebridge-securitysystem", - "version": "3.1.0-beta.2", + "version": "3.1.0-beta.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index cd3b6aa..e493349 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "homebridge-securitysystem", - "version": "3.1.0-beta.2", + "version": "3.1.0-beta.3", "description": "Homebridge plugin that creates a security system accessory that can be triggered by HomeKit accessories.", "main": "index.js", "scripts": {