From af74a0b36f2c2880b874ca5cd338ed971d18cc75 Mon Sep 17 00:00:00 2001 From: Joost Loohuis Date: Fri, 16 Aug 2024 15:23:41 +0200 Subject: [PATCH 1/6] Refactor camera alarm timeouts --- .../drivers/settings/alarmTimeout.json | 12 ++++++ drivers/camera/device.ts | 42 +++++++------------ drivers/camera/driver.settings.compose.json | 11 +---- lib/TuyaTimeOutAlarmDevice.ts | 30 +++++++++++++ 4 files changed, 58 insertions(+), 37 deletions(-) create mode 100644 .homeycompose/drivers/settings/alarmTimeout.json create mode 100644 lib/TuyaTimeOutAlarmDevice.ts diff --git a/.homeycompose/drivers/settings/alarmTimeout.json b/.homeycompose/drivers/settings/alarmTimeout.json new file mode 100644 index 00000000..fcb74751 --- /dev/null +++ b/.homeycompose/drivers/settings/alarmTimeout.json @@ -0,0 +1,12 @@ +{ + "id": "alarm_timeout", + "type": "number", + "label": { + "en": "Alarm Timeout" + }, + "value": 10, + "min": 1, + "units": { + "en": "seconds" + } +} diff --git a/drivers/camera/device.ts b/drivers/camera/device.ts index 35f37a8f..372febc1 100644 --- a/drivers/camera/device.ts +++ b/drivers/camera/device.ts @@ -1,4 +1,3 @@ -import TuyaOAuth2Device from '../../lib/TuyaOAuth2Device'; import * as TuyaOAuth2Util from '../../lib/TuyaOAuth2Util'; import { constIncludes, getFromMap } from '../../lib/TuyaOAuth2Util'; import { SettingsEvent, TuyaStatus } from '../../types/TuyaTypes'; @@ -7,10 +6,9 @@ import { CAMERA_SETTING_LABELS, SIMPLE_CAMERA_CAPABILITIES, } from './TuyaCameraConstants'; +import TuyaTimeOutAlarmDevice from '../../lib/TuyaTimeOutAlarmDevice'; -module.exports = class TuyaOAuth2DeviceCamera extends TuyaOAuth2Device { - alarmTimeouts: Record = {}; - +module.exports = class TuyaOAuth2DeviceCamera extends TuyaTimeOutAlarmDevice { async onOAuth2Init(): Promise { await super.onOAuth2Init(); @@ -126,29 +124,19 @@ module.exports = class TuyaOAuth2DeviceCamera extends TuyaOAuth2Device { } async setAlarm(capability: string): Promise { - if (this.alarmTimeouts[capability] !== undefined) { - // Extend the existing timeout if already running - clearTimeout(this.alarmTimeouts[capability]); - } else { - // Trigger capability change if not - const deviceTriggerCard = this.homey.flow.getDeviceTriggerCard(`camera_${capability}_true`); - await deviceTriggerCard.trigger(this).catch(this.error); - await this.setCapabilityValue(capability, true).catch(this.error); - } - // Disable the alarm after a set time, since we only get an "on" event - const alarmTimeout = Math.round((this.getSetting('alarm_timeout') ?? 10) * 1000); - this.alarmTimeouts[capability] = setTimeout(() => this.resetAlarm(capability), alarmTimeout); - } - - async resetAlarm(capability: string): Promise { - // Clear the timeout for the next event - const currentTimeout = this.alarmTimeouts[capability]; - clearTimeout(currentTimeout); - this.alarmTimeouts[capability] = undefined; - // Trigger capability change - const deviceTriggerCard = this.homey.flow.getDeviceTriggerCard(`camera_${capability}_false`); - await deviceTriggerCard.trigger(this).catch(this.error); - await this.setCapabilityValue(capability, false).catch(this.error); + await super.setAlarm( + capability, + async () => { + const deviceTriggerCard = this.homey.flow.getDeviceTriggerCard(`camera_${capability}_true`); + await deviceTriggerCard.trigger(this).catch(this.error); + await this.setCapabilityValue(capability, true).catch(this.error); + }, + async () => { + const deviceTriggerCard = this.homey.flow.getDeviceTriggerCard(`camera_${capability}_false`); + await deviceTriggerCard.trigger(this).catch(this.error); + await this.setCapabilityValue(capability, false).catch(this.error); + }, + ); } // Map from up/idle/down to commands so the ternary UI shows arrows diff --git a/drivers/camera/driver.settings.compose.json b/drivers/camera/driver.settings.compose.json index 0054d655..fa5a1ad7 100644 --- a/drivers/camera/driver.settings.compose.json +++ b/drivers/camera/driver.settings.compose.json @@ -189,16 +189,7 @@ ] }, { - "id": "alarm_timeout", - "type": "number", - "label": { - "en": "Alarm Timeout" - }, - "value": 10, - "min": 1, - "units": { - "en": "seconds" - } + "$extends": "alarmTimeout" }, { "$extends": "deviceSpecification" diff --git a/lib/TuyaTimeOutAlarmDevice.ts b/lib/TuyaTimeOutAlarmDevice.ts new file mode 100644 index 00000000..af10ae44 --- /dev/null +++ b/lib/TuyaTimeOutAlarmDevice.ts @@ -0,0 +1,30 @@ +import TuyaOAuth2Device from './TuyaOAuth2Device'; + +export default class TuyaTimeOutAlarmDevice extends TuyaOAuth2Device { + alarmTimeouts: Record = {}; + + async setAlarm( + capability: string, + onAlarmStarted: () => Promise, + onAlarmEnded: () => Promise, + ): Promise { + if (this.alarmTimeouts[capability] !== undefined) { + // Extend the existing timeout if already running + clearTimeout(this.alarmTimeouts[capability]); + } else { + // Trigger if not + await onAlarmStarted(); + } + // Disable the alarm after a set time, since we only get an "on" event + const alarmTimeout = Math.round((this.getSetting('alarm_timeout') ?? 10) * 1000); + this.alarmTimeouts[capability] = setTimeout(() => this.resetAlarm(capability, onAlarmEnded), alarmTimeout); + } + + async resetAlarm(capability: string, onAlarmEnded: () => Promise): Promise { + // Clear the timeout for the next event + const currentTimeout = this.alarmTimeouts[capability]; + clearTimeout(currentTimeout); + this.alarmTimeouts[capability] = undefined; + await onAlarmEnded(); + } +} From d4c275ac7b7893eb9beec9a23a4ef9da3257346f Mon Sep 17 00:00:00 2001 From: Joost Loohuis Date: Fri, 16 Aug 2024 15:55:43 +0200 Subject: [PATCH 2/6] Add alarm timeouts to sensors --- .../drivers/settings/useAlarmTimeout.json | 11 +++ app.json | 69 +++++++++++++++++++ drivers/sensor_contact/device.ts | 7 +- .../driver.settings.compose.json | 6 ++ drivers/sensor_motion/device.ts | 7 +- .../driver.settings.compose.json | 6 ++ drivers/sensor_smoke/device.ts | 7 +- .../sensor_smoke/driver.settings.compose.json | 6 ++ lib/TuyaOAuth2DeviceSensor.ts | 21 +++++- 9 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 .homeycompose/drivers/settings/useAlarmTimeout.json diff --git a/.homeycompose/drivers/settings/useAlarmTimeout.json b/.homeycompose/drivers/settings/useAlarmTimeout.json new file mode 100644 index 00000000..290f6bae --- /dev/null +++ b/.homeycompose/drivers/settings/useAlarmTimeout.json @@ -0,0 +1,11 @@ +{ + "id": "use_alarm_timeout", + "type": "checkbox", + "hint": { + "en": "Turn the alarm off a set time after the start signal, even if no end signal is received." + }, + "label": { + "en": "Use Alarm Timeout" + }, + "value": false +} diff --git a/app.json b/app.json index f2710cb2..6c6dc218 100644 --- a/app.json +++ b/app.json @@ -2805,6 +2805,29 @@ }, "id": "sensor_contact", "settings": [ + { + "id": "use_alarm_timeout", + "type": "checkbox", + "hint": { + "en": "Turn the alarm off a set time after the start signal, even if no end signal is received." + }, + "label": { + "en": "Use Alarm Timeout" + }, + "value": false + }, + { + "id": "alarm_timeout", + "type": "number", + "label": { + "en": "Alarm Timeout" + }, + "value": 10, + "min": 1, + "units": { + "en": "seconds" + } + }, { "id": "deviceSpecification", "type": "label", @@ -2870,6 +2893,29 @@ }, "id": "sensor_motion", "settings": [ + { + "id": "use_alarm_timeout", + "type": "checkbox", + "hint": { + "en": "Turn the alarm off a set time after the start signal, even if no end signal is received." + }, + "label": { + "en": "Use Alarm Timeout" + }, + "value": false + }, + { + "id": "alarm_timeout", + "type": "number", + "label": { + "en": "Alarm Timeout" + }, + "value": 10, + "min": 1, + "units": { + "en": "seconds" + } + }, { "id": "deviceSpecification", "type": "label", @@ -2935,6 +2981,29 @@ }, "id": "sensor_smoke", "settings": [ + { + "id": "use_alarm_timeout", + "type": "checkbox", + "hint": { + "en": "Turn the alarm off a set time after the start signal, even if no end signal is received." + }, + "label": { + "en": "Use Alarm Timeout" + }, + "value": false + }, + { + "id": "alarm_timeout", + "type": "number", + "label": { + "en": "Alarm Timeout" + }, + "value": 10, + "min": 1, + "units": { + "en": "seconds" + } + }, { "id": "deviceSpecification", "type": "label", diff --git a/drivers/sensor_contact/device.ts b/drivers/sensor_contact/device.ts index e2b66d70..9abbf378 100644 --- a/drivers/sensor_contact/device.ts +++ b/drivers/sensor_contact/device.ts @@ -6,8 +6,11 @@ module.exports = class TuyaOAuth2DeviceSensorContact extends TuyaOAuth2DeviceSen await super.onTuyaStatus(status, changedStatusCodes); // alarm_contact - if (typeof status['doorcontact_state'] === 'boolean') { - this.setCapabilityValue('alarm_contact', status['doorcontact_state']).catch(this.error); + if ( + typeof status['doorcontact_state'] === 'boolean' && + (!this.getSetting('use_alarm_timeout') || changedStatusCodes.includes('doorcontact_state')) + ) { + this.setAlarmCapabilityValue('alarm_contact', status['doorcontact_state']).catch(this.error); } } }; diff --git a/drivers/sensor_contact/driver.settings.compose.json b/drivers/sensor_contact/driver.settings.compose.json index dceebc0d..3aeb8d1f 100644 --- a/drivers/sensor_contact/driver.settings.compose.json +++ b/drivers/sensor_contact/driver.settings.compose.json @@ -1,4 +1,10 @@ [ + { + "$extends": "useAlarmTimeout" + }, + { + "$extends": "alarmTimeout" + }, { "$extends": "deviceSpecification" } diff --git a/drivers/sensor_motion/device.ts b/drivers/sensor_motion/device.ts index 805837cf..37514bcb 100644 --- a/drivers/sensor_motion/device.ts +++ b/drivers/sensor_motion/device.ts @@ -6,8 +6,11 @@ module.exports = class TuyaOAuth2DeviceSensorMotion extends TuyaOAuth2DeviceSens await super.onTuyaStatus(status, changedStatusCodes); // alarm_motion - if (typeof status['pir'] === 'string') { - this.setCapabilityValue('alarm_motion', status['pir'] === 'pir').catch(this.error); + if ( + typeof status['pir'] === 'string' && + (!this.getSetting('use_alarm_timeout') || changedStatusCodes.includes('pir')) + ) { + this.setAlarmCapabilityValue('alarm_motion', status['pir'] === 'pir').catch(this.error); } } }; diff --git a/drivers/sensor_motion/driver.settings.compose.json b/drivers/sensor_motion/driver.settings.compose.json index dceebc0d..3aeb8d1f 100644 --- a/drivers/sensor_motion/driver.settings.compose.json +++ b/drivers/sensor_motion/driver.settings.compose.json @@ -1,4 +1,10 @@ [ + { + "$extends": "useAlarmTimeout" + }, + { + "$extends": "alarmTimeout" + }, { "$extends": "deviceSpecification" } diff --git a/drivers/sensor_smoke/device.ts b/drivers/sensor_smoke/device.ts index a0c2229f..b3212950 100644 --- a/drivers/sensor_smoke/device.ts +++ b/drivers/sensor_smoke/device.ts @@ -6,8 +6,11 @@ module.exports = class TuyaOAuth2DeviceSensorSmoke extends TuyaOAuth2DeviceSenso await super.onTuyaStatus(status, changedStatusCodes); // alarm_smoke - if (typeof status['smoke_sensor_status'] === 'string') { - this.setCapabilityValue('alarm_smoke', status['smoke_sensor_status'] === 'alarm').catch(this.error); + if ( + typeof status['smoke_sensor_status'] === 'string' && + (!this.getSetting('use_alarm_timeout') || changedStatusCodes.includes('smoke_sensor_status')) + ) { + this.setAlarmCapabilityValue('alarm_smoke', status['smoke_sensor_status'] === 'alarm').catch(this.error); } } }; diff --git a/drivers/sensor_smoke/driver.settings.compose.json b/drivers/sensor_smoke/driver.settings.compose.json index dceebc0d..3aeb8d1f 100644 --- a/drivers/sensor_smoke/driver.settings.compose.json +++ b/drivers/sensor_smoke/driver.settings.compose.json @@ -1,4 +1,10 @@ [ + { + "$extends": "useAlarmTimeout" + }, + { + "$extends": "alarmTimeout" + }, { "$extends": "deviceSpecification" } diff --git a/lib/TuyaOAuth2DeviceSensor.ts b/lib/TuyaOAuth2DeviceSensor.ts index 5e67a2b4..4369ffa4 100644 --- a/lib/TuyaOAuth2DeviceSensor.ts +++ b/lib/TuyaOAuth2DeviceSensor.ts @@ -1,8 +1,8 @@ import { TuyaStatus } from '../types/TuyaTypes'; -import TuyaOAuth2Device from './TuyaOAuth2Device'; import * as TuyaSensorMigrations from '../lib/migrations/TuyaSensorMigrations'; +import TuyaTimeOutAlarmDevice from './TuyaTimeOutAlarmDevice'; -export default class TuyaOAuth2DeviceSensor extends TuyaOAuth2Device { +export default class TuyaOAuth2DeviceSensor extends TuyaTimeOutAlarmDevice { async performMigrations(): Promise { await super.performMigrations(); await TuyaSensorMigrations.performMigrations(this); @@ -26,6 +26,23 @@ export default class TuyaOAuth2DeviceSensor extends TuyaOAuth2Device { await this.safeSetCapabilityValue('alarm_tamper', status['temper_alarm']); } } + + async setAlarmCapabilityValue(capability: string, value: boolean): Promise { + if (this.getSetting('use_alarm_timeout')) { + if (value) { + await this.setAlarm( + capability, + () => this.setCapabilityValue(capability, true).catch(this.error), + () => this.setCapabilityValue(capability, false).catch(this.error), + ); + } else { + // If the device does send false before the timeout ends we cut it short + await this.resetAlarm(capability, () => this.setCapabilityValue(capability, false).catch(this.error)); + } + } else { + await this.setCapabilityValue(capability, value); + } + } } module.exports = TuyaOAuth2DeviceSensor; From ed7dcb1732b3155ea43252d2af96dbfd4a136db0 Mon Sep 17 00:00:00 2001 From: Joost Loohuis Date: Fri, 16 Aug 2024 16:12:26 +0200 Subject: [PATCH 3/6] Detect alarm timeouts setting for motion and smoke sensors --- drivers/sensor_motion/driver.ts | 14 ++++++++++++++ drivers/sensor_smoke/driver.ts | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/drivers/sensor_motion/driver.ts b/drivers/sensor_motion/driver.ts index 8fc80c95..cf71d06b 100644 --- a/drivers/sensor_motion/driver.ts +++ b/drivers/sensor_motion/driver.ts @@ -24,6 +24,20 @@ module.exports = class TuyaOAuth2DriverSensorMotion extends TuyaOAuth2DriverSens props.capabilities.push('alarm_motion'); } + if (!specifications) { + return props; + } + + for (const specification of specifications.status) { + const tuyaCapability = specification.code; + const values = JSON.parse(specification.values); + if (tuyaCapability === 'pir') { + if (!values.range.includes('none')) { + props.settings['use_alarm_timeout'] = true; + } + } + } + return props; } }; diff --git a/drivers/sensor_smoke/driver.ts b/drivers/sensor_smoke/driver.ts index b829fe97..38484c19 100644 --- a/drivers/sensor_smoke/driver.ts +++ b/drivers/sensor_smoke/driver.ts @@ -24,6 +24,20 @@ module.exports = class TuyaOAuth2DriverSensorSmoke extends TuyaOAuth2DriverSenso props.capabilities.push('alarm_smoke'); } + if (!specifications) { + return props; + } + + for (const specification of specifications.status) { + const tuyaCapability = specification.code; + const values = JSON.parse(specification.values); + if (tuyaCapability === 'alarm_smoke') { + if (!values.range.includes('normal')) { + props.settings['use_alarm_timeout'] = true; + } + } + } + return props; } }; From e5c7bec785c991c66683118138e9fe333248fcd7 Mon Sep 17 00:00:00 2001 From: Bob van de Vijver Date: Tue, 27 Aug 2024 09:21:00 +0200 Subject: [PATCH 4/6] Use Homey SDK timeout functions --- lib/TuyaOAuth2Client.ts | 4 ++-- lib/TuyaOAuth2Device.ts | 2 +- lib/TuyaTimeOutAlarmDevice.ts | 11 +++++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/TuyaOAuth2Client.ts b/lib/TuyaOAuth2Client.ts index 496ec881..39263c3a 100644 --- a/lib/TuyaOAuth2Client.ts +++ b/lib/TuyaOAuth2Client.ts @@ -337,10 +337,10 @@ export default class TuyaOAuth2Client extends OAuth2Client { onUpdateWebhook(): void { if (this.__updateWebhookTimeout) { - clearTimeout(this.__updateWebhookTimeout); + this.homey.clearTimeout(this.__updateWebhookTimeout); } - this.__updateWebhookTimeout = setTimeout(() => { + this.__updateWebhookTimeout = this.homey.setTimeout(() => { Promise.resolve() .then(async () => { const keys = Array.from(this.registeredDevices.keys()); diff --git a/lib/TuyaOAuth2Device.ts b/lib/TuyaOAuth2Device.ts index d8d0908c..5051cc4c 100644 --- a/lib/TuyaOAuth2Device.ts +++ b/lib/TuyaOAuth2Device.ts @@ -154,7 +154,7 @@ export default class TuyaOAuth2Device extends OAuth2Device { async onTuyaStatus(status: TuyaStatus, _changedStatusCodes: string[]): Promise { // Wait at least 100ms for initialization before trying to pass the barrier again while (this.initBarrier) { - await new Promise(resolve => setTimeout(resolve, 100)); + await new Promise(resolve => this.homey.setTimeout(resolve, 100)); } this.log('onTuyaStatus', JSON.stringify(status)); diff --git a/lib/TuyaTimeOutAlarmDevice.ts b/lib/TuyaTimeOutAlarmDevice.ts index af10ae44..49fa0505 100644 --- a/lib/TuyaTimeOutAlarmDevice.ts +++ b/lib/TuyaTimeOutAlarmDevice.ts @@ -10,21 +10,24 @@ export default class TuyaTimeOutAlarmDevice extends TuyaOAuth2Device { ): Promise { if (this.alarmTimeouts[capability] !== undefined) { // Extend the existing timeout if already running - clearTimeout(this.alarmTimeouts[capability]); + this.homey.clearTimeout(this.alarmTimeouts[capability]); } else { // Trigger if not await onAlarmStarted(); } // Disable the alarm after a set time, since we only get an "on" event const alarmTimeout = Math.round((this.getSetting('alarm_timeout') ?? 10) * 1000); - this.alarmTimeouts[capability] = setTimeout(() => this.resetAlarm(capability, onAlarmEnded), alarmTimeout); + this.alarmTimeouts[capability] = this.homey.setTimeout( + () => this.resetAlarm(capability, onAlarmEnded), + alarmTimeout, + ); } async resetAlarm(capability: string, onAlarmEnded: () => Promise): Promise { // Clear the timeout for the next event const currentTimeout = this.alarmTimeouts[capability]; - clearTimeout(currentTimeout); - this.alarmTimeouts[capability] = undefined; + this.homey.clearTimeout(currentTimeout); + delete this.alarmTimeouts[capability]; await onAlarmEnded(); } } From ffa2d25d4f21808d0dc8e1d0f924e579ee29e994 Mon Sep 17 00:00:00 2001 From: Bob van de Vijver Date: Tue, 27 Aug 2024 09:53:03 +0200 Subject: [PATCH 5/6] Initialize alarm values when not set, or reset when app restarted with timeout setting active --- drivers/sensor_contact/device.ts | 6 ++++++ drivers/sensor_motion/device.ts | 6 ++++++ drivers/sensor_smoke/device.ts | 6 ++++++ lib/TuyaTimeOutAlarmDevice.ts | 20 ++++++++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/drivers/sensor_contact/device.ts b/drivers/sensor_contact/device.ts index 9abbf378..ed25167f 100644 --- a/drivers/sensor_contact/device.ts +++ b/drivers/sensor_contact/device.ts @@ -2,6 +2,12 @@ import TuyaOAuth2DeviceSensor from '../../lib/TuyaOAuth2DeviceSensor'; import { TuyaStatus } from '../../types/TuyaTypes'; module.exports = class TuyaOAuth2DeviceSensorContact extends TuyaOAuth2DeviceSensor { + async onOAuth2Init(): Promise { + await this.initAlarm('alarm_contact').catch(this.error); + + return super.onOAuth2Init(); + } + async onTuyaStatus(status: TuyaStatus, changedStatusCodes: string[]): Promise { await super.onTuyaStatus(status, changedStatusCodes); diff --git a/drivers/sensor_motion/device.ts b/drivers/sensor_motion/device.ts index 37514bcb..93534387 100644 --- a/drivers/sensor_motion/device.ts +++ b/drivers/sensor_motion/device.ts @@ -2,6 +2,12 @@ import TuyaOAuth2DeviceSensor from '../../lib/TuyaOAuth2DeviceSensor'; import { TuyaStatus } from '../../types/TuyaTypes'; module.exports = class TuyaOAuth2DeviceSensorMotion extends TuyaOAuth2DeviceSensor { + async onOAuth2Init(): Promise { + await this.initAlarm('alarm_motion').catch(this.error); + + return super.onOAuth2Init(); + } + async onTuyaStatus(status: TuyaStatus, changedStatusCodes: string[]): Promise { await super.onTuyaStatus(status, changedStatusCodes); diff --git a/drivers/sensor_smoke/device.ts b/drivers/sensor_smoke/device.ts index b3212950..6495845a 100644 --- a/drivers/sensor_smoke/device.ts +++ b/drivers/sensor_smoke/device.ts @@ -2,6 +2,12 @@ import TuyaOAuth2DeviceSensor from '../../lib/TuyaOAuth2DeviceSensor'; import { TuyaStatus } from '../../types/TuyaTypes'; module.exports = class TuyaOAuth2DeviceSensorSmoke extends TuyaOAuth2DeviceSensor { + async onOAuth2Init(): Promise { + await this.initAlarm('alarm_smoke').catch(this.error); + + return super.onOAuth2Init(); + } + async onTuyaStatus(status: TuyaStatus, changedStatusCodes: string[]): Promise { await super.onTuyaStatus(status, changedStatusCodes); diff --git a/lib/TuyaTimeOutAlarmDevice.ts b/lib/TuyaTimeOutAlarmDevice.ts index 49fa0505..0b4c5ed3 100644 --- a/lib/TuyaTimeOutAlarmDevice.ts +++ b/lib/TuyaTimeOutAlarmDevice.ts @@ -3,6 +3,26 @@ import TuyaOAuth2Device from './TuyaOAuth2Device'; export default class TuyaTimeOutAlarmDevice extends TuyaOAuth2Device { alarmTimeouts: Record = {}; + async initAlarm(capability: string): Promise { + const capabilityValue = this.getCapabilityValue(capability); + if (typeof capabilityValue !== 'boolean') { + // No value set, so reset it to false + await this.setCapabilityValue(capability, false).catch(this.error); + return; + } + + if (!capabilityValue) { + return; + } + + if (!this.getSetting('use_alarm_timeout')) { + return; + } + + // Still active, reset now because timeout is no longer running + await this.setCapabilityValue(capability, false).catch(this.error); + } + async setAlarm( capability: string, onAlarmStarted: () => Promise, From 921835883a16788bde9cb36e05696d1fd0676de2 Mon Sep 17 00:00:00 2001 From: Bob van de Vijver Date: Tue, 27 Aug 2024 10:36:56 +0200 Subject: [PATCH 6/6] Add alarm_tamper support to contact & motion sensors --- lib/TuyaOAuth2DeviceSensor.ts | 6 ++++++ lib/TuyaTimeOutAlarmDevice.ts | 8 ++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/TuyaOAuth2DeviceSensor.ts b/lib/TuyaOAuth2DeviceSensor.ts index 4369ffa4..92126e9b 100644 --- a/lib/TuyaOAuth2DeviceSensor.ts +++ b/lib/TuyaOAuth2DeviceSensor.ts @@ -3,6 +3,12 @@ import * as TuyaSensorMigrations from '../lib/migrations/TuyaSensorMigrations'; import TuyaTimeOutAlarmDevice from './TuyaTimeOutAlarmDevice'; export default class TuyaOAuth2DeviceSensor extends TuyaTimeOutAlarmDevice { + async onOAuth2Init(): Promise { + await this.initAlarm('alarm_tamper', false).catch(this.error); + + return super.onOAuth2Init(); + } + async performMigrations(): Promise { await super.performMigrations(); await TuyaSensorMigrations.performMigrations(this); diff --git a/lib/TuyaTimeOutAlarmDevice.ts b/lib/TuyaTimeOutAlarmDevice.ts index 0b4c5ed3..68069c8a 100644 --- a/lib/TuyaTimeOutAlarmDevice.ts +++ b/lib/TuyaTimeOutAlarmDevice.ts @@ -3,7 +3,11 @@ import TuyaOAuth2Device from './TuyaOAuth2Device'; export default class TuyaTimeOutAlarmDevice extends TuyaOAuth2Device { alarmTimeouts: Record = {}; - async initAlarm(capability: string): Promise { + async initAlarm(capability: string, checkResetSetting = true): Promise { + if (!this.hasCapability(capability)) { + return; + } + const capabilityValue = this.getCapabilityValue(capability); if (typeof capabilityValue !== 'boolean') { // No value set, so reset it to false @@ -15,7 +19,7 @@ export default class TuyaTimeOutAlarmDevice extends TuyaOAuth2Device { return; } - if (!this.getSetting('use_alarm_timeout')) { + if (!checkResetSetting || !this.getSetting('use_alarm_timeout')) { return; }