UNPKG

homebridge-eufy-security

Version:
160 lines 8.43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AutoSyncStationAccessory = void 0; const eufy_security_client_1 = require("eufy-security-client"); const StationAccessory_1 = require("./StationAccessory"); const utils_1 = require("../utils/utils"); /** * Platform Auto 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 AutoSyncStationAccessory { accessory; device; static first = true; static alarmFired = false; static childs = []; static first_station = {}; name; guardModeChangeTimeout = { timeout: null, delay: 5000 }; static alarmFiredTimeout = { timeout: null, delay: 5000 }; constructor(platform, accessory, device) { this.accessory = accessory; this.device = device; // Must be subsecond since station are initiated in // let first = false; if (AutoSyncStationAccessory.first) { AutoSyncStationAccessory.first = false; first = true; } this.name = this.device.getName(); // if it's the first we do create a full station accessory and then store it // if not we need to fire event from Eufy to push to HK and vice versa if (first) { utils_1.log.debug(`${this.accessory.displayName} Constructed First Station`); // Create the Station accessory AutoSyncStationAccessory.first_station = new StationAccessory_1.StationAccessory(platform, accessory, device); this.device.on('guard mode', this.changeModeToAllChilds.bind(this)); this.device.on('alarm event', this.fireAlarmToAllChilds.bind(this)); } else { utils_1.log.debug(`${this.accessory.displayName} Constructed Child Station`); // Register to Eufy event of all childs this.initChildEventRegister(); } // Register child AutoSyncStationAccessory.childs.push(this); } initChildEventRegister() { const first_station = AutoSyncStationAccessory.first_station; this.device.on('current mode', (station, currentMode) => { utils_1.log.debug(`FWD ${this.name} 'current mode' TO clearTimeout (${currentMode})`); if (this.guardModeChangeTimeout.timeout) { // If there's an existing timeout, clear it clearTimeout(this.guardModeChangeTimeout.timeout); } }); this.device.on('alarm arm delay event', (station, armDelay) => { utils_1.log.debug(`FWD ${this.name} 'alarm arm delay event' TO ${first_station.name}`); first_station.onStationAlarmDelayedEvent(station, armDelay); }); this.device.on('alarm armed event', () => { utils_1.log.debug(`FWD ${this.name} 'alarm armed event' TO ${first_station.name}`); first_station.onStationAlarmArmedEvent(); }); this.device.on('alarm event', this.fireAlarmToAllChilds.bind(this)); } /** * Handle requests to set the 'Security System Target State' to all childs */ changeModeToAllChilds(station, guardMode) { utils_1.log.info(`FWD ${this.name} 'guard mode (${eufy_security_client_1.GuardMode[guardMode]})' TO all the childs`); AutoSyncStationAccessory.childs.forEach((child, index) => { if (index === 0) { return; } // Already changed so do nothing for him child.handleSecuritySystemTargetStateSet(guardMode); }); } /** * Handle requests to synchronize alarm events to all child stations. * @param station The station triggering the alarm event. * @param alarmEvent The type of alarm event. */ fireAlarmToAllChilds(station, alarmEvent) { const first_station = AutoSyncStationAccessory.first_station; const manualAlarmSeconds = first_station.stationConfig.manualAlarmSeconds; // Log the received alarm event utils_1.log.debug(`RECEIVED ${this.name} 'alarm event' REASON ${eufy_security_client_1.AlarmEvent[alarmEvent]}`); // Prevent looping with multiple received events // Reinit after manualAlarmSeconds * 4 / 5 if (AutoSyncStationAccessory.alarmFired) { return; } else { AutoSyncStationAccessory.alarmFired = true; utils_1.log.debug(`SET TIMEOUT ${this.name} 'alarm event' REASON ${eufy_security_client_1.AlarmEvent[alarmEvent]} FOR ${manualAlarmSeconds * 4 / 5}sec`); AutoSyncStationAccessory.alarmFiredTimeout.timeout = setTimeout(() => { AutoSyncStationAccessory.alarmFired = false; utils_1.log.debug(`TIMEOUT ${this.name} 'alarm event' REASON ${eufy_security_client_1.AlarmEvent[alarmEvent]}`); }, manualAlarmSeconds * 4 / 5 * 1000); } // List of alarm events fired to stop alarm const pluginFiredAlarmStopEvents = [ eufy_security_client_1.AlarmEvent.HUB_STOP, eufy_security_client_1.AlarmEvent.HUB_STOP_BY_APP, eufy_security_client_1.AlarmEvent.HUB_STOP_BY_HAND, eufy_security_client_1.AlarmEvent.HUB_STOP_BY_KEYPAD, eufy_security_client_1.AlarmEvent.DEV_STOP ]; // Check if the alarm event is a plugin-fired alarm stop event if (pluginFiredAlarmStopEvents.includes(alarmEvent)) { return; } const characteristic = first_station.getService(utils_1.SERV.SecuritySystem) .getCharacteristic(utils_1.CHAR.SecuritySystemCurrentState); first_station.onStationAlarmEventPushNotification(characteristic, alarmEvent); // Iterate over child stations to synchronize the alarm event AutoSyncStationAccessory.childs.forEach(child => { // Check if the alarm is already handled by the child itself if (this.device.getSerial() === child.device.getSerial()) { return; // Already fired by itself so do nothing for him } // Log the forwarded alarm event along with the reason and duration utils_1.log.debug(`FWD ${this.name} 'alarm event' TO ${child.name} REASON ${eufy_security_client_1.AlarmEvent[alarmEvent]} FOR ${manualAlarmSeconds}sec`); // Trigger the alarm sound on the child station with the specified duration child.device.triggerStationAlarmSound(manualAlarmSeconds); }); } /** * Handle requests to set the 'Security System Target State' characteristic */ handleSecuritySystemTargetStateSet(mode) { try { utils_1.log.debug(`${this.name} SET StationGuardMode Eufy: ${eufy_security_client_1.GuardMode[mode]}(${mode})`); // Call the device's setGuardMode method to initiate the action this.device.setGuardMode(mode); // Set a new timeout this.guardModeChangeTimeout.timeout = setTimeout(() => { // This code is executed when the timeout elapses, indicating that the action may not have completed yet. // You can include a message indicating that the action is being retried. utils_1.log.warn(`${this.accessory.displayName} Changing guard mode to ${eufy_security_client_1.GuardMode[mode]} did not complete. Retry...'`); // Call the device's setGuardMode method to initiate the action this.device.setGuardMode(mode); // Set a secondary timeout for retry, if needed const retryTimeout = setTimeout(() => { // This code is executed if the retry also times out, indicating a failure. utils_1.log.error(`${this.accessory.displayName} Changing guard mode to ${eufy_security_client_1.GuardMode[mode]} timed out!`); }, this.guardModeChangeTimeout.delay); // Store the retry timeout as part of guardModeChangeTimeout this.guardModeChangeTimeout.timeout = retryTimeout; }, this.guardModeChangeTimeout.delay); } catch (error) { utils_1.log.error(`${this.name} Error Setting security mode! ${error}`); } } } exports.AutoSyncStationAccessory = AutoSyncStationAccessory; //# sourceMappingURL=AutoSyncStationAccessory.js.map