From 77234adcfec4ddf3dc79d05dbf42c76b2bb03bab Mon Sep 17 00:00:00 2001 From: bropat Date: Thu, 31 Aug 2023 19:32:18 +0200 Subject: [PATCH] Updated version of the package eufy-security-client (2.8.1) Updated docs and version --- README.md | 5 + build/main.js | 12 +- build/main.js.map | 4 +- docs/_coverpage.md | 2 +- io-package.json | 15 +- package-lock.json | 634 ++++++++++++++++++++++----------------------- package.json | 16 +- src/main.ts | 12 +- 8 files changed, 355 insertions(+), 345 deletions(-) diff --git a/README.md b/README.md index 7d8bad5..c6add56 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,11 @@ Best is to set the adapter to Debug log mode (see [here](https://bropat.github.i ## Changelog +### 1.1.2 (2023-08-31) + +* (bropat) Updated version of the package eufy-security-client (2.8.1) +* (bropat) Further details can be found in the changelog of eufy-security-client (2.8.1) + ### 1.1.1 (2023-08-20) * (bropat) Fixed issue #365 diff --git a/build/main.js b/build/main.js index 7827e75..bcc3c27 100644 --- a/build/main.js +++ b/build/main.js @@ -879,28 +879,28 @@ class euSec extends utils.Adapter { try { const allDevices = await this.getDevicesAsync(); const reg = new RegExp(`^${this.namespace}.[0-9A-Z]+$`); - allDevices.forEach((id) => { + for (const id of allDevices) { if (id._id.match(reg)) { const serial = id._id.replace(`${this.namespace}.`, ""); if (!stationSerials.includes(serial)) { - this.delObjectAsync(id._id, { recursive: true }); + await this.delObjectAsync(id._id, { recursive: true }); } } - }); + } } catch (error) { this.log.error(`Delete obsolete stations ERROR - ${JSON.stringify(error)}`); } try { const allDevices = await this.getDevicesAsync(); const reg = new RegExp(`^${this.namespace}.[0-9A-Z]+.[a-z]+.[0-9A-Z]+$`); - allDevices.forEach((id) => { + for (const id of allDevices) { if (id._id.match(reg)) { const serial = id._id.split(".")[4]; if (!deviceSerials.includes(serial)) { - this.delObjectAsync(id._id, { recursive: true }); + await this.delObjectAsync(id._id, { recursive: true }); } } - }); + } } catch (error) { this.log.error(`Delete obsolete devices ERROR - ${JSON.stringify(error)}`); } diff --git a/build/main.js.map b/build/main.js.map index b49b30a..22e4c52 100644 --- a/build/main.js.map +++ b/build/main.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/main.ts"], - "sourcesContent": ["/*\r\n * Created with @iobroker/create-adapter v2.5.0\r\n */\r\n\r\n// The adapter-core module gives you access to the core ioBroker functions\r\n// you need to create an adapter\r\nimport * as utils from \"@iobroker/adapter-core\";\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nimport { strict } from \"assert\";\r\nimport * as path from \"path\";\r\nimport { Camera, Device, Station, PushMessage, P2PConnectionType, EufySecurity, EufySecurityConfig, CommandResult, CommandType, ErrorCode, PropertyValue, PropertyName, StreamMetadata, PropertyMetadataNumeric, PropertyMetadataAny, CommandName, PanTiltDirection, DeviceNotFoundError, LoginOptions, Picture, StationNotFoundError, ensureError } from \"eufy-security-client\";\r\nimport { getAlpha2Code as getCountryCode } from \"i18n-iso-countries\"\r\nimport { isValid as isValidLanguageCode } from \"@cospired/i18n-iso-languages\"\r\nimport fse from \"fs-extra\";\r\nimport { Readable } from \"stream\";\r\nimport util from \"util\";\r\nimport childProcess from \"child_process\";\r\nimport pathToGo2rtc from \"go2rtc-static\";\r\nimport os from \"os\";\r\n\r\n//import * as Interface from \"./lib/interfaces\"\r\nimport { DeviceStateID, DataLocation, RoleMapping, StationStateID } from \"./lib/types\";\r\nimport { convertCamelCaseToSnakeCase, getImageAsHTML, handleUpdate, removeFiles, removeLastChar, setStateChangedAsync } from \"./lib/utils\";\r\nimport { PersistentData } from \"./lib/interfaces\";\r\nimport { ioBrokerLogger } from \"./lib/log\";\r\nimport { ffmpegStreamToGo2rtc } from \"./lib/video\";\r\n\r\n// Augment the adapter.config object with the actual types\r\n// TODO: delete this in the next version\r\n/*declare global {\r\n // eslint-disable-next-line @typescript-eslint/no-namespace\r\n namespace ioBroker {\r\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\r\n interface AdapterConfig extends Interface.AdapterConfig{\r\n // Define the shape of your options here (recommended)\r\n // Or use a catch-all approach\r\n //[key: string]: any;\r\n }\r\n }\r\n}*/\r\n\r\nclass euSec extends utils.Adapter {\r\n\r\n private eufy!: EufySecurity;\r\n /*private downloadEvent: {\r\n [index: string]: NodeJS.Timeout;\r\n } = {};*/\r\n\r\n private persistentFile: string;\r\n private logger!: ioBrokerLogger;\r\n private persistentData: PersistentData = {\r\n version: \"\"\r\n };\r\n private captchaId: string | null = null;\r\n private verify_code = false;\r\n\r\n public constructor(options: Partial = {}) {\r\n super({\r\n ...options,\r\n name: \"eusec\",\r\n });\r\n const data_dir = utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter);\r\n this.persistentFile = path.join(data_dir, \"adapter.json\");\r\n\r\n if (!fse.existsSync(data_dir))\r\n fse.mkdirSync(data_dir);\r\n\r\n this.on(\"ready\", this.onReady.bind(this));\r\n this.on(\"stateChange\", this.onStateChange.bind(this));\r\n // this.on(\"objectChange\", this.onObjectChange.bind(this));\r\n // this.on(\"message\", this.onMessage.bind(this));\r\n this.on(\"unload\", this.onUnload.bind(this));\r\n }\r\n\r\n /**\r\n * Is called when databases are connected and adapter received configuration.\r\n */\r\n private async onReady(): Promise {\r\n\r\n this.logger = new ioBrokerLogger(this.log as ioBroker.Logger);\r\n\r\n await this.setObjectNotExistsAsync(\"verify_code\", {\r\n type: \"state\",\r\n common: {\r\n name: \"2FA verification code\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"received_captcha_html\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Received captcha image HTML\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"captcha\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Enter captcha\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Global connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: false, ack: true });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: false, ack: true });\r\n\r\n try {\r\n const connection = await this.getStatesAsync(\"*.connection\");\r\n if (connection)\r\n Object.keys(connection).forEach(async id => {\r\n await this.setStateAsync(id, { val: false, ack: true });\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Reset connection states - Error\", error);\r\n }\r\n\r\n try {\r\n const sensorList = [\r\n PropertyName.DeviceMotionDetected,\r\n PropertyName.DevicePersonDetected,\r\n PropertyName.DeviceSoundDetected,\r\n PropertyName.DeviceCryingDetected,\r\n PropertyName.DevicePetDetected,\r\n PropertyName.DeviceRinging\r\n ];\r\n for(const sensorName of sensorList) {\r\n const sensors = await this.getStatesAsync(`*.${convertCamelCaseToSnakeCase(sensorName)}`);\r\n if (sensors)\r\n Object.keys(sensors).forEach(async id => {\r\n await this.setStateAsync(id, { val: false, ack: true });\r\n });\r\n }\r\n } catch (error) {\r\n this.logger.error(\"Reset sensor states - Error\", error);\r\n }\r\n\r\n try {\r\n if (fse.statSync(this.persistentFile).isFile()) {\r\n const fileContent = fse.readFileSync(this.persistentFile, \"utf8\");\r\n this.persistentData = JSON.parse(fileContent) as PersistentData;\r\n }\r\n } catch (error) {\r\n this.logger.debug(\"No stored data from last exit found.\", error);\r\n }\r\n\r\n this.subscribeStates(\"verify_code\");\r\n this.subscribeStates(\"captcha\");\r\n\r\n const systemConfig = await this.getForeignObjectAsync(\"system.config\");\r\n let countryCode = undefined;\r\n let languageCode = undefined;\r\n if (systemConfig) {\r\n countryCode = getCountryCode(systemConfig.common.country, \"en\");\r\n if (isValidLanguageCode(systemConfig.common.language))\r\n languageCode = systemConfig.common.language;\r\n }\r\n\r\n if (this.config.hostname === \"\") {\r\n this.config.hostname = os.hostname();\r\n }\r\n\r\n // Handling adapter version update\r\n try {\r\n if (this.persistentData.version !== this.version) {\r\n const currentVersion = Number.parseFloat(removeLastChar(this.version!, \".\"));\r\n const previousVersion = this.persistentData.version !== \"\" && this.persistentData.version !== undefined ? Number.parseFloat(removeLastChar(this.persistentData.version, \".\")) : 0;\r\n this.logger.debug(`Handling of adapter update - currentVersion: ${currentVersion} previousVersion: ${previousVersion}`);\r\n\r\n if (previousVersion < currentVersion) {\r\n await handleUpdate(this as unknown as ioBroker.Adapter, this.logger, previousVersion);\r\n this.persistentData.version = this.version!;\r\n this.writePersistentData();\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`Handling of adapter update - Error:`, error);\r\n }\r\n\r\n let connectionType = P2PConnectionType.QUICKEST;\r\n if (this.config.p2pConnectionType === \"only_local\") {\r\n connectionType = P2PConnectionType.ONLY_LOCAL;\r\n }\r\n\r\n const config: EufySecurityConfig = {\r\n username: this.config.username,\r\n password: this.config.password,\r\n country: countryCode,\r\n language: languageCode,\r\n persistentDir: utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter),\r\n eventDurationSeconds: this.config.eventDuration,\r\n p2pConnectionSetup: connectionType,\r\n pollingIntervalMinutes: this.config.pollingInterval,\r\n acceptInvitations: this.config.acceptInvitations,\r\n };\r\n\r\n this.eufy = await EufySecurity.initialize(config, this.logger);\r\n this.eufy.on(\"station added\", (station: Station) => this.onStationAdded(station));\r\n this.eufy.on(\"device added\", (device: Device) => this.onDeviceAdded(device));\r\n this.eufy.on(\"station removed\", (station: Station) => this.onStationRemoved(station));\r\n this.eufy.on(\"device removed\", (device: Device) => this.onDeviceRemoved(device));\r\n this.eufy.on(\"push message\", (messages) => this.handlePushNotification(messages));\r\n this.eufy.on(\"push connect\", () => this.onPushConnect());\r\n this.eufy.on(\"push close\", () => this.onPushClose());\r\n this.eufy.on(\"mqtt connect\", () => this.onMQTTConnect());\r\n this.eufy.on(\"mqtt close\", () => this.onMQTTClose());\r\n this.eufy.on(\"connect\", () => this.onConnect());\r\n this.eufy.on(\"close\", () => this.onClose());\r\n\r\n this.eufy.on(\"device property changed\", (device: Device, name: string, value: PropertyValue) => this.onDevicePropertyChanged(device, name, value));\r\n\r\n this.eufy.on(\"station command result\", (station: Station, result: CommandResult) => this.onStationCommandResult(station, result));\r\n //this.eufy.on(\"station download start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationDownloadStart(station, device, metadata, videostream, audiostream));\r\n //this.eufy.on(\"station download finish\", (station: Station, device: Device) => this.onStationDownloadFinish(station, device));\r\n this.eufy.on(\"station livestream start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationLivestreamStart(station, device, metadata, videostream, audiostream));\r\n this.eufy.on(\"station livestream stop\", (station: Station, device: Device) => this.onStationLivestreamStop(station, device));\r\n this.eufy.on(\"station rtsp url\", (station: Station, device: Device, value: string) => this.onStationRTSPUrl(station, device, value));\r\n this.eufy.on(\"station property changed\", (station: Station, name: string, value: PropertyValue) => this.onStationPropertyChanged(station, name, value));\r\n this.eufy.on(\"station connect\", (station: Station) => this.onStationConnect(station));\r\n this.eufy.on(\"station close\", (station: Station) => this.onStationClose(station));\r\n this.eufy.on(\"tfa request\", () => this.onTFARequest());\r\n this.eufy.on(\"captcha request\", (captchaId: string, captcha: string) => this.onCaptchaRequest(captchaId, captcha));\r\n this.eufy.setCameraMaxLivestreamDuration(this.config.maxLivestreamDuration);\r\n\r\n await this.eufy.connect();\r\n\r\n if (pathToGo2rtc) {\r\n const go2rtcConfig: {\r\n [index: string]: {\r\n [index: string]: string | number | null\r\n }\r\n } = {\r\n \"api\": {\r\n \"listen\": `:${this.config.go2rtc_api_port}`\r\n },\r\n \"rtsp\": {\r\n \"listen\": `:${this.config.go2rtc_rtsp_port}`\r\n },\r\n \"srtp\": {\r\n \"listen\": `:${this.config.go2rtc_srtp_port}`\r\n },\r\n \"webrtc\": {\r\n \"listen\": `:${this.config.go2rtc_webrtc_port}`\r\n },\r\n \"streams\": {}\r\n };\r\n if (this.config.go2rtc_rtsp_username !== \"\" && this.config.go2rtc_rtsp_password !== \"\") {\r\n go2rtcConfig.rtsp.username = this.config.go2rtc_rtsp_username;\r\n go2rtcConfig.rtsp.password = this.config.go2rtc_rtsp_password;\r\n }\r\n for (const device of await this.eufy.getDevices()) {\r\n go2rtcConfig.streams[device.getSerial()] = null;\r\n }\r\n const go2rtc = childProcess.spawn(pathToGo2rtc, [\"-config\", JSON.stringify(go2rtcConfig)], { shell: false, detached: false, windowsHide: true });\r\n go2rtc.on(\"error\", (error) => {\r\n this.log.error(`go2rtc error: ${error}`);\r\n });\r\n go2rtc.stdout.setEncoding(\"utf8\");\r\n go2rtc.stdout.on(\"data\", (data) => {\r\n this.log.info(`go2rtc started: ${data}`);\r\n });\r\n go2rtc.stderr.setEncoding(\"utf8\");\r\n go2rtc.stderr.on(\"data\", (data) => {\r\n this.log.error(`go2rtc error: ${data}`);\r\n });\r\n go2rtc.on(\"close\", (exitcode) => {\r\n this.log.info(`go2rtc terminated with exitcode ${exitcode}`);\r\n });\r\n process.on(\"exit\", () => {\r\n go2rtc.kill();\r\n });\r\n }\r\n }\r\n\r\n public writePersistentData(): void {\r\n try {\r\n fse.writeFileSync(this.persistentFile, JSON.stringify(this.persistentData));\r\n } catch (error) {\r\n this.logger.error(`writePersistentData() - Error: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Is called when adapter shuts down - callback has to be called under any circumstances!\r\n */\r\n private async onUnload(callback: () => void): Promise {\r\n try {\r\n\r\n this.writePersistentData();\r\n\r\n if (this.eufy) {\r\n if (this.eufy.isConnected())\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true }).catch();\r\n this.eufy.removeAllListeners();\r\n this.eufy.close();\r\n }\r\n\r\n callback();\r\n } catch (e) {\r\n callback();\r\n }\r\n }\r\n\r\n // If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.\r\n // You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`.\r\n // /**\r\n // * Is called if a subscribed object changes\r\n // */\r\n // private onObjectChange(id: string, obj: ioBroker.Object | null | undefined): void {\r\n // if (obj) {\r\n // // The object was changed\r\n // this.log.info(`object ${id} changed: ${JSON.stringify(obj)}`);\r\n // } else {\r\n // // The object was deleted\r\n // this.log.info(`object ${id} deleted`);\r\n // }\r\n // }\r\n\r\n /**\r\n * Is called if a subscribed state changes\r\n */\r\n private async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise {\r\n if (state) {\r\n\r\n // don't do anything if the state is acked\r\n if (!id || state.ack) {\r\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack}) was already acknowledged, ignore it...`);\r\n return;\r\n }\r\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);\r\n\r\n const values = id.split(\".\");\r\n const station_sn = values[2];\r\n const device_type = values[3];\r\n\r\n if (station_sn == \"verify_code\") {\r\n if (this.eufy && this.verify_code) {\r\n this.logger.info(`Verification code received, send it. (verify_code: ${state.val})`);\r\n await this.eufy.connect({ verifyCode: state.val as string } as LoginOptions);\r\n this.verify_code = false;\r\n await this.delStateAsync(id);\r\n }\r\n } else if (station_sn == \"captcha\") {\r\n if (this.eufy && this.captchaId) {\r\n this.logger.info(`Captcha received, send it. (captcha: ${state.val})`);\r\n await this.eufy.connect({\r\n captcha: {\r\n captchaCode: state.val as string,\r\n captchaId: this.captchaId\r\n }\r\n } as LoginOptions);\r\n this.captchaId = null;\r\n await this.delStateAsync(id);\r\n await this.delStateAsync(\"received_captcha_html\");\r\n }\r\n } else if (device_type == \"station\") {\r\n try {\r\n const station_state_name = values[4];\r\n if (this.eufy) {\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n if (obj.native.name !== undefined) {\r\n await this.eufy.setStationProperty(station_sn, obj.native.name, state.val);\r\n return;\r\n }\r\n }\r\n\r\n const station = await this.eufy.getStation(station_sn);\r\n switch(station_state_name) {\r\n case StationStateID.REBOOT:\r\n await station.rebootHUB();\r\n break;\r\n case StationStateID.TRIGGER_ALARM_SOUND:\r\n await station.triggerStationAlarmSound(this.config.alarmSoundDuration);\r\n break;\r\n case StationStateID.RESET_ALARM_SOUND:\r\n await station.resetStationAlarmSound();\r\n break;\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`station - Error:`, error);\r\n }\r\n } else {\r\n try {\r\n const device_sn = values[4];\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n if (obj.native.name !== undefined) {\r\n try {\r\n await this.eufy.setDeviceProperty(device_sn, obj.native.name, obj.common.type === \"object\" ? JSON.parse(state.val as string) : state.val);\r\n } catch (error) {\r\n this.logger.error(`Error in setting property value (property: ${obj.native.name} value: ${state.val})`, error);\r\n }\r\n return;\r\n }\r\n }\r\n\r\n const device_state_name = values[5];\r\n const station = await this.eufy.getStation(station_sn);\r\n const device = await this.eufy.getDevice(device_sn);\r\n\r\n switch(device_state_name) {\r\n case DeviceStateID.START_STREAM:\r\n await this.startLivestream(device_sn);\r\n break;\r\n case DeviceStateID.STOP_STREAM:\r\n await this.stopLivestream(device_sn);\r\n break;\r\n case DeviceStateID.TRIGGER_ALARM_SOUND:\r\n await station.triggerDeviceAlarmSound(device, this.config.alarmSoundDuration);\r\n break;\r\n case DeviceStateID.RESET_ALARM_SOUND:\r\n await station.resetDeviceAlarmSound(device);\r\n break;\r\n case DeviceStateID.ROTATE_360:\r\n await station.panAndTilt(device, PanTiltDirection.ROTATE360);\r\n break;\r\n case DeviceStateID.PAN_LEFT:\r\n await station.panAndTilt(device, PanTiltDirection.LEFT);\r\n break;\r\n case DeviceStateID.PAN_RIGHT:\r\n await station.panAndTilt(device, PanTiltDirection.RIGHT);\r\n break;\r\n case DeviceStateID.TILT_UP:\r\n await station.panAndTilt(device, PanTiltDirection.UP);\r\n break;\r\n case DeviceStateID.TILT_DOWN:\r\n await station.panAndTilt(device, PanTiltDirection.DOWN);\r\n break;\r\n case DeviceStateID.CALIBRATE:\r\n if (device.isLock()) {\r\n await station.calibrateLock(device);\r\n } else {\r\n await station.calibrate(device);\r\n }\r\n break;\r\n case DeviceStateID.UNLOCK:\r\n await station.unlock(device);\r\n break;\r\n case DeviceStateID.SET_DEFAULT_ANGLE:\r\n await station.setDefaultAngle(device);\r\n break;\r\n case DeviceStateID.SET_PRIVACY_ANGLE:\r\n await station.setPrivacyAngle(device);\r\n break;\r\n }\r\n } catch (error) {\r\n this.logger.error(`cameras - Error:`, error);\r\n }\r\n }\r\n } else {\r\n // The state was deleted\r\n this.logger.debug(`state ${id} deleted`);\r\n }\r\n }\r\n\r\n // If you need to accept messages in your adapter, uncomment the following block and the corresponding line in the constructor.\r\n // /**\r\n // * Some message was sent to this instance over message box. Used by email, pushover, text2speech, ...\r\n // * Using this method requires \"common.message\" property to be set to true in io-package.json\r\n // */\r\n // private onMessage(obj: ioBroker.Message): void {\r\n // if (typeof obj === \"object\" && obj.message) {\r\n // if (obj.command === \"send\") {\r\n // // e.g. send email or pushover or whatever\r\n // this.log.info(\"send command\");\r\n\r\n // // Send response in callback if required\r\n // if (obj.callback) this.sendTo(obj.from, obj.command, \"Message received\", obj.callback);\r\n // }\r\n // }\r\n // }\r\n\r\n private getStateCommon(property: PropertyMetadataAny): ioBroker.StateCommon {\r\n const state: ioBroker.StateCommon = {\r\n name: property.label!,\r\n type: property.type,\r\n role: \"state\",\r\n read: property.readable,\r\n write: property.writeable,\r\n def: property.default\r\n };\r\n switch (property.type) {\r\n case \"number\": {\r\n const numberProperty = property as PropertyMetadataNumeric;\r\n state.min = numberProperty.min;\r\n state.max = numberProperty.max;\r\n state.states = numberProperty.states;\r\n state.unit = numberProperty.unit;\r\n state.step = numberProperty.steps;\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : \"value\";\r\n break;\r\n }\r\n case \"string\": {\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : \"text\";\r\n break;\r\n }\r\n case \"boolean\": {\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : (property.writeable ? \"switch.enable\" : \"state\");\r\n break;\r\n }\r\n }\r\n return state;\r\n }\r\n\r\n private async createAndSetState(device: Device | Station, property: PropertyMetadataAny): Promise {\r\n if (property.name !== PropertyName.Type && property.name !== PropertyName.DeviceStationSN) {\r\n const state = this.getStateCommon(property);\r\n const id: string = device.getStateID(convertCamelCaseToSnakeCase(property.name));\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n let changed = false;\r\n if (obj.native.name !== undefined && obj.native.name !== property.name) {\r\n obj.native.name = property.name;\r\n changed = true;\r\n }\r\n if (obj.native.key !== undefined && obj.native.key !== property.key) {\r\n obj.native.key = property.key;\r\n changed = true;\r\n }\r\n if (obj.native.commandId !== undefined && obj.native.commandId !== property.commandId) {\r\n obj.native.commandId = property.commandId;\r\n changed = true;\r\n }\r\n if (obj.common !== undefined && !util.isDeepStrictEqual(obj.common, state)) {\r\n changed = true;\r\n }\r\n if (changed) {\r\n const propertyMetadata = device.getPropertiesMetadata()[property.name];\r\n if (propertyMetadata !== undefined) {\r\n const newState = this.getStateCommon(propertyMetadata);\r\n obj.common = newState;\r\n }\r\n await this.setObjectAsync(id, obj);\r\n }\r\n } else {\r\n await this.setObjectNotExistsAsync(id, {\r\n type: \"state\",\r\n common: state,\r\n native: {\r\n key: property.key,\r\n commandId: property.commandId,\r\n name: property.name,\r\n },\r\n });\r\n }\r\n const value = device.getPropertyValue(property.name);\r\n if (value !== undefined)\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, id, (property.type === \"string\" || property.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n }\r\n }\r\n\r\n private async onDeviceAdded(device: Device): Promise {\r\n this.logger.debug(`onDeviceAdded - device: ${device.getSerial()}`);\r\n\r\n await this.setObjectNotExistsAsync(device.getStateID(\"\", 0), {\r\n type: \"channel\",\r\n common: {\r\n name: device.getStateChannel()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(device.getStateID(\"\", 1), {\r\n type: \"device\",\r\n common: {\r\n name: device.getName()\r\n },\r\n native: {},\r\n });\r\n\r\n const metadata = device.getPropertiesMetadata();\r\n for(const property of Object.values(metadata)) {\r\n if (property.name !== PropertyName.DevicePicture)\r\n this.createAndSetState(device, property);\r\n }\r\n\r\n if (device.hasProperty(PropertyName.DevicePicture)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Picture URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_HTML), {\r\n type: \"state\",\r\n common: {\r\n name: \"Picture HTML image\",\r\n type: \"string\",\r\n role: \"html\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n if (device.hasCommand(CommandName.DeviceTriggerAlarmSound)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TRIGGER_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Trigger Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RESET_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reset Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DevicePanAndTilt)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_LEFT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Pan Left\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_RIGHT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Pan Right\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.ROTATE_360), {\r\n type: \"state\",\r\n common: {\r\n name: \"Rotate 360\u00B0\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_UP), {\r\n type: \"state\",\r\n common: {\r\n name: \"Tilt Up\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_DOWN), {\r\n type: \"state\",\r\n common: {\r\n name: \"Tilt Down\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceLockCalibration)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Calibrate Lock\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceUnlock)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.UNLOCK), {\r\n type: \"state\",\r\n common: {\r\n name: \"Unlock\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceSetDefaultAngle)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_DEFAULT_ANGLE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Set Default Angle\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceSetPrivacyAngle)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_PRIVACY_ANGLE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Set Default Angle\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceCalibrate)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Calibrate\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceStartLivestream)) {\r\n // Start Stream\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.START_STREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Start stream\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n\r\n // Stop Stream\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.STOP_STREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Stop stream\",\r\n type: \"boolean\",\r\n role: \"button.stop\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n\r\n // Livestream URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Livestream URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n\r\n // Livestream RTSP URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), {\r\n type: \"state\",\r\n common: {\r\n name: \"Livestream RTSP URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n if (device.hasProperty(PropertyName.DeviceRTSPStream)) {\r\n // RTSP Stream URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"RTSP stream URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n /*if (device.hasCommand(CommandName.DeviceStartDownload)) {\r\n // Last event video URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event video URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n\r\n // Last event picture URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event picture URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n\r\n // Last event picture HTML image\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event picture HTML image\",\r\n type: \"string\",\r\n role: \"html\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n }*/\r\n }\r\n\r\n private async onDeviceRemoved(device: Device): Promise {\r\n this.delObjectAsync(device.getStateID(\"\", 0), { recursive: true }).catch((error) => {\r\n this.logger.error(`Error deleting states of removed device`, error);\r\n });\r\n removeFiles(this as unknown as ioBroker.Adapter, device.getStationSerial(), DataLocation.LAST_EVENT, device.getSerial()).catch((error) => {\r\n this.logger.error(`Error deleting fs contents of removed device`, error);\r\n });\r\n }\r\n\r\n private async onStationAdded(station: Station): Promise {\r\n this.subscribeStates(`${station.getStateID(\"\", 0)}.*`);\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(\"\", 0), {\r\n type: \"device\",\r\n common: {\r\n name: station.getName()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(\"\", 1), {\r\n type: \"channel\",\r\n common: {\r\n name: station.getStateChannel()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\r\n\r\n const metadata = station.getPropertiesMetadata();\r\n for(const property of Object.values(metadata)) {\r\n this.createAndSetState(station, property);\r\n }\r\n\r\n // Reboot station\r\n if (station.hasCommand(CommandName.StationReboot)) {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.REBOOT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reboot station\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n // Alarm Sound\r\n if (station.hasCommand(CommandName.StationTriggerAlarmSound)) {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.TRIGGER_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Trigger Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.RESET_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reset Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n }\r\n\r\n private async onStationRemoved(station: Station): Promise {\r\n this.delObjectAsync(station.getStateID(\"\", 0), { recursive: true }).catch((error) => {\r\n this.logger.error(`Error deleting states of removed station`, error);\r\n });\r\n fse.remove(path.join(utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter), station.getSerial())).catch((error) => {\r\n this.logger.error(`Error deleting fs contents of removed station`, error);\r\n });\r\n }\r\n\r\n /*private async downloadEventVideo(device: Device, event_time: number, full_path: string | undefined, cipher_id: number | undefined): Promise {\r\n this.logger.debug(`Device: ${device.getSerial()} full_path: ${full_path} cipher_id: ${cipher_id}`);\r\n try {\r\n if (!isEmpty(full_path) && cipher_id !== undefined) {\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n\r\n if (station !== undefined) {\r\n if (this.downloadEvent[device.getSerial()])\r\n clearTimeout(this.downloadEvent[device.getSerial()]);\r\n\r\n let videoLength = getVideoClipLength(device);\r\n const time_passed = (new Date().getTime() - new Date(event_time).getTime()) / 1000;\r\n\r\n if (time_passed >= videoLength)\r\n videoLength = 1;\r\n else\r\n videoLength = videoLength - time_passed;\r\n\r\n this.logger.info(`Downloading video event for device ${device.getSerial()} in ${videoLength} seconds...`);\r\n this.downloadEvent[device.getSerial()] = setTimeout(async () => {\r\n station.startDownload(device, full_path!, cipher_id);\r\n }, videoLength * 1000);\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`Device: ${device.getSerial()} - Error`, error);\r\n }\r\n }*/\r\n\r\n private async handlePushNotification(message: PushMessage): Promise {\r\n try {\r\n if (message.device_sn !== undefined) {\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n /*const device: Device = await this.eufy.getDevice(message.device_sn);\r\n if ((message.push_count === 1 || message.push_count === undefined) && (message.file_path !== undefined && message.file_path !== \"\" && message.cipher !== undefined))\r\n if (this.config.autoDownloadVideo)\r\n await this.downloadEventVideo(device, message.event_time, message.file_path, message.cipher);*/\r\n }\r\n } catch (error) {\r\n if (error instanceof DeviceNotFoundError) {\r\n //Do nothing\r\n } else {\r\n this.logger.error(\"Handling push notification - Error\", error);\r\n }\r\n }\r\n }\r\n\r\n private async onConnect(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Global connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.connection\", { val: true, ack: true });\r\n\r\n const stations = await this.eufy.getStations();\r\n const stationSerials: string[] = [];\r\n for(const station of stations) {\r\n stationSerials.push(station.getSerial());\r\n }\r\n const devices = await this.eufy.getDevices();\r\n const deviceSerials: string[] = [];\r\n for(const device of devices) {\r\n deviceSerials.push(device.getSerial());\r\n }\r\n\r\n // Delete obsolete stations\r\n try {\r\n const allDevices = await this.getDevicesAsync();\r\n const reg = new RegExp(`^${this.namespace}\\.[0-9A-Z]+$`);\r\n allDevices.forEach((id) => {\r\n if (id._id.match(reg)) {\r\n const serial = id._id.replace(`${this.namespace}.`, \"\");\r\n if (!stationSerials.includes(serial)) {\r\n this.delObjectAsync(id._id, { recursive: true });\r\n }\r\n }\r\n });\r\n } catch (error) {\r\n this.log.error(`Delete obsolete stations ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete devices\r\n try {\r\n const allDevices = await this.getDevicesAsync();\r\n const reg = new RegExp(`^${this.namespace}\\.[0-9A-Z]+\\.[a-z]+\\.[0-9A-Z]+$`);\r\n allDevices.forEach((id) => {\r\n if (id._id.match(reg)) {\r\n const serial = id._id.split(\".\")[4];\r\n if (!deviceSerials.includes(serial)) {\r\n this.delObjectAsync(id._id, { recursive: true });\r\n }\r\n }\r\n });\r\n } catch (error) {\r\n this.log.error(`Delete obsolete devices ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete properties\r\n try {\r\n const all = await this.getStatesAsync(\"*\");\r\n if (all) {\r\n Object.keys(all).forEach(async (stateid) => {\r\n const object = await this.getObjectAsync(stateid);\r\n if (object?.native?.name !== undefined) {\r\n const tmp = stateid.split(\".\");\r\n if (tmp.length >= 5) {\r\n const stationSerial = tmp[2];\r\n const deviceSerial = tmp[4];\r\n\r\n if (deviceSerial.match(/^[A-Z0-9]+/)) {\r\n // Device\r\n try {\r\n const device = await this.eufy.getDevice(deviceSerial);\r\n if (!device.hasProperty(object.native.name)) {\r\n this.delObjectAsync(stateid);\r\n }\r\n } catch (error) {\r\n if (error instanceof DeviceNotFoundError) {\r\n } else {\r\n this.log.error(`Delete obsolete properties ERROR - device - ${JSON.stringify(error)}`);\r\n }\r\n }\r\n } else {\r\n // Station\r\n try {\r\n const station = await this.eufy.getStation(stationSerial);\r\n if (!station.hasProperty(object.native.name)) {\r\n this.delObjectAsync(stateid);\r\n }\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n } else {\r\n this.log.error(`Delete obsolete properties ERROR - station - ${JSON.stringify(error)}`);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete properties ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete directories/files\r\n new Promise(async (resolve, reject) => {\r\n try {\r\n const dir_path = path.join(utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter));\r\n if (fse.existsSync(dir_path)) {\r\n for (const content of fse.readdirSync(dir_path).filter(fn => fn.match(\"^T[0-9A-Z]+$\") !== null)) {\r\n if (!stationSerials.includes(content)) {\r\n fse.removeSync(path.join(dir_path, content));\r\n } else {\r\n for (const dir of fse.readdirSync(path.join(dir_path, content))) {\r\n if (dir === DataLocation.LIVESTREAM || dir === DataLocation.LAST_LIVESTREAM || dir === DataLocation.TEMP) {\r\n fse.removeSync(path.join(dir_path, content, dir));\r\n } else {\r\n const files = fse.readdirSync(path.join(dir_path, content, dir));\r\n let deletedFiles = 0;\r\n for (const file of files) {\r\n if (!deviceSerials.includes(file.substring(0, 16))) {\r\n fse.removeSync(path.join(dir_path, content, dir, file));\r\n deletedFiles++;\r\n }\r\n }\r\n if (deletedFiles === files.length) {\r\n fse.removeSync(path.join(dir_path, content, dir));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n resolve();\r\n } catch (error) {\r\n reject(error);\r\n }\r\n }).catch(error => {\r\n this.log.error(`Delete obsolete directories/files ERROR - ${JSON.stringify(error)}`);\r\n });\r\n }\r\n\r\n private async onClose(): Promise {\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true }).catch();\r\n }\r\n\r\n public getPersistentData(): PersistentData {\r\n return this.persistentData;\r\n }\r\n\r\n private async onPushConnect(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: true, ack: true });\r\n }\r\n\r\n private async onPushClose(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: false, ack: true });\r\n }\r\n\r\n private async onMQTTConnect(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: true, ack: true });\r\n }\r\n\r\n private async onMQTTClose(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: false, ack: true });\r\n }\r\n\r\n private async onStationCommandResult(station: Station, result: CommandResult): Promise {\r\n if (result.return_code !== 0 && result.command_type === CommandType.CMD_START_REALTIME_MEDIA) {\r\n this.logger.debug(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${ErrorCode[result.return_code]} (${result.return_code}) fallback to RTMP livestream...`);\r\n try {\r\n const device = await this.eufy.getStationDevice(station.getSerial(), result.channel);\r\n if (device.isCamera())\r\n this.eufy.startCloudLivestream(device.getSerial());\r\n } catch (error) {\r\n this.logger.error(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} RTMP fallback failed - Error ${error}`);\r\n }\r\n } else if (result.return_code !== 0 && result.command_type !== CommandType.P2P_QUERY_STATUS_IN_LOCK) {\r\n this.logger.error(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${ErrorCode[result.return_code]} (${result.return_code})`);\r\n }\r\n }\r\n\r\n private async onStationPropertyChanged(station: Station, name: string, value: PropertyValue): Promise {\r\n const states = await this.getStatesAsync(`${station.getStateID(\"\", 1)}.*`);\r\n for (const state in states) {\r\n const obj = await this.getObjectAsync(state);\r\n if (obj) {\r\n if (obj.native.name !== undefined && obj.native.name === name) {\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, state, (obj.common.type === \"string\" || obj.common.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n return;\r\n }\r\n }\r\n }\r\n this.logger.debug(`onStationPropertyChanged(): Property \"${name}\" not implemented in this adapter (station: ${station.getSerial()} value: ${JSON.stringify(value)})`);\r\n }\r\n\r\n private async onDevicePropertyChanged(device: Device, name: string, value: PropertyValue): Promise {\r\n const states = await this.getStatesAsync(`${device.getStateID(\"\", 1)}.*`);\r\n for (const state in states) {\r\n const obj = await this.getObjectAsync(state);\r\n if (obj) {\r\n if (obj.native.name !== undefined && obj.native.name === name) {\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, state, (obj.common.type === \"string\" || obj.common.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n switch(name) {\r\n case PropertyName.DeviceRTSPStream:\r\n if (value as boolean === false) {\r\n this.delStateAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL));\r\n }\r\n break;\r\n }\r\n return;\r\n }\r\n }\r\n }\r\n if (name === PropertyName.DevicePicture) {\r\n try {\r\n const picture = value as Picture;\r\n const fileName = `${device.getSerial()}.${picture.type.ext}`;\r\n const filePath = path.join(utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter), device.getStationSerial(), DataLocation.LAST_EVENT);\r\n\r\n if (!fse.existsSync(filePath)) {\r\n fse.mkdirSync(filePath, {mode: 0o775, recursive: true});\r\n }\r\n\r\n await fse.writeFile(path.join(filePath, fileName), picture.data);\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.PICTURE_URL), `/${this.namespace}/${device.getStationSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}.${picture.type.ext}`);\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.PICTURE_HTML), getImageAsHTML(picture.data, picture.type.mime));\r\n } catch (err) {\r\n const error = ensureError(err);\r\n this.logger.error(\"onDevicePropertyChanged - Property picture - Error\", error);\r\n }\r\n } else {\r\n this.logger.debug(`onDevicePropertyChanged(): Property \"${name}\" not implemented in this adapter (device: ${device.getSerial()} value: ${JSON.stringify(value)})`);\r\n }\r\n }\r\n\r\n private async startLivestream(device_sn: string): Promise {\r\n try {\r\n const device = await this.eufy.getDevice(device_sn);\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n\r\n if (station.isConnected() || station.isEnergySavingDevice()) {\r\n if (!station.isLiveStreaming(device)) {\r\n this.eufy.startStationLivestream(device_sn);\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be started, because it is already streaming!`);\r\n }\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be started, because there is no connection to station ${station.getSerial()}!`);\r\n }\r\n } catch (error) {\r\n this.logger.error(\"Start livestream - Error\", error);\r\n }\r\n }\r\n\r\n private async stopLivestream(device_sn: string): Promise {\r\n try {\r\n const device = await this.eufy.getDevice(device_sn);\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n if (device.isCamera()) {\r\n const camera = device as Camera;\r\n if (await this.eufy.isStationConnected(device.getStationSerial()) && station.isLiveStreaming(camera)) {\r\n await this.eufy.stopStationLivestream(device_sn);\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be stopped, because it isn't streaming!`);\r\n }\r\n }\r\n\r\n } catch (error) {\r\n this.logger.error(\"Stop livestream - Error\", error);\r\n }\r\n }\r\n\r\n private async onStationLivestreamStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise {\r\n try {\r\n this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM), { val: `${this.config.https ? \"https\" : \"http\"}://${this.config.hostname}:${this.config.go2rtc_api_port}/stream.html?src=${device.getSerial()}`, ack: true });\r\n this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), { val: `rtsp://${this.config.hostname}:${this.config.go2rtc_rtsp_port}/${device.getSerial()}`, ack: true });\r\n await ffmpegStreamToGo2rtc(this.config, this.namespace, device.getSerial(), metadata, videostream, audiostream, this.logger)\r\n .catch(async (error) => {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Stopping livestream...`, error);\r\n await this.eufy.stopStationLivestream(device.getSerial());\r\n });\r\n } catch(error) {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Stopping livestream...`, error);\r\n await this.eufy.stopStationLivestream(device.getSerial());\r\n }\r\n }\r\n\r\n private onStationLivestreamStop(_station: Station, device: Device): void {\r\n this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM));\r\n this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP));\r\n }\r\n\r\n /*private async onStationDownloadFinish(_station: Station, _device: Device): Promise {\r\n //this.logger.trace(`Station: ${station.getSerial()} channel: ${channel}`);\r\n }*/\r\n\r\n /*private async onStationDownloadStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise {\r\n try {\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n await removeFiles(this, station.getSerial(), DataLocation.TEMP, device.getSerial()).catch();\r\n const file_path = getDataFilePath(this, station.getSerial(), DataLocation.TEMP, `${device.getSerial()}${STREAM_FILE_NAME_EXT}`);\r\n\r\n await ffmpegStreamToHls(this.config, this.namespace, metadata, videostream, audiostream, file_path, this.logger)\r\n .then(async () => {\r\n if (fse.pathExistsSync(file_path)) {\r\n await removeFiles(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\r\n return true;\r\n }\r\n return false;\r\n })\r\n .then(async (result) => {\r\n if (result)\r\n await moveFiles(this, station.getSerial(), device.getSerial(), DataLocation.TEMP, DataLocation.LAST_EVENT);\r\n return result;\r\n })\r\n .then(async (result) => {\r\n if (result) {\r\n const filename_without_ext = getDataFilePath(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), \"Last captured video URL\", `/${this.namespace}/${station.getSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}${STREAM_FILE_NAME_EXT}`, \"url\");\r\n if (fse.pathExistsSync(`${filename_without_ext}${STREAM_FILE_NAME_EXT}`))\r\n await ffmpegPreviewImage(this.config, `${filename_without_ext}${STREAM_FILE_NAME_EXT}`, `${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`, this.logger)\r\n .then(() => {\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), \"Last event picture URL\", `/${this.namespace}/${station.getSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}${IMAGE_FILE_JPEG_EXT}`, \"url\");\r\n try {\r\n if (fse.existsSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`)) {\r\n const image_data = getImageAsHTML(fse.readFileSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`));\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), \"Last event picture HTML image\", image_data, \"html\");\r\n }\r\n } catch (error) {\r\n this.logger.error(`Station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\r\n }\r\n })\r\n .catch((error) => {\r\n this.logger.error(`ffmpegPreviewImage - station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\r\n });\r\n }\r\n })\r\n .catch(async (error) => {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\r\n await this.eufy.cancelStationDownload(device.getSerial());\r\n });\r\n } catch(error) {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\r\n await this.eufy.cancelStationDownload(device.getSerial());\r\n }\r\n }*/\r\n\r\n private onStationRTSPUrl(station: Station, device: Device, value: string): void {\r\n setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.RTSP_STREAM_URL), value);\r\n }\r\n\r\n private async onStationConnect(station: Station): Promise {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: true, ack: true });\r\n }\r\n\r\n private async onStationClose(station: Station): Promise {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\r\n }\r\n\r\n private onTFARequest(): void {\r\n this.logger.warn(`Two factor authentication request received, please enter valid verification code in state ${this.namespace}.verify_code`);\r\n this.verify_code= true;\r\n }\r\n\r\n private onCaptchaRequest(captchaId: string, captcha: string): void {\r\n this.captchaId = captchaId;\r\n this.logger.warn(`Captcha authentication request received, please enter valid captcha in state ${this.namespace}.captcha`);\r\n this.logger.warn(`Captcha: `);\r\n this.setStateAsync(\"received_captcha_html\", { val: ``, ack: true });\r\n }\r\n\r\n}\r\n\r\nif (require.main !== module) {\r\n // Export the constructor in compact mode\r\n module.exports = (options: Partial | undefined) => new euSec(options);\r\n} else {\r\n // otherwise start the instance directly\r\n (() => new euSec())();\r\n}"], - "mappings": "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", + "sourcesContent": ["/*\r\n * Created with @iobroker/create-adapter v2.5.0\r\n */\r\n\r\n// The adapter-core module gives you access to the core ioBroker functions\r\n// you need to create an adapter\r\nimport * as utils from \"@iobroker/adapter-core\";\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nimport { strict } from \"assert\";\r\nimport * as path from \"path\";\r\nimport { Camera, Device, Station, PushMessage, P2PConnectionType, EufySecurity, EufySecurityConfig, CommandResult, CommandType, ErrorCode, PropertyValue, PropertyName, StreamMetadata, PropertyMetadataNumeric, PropertyMetadataAny, CommandName, PanTiltDirection, DeviceNotFoundError, LoginOptions, Picture, StationNotFoundError, ensureError } from \"eufy-security-client\";\r\nimport { getAlpha2Code as getCountryCode } from \"i18n-iso-countries\"\r\nimport { isValid as isValidLanguageCode } from \"@cospired/i18n-iso-languages\"\r\nimport fse from \"fs-extra\";\r\nimport { Readable } from \"stream\";\r\nimport util from \"util\";\r\nimport childProcess from \"child_process\";\r\nimport pathToGo2rtc from \"go2rtc-static\";\r\nimport os from \"os\";\r\n\r\n//import * as Interface from \"./lib/interfaces\"\r\nimport { DeviceStateID, DataLocation, RoleMapping, StationStateID } from \"./lib/types\";\r\nimport { convertCamelCaseToSnakeCase, getImageAsHTML, handleUpdate, removeFiles, removeLastChar, setStateChangedAsync } from \"./lib/utils\";\r\nimport { PersistentData } from \"./lib/interfaces\";\r\nimport { ioBrokerLogger } from \"./lib/log\";\r\nimport { ffmpegStreamToGo2rtc } from \"./lib/video\";\r\n\r\n// Augment the adapter.config object with the actual types\r\n// TODO: delete this in the next version\r\n/*declare global {\r\n // eslint-disable-next-line @typescript-eslint/no-namespace\r\n namespace ioBroker {\r\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\r\n interface AdapterConfig extends Interface.AdapterConfig{\r\n // Define the shape of your options here (recommended)\r\n // Or use a catch-all approach\r\n //[key: string]: any;\r\n }\r\n }\r\n}*/\r\n\r\nclass euSec extends utils.Adapter {\r\n\r\n private eufy!: EufySecurity;\r\n /*private downloadEvent: {\r\n [index: string]: NodeJS.Timeout;\r\n } = {};*/\r\n\r\n private persistentFile: string;\r\n private logger!: ioBrokerLogger;\r\n private persistentData: PersistentData = {\r\n version: \"\"\r\n };\r\n private captchaId: string | null = null;\r\n private verify_code = false;\r\n\r\n public constructor(options: Partial = {}) {\r\n super({\r\n ...options,\r\n name: \"eusec\",\r\n });\r\n const data_dir = utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter);\r\n this.persistentFile = path.join(data_dir, \"adapter.json\");\r\n\r\n if (!fse.existsSync(data_dir))\r\n fse.mkdirSync(data_dir);\r\n\r\n this.on(\"ready\", this.onReady.bind(this));\r\n this.on(\"stateChange\", this.onStateChange.bind(this));\r\n // this.on(\"objectChange\", this.onObjectChange.bind(this));\r\n // this.on(\"message\", this.onMessage.bind(this));\r\n this.on(\"unload\", this.onUnload.bind(this));\r\n }\r\n\r\n /**\r\n * Is called when databases are connected and adapter received configuration.\r\n */\r\n private async onReady(): Promise {\r\n\r\n this.logger = new ioBrokerLogger(this.log as ioBroker.Logger);\r\n\r\n await this.setObjectNotExistsAsync(\"verify_code\", {\r\n type: \"state\",\r\n common: {\r\n name: \"2FA verification code\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"received_captcha_html\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Received captcha image HTML\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"captcha\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Enter captcha\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Global connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: false, ack: true });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: false, ack: true });\r\n\r\n try {\r\n const connection = await this.getStatesAsync(\"*.connection\");\r\n if (connection)\r\n Object.keys(connection).forEach(async id => {\r\n await this.setStateAsync(id, { val: false, ack: true });\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Reset connection states - Error\", error);\r\n }\r\n\r\n try {\r\n const sensorList = [\r\n PropertyName.DeviceMotionDetected,\r\n PropertyName.DevicePersonDetected,\r\n PropertyName.DeviceSoundDetected,\r\n PropertyName.DeviceCryingDetected,\r\n PropertyName.DevicePetDetected,\r\n PropertyName.DeviceRinging\r\n ];\r\n for(const sensorName of sensorList) {\r\n const sensors = await this.getStatesAsync(`*.${convertCamelCaseToSnakeCase(sensorName)}`);\r\n if (sensors)\r\n Object.keys(sensors).forEach(async id => {\r\n await this.setStateAsync(id, { val: false, ack: true });\r\n });\r\n }\r\n } catch (error) {\r\n this.logger.error(\"Reset sensor states - Error\", error);\r\n }\r\n\r\n try {\r\n if (fse.statSync(this.persistentFile).isFile()) {\r\n const fileContent = fse.readFileSync(this.persistentFile, \"utf8\");\r\n this.persistentData = JSON.parse(fileContent) as PersistentData;\r\n }\r\n } catch (error) {\r\n this.logger.debug(\"No stored data from last exit found.\", error);\r\n }\r\n\r\n this.subscribeStates(\"verify_code\");\r\n this.subscribeStates(\"captcha\");\r\n\r\n const systemConfig = await this.getForeignObjectAsync(\"system.config\");\r\n let countryCode = undefined;\r\n let languageCode = undefined;\r\n if (systemConfig) {\r\n countryCode = getCountryCode(systemConfig.common.country, \"en\");\r\n if (isValidLanguageCode(systemConfig.common.language))\r\n languageCode = systemConfig.common.language;\r\n }\r\n\r\n if (this.config.hostname === \"\") {\r\n this.config.hostname = os.hostname();\r\n }\r\n\r\n // Handling adapter version update\r\n try {\r\n if (this.persistentData.version !== this.version) {\r\n const currentVersion = Number.parseFloat(removeLastChar(this.version!, \".\"));\r\n const previousVersion = this.persistentData.version !== \"\" && this.persistentData.version !== undefined ? Number.parseFloat(removeLastChar(this.persistentData.version, \".\")) : 0;\r\n this.logger.debug(`Handling of adapter update - currentVersion: ${currentVersion} previousVersion: ${previousVersion}`);\r\n\r\n if (previousVersion < currentVersion) {\r\n await handleUpdate(this as unknown as ioBroker.Adapter, this.logger, previousVersion);\r\n this.persistentData.version = this.version!;\r\n this.writePersistentData();\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`Handling of adapter update - Error:`, error);\r\n }\r\n\r\n let connectionType = P2PConnectionType.QUICKEST;\r\n if (this.config.p2pConnectionType === \"only_local\") {\r\n connectionType = P2PConnectionType.ONLY_LOCAL;\r\n }\r\n\r\n const config: EufySecurityConfig = {\r\n username: this.config.username,\r\n password: this.config.password,\r\n country: countryCode,\r\n language: languageCode,\r\n persistentDir: utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter),\r\n eventDurationSeconds: this.config.eventDuration,\r\n p2pConnectionSetup: connectionType,\r\n pollingIntervalMinutes: this.config.pollingInterval,\r\n acceptInvitations: this.config.acceptInvitations,\r\n };\r\n\r\n this.eufy = await EufySecurity.initialize(config, this.logger);\r\n this.eufy.on(\"station added\", (station: Station) => this.onStationAdded(station));\r\n this.eufy.on(\"device added\", (device: Device) => this.onDeviceAdded(device));\r\n this.eufy.on(\"station removed\", (station: Station) => this.onStationRemoved(station));\r\n this.eufy.on(\"device removed\", (device: Device) => this.onDeviceRemoved(device));\r\n this.eufy.on(\"push message\", (messages) => this.handlePushNotification(messages));\r\n this.eufy.on(\"push connect\", () => this.onPushConnect());\r\n this.eufy.on(\"push close\", () => this.onPushClose());\r\n this.eufy.on(\"mqtt connect\", () => this.onMQTTConnect());\r\n this.eufy.on(\"mqtt close\", () => this.onMQTTClose());\r\n this.eufy.on(\"connect\", () => this.onConnect());\r\n this.eufy.on(\"close\", () => this.onClose());\r\n\r\n this.eufy.on(\"device property changed\", (device: Device, name: string, value: PropertyValue) => this.onDevicePropertyChanged(device, name, value));\r\n\r\n this.eufy.on(\"station command result\", (station: Station, result: CommandResult) => this.onStationCommandResult(station, result));\r\n //this.eufy.on(\"station download start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationDownloadStart(station, device, metadata, videostream, audiostream));\r\n //this.eufy.on(\"station download finish\", (station: Station, device: Device) => this.onStationDownloadFinish(station, device));\r\n this.eufy.on(\"station livestream start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationLivestreamStart(station, device, metadata, videostream, audiostream));\r\n this.eufy.on(\"station livestream stop\", (station: Station, device: Device) => this.onStationLivestreamStop(station, device));\r\n this.eufy.on(\"station rtsp url\", (station: Station, device: Device, value: string) => this.onStationRTSPUrl(station, device, value));\r\n this.eufy.on(\"station property changed\", (station: Station, name: string, value: PropertyValue) => this.onStationPropertyChanged(station, name, value));\r\n this.eufy.on(\"station connect\", (station: Station) => this.onStationConnect(station));\r\n this.eufy.on(\"station close\", (station: Station) => this.onStationClose(station));\r\n this.eufy.on(\"tfa request\", () => this.onTFARequest());\r\n this.eufy.on(\"captcha request\", (captchaId: string, captcha: string) => this.onCaptchaRequest(captchaId, captcha));\r\n this.eufy.setCameraMaxLivestreamDuration(this.config.maxLivestreamDuration);\r\n\r\n await this.eufy.connect();\r\n\r\n if (pathToGo2rtc) {\r\n const go2rtcConfig: {\r\n [index: string]: {\r\n [index: string]: string | number | null\r\n }\r\n } = {\r\n \"api\": {\r\n \"listen\": `:${this.config.go2rtc_api_port}`\r\n },\r\n \"rtsp\": {\r\n \"listen\": `:${this.config.go2rtc_rtsp_port}`\r\n },\r\n \"srtp\": {\r\n \"listen\": `:${this.config.go2rtc_srtp_port}`\r\n },\r\n \"webrtc\": {\r\n \"listen\": `:${this.config.go2rtc_webrtc_port}`\r\n },\r\n \"streams\": {}\r\n };\r\n if (this.config.go2rtc_rtsp_username !== \"\" && this.config.go2rtc_rtsp_password !== \"\") {\r\n go2rtcConfig.rtsp.username = this.config.go2rtc_rtsp_username;\r\n go2rtcConfig.rtsp.password = this.config.go2rtc_rtsp_password;\r\n }\r\n for (const device of await this.eufy.getDevices()) {\r\n go2rtcConfig.streams[device.getSerial()] = null;\r\n }\r\n const go2rtc = childProcess.spawn(pathToGo2rtc, [\"-config\", JSON.stringify(go2rtcConfig)], { shell: false, detached: false, windowsHide: true });\r\n go2rtc.on(\"error\", (error) => {\r\n this.log.error(`go2rtc error: ${error}`);\r\n });\r\n go2rtc.stdout.setEncoding(\"utf8\");\r\n go2rtc.stdout.on(\"data\", (data) => {\r\n this.log.info(`go2rtc started: ${data}`);\r\n });\r\n go2rtc.stderr.setEncoding(\"utf8\");\r\n go2rtc.stderr.on(\"data\", (data) => {\r\n this.log.error(`go2rtc error: ${data}`);\r\n });\r\n go2rtc.on(\"close\", (exitcode) => {\r\n this.log.info(`go2rtc terminated with exitcode ${exitcode}`);\r\n });\r\n process.on(\"exit\", () => {\r\n go2rtc.kill();\r\n });\r\n }\r\n }\r\n\r\n public writePersistentData(): void {\r\n try {\r\n fse.writeFileSync(this.persistentFile, JSON.stringify(this.persistentData));\r\n } catch (error) {\r\n this.logger.error(`writePersistentData() - Error: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Is called when adapter shuts down - callback has to be called under any circumstances!\r\n */\r\n private async onUnload(callback: () => void): Promise {\r\n try {\r\n\r\n this.writePersistentData();\r\n\r\n if (this.eufy) {\r\n if (this.eufy.isConnected())\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true }).catch();\r\n this.eufy.removeAllListeners();\r\n this.eufy.close();\r\n }\r\n\r\n callback();\r\n } catch (e) {\r\n callback();\r\n }\r\n }\r\n\r\n // If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.\r\n // You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`.\r\n // /**\r\n // * Is called if a subscribed object changes\r\n // */\r\n // private onObjectChange(id: string, obj: ioBroker.Object | null | undefined): void {\r\n // if (obj) {\r\n // // The object was changed\r\n // this.log.info(`object ${id} changed: ${JSON.stringify(obj)}`);\r\n // } else {\r\n // // The object was deleted\r\n // this.log.info(`object ${id} deleted`);\r\n // }\r\n // }\r\n\r\n /**\r\n * Is called if a subscribed state changes\r\n */\r\n private async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise {\r\n if (state) {\r\n\r\n // don't do anything if the state is acked\r\n if (!id || state.ack) {\r\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack}) was already acknowledged, ignore it...`);\r\n return;\r\n }\r\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);\r\n\r\n const values = id.split(\".\");\r\n const station_sn = values[2];\r\n const device_type = values[3];\r\n\r\n if (station_sn == \"verify_code\") {\r\n if (this.eufy && this.verify_code) {\r\n this.logger.info(`Verification code received, send it. (verify_code: ${state.val})`);\r\n await this.eufy.connect({ verifyCode: state.val as string } as LoginOptions);\r\n this.verify_code = false;\r\n await this.delStateAsync(id);\r\n }\r\n } else if (station_sn == \"captcha\") {\r\n if (this.eufy && this.captchaId) {\r\n this.logger.info(`Captcha received, send it. (captcha: ${state.val})`);\r\n await this.eufy.connect({\r\n captcha: {\r\n captchaCode: state.val as string,\r\n captchaId: this.captchaId\r\n }\r\n } as LoginOptions);\r\n this.captchaId = null;\r\n await this.delStateAsync(id);\r\n await this.delStateAsync(\"received_captcha_html\");\r\n }\r\n } else if (device_type == \"station\") {\r\n try {\r\n const station_state_name = values[4];\r\n if (this.eufy) {\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n if (obj.native.name !== undefined) {\r\n await this.eufy.setStationProperty(station_sn, obj.native.name, state.val);\r\n return;\r\n }\r\n }\r\n\r\n const station = await this.eufy.getStation(station_sn);\r\n switch(station_state_name) {\r\n case StationStateID.REBOOT:\r\n await station.rebootHUB();\r\n break;\r\n case StationStateID.TRIGGER_ALARM_SOUND:\r\n await station.triggerStationAlarmSound(this.config.alarmSoundDuration);\r\n break;\r\n case StationStateID.RESET_ALARM_SOUND:\r\n await station.resetStationAlarmSound();\r\n break;\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`station - Error:`, error);\r\n }\r\n } else {\r\n try {\r\n const device_sn = values[4];\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n if (obj.native.name !== undefined) {\r\n try {\r\n await this.eufy.setDeviceProperty(device_sn, obj.native.name, obj.common.type === \"object\" ? JSON.parse(state.val as string) : state.val);\r\n } catch (error) {\r\n this.logger.error(`Error in setting property value (property: ${obj.native.name} value: ${state.val})`, error);\r\n }\r\n return;\r\n }\r\n }\r\n\r\n const device_state_name = values[5];\r\n const station = await this.eufy.getStation(station_sn);\r\n const device = await this.eufy.getDevice(device_sn);\r\n\r\n switch(device_state_name) {\r\n case DeviceStateID.START_STREAM:\r\n await this.startLivestream(device_sn);\r\n break;\r\n case DeviceStateID.STOP_STREAM:\r\n await this.stopLivestream(device_sn);\r\n break;\r\n case DeviceStateID.TRIGGER_ALARM_SOUND:\r\n await station.triggerDeviceAlarmSound(device, this.config.alarmSoundDuration);\r\n break;\r\n case DeviceStateID.RESET_ALARM_SOUND:\r\n await station.resetDeviceAlarmSound(device);\r\n break;\r\n case DeviceStateID.ROTATE_360:\r\n await station.panAndTilt(device, PanTiltDirection.ROTATE360);\r\n break;\r\n case DeviceStateID.PAN_LEFT:\r\n await station.panAndTilt(device, PanTiltDirection.LEFT);\r\n break;\r\n case DeviceStateID.PAN_RIGHT:\r\n await station.panAndTilt(device, PanTiltDirection.RIGHT);\r\n break;\r\n case DeviceStateID.TILT_UP:\r\n await station.panAndTilt(device, PanTiltDirection.UP);\r\n break;\r\n case DeviceStateID.TILT_DOWN:\r\n await station.panAndTilt(device, PanTiltDirection.DOWN);\r\n break;\r\n case DeviceStateID.CALIBRATE:\r\n if (device.isLock()) {\r\n await station.calibrateLock(device);\r\n } else {\r\n await station.calibrate(device);\r\n }\r\n break;\r\n case DeviceStateID.UNLOCK:\r\n await station.unlock(device);\r\n break;\r\n case DeviceStateID.SET_DEFAULT_ANGLE:\r\n await station.setDefaultAngle(device);\r\n break;\r\n case DeviceStateID.SET_PRIVACY_ANGLE:\r\n await station.setPrivacyAngle(device);\r\n break;\r\n }\r\n } catch (error) {\r\n this.logger.error(`cameras - Error:`, error);\r\n }\r\n }\r\n } else {\r\n // The state was deleted\r\n this.logger.debug(`state ${id} deleted`);\r\n }\r\n }\r\n\r\n // If you need to accept messages in your adapter, uncomment the following block and the corresponding line in the constructor.\r\n // /**\r\n // * Some message was sent to this instance over message box. Used by email, pushover, text2speech, ...\r\n // * Using this method requires \"common.message\" property to be set to true in io-package.json\r\n // */\r\n // private onMessage(obj: ioBroker.Message): void {\r\n // if (typeof obj === \"object\" && obj.message) {\r\n // if (obj.command === \"send\") {\r\n // // e.g. send email or pushover or whatever\r\n // this.log.info(\"send command\");\r\n\r\n // // Send response in callback if required\r\n // if (obj.callback) this.sendTo(obj.from, obj.command, \"Message received\", obj.callback);\r\n // }\r\n // }\r\n // }\r\n\r\n private getStateCommon(property: PropertyMetadataAny): ioBroker.StateCommon {\r\n const state: ioBroker.StateCommon = {\r\n name: property.label!,\r\n type: property.type,\r\n role: \"state\",\r\n read: property.readable,\r\n write: property.writeable,\r\n def: property.default\r\n };\r\n switch (property.type) {\r\n case \"number\": {\r\n const numberProperty = property as PropertyMetadataNumeric;\r\n state.min = numberProperty.min;\r\n state.max = numberProperty.max;\r\n state.states = numberProperty.states;\r\n state.unit = numberProperty.unit;\r\n state.step = numberProperty.steps;\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : \"value\";\r\n break;\r\n }\r\n case \"string\": {\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : \"text\";\r\n break;\r\n }\r\n case \"boolean\": {\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : (property.writeable ? \"switch.enable\" : \"state\");\r\n break;\r\n }\r\n }\r\n return state;\r\n }\r\n\r\n private async createAndSetState(device: Device | Station, property: PropertyMetadataAny): Promise {\r\n if (property.name !== PropertyName.Type && property.name !== PropertyName.DeviceStationSN) {\r\n const state = this.getStateCommon(property);\r\n const id: string = device.getStateID(convertCamelCaseToSnakeCase(property.name));\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n let changed = false;\r\n if (obj.native.name !== undefined && obj.native.name !== property.name) {\r\n obj.native.name = property.name;\r\n changed = true;\r\n }\r\n if (obj.native.key !== undefined && obj.native.key !== property.key) {\r\n obj.native.key = property.key;\r\n changed = true;\r\n }\r\n if (obj.native.commandId !== undefined && obj.native.commandId !== property.commandId) {\r\n obj.native.commandId = property.commandId;\r\n changed = true;\r\n }\r\n if (obj.common !== undefined && !util.isDeepStrictEqual(obj.common, state)) {\r\n changed = true;\r\n }\r\n if (changed) {\r\n const propertyMetadata = device.getPropertiesMetadata()[property.name];\r\n if (propertyMetadata !== undefined) {\r\n const newState = this.getStateCommon(propertyMetadata);\r\n obj.common = newState;\r\n }\r\n await this.setObjectAsync(id, obj);\r\n }\r\n } else {\r\n await this.setObjectNotExistsAsync(id, {\r\n type: \"state\",\r\n common: state,\r\n native: {\r\n key: property.key,\r\n commandId: property.commandId,\r\n name: property.name,\r\n },\r\n });\r\n }\r\n const value = device.getPropertyValue(property.name);\r\n if (value !== undefined)\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, id, (property.type === \"string\" || property.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n }\r\n }\r\n\r\n private async onDeviceAdded(device: Device): Promise {\r\n this.logger.debug(`onDeviceAdded - device: ${device.getSerial()}`);\r\n\r\n await this.setObjectNotExistsAsync(device.getStateID(\"\", 0), {\r\n type: \"channel\",\r\n common: {\r\n name: device.getStateChannel()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(device.getStateID(\"\", 1), {\r\n type: \"device\",\r\n common: {\r\n name: device.getName()\r\n },\r\n native: {},\r\n });\r\n\r\n const metadata = device.getPropertiesMetadata();\r\n for(const property of Object.values(metadata)) {\r\n if (property.name !== PropertyName.DevicePicture)\r\n this.createAndSetState(device, property);\r\n }\r\n\r\n if (device.hasProperty(PropertyName.DevicePicture)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Picture URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_HTML), {\r\n type: \"state\",\r\n common: {\r\n name: \"Picture HTML image\",\r\n type: \"string\",\r\n role: \"html\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n if (device.hasCommand(CommandName.DeviceTriggerAlarmSound)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TRIGGER_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Trigger Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RESET_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reset Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DevicePanAndTilt)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_LEFT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Pan Left\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_RIGHT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Pan Right\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.ROTATE_360), {\r\n type: \"state\",\r\n common: {\r\n name: \"Rotate 360\u00B0\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_UP), {\r\n type: \"state\",\r\n common: {\r\n name: \"Tilt Up\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_DOWN), {\r\n type: \"state\",\r\n common: {\r\n name: \"Tilt Down\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceLockCalibration)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Calibrate Lock\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceUnlock)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.UNLOCK), {\r\n type: \"state\",\r\n common: {\r\n name: \"Unlock\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceSetDefaultAngle)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_DEFAULT_ANGLE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Set Default Angle\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceSetPrivacyAngle)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_PRIVACY_ANGLE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Set Default Angle\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceCalibrate)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Calibrate\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceStartLivestream)) {\r\n // Start Stream\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.START_STREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Start stream\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n\r\n // Stop Stream\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.STOP_STREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Stop stream\",\r\n type: \"boolean\",\r\n role: \"button.stop\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n\r\n // Livestream URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Livestream URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n\r\n // Livestream RTSP URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), {\r\n type: \"state\",\r\n common: {\r\n name: \"Livestream RTSP URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n if (device.hasProperty(PropertyName.DeviceRTSPStream)) {\r\n // RTSP Stream URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"RTSP stream URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n /*if (device.hasCommand(CommandName.DeviceStartDownload)) {\r\n // Last event video URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event video URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n\r\n // Last event picture URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event picture URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n\r\n // Last event picture HTML image\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event picture HTML image\",\r\n type: \"string\",\r\n role: \"html\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n }*/\r\n }\r\n\r\n private async onDeviceRemoved(device: Device): Promise {\r\n this.delObjectAsync(device.getStateID(\"\", 0), { recursive: true }).catch((error) => {\r\n this.logger.error(`Error deleting states of removed device`, error);\r\n });\r\n removeFiles(this as unknown as ioBroker.Adapter, device.getStationSerial(), DataLocation.LAST_EVENT, device.getSerial()).catch((error) => {\r\n this.logger.error(`Error deleting fs contents of removed device`, error);\r\n });\r\n }\r\n\r\n private async onStationAdded(station: Station): Promise {\r\n this.subscribeStates(`${station.getStateID(\"\", 0)}.*`);\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(\"\", 0), {\r\n type: \"device\",\r\n common: {\r\n name: station.getName()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(\"\", 1), {\r\n type: \"channel\",\r\n common: {\r\n name: station.getStateChannel()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\r\n\r\n const metadata = station.getPropertiesMetadata();\r\n for(const property of Object.values(metadata)) {\r\n this.createAndSetState(station, property);\r\n }\r\n\r\n // Reboot station\r\n if (station.hasCommand(CommandName.StationReboot)) {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.REBOOT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reboot station\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n // Alarm Sound\r\n if (station.hasCommand(CommandName.StationTriggerAlarmSound)) {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.TRIGGER_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Trigger Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.RESET_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reset Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n }\r\n\r\n private async onStationRemoved(station: Station): Promise {\r\n this.delObjectAsync(station.getStateID(\"\", 0), { recursive: true }).catch((error) => {\r\n this.logger.error(`Error deleting states of removed station`, error);\r\n });\r\n fse.remove(path.join(utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter), station.getSerial())).catch((error) => {\r\n this.logger.error(`Error deleting fs contents of removed station`, error);\r\n });\r\n }\r\n\r\n /*private async downloadEventVideo(device: Device, event_time: number, full_path: string | undefined, cipher_id: number | undefined): Promise {\r\n this.logger.debug(`Device: ${device.getSerial()} full_path: ${full_path} cipher_id: ${cipher_id}`);\r\n try {\r\n if (!isEmpty(full_path) && cipher_id !== undefined) {\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n\r\n if (station !== undefined) {\r\n if (this.downloadEvent[device.getSerial()])\r\n clearTimeout(this.downloadEvent[device.getSerial()]);\r\n\r\n let videoLength = getVideoClipLength(device);\r\n const time_passed = (new Date().getTime() - new Date(event_time).getTime()) / 1000;\r\n\r\n if (time_passed >= videoLength)\r\n videoLength = 1;\r\n else\r\n videoLength = videoLength - time_passed;\r\n\r\n this.logger.info(`Downloading video event for device ${device.getSerial()} in ${videoLength} seconds...`);\r\n this.downloadEvent[device.getSerial()] = setTimeout(async () => {\r\n station.startDownload(device, full_path!, cipher_id);\r\n }, videoLength * 1000);\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`Device: ${device.getSerial()} - Error`, error);\r\n }\r\n }*/\r\n\r\n private async handlePushNotification(message: PushMessage): Promise {\r\n try {\r\n if (message.device_sn !== undefined) {\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n /*const device: Device = await this.eufy.getDevice(message.device_sn);\r\n if ((message.push_count === 1 || message.push_count === undefined) && (message.file_path !== undefined && message.file_path !== \"\" && message.cipher !== undefined))\r\n if (this.config.autoDownloadVideo)\r\n await this.downloadEventVideo(device, message.event_time, message.file_path, message.cipher);*/\r\n }\r\n } catch (error) {\r\n if (error instanceof DeviceNotFoundError) {\r\n //Do nothing\r\n } else {\r\n this.logger.error(\"Handling push notification - Error\", error);\r\n }\r\n }\r\n }\r\n\r\n private async onConnect(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Global connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.connection\", { val: true, ack: true });\r\n\r\n const stations = await this.eufy.getStations();\r\n const stationSerials: string[] = [];\r\n for(const station of stations) {\r\n stationSerials.push(station.getSerial());\r\n }\r\n const devices = await this.eufy.getDevices();\r\n const deviceSerials: string[] = [];\r\n for(const device of devices) {\r\n deviceSerials.push(device.getSerial());\r\n }\r\n\r\n // Delete obsolete stations\r\n try {\r\n const allDevices = await this.getDevicesAsync();\r\n const reg = new RegExp(`^${this.namespace}\\.[0-9A-Z]+$`);\r\n for (const id of allDevices) {\r\n if (id._id.match(reg)) {\r\n const serial = id._id.replace(`${this.namespace}.`, \"\");\r\n if (!stationSerials.includes(serial)) {\r\n await this.delObjectAsync(id._id, { recursive: true });\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete stations ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete devices\r\n try {\r\n const allDevices = await this.getDevicesAsync();\r\n const reg = new RegExp(`^${this.namespace}\\.[0-9A-Z]+\\.[a-z]+\\.[0-9A-Z]+$`);\r\n for (const id of allDevices) {\r\n if (id._id.match(reg)) {\r\n const serial = id._id.split(\".\")[4];\r\n if (!deviceSerials.includes(serial)) {\r\n await this.delObjectAsync(id._id, { recursive: true });\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete devices ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete properties\r\n try {\r\n const all = await this.getStatesAsync(\"*\");\r\n if (all) {\r\n Object.keys(all).forEach(async (stateid) => {\r\n const object = await this.getObjectAsync(stateid);\r\n if (object?.native?.name !== undefined) {\r\n const tmp = stateid.split(\".\");\r\n if (tmp.length >= 5) {\r\n const stationSerial = tmp[2];\r\n const deviceSerial = tmp[4];\r\n\r\n if (deviceSerial.match(/^[A-Z0-9]+/)) {\r\n // Device\r\n try {\r\n const device = await this.eufy.getDevice(deviceSerial);\r\n if (!device.hasProperty(object.native.name)) {\r\n this.delObjectAsync(stateid);\r\n }\r\n } catch (error) {\r\n if (error instanceof DeviceNotFoundError) {\r\n } else {\r\n this.log.error(`Delete obsolete properties ERROR - device - ${JSON.stringify(error)}`);\r\n }\r\n }\r\n } else {\r\n // Station\r\n try {\r\n const station = await this.eufy.getStation(stationSerial);\r\n if (!station.hasProperty(object.native.name)) {\r\n this.delObjectAsync(stateid);\r\n }\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n } else {\r\n this.log.error(`Delete obsolete properties ERROR - station - ${JSON.stringify(error)}`);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete properties ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete directories/files\r\n new Promise(async (resolve, reject) => {\r\n try {\r\n const dir_path = path.join(utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter));\r\n if (fse.existsSync(dir_path)) {\r\n for (const content of fse.readdirSync(dir_path).filter(fn => fn.match(\"^T[0-9A-Z]+$\") !== null)) {\r\n if (!stationSerials.includes(content)) {\r\n fse.removeSync(path.join(dir_path, content));\r\n } else {\r\n for (const dir of fse.readdirSync(path.join(dir_path, content))) {\r\n if (dir === DataLocation.LIVESTREAM || dir === DataLocation.LAST_LIVESTREAM || dir === DataLocation.TEMP) {\r\n fse.removeSync(path.join(dir_path, content, dir));\r\n } else {\r\n const files = fse.readdirSync(path.join(dir_path, content, dir));\r\n let deletedFiles = 0;\r\n for (const file of files) {\r\n if (!deviceSerials.includes(file.substring(0, 16))) {\r\n fse.removeSync(path.join(dir_path, content, dir, file));\r\n deletedFiles++;\r\n }\r\n }\r\n if (deletedFiles === files.length) {\r\n fse.removeSync(path.join(dir_path, content, dir));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n resolve();\r\n } catch (error) {\r\n reject(error);\r\n }\r\n }).catch(error => {\r\n this.log.error(`Delete obsolete directories/files ERROR - ${JSON.stringify(error)}`);\r\n });\r\n }\r\n\r\n private async onClose(): Promise {\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true }).catch();\r\n }\r\n\r\n public getPersistentData(): PersistentData {\r\n return this.persistentData;\r\n }\r\n\r\n private async onPushConnect(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: true, ack: true });\r\n }\r\n\r\n private async onPushClose(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: false, ack: true });\r\n }\r\n\r\n private async onMQTTConnect(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: true, ack: true });\r\n }\r\n\r\n private async onMQTTClose(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: false, ack: true });\r\n }\r\n\r\n private async onStationCommandResult(station: Station, result: CommandResult): Promise {\r\n if (result.return_code !== 0 && result.command_type === CommandType.CMD_START_REALTIME_MEDIA) {\r\n this.logger.debug(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${ErrorCode[result.return_code]} (${result.return_code}) fallback to RTMP livestream...`);\r\n try {\r\n const device = await this.eufy.getStationDevice(station.getSerial(), result.channel);\r\n if (device.isCamera())\r\n this.eufy.startCloudLivestream(device.getSerial());\r\n } catch (error) {\r\n this.logger.error(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} RTMP fallback failed - Error ${error}`);\r\n }\r\n } else if (result.return_code !== 0 && result.command_type !== CommandType.P2P_QUERY_STATUS_IN_LOCK) {\r\n this.logger.error(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${ErrorCode[result.return_code]} (${result.return_code})`);\r\n }\r\n }\r\n\r\n private async onStationPropertyChanged(station: Station, name: string, value: PropertyValue): Promise {\r\n const states = await this.getStatesAsync(`${station.getStateID(\"\", 1)}.*`);\r\n for (const state in states) {\r\n const obj = await this.getObjectAsync(state);\r\n if (obj) {\r\n if (obj.native.name !== undefined && obj.native.name === name) {\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, state, (obj.common.type === \"string\" || obj.common.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n return;\r\n }\r\n }\r\n }\r\n this.logger.debug(`onStationPropertyChanged(): Property \"${name}\" not implemented in this adapter (station: ${station.getSerial()} value: ${JSON.stringify(value)})`);\r\n }\r\n\r\n private async onDevicePropertyChanged(device: Device, name: string, value: PropertyValue): Promise {\r\n const states = await this.getStatesAsync(`${device.getStateID(\"\", 1)}.*`);\r\n for (const state in states) {\r\n const obj = await this.getObjectAsync(state);\r\n if (obj) {\r\n if (obj.native.name !== undefined && obj.native.name === name) {\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, state, (obj.common.type === \"string\" || obj.common.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n switch(name) {\r\n case PropertyName.DeviceRTSPStream:\r\n if (value as boolean === false) {\r\n this.delStateAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL));\r\n }\r\n break;\r\n }\r\n return;\r\n }\r\n }\r\n }\r\n if (name === PropertyName.DevicePicture) {\r\n try {\r\n const picture = value as Picture;\r\n const fileName = `${device.getSerial()}.${picture.type.ext}`;\r\n const filePath = path.join(utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter), device.getStationSerial(), DataLocation.LAST_EVENT);\r\n\r\n if (!fse.existsSync(filePath)) {\r\n fse.mkdirSync(filePath, {mode: 0o775, recursive: true});\r\n }\r\n\r\n await fse.writeFile(path.join(filePath, fileName), picture.data);\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.PICTURE_URL), `/${this.namespace}/${device.getStationSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}.${picture.type.ext}`);\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.PICTURE_HTML), getImageAsHTML(picture.data, picture.type.mime));\r\n } catch (err) {\r\n const error = ensureError(err);\r\n this.logger.error(\"onDevicePropertyChanged - Property picture - Error\", error);\r\n }\r\n } else {\r\n this.logger.debug(`onDevicePropertyChanged(): Property \"${name}\" not implemented in this adapter (device: ${device.getSerial()} value: ${JSON.stringify(value)})`);\r\n }\r\n }\r\n\r\n private async startLivestream(device_sn: string): Promise {\r\n try {\r\n const device = await this.eufy.getDevice(device_sn);\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n\r\n if (station.isConnected() || station.isEnergySavingDevice()) {\r\n if (!station.isLiveStreaming(device)) {\r\n this.eufy.startStationLivestream(device_sn);\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be started, because it is already streaming!`);\r\n }\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be started, because there is no connection to station ${station.getSerial()}!`);\r\n }\r\n } catch (error) {\r\n this.logger.error(\"Start livestream - Error\", error);\r\n }\r\n }\r\n\r\n private async stopLivestream(device_sn: string): Promise {\r\n try {\r\n const device = await this.eufy.getDevice(device_sn);\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n if (device.isCamera()) {\r\n const camera = device as Camera;\r\n if (await this.eufy.isStationConnected(device.getStationSerial()) && station.isLiveStreaming(camera)) {\r\n await this.eufy.stopStationLivestream(device_sn);\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be stopped, because it isn't streaming!`);\r\n }\r\n }\r\n\r\n } catch (error) {\r\n this.logger.error(\"Stop livestream - Error\", error);\r\n }\r\n }\r\n\r\n private async onStationLivestreamStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise {\r\n try {\r\n this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM), { val: `${this.config.https ? \"https\" : \"http\"}://${this.config.hostname}:${this.config.go2rtc_api_port}/stream.html?src=${device.getSerial()}`, ack: true });\r\n this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), { val: `rtsp://${this.config.hostname}:${this.config.go2rtc_rtsp_port}/${device.getSerial()}`, ack: true });\r\n await ffmpegStreamToGo2rtc(this.config, this.namespace, device.getSerial(), metadata, videostream, audiostream, this.logger)\r\n .catch(async (error) => {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Stopping livestream...`, error);\r\n await this.eufy.stopStationLivestream(device.getSerial());\r\n });\r\n } catch(error) {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Stopping livestream...`, error);\r\n await this.eufy.stopStationLivestream(device.getSerial());\r\n }\r\n }\r\n\r\n private onStationLivestreamStop(_station: Station, device: Device): void {\r\n this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM));\r\n this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP));\r\n }\r\n\r\n /*private async onStationDownloadFinish(_station: Station, _device: Device): Promise {\r\n //this.logger.trace(`Station: ${station.getSerial()} channel: ${channel}`);\r\n }*/\r\n\r\n /*private async onStationDownloadStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise {\r\n try {\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n await removeFiles(this, station.getSerial(), DataLocation.TEMP, device.getSerial()).catch();\r\n const file_path = getDataFilePath(this, station.getSerial(), DataLocation.TEMP, `${device.getSerial()}${STREAM_FILE_NAME_EXT}`);\r\n\r\n await ffmpegStreamToHls(this.config, this.namespace, metadata, videostream, audiostream, file_path, this.logger)\r\n .then(async () => {\r\n if (fse.pathExistsSync(file_path)) {\r\n await removeFiles(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\r\n return true;\r\n }\r\n return false;\r\n })\r\n .then(async (result) => {\r\n if (result)\r\n await moveFiles(this, station.getSerial(), device.getSerial(), DataLocation.TEMP, DataLocation.LAST_EVENT);\r\n return result;\r\n })\r\n .then(async (result) => {\r\n if (result) {\r\n const filename_without_ext = getDataFilePath(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), \"Last captured video URL\", `/${this.namespace}/${station.getSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}${STREAM_FILE_NAME_EXT}`, \"url\");\r\n if (fse.pathExistsSync(`${filename_without_ext}${STREAM_FILE_NAME_EXT}`))\r\n await ffmpegPreviewImage(this.config, `${filename_without_ext}${STREAM_FILE_NAME_EXT}`, `${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`, this.logger)\r\n .then(() => {\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), \"Last event picture URL\", `/${this.namespace}/${station.getSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}${IMAGE_FILE_JPEG_EXT}`, \"url\");\r\n try {\r\n if (fse.existsSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`)) {\r\n const image_data = getImageAsHTML(fse.readFileSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`));\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), \"Last event picture HTML image\", image_data, \"html\");\r\n }\r\n } catch (error) {\r\n this.logger.error(`Station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\r\n }\r\n })\r\n .catch((error) => {\r\n this.logger.error(`ffmpegPreviewImage - station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\r\n });\r\n }\r\n })\r\n .catch(async (error) => {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\r\n await this.eufy.cancelStationDownload(device.getSerial());\r\n });\r\n } catch(error) {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\r\n await this.eufy.cancelStationDownload(device.getSerial());\r\n }\r\n }*/\r\n\r\n private onStationRTSPUrl(station: Station, device: Device, value: string): void {\r\n setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.RTSP_STREAM_URL), value);\r\n }\r\n\r\n private async onStationConnect(station: Station): Promise {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: true, ack: true });\r\n }\r\n\r\n private async onStationClose(station: Station): Promise {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\r\n }\r\n\r\n private onTFARequest(): void {\r\n this.logger.warn(`Two factor authentication request received, please enter valid verification code in state ${this.namespace}.verify_code`);\r\n this.verify_code= true;\r\n }\r\n\r\n private onCaptchaRequest(captchaId: string, captcha: string): void {\r\n this.captchaId = captchaId;\r\n this.logger.warn(`Captcha authentication request received, please enter valid captcha in state ${this.namespace}.captcha`);\r\n this.logger.warn(`Captcha: `);\r\n this.setStateAsync(\"received_captcha_html\", { val: ``, ack: true });\r\n }\r\n\r\n}\r\n\r\nif (require.main !== module) {\r\n // Export the constructor in compact mode\r\n module.exports = (options: Partial | undefined) => new euSec(options);\r\n} else {\r\n // otherwise start the instance directly\r\n (() => new euSec())();\r\n}"], + "mappings": "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", "names": ["fse", "getCountryCode", "isValidLanguageCode", "os", "pathToGo2rtc", "childProcess", "util"] } diff --git a/docs/_coverpage.md b/docs/_coverpage.md index 97731b1..1dbe75e 100644 --- a/docs/_coverpage.md +++ b/docs/_coverpage.md @@ -1,6 +1,6 @@ ![logo](_media/ioBroker.euSec.png) -# ioBroker.euSec 1.1.1 +# ioBroker.euSec 1.1.2 > An [ioBroker](https://www.iobroker.net) adapter that uses the [eufy-security-client](https://github.com/bropat/eufy-security-client) library to comunicate with Eufy devices diff --git a/io-package.json b/io-package.json index 33627fa..ae3ad69 100644 --- a/io-package.json +++ b/io-package.json @@ -1,8 +1,21 @@ { "common": { "name": "eusec", - "version": "1.1.1", + "version": "1.1.2", "news": { + "1.1.2": { + "en": "Updated version of the package eufy-security-client (2.8.1)\n", + "uk": "Updated version of the package eufy-security-client (2.8.1)\n", + "de": "Version des Pakets eufy-security-client (2.8.1) aktualisiert\n", + "ru": "Обновленная версия пакета eufy-security-client (2.8.1)\n", + "pt": "Versão atualizada do pacote eufy-security-client (2.8.1)\n", + "nl": "Bijgewerkte versie van het pakket eufy-security-client (2.8.1)\n", + "fr": "Version mise à jour du paquet eufy-security-client (2.8.1)\n", + "it": "Aggiornata la versione del pacchetto eufy-security-client (2.8.1)\n", + "es": "Versión actualizada del paquete eufy-security-client (2.8.1)\n", + "pl": "Zaktualizowana wersja pakietu eufy-security-client (2.8.1)\n", + "zh-cn": "包 eufy-security-client (2.8.1) 的更新版本\n" + }, "1.1.1": { "en": "Fixed issues #365, #363\nUpdated version of the package ffmpeg-static (5.2.0)\nUpdated version of the package eufy-security-client (2.8.0)\n", "uk": "Fixed issues #365, #363\nUpdated version of the package ffmpeg-static (5.2.0)\nUpdated version of the package eufy-security-client (2.8.0)\n", diff --git a/package-lock.json b/package-lock.json index 4a60f11..5e37837 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { "name": "iobroker.eusec", - "version": "1.1.1", + "version": "1.1.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "iobroker.eusec", - "version": "1.1.1", + "version": "1.1.2", "license": "MIT", "dependencies": { "@bropat/fluent-ffmpeg": "^2.1.3", "@cospired/i18n-iso-languages": "^4.1.0", "@iobroker/adapter-core": "^3.0.3", - "eufy-security-client": "^2.8.0", + "eufy-security-client": "^2.8.1", "ffmpeg-static": "^5.2.0", "fs-extra": "^11.1.1", "go2rtc-static": "^1.6.2", @@ -32,15 +32,15 @@ "@types/fs-extra": "^11.0.1", "@types/mime": "^3.0.1", "@types/mocha": "^10.0.1", - "@types/node": "^16.18.41", + "@types/node": "^16.18.46", "@types/proxyquire": "^1.3.28", "@types/sinon": "^10.0.16", "@types/sinon-chai": "^3.2.9", - "@typescript-eslint/eslint-plugin": "^6.4.0", - "@typescript-eslint/parser": "^6.4.0", - "chai": "^4.3.7", + "@typescript-eslint/eslint-plugin": "^6.5.0", + "@typescript-eslint/parser": "^6.5.0", + "chai": "^4.3.8", "chai-as-promised": "^7.1.1", - "eslint": "^8.47.0", + "eslint": "^8.48.0", "mocha": "^10.2.0", "proxyquire": "^2.1.3", "rimraf": "^5.0.1", @@ -48,7 +48,7 @@ "sinon-chai": "^3.7.0", "source-map-support": "^0.5.21", "ts-node": "^10.9.1", - "typescript": "5.1.6" + "typescript": "5.2.2" }, "engines": { "node": ">=16.9.0" @@ -427,9 +427,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -580,32 +580,6 @@ "node": ">=12.0.0" } }, - "node_modules/@google-cloud/common/node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "node_modules/@google-cloud/common/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/@google-cloud/projectify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-3.0.0.tgz", @@ -1325,9 +1299,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "16.18.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.41.tgz", - "integrity": "sha512-YZJjn+Aaw0xihnpdImxI22jqGbp0DCgTFKRycygjGx/Y27NnWFJa5FJ7P+MRT3u07dogEeMVh70pWpbIQollTA==" + "version": "16.18.46", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.46.tgz", + "integrity": "sha512-Mnq3O9Xz52exs3mlxMcQuA7/9VFe/dXcrgAyfjLkABIqxXKOgBRjyazTxUbjsxDa4BP7hhPliyjVTP9RDP14xg==" }, "node_modules/@types/proxyquire": { "version": "1.3.28", @@ -1347,6 +1321,20 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, + "node_modules/@types/readable-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.2.tgz", + "integrity": "sha512-hhzOsMEISZ+mX1l+01F0duYt9wHEbCGmjARed0PcQoVS5zAdu7u5YbWYuNGhw09M1MgGr3kfsto+ut/MnAdKqA==", + "dependencies": { + "@types/node": "*", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/@types/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -1366,9 +1354,9 @@ } }, "node_modules/@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", "dev": true }, "node_modules/@types/serve-static": { @@ -1406,17 +1394,25 @@ "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", "dev": true }, + "node_modules/@types/ws": { + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", + "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.0.tgz", - "integrity": "sha512-62o2Hmc7Gs3p8SLfbXcipjWAa6qk2wZGChXG2JbBtYpwSRmti/9KHLqfbLs9uDigOexG+3PaQ9G2g3201FWLKg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", + "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/type-utils": "6.4.0", - "@typescript-eslint/utils": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/type-utils": "6.5.0", + "@typescript-eslint/utils": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1442,15 +1438,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.0.tgz", - "integrity": "sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", + "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/typescript-estree": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4" }, "engines": { @@ -1470,13 +1466,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz", - "integrity": "sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", + "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0" + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1487,13 +1483,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.4.0.tgz", - "integrity": "sha512-TvqrUFFyGY0cX3WgDHcdl2/mMCWCDv/0thTtx/ODMY1QhEiyFtv/OlLaNIiYLwRpAxAtOLOY9SUf1H3Q3dlwAg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", + "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.4.0", - "@typescript-eslint/utils": "6.4.0", + "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/utils": "6.5.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1514,9 +1510,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz", - "integrity": "sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", + "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1527,13 +1523,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz", - "integrity": "sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", + "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1554,17 +1550,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.4.0.tgz", - "integrity": "sha512-BvvwryBQpECPGo8PwF/y/q+yacg8Hn/2XS+DqL/oRsOPK+RPt29h5Ui5dqOKHDlbXrAeHUTnyG3wZA0KTDxRZw==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", + "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/typescript-estree": "6.4.0", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/typescript-estree": "6.5.0", "semver": "^7.5.4" }, "engines": { @@ -1579,12 +1575,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz", - "integrity": "sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", + "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/types": "6.5.0", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -1998,9 +1994,9 @@ } }, "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.8.tgz", + "integrity": "sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", @@ -2316,6 +2312,30 @@ "node": ">=6.0.0" } }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "node_modules/duplexify/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -2851,15 +2871,15 @@ } }, "node_modules/eslint": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "^8.47.0", + "@eslint/js": "8.48.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -3017,9 +3037,9 @@ } }, "node_modules/eufy-security-client": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eufy-security-client/-/eufy-security-client-2.8.0.tgz", - "integrity": "sha512-pS43fmB2d+YD+9RpK1DO1xHuvHI2q9Tz2TkkER+MhdkoOtHPPFUx34nTFJWMFRpBEPdpRUy4VnCrbn3nDF44LA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eufy-security-client/-/eufy-security-client-2.8.1.tgz", + "integrity": "sha512-EbqOJZnFEqq0ruNN2KTh/rW4xubQdNnGA6uu65dnLPEU9uE9ZoRxXEP2hDDn9HVNxmGbWHmOuT5rNlDI1OvkUQ==", "dependencies": { "@cospired/i18n-iso-languages": "^4.1.0", "crypto-js": "^4.1.1", @@ -3029,11 +3049,11 @@ "i18n-iso-countries": "^7.6.0", "image-type": "^4.1.0", "long": "^5.2.3", - "mqtt": "^5.0.3", + "mqtt": "^5.0.4", "node-rsa": "^1.1.1", "node-schedule": "^2.1.1", "p-throttle": "^4.1.1", - "protobufjs": "^7.2.4", + "protobufjs": "^7.2.5", "qs": "^6.11.2", "sweet-collections": "^1.1.0", "tiny-typed-emitter": "^2.1.0", @@ -3043,6 +3063,29 @@ "node": ">=16.9.0" } }, + "node_modules/eufy-security-client/node_modules/protobufjs": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", + "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -3122,19 +3165,6 @@ "node": ">=8.6.0" } }, - "node_modules/fast-glob/node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3589,32 +3619,6 @@ "node": ">=12" } }, - "node_modules/google-gax/node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "node_modules/google-gax/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/google-p12-pem": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-4.0.1.tgz", @@ -4430,6 +4434,19 @@ "node": ">= 8" } }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", @@ -4668,10 +4685,12 @@ "dev": true }, "node_modules/mqtt": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.0.3.tgz", - "integrity": "sha512-XyCzdCNFm4XXBUV7HQPd1qXYdu7GC/H+wXr+RfaztwZ72/c3sD8yRivOBdh8iKWHc+EGawSeDIvXCnvEykcJVA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.0.4.tgz", + "integrity": "sha512-Ao+DA4QYzIFXTQPIF0WKJfeHM2BV0kbP1xt/POPyJY2dQ02dscUJonh94NG9/aw0Fbk2L8Ex0YxobDSKUyQvcQ==", "dependencies": { + "@types/readable-stream": "^4.0.1", + "@types/ws": "^8.5.5", "commist": "^3.2.0", "concat-stream": "^2.0.0", "debug": "^4.3.4", @@ -4733,30 +4752,6 @@ "node": ">= 6" } }, - "node_modules/mqtt/node_modules/duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dependencies": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "node_modules/mqtt/node_modules/duplexify/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/mqtt/node_modules/readable-stream": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", @@ -5188,6 +5183,7 @@ "version": "7.2.4", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz", "integrity": "sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==", + "dev": true, "hasInstallScript": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", @@ -6128,9 +6124,9 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -6700,9 +6696,9 @@ } }, "@eslint/js": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", "dev": true }, "@esm2cjs/execa": { @@ -6793,31 +6789,6 @@ "google-auth-library": "^8.0.2", "retry-request": "^5.0.0", "teeny-request": "^8.0.0" - }, - "dependencies": { - "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } } }, "@google-cloud/projectify": { @@ -7430,9 +7401,9 @@ "dev": true }, "@types/node": { - "version": "16.18.41", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.41.tgz", - "integrity": "sha512-YZJjn+Aaw0xihnpdImxI22jqGbp0DCgTFKRycygjGx/Y27NnWFJa5FJ7P+MRT3u07dogEeMVh70pWpbIQollTA==" + "version": "16.18.46", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.46.tgz", + "integrity": "sha512-Mnq3O9Xz52exs3mlxMcQuA7/9VFe/dXcrgAyfjLkABIqxXKOgBRjyazTxUbjsxDa4BP7hhPliyjVTP9RDP14xg==" }, "@types/proxyquire": { "version": "1.3.28", @@ -7452,6 +7423,22 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, + "@types/readable-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.2.tgz", + "integrity": "sha512-hhzOsMEISZ+mX1l+01F0duYt9wHEbCGmjARed0PcQoVS5zAdu7u5YbWYuNGhw09M1MgGr3kfsto+ut/MnAdKqA==", + "requires": { + "@types/node": "*", + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, "@types/responselike": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", @@ -7471,9 +7458,9 @@ } }, "@types/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", + "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", "dev": true }, "@types/serve-static": { @@ -7511,17 +7498,25 @@ "integrity": "sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA==", "dev": true }, + "@types/ws": { + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", + "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "requires": { + "@types/node": "*" + } + }, "@typescript-eslint/eslint-plugin": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.4.0.tgz", - "integrity": "sha512-62o2Hmc7Gs3p8SLfbXcipjWAa6qk2wZGChXG2JbBtYpwSRmti/9KHLqfbLs9uDigOexG+3PaQ9G2g3201FWLKg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", + "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/type-utils": "6.4.0", - "@typescript-eslint/utils": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/type-utils": "6.5.0", + "@typescript-eslint/utils": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -7531,54 +7526,54 @@ } }, "@typescript-eslint/parser": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.4.0.tgz", - "integrity": "sha512-I1Ah1irl033uxjxO9Xql7+biL3YD7w9IU8zF+xlzD/YxY6a4b7DYA08PXUUCbm2sEljwJF6ERFy2kTGAGcNilg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", + "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/typescript-estree": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.4.0.tgz", - "integrity": "sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", + "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", "dev": true, "requires": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0" + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0" } }, "@typescript-eslint/type-utils": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.4.0.tgz", - "integrity": "sha512-TvqrUFFyGY0cX3WgDHcdl2/mMCWCDv/0thTtx/ODMY1QhEiyFtv/OlLaNIiYLwRpAxAtOLOY9SUf1H3Q3dlwAg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", + "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.4.0", - "@typescript-eslint/utils": "6.4.0", + "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/utils": "6.5.0", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.4.0.tgz", - "integrity": "sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", + "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.4.0.tgz", - "integrity": "sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", + "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", "dev": true, "requires": { - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/visitor-keys": "6.4.0", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/visitor-keys": "6.5.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -7587,27 +7582,27 @@ } }, "@typescript-eslint/utils": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.4.0.tgz", - "integrity": "sha512-BvvwryBQpECPGo8PwF/y/q+yacg8Hn/2XS+DqL/oRsOPK+RPt29h5Ui5dqOKHDlbXrAeHUTnyG3wZA0KTDxRZw==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", + "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.4.0", - "@typescript-eslint/types": "6.4.0", - "@typescript-eslint/typescript-estree": "6.4.0", + "@typescript-eslint/scope-manager": "6.5.0", + "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/typescript-estree": "6.5.0", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.4.0.tgz", - "integrity": "sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", + "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", "dev": true, "requires": { - "@typescript-eslint/types": "6.4.0", + "@typescript-eslint/types": "6.5.0", "eslint-visitor-keys": "^3.4.1" } }, @@ -7907,9 +7902,9 @@ } }, "chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.8.tgz", + "integrity": "sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==", "dev": true, "requires": { "assertion-error": "^1.1.0", @@ -8145,6 +8140,29 @@ "esutils": "^2.0.2" } }, + "duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -8450,15 +8468,15 @@ } }, "eslint": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "^8.47.0", + "@eslint/js": "8.48.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -8569,9 +8587,9 @@ "dev": true }, "eufy-security-client": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eufy-security-client/-/eufy-security-client-2.8.0.tgz", - "integrity": "sha512-pS43fmB2d+YD+9RpK1DO1xHuvHI2q9Tz2TkkER+MhdkoOtHPPFUx34nTFJWMFRpBEPdpRUy4VnCrbn3nDF44LA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eufy-security-client/-/eufy-security-client-2.8.1.tgz", + "integrity": "sha512-EbqOJZnFEqq0ruNN2KTh/rW4xubQdNnGA6uu65dnLPEU9uE9ZoRxXEP2hDDn9HVNxmGbWHmOuT5rNlDI1OvkUQ==", "requires": { "@cospired/i18n-iso-languages": "^4.1.0", "crypto-js": "^4.1.1", @@ -8581,15 +8599,36 @@ "i18n-iso-countries": "^7.6.0", "image-type": "^4.1.0", "long": "^5.2.3", - "mqtt": "^5.0.3", + "mqtt": "^5.0.4", "node-rsa": "^1.1.1", "node-schedule": "^2.1.1", "p-throttle": "^4.1.1", - "protobufjs": "^7.2.4", + "protobufjs": "^7.2.5", "qs": "^6.11.2", "sweet-collections": "^1.1.0", "tiny-typed-emitter": "^2.1.0", "ts-log": "^2.2.5" + }, + "dependencies": { + "protobufjs": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", + "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + } + } } }, "event-target-shim": { @@ -8650,18 +8689,6 @@ "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" - }, - "dependencies": { - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - } } }, "fast-json-stable-stringify": { @@ -9002,31 +9029,6 @@ "protobufjs": "7.2.4", "protobufjs-cli": "1.1.1", "retry-request": "^5.0.0" - }, - "dependencies": { - "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "dev": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } } }, "google-p12-pem": { @@ -9657,6 +9659,16 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, "mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", @@ -9833,10 +9845,12 @@ "dev": true }, "mqtt": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.0.3.tgz", - "integrity": "sha512-XyCzdCNFm4XXBUV7HQPd1qXYdu7GC/H+wXr+RfaztwZ72/c3sD8yRivOBdh8iKWHc+EGawSeDIvXCnvEykcJVA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.0.4.tgz", + "integrity": "sha512-Ao+DA4QYzIFXTQPIF0WKJfeHM2BV0kbP1xt/POPyJY2dQ02dscUJonh94NG9/aw0Fbk2L8Ex0YxobDSKUyQvcQ==", "requires": { + "@types/readable-stream": "^4.0.1", + "@types/ws": "^8.5.5", "commist": "^3.2.0", "concat-stream": "^2.0.0", "debug": "^4.3.4", @@ -9876,29 +9890,6 @@ } } }, - "duplexify": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", - "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, "readable-stream": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", @@ -10227,6 +10218,7 @@ "version": "7.2.4", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.4.tgz", "integrity": "sha512-AT+RJgD2sH8phPmCf7OUZR8xGdcJRga4+1cOaXJ64hvcSkVhNcRHOwIxUatPH15+nj59WAGTDv3LSGZPEQbJaQ==", + "dev": true, "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -10928,9 +10920,9 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true }, "uc.micro": { diff --git a/package.json b/package.json index 4daa2a6..8832b63 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iobroker.eusec", - "version": "1.1.1", + "version": "1.1.2", "description": "ioBroker adapter that integrates Eufy-Security cameras with stations", "author": { "name": "bropat", @@ -26,7 +26,7 @@ "@bropat/fluent-ffmpeg": "^2.1.3", "@cospired/i18n-iso-languages": "^4.1.0", "@iobroker/adapter-core": "^3.0.3", - "eufy-security-client": "^2.8.0", + "eufy-security-client": "^2.8.1", "ffmpeg-static": "^5.2.0", "fs-extra": "^11.1.1", "go2rtc-static": "^1.6.2", @@ -46,15 +46,15 @@ "@types/fs-extra": "^11.0.1", "@types/mime": "^3.0.1", "@types/mocha": "^10.0.1", - "@types/node": "^16.18.41", + "@types/node": "^16.18.46", "@types/proxyquire": "^1.3.28", "@types/sinon": "^10.0.16", "@types/sinon-chai": "^3.2.9", - "@typescript-eslint/eslint-plugin": "^6.4.0", - "@typescript-eslint/parser": "^6.4.0", - "chai": "^4.3.7", + "@typescript-eslint/eslint-plugin": "^6.5.0", + "@typescript-eslint/parser": "^6.5.0", + "chai": "^4.3.8", "chai-as-promised": "^7.1.1", - "eslint": "^8.47.0", + "eslint": "^8.48.0", "mocha": "^10.2.0", "proxyquire": "^2.1.3", "rimraf": "^5.0.1", @@ -62,7 +62,7 @@ "sinon-chai": "^3.7.0", "source-map-support": "^0.5.21", "ts-node": "^10.9.1", - "typescript": "5.1.6" + "typescript": "5.2.2" }, "main": "build/main.js", "files": [ diff --git a/src/main.ts b/src/main.ts index 7e44da1..b287861 100755 --- a/src/main.ts +++ b/src/main.ts @@ -1092,14 +1092,14 @@ class euSec extends utils.Adapter { try { const allDevices = await this.getDevicesAsync(); const reg = new RegExp(`^${this.namespace}\.[0-9A-Z]+$`); - allDevices.forEach((id) => { + for (const id of allDevices) { if (id._id.match(reg)) { const serial = id._id.replace(`${this.namespace}.`, ""); if (!stationSerials.includes(serial)) { - this.delObjectAsync(id._id, { recursive: true }); + await this.delObjectAsync(id._id, { recursive: true }); } } - }); + } } catch (error) { this.log.error(`Delete obsolete stations ERROR - ${JSON.stringify(error)}`); } @@ -1108,14 +1108,14 @@ class euSec extends utils.Adapter { try { const allDevices = await this.getDevicesAsync(); const reg = new RegExp(`^${this.namespace}\.[0-9A-Z]+\.[a-z]+\.[0-9A-Z]+$`); - allDevices.forEach((id) => { + for (const id of allDevices) { if (id._id.match(reg)) { const serial = id._id.split(".")[4]; if (!deviceSerials.includes(serial)) { - this.delObjectAsync(id._id, { recursive: true }); + await this.delObjectAsync(id._id, { recursive: true }); } } - }); + } } catch (error) { this.log.error(`Delete obsolete devices ERROR - ${JSON.stringify(error)}`); }