iobroker.eusec 2.0.2 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +25 -10
- package/build/lib/eufyApiCompat.js +63 -0
- package/build/lib/eufyApiCompat.js.map +7 -0
- package/build/lib/go2rtc.js +36 -0
- package/build/lib/go2rtc.js.map +7 -0
- package/build/lib/interfaces.js.map +1 -1
- package/build/lib/log.js.map +2 -2
- package/build/lib/types.js.map +1 -1
- package/build/lib/utils.js +53 -35
- package/build/lib/utils.js.map +2 -2
- package/build/lib/video.js +55 -38
- package/build/lib/video.js.map +2 -2
- package/build/main.js +586 -238
- package/build/main.js.map +2 -2
- package/cleanupCveFix.js +1 -1
- package/io-package.json +17 -29
- package/package.json +24 -35
package/build/main.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/main.ts"],
|
|
4
|
-
"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, LogLevel, TFCardStatus } 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 { Readable } from \"stream\";\r\nimport util from \"util\";\r\nimport childProcess from \"child_process\";\r\nimport pathToGo2rtc from \"go2rtc-static\";\r\nimport pathToFfmpeg from \"ffmpeg-for-homebridge\";\r\n\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 { streamToGo2rtc } from \"./lib/video\";\r\n\r\nexport class 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 = \"adapter.json\";\r\n private persistentDriverFile: string = \"driver.json\";\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 private skipInit = false;\r\n\r\n public constructor(options: Partial<utils.AdapterOptions> = {}) {\r\n super({\r\n ...options,\r\n name: \"eusec\",\r\n });\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 public restartAdapter(): void {\r\n this.skipInit = true;\r\n this.restart();\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<void> {\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 (await this.fileExistsAsync(this.namespace, this.persistentFile)) {\r\n const fileContent = await this.readFileAsync(this.namespace, this.persistentFile);\r\n this.persistentData = JSON.parse(fileContent.file.toString(\"utf8\")) as PersistentData;\r\n }\r\n } catch (error) {\r\n this.logger.debug(\"No adapter stored data from last exit found.\", error);\r\n }\r\n\r\n let persistentDriverData: string = \"{}\";\r\n try {\r\n if (await this.fileExistsAsync(this.namespace, this.persistentDriverFile)) {\r\n const fileContent = await this.readFileAsync(this.namespace, this.persistentDriverFile);\r\n persistentDriverData = fileContent.file.toString(\"utf8\");\r\n }\r\n } catch (error) {\r\n this.logger.debug(\"No driver 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 // -------------------------------------------------------------------------------\r\n // The following sequence can be removed as soon as node 22 is required as minimum\r\n // -------------------------------------------------------------------------------\r\n const hosts = await this.getForeignObjectsAsync(\"system.host.*\", \"host\");\r\n if (hosts !== undefined && hosts !== null && Object.values(hosts).length !== 0) {\r\n if (this.config.hostname === \"\") {\r\n this.config.hostname = Object.values(hosts)[0].native.os.hostname;\r\n }\r\n\r\n const nodeVersion = Object.values(hosts)[0].native.process.versions.node;\r\n const nodeMajorVersion = nodeVersion.split(\".\")[0];\r\n\r\n let fixNeeded;\r\n switch (parseInt(nodeMajorVersion)) {\r\n // node 18 is no longer supported\r\n case 20:\r\n fixNeeded = nodeVersion.localeCompare(\"20.11.1\", undefined, { numeric: true, sensitivity: \"base\" });\r\n break;\r\n // node 21 is and was not supported\r\n // node 22 and newer do NOT require any fix\r\n default:\r\n fixNeeded = -1; // no fix\r\n break;\r\n }\r\n if (fixNeeded >= 0) {\r\n const adapter = await this.getForeignObjectAsync(`system.adapter.${this.namespace}`);\r\n if (adapter !== undefined && adapter !== null) {\r\n if (!adapter.common.nodeProcessParams?.includes(\"--security-revert=CVE-2023-46809\")) {\r\n adapter.common.nodeProcessParams = [\"--security-revert=CVE-2023-46809\"]\r\n await this.setForeignObjectAsync(`system.adapter.${this.namespace}`, adapter);\r\n this.log.warn(\"Required fix to use livestreaming with this version of Node.js (CVE-2023-46809) applied. Restart of the adapter initiated to activate the fix.\");\r\n this.restartAdapter();\r\n }\r\n }\r\n }\r\n }\r\n // -------------------------------------------------------------------------------\r\n\r\n if (!this.skipInit) {\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 if (this.config.country !== \"iobroker\") {\r\n countryCode = this.config.country;\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, this.logger, previousVersion, currentVersion);\r\n this.persistentData.version = this.version!;\r\n await 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 if (this.config.username !== \"\" && this.config.password !== \"\") {\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 persistentData: persistentDriverData,\r\n eventDurationSeconds: this.config.eventDuration,\r\n p2pConnectionSetup: connectionType,\r\n pollingIntervalMinutes: this.config.pollingInterval,\r\n acceptInvitations: this.config.acceptInvitations,\r\n logging: {\r\n level: this.log.level === \"silly\" ? LogLevel.Trace : this.log.level === \"debug\" ? LogLevel.Debug : this.log.level === \"info\" ? LogLevel.Info : this.log.level === \"warn\" ? LogLevel.Warn : this.log.level === \"error\" ? LogLevel.Error : LogLevel.Info\r\n }\r\n };\r\n\r\n this.eufy = await EufySecurity.initialize(config, this.logger);\r\n this.eufy.on(\"persistent data\", (data: string) => this.onPersistentData(data))\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 \"ffmpeg\": {\r\n // @ts-expect-error old code\r\n \"bin\": pathToFfmpeg !== \"\" && pathToFfmpeg !== undefined ? pathToFfmpeg : \"ffmpeg\",\r\n },\r\n \"streams\": {},\r\n /*\"log\": {\r\n \"level\": \"debug\", // default level\r\n \"api\": \"debug\",\r\n \"exec\": \"debug\",\r\n \"ngrok\": \"debug\",\r\n \"rtsp\": \"debug\",\r\n \"streams\": \"debug\",\r\n \"webrtc\": \"debug\",\r\n }*/\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 // Delete cunknown channels without childs\r\n const channels = await this.getChannelsAsync();\r\n for (const channel of channels) {\r\n if (channel.common.name === \"unknown\") {\r\n const states = await this.getStatesAsync(`${channel._id}.*`);\r\n if (Object.keys(states).length === 0) {\r\n await this.delObjectAsync(channel._id);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n public async writePersistentData(): Promise<void> {\r\n try {\r\n await this.writeFileAsync(this.namespace, 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 private onPersistentData(data: string): void {\r\n this.writeFileAsync(this.namespace, this.persistentDriverFile, data).catch((error) => {\r\n this.logger.error(`writePersistentDriverData() - 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<void> {\r\n try {\r\n\r\n await 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 // eslint-disable-next-line @typescript-eslint/no-unused-vars\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<void> {\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 case DeviceStateID.OPEN_BOX:\r\n await station.open(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 /**\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 async onMessage(obj: ioBroker.Message): Promise<void> {\r\n if (typeof obj === \"object\" && obj.message) {\r\n try {\r\n if (obj.command === \"quickResponse\") {\r\n this.log.debug(`quickResponse command - message: ${JSON.stringify(obj.message)}`);\r\n if (typeof obj.message === \"object\" &&\r\n typeof obj.message.station_sn === \"string\" && obj.message.station_sn !== \"\" &&\r\n typeof obj.message.device_sn === \"string\" && obj.message.device_sn !== \"\" &&\r\n typeof obj.message.voice_id === \"number\") {\r\n try {\r\n const station = await this.eufy.getStation(obj.message.station_sn);\r\n const device = await this.eufy.getDevice(obj.message.device_sn);\r\n\r\n if (device.hasCommand(CommandName.DeviceQuickResponse)) {\r\n await station.quickResponse(device, obj.message.voice_id);\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: \"quickResponse command sended\"\r\n }, obj.callback);\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"quickResponse command not supported by specified device\"\r\n }, obj.callback);\r\n }\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"quickResponse command not sended because specified station doesn't exists\"\r\n }, obj.callback);\r\n } else if (error instanceof DeviceNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"quickResponse command not sended because specified device doesn't exists\"\r\n }, obj.callback);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"quickResponse command not sended because some required parameters are missing\"\r\n }, obj.callback);\r\n }\r\n } else if (obj.command === \"getQuickResponseVoices\") {\r\n this.log.debug(`getQuickResponseVoices command - message: ${JSON.stringify(obj.message)}`);\r\n if (typeof obj.message === \"object\" &&\r\n typeof obj.message.device_sn === \"string\" && obj.message.device_sn !== \"\") {\r\n const voices = await this.eufy.getApi().getVoices(obj.message.device_sn);\r\n\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: voices\r\n }, obj.callback);\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"getQuickResponseVoices command not sended because some required parameters are missing\"\r\n }, obj.callback);\r\n }\r\n } else if (obj.command === \"snooze\") {\r\n this.log.debug(`snooze command - message: ${JSON.stringify(obj.message)}`);\r\n if (typeof obj.message === \"object\" &&\r\n typeof obj.message.station_sn === \"string\" && obj.message.station_sn !== \"\" &&\r\n typeof obj.message.device_sn === \"string\" && obj.message.device_sn !== \"\" &&\r\n typeof obj.message.snooze_time === \"number\" &&\r\n (obj.message.snooze_chime === undefined || typeof obj.message.snooze_chime === \"boolean\") &&\r\n (obj.message.snooze_homebase === undefined || typeof obj.message.snooze_homebase === \"boolean\") &&\r\n (obj.message.snooze_motion === undefined || typeof obj.message.snooze_motion === \"boolean\")) {\r\n try {\r\n const station = await this.eufy.getStation(obj.message.station_sn);\r\n const device = await this.eufy.getDevice(obj.message.device_sn);\r\n\r\n if (device.hasCommand(CommandName.DeviceSnooze)) {\r\n await station.snooze(device, {\r\n snooze_time: obj.message.snooze_time,\r\n snooze_chime: obj.message.snooze_chime,\r\n snooze_homebase: obj.message.snooze_homebase,\r\n snooze_motion: obj.message.snooze_motion,\r\n });\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: \"snooze command sended\"\r\n }, obj.callback);\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not supported by specified device\"\r\n }, obj.callback);\r\n }\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not sended because specified station doesn't exists\"\r\n }, obj.callback);\r\n } else if (error instanceof DeviceNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not sended because specified device doesn't exists\"\r\n }, obj.callback);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not sended because some required parameters are missing\"\r\n }, obj.callback);\r\n }\r\n } else if (obj.command === \"chime\") {\r\n this.log.debug(`snooze command - message: ${JSON.stringify(obj.message)}`);\r\n if (typeof obj.message === \"object\" &&\r\n typeof obj.message.station_sn === \"string\" && obj.message.station_sn !== \"\" &&\r\n (obj.message.ringtone === undefined || typeof obj.message.ringtone === \"number\")) {\r\n try {\r\n const station = await this.eufy.getStation(obj.message.station_sn);\r\n\r\n if (station.hasCommand(CommandName.StationChime)) {\r\n await station.chimeHomebase(obj.message.ringtone !== undefined && typeof obj.message.ringtone === \"number\" ? obj.message.ringtone : 0);\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: \"chime command sended\"\r\n }, obj.callback);\r\n } else {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"chime command not supported by specified station\"\r\n }, obj.callback);\r\n }\r\n\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, \"chime command sended\", obj.callback);\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: \"snooze command not sended because specified station doesn't exists\"\r\n }, obj.callback);\r\n } else {\r\n throw error;\r\n }\r\n }\r\n }\r\n } else if (obj.command === \"pollRefresh\") {\r\n this.log.debug(`pollRefresh command`);\r\n await this.eufy.refreshCloudData();\r\n\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: true,\r\n result: \"pollRefresh command sended\"\r\n }, obj.callback);\r\n } else {\r\n const errorMessage = `Received unknown message: ${JSON.stringify(obj.message)}`;\r\n this.log.warn(errorMessage);\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: errorMessage\r\n }, obj.callback);\r\n }\r\n } catch (error) {\r\n const errorMessage = `Error during processing of received message: ${error instanceof Error ? `${error.name} - ${error.message}` : error }`;\r\n this.log.error(errorMessage);\r\n if (obj.callback)\r\n this.sendTo(obj.from, obj.command, {\r\n sended: false,\r\n result: errorMessage\r\n }, 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.type === \"object\" && typeof property.default === \"object\" ? JSON.stringify(property.default) : 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<void> {\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<void> {\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.DeviceOpen)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.OPEN_BOX), {\r\n type: \"state\",\r\n common: {\r\n name: \"Open Box\",\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<void> {\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<void> {\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<void> {\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 this.delFileAsync(this.namespace, 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<void> {\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<void> {\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<void> {\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 values = id._id.split(\".\");\r\n const stateChannel = values[3];\r\n const serial = values[4];\r\n if (!deviceSerials.includes(serial) ||\r\n (deviceSerials.includes(serial) && devices[deviceSerials.indexOf(serial)].getStateChannel() !== \"unknown\" && stateChannel === \"unknown\")) {\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 try {\r\n const contents = await this.readDirAsync(this.namespace, \"\");\r\n for (const content of contents.filter((fn) => fn.file.match(\"^T[0-9A-Z]+$\") !== null && fn.isDir)) {\r\n if (!stationSerials.includes(content.file)) {\r\n await this.delFileAsync(this.namespace, content.file);\r\n } else {\r\n const dirContents = await this.readDirAsync(this.namespace, content.file);\r\n for (const dir of dirContents.filter((fn) => Object.values(DataLocation).includes(fn.file) && fn.isDir)) {\r\n const files = await this.readDirAsync(this.namespace, path.join(content.file, dir.file));\r\n let deletedFiles = 0;\r\n for (const file of files.filter((fn) => !deviceSerials.includes(fn.file.substring(0, 16)) && !fn.isDir)) {\r\n await this.delFileAsync(this.namespace, path.join(content.file, dir.file, file.file));\r\n deletedFiles++;\r\n }\r\n if (deletedFiles === files.length) {\r\n await this.delFileAsync(this.namespace, path.join(content.file, dir.file));\r\n }\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete directories/files ERROR - ${error}`);\r\n }\r\n }\r\n\r\n private async onClose(): Promise<void> {\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<void> {\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<void> {\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<void> {\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<void> {\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<void> {\r\n if ((result.return_code !== 0 && result.command_type !== CommandType.P2P_QUERY_STATUS_IN_LOCK && result.command_type !== CommandType.CMD_STORAGE_INFO_HB3 && result.command_type !== CommandType.CMD_SDINFO_EX) ||\r\n (result.return_code !== 0 && result.return_code !== ErrorCode.ERROR_DEV_BUSY && result.command_type === CommandType.CMD_STORAGE_INFO_HB3)) {\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 } else if (result.return_code !== 0 && result.return_code !== TFCardStatus.REMOVE && result.return_code !== TFCardStatus.BUSY && result.command_type === CommandType.CMD_SDINFO_EX) {\r\n this.logger.error(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${TFCardStatus[result.return_code]} (${result.return_code})`);\r\n }\r\n }\r\n\r\n private async onStationPropertyChanged(station: Station, name: string, value: PropertyValue): Promise<void> {\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<void> {\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(device.getStationSerial(), DataLocation.LAST_EVENT);\r\n if (!await this.fileExistsAsync(this.namespace, filePath)) {\r\n await this.mkdirAsync(this.namespace, filePath);\r\n }\r\n await this.writeFileAsync(this.namespace, path.join(filePath, fileName), picture.data);\r\n\r\n await this.setStateAsync(device.getStateID(DeviceStateID.PICTURE_URL), `/files/${this.namespace}/${device.getStationSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}.${picture.type.ext}`, true);\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<void> {\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<void> {\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<void> {\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 await streamToGo2rtc(device.getSerial(), videostream, audiostream, this.logger, this.config, this.namespace, metadata).catch((error) => {\r\n this.logger.debug(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Stopping livestream...`, error);\r\n });\r\n } catch(error) {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Stopping livestream...`, error);\r\n this.eufy.stopStationLivestream(device.getSerial())\r\n .catch(async (error) => {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error during stopping livestream...`, error);\r\n });\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<void> {\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<void> {\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<void> {\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<void> {\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: <img src=\"${captcha}\">`);\r\n this.setStateAsync(\"received_captcha_html\", { val: `<img src=\"${captcha}\">`, 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<utils.AdapterOptions> | undefined) => new euSec(options);\r\n} else {\r\n // otherwise start the instance directly\r\n (() => new euSec())();\r\n}"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/*\n * Created with @iobroker/create-adapter v2.5.0\n */\n\n// The adapter-core module gives you access to the core ioBroker functions\n// you need to create an adapter\nimport { Adapter, type AdapterOptions } from '@iobroker/adapter-core';\nimport * as path from 'node:path';\nimport {\n type Camera,\n type Device,\n type Station,\n type PushMessage,\n type EufySecurityConfig,\n type CommandResult,\n type PropertyValue,\n type StreamMetadata,\n type PropertyMetadataNumeric,\n type PropertyMetadataAny,\n type LoginOptions,\n type Picture,\n P2PConnectionType,\n EufySecurity,\n CommandType,\n ErrorCode,\n PropertyName,\n CommandName,\n PanTiltDirection,\n DeviceNotFoundError,\n StationNotFoundError,\n ensureError,\n LogLevel,\n TFCardStatus,\n} from 'eufy-security-client';\nimport { getAlpha2Code as getCountryCode } from 'i18n-iso-countries';\nimport { isValid as isValidLanguageCode } from '@cospired/i18n-iso-languages';\nimport type { Readable } from 'node:stream';\nimport util from 'node:util';\nimport childProcess from 'node:child_process';\nimport pathToGo2rtc from 'go2rtc-static';\nimport pathToFfmpeg from 'ffmpeg-for-homebridge';\n\nimport { DeviceStateID, DataLocation, RoleMapping, StationStateID } from './lib/types';\nimport {\n convertCamelCaseToSnakeCase,\n getImageAsHTML,\n handleUpdate,\n removeFiles,\n removeLastChar,\n setStateChangedAsync,\n} from './lib/utils';\nimport type { PersistentData } from './lib/interfaces';\nimport { ioBrokerLogger } from './lib/log';\nimport { applyEufyApiCompatibility } from './lib/eufyApiCompat';\nimport { streamToGo2rtcFailed } from './lib/go2rtc';\nimport { streamToGo2rtc } from './lib/video';\n\n/** Restart backoff for go2rtc: 1s, 2s, 4s ... capped, reset once it stayed up for a while. */\nconst GO2RTC_RESTART_DELAY_MIN = 1000;\nconst GO2RTC_RESTART_DELAY_MAX = 30000;\nconst GO2RTC_HEALTHY_RUNTIME = 60000;\n\n/**\n * Label prefix of the \"Auto\" entries in DeviceVideoStreamingQualityProperty.states. The numeric\n * value behind it differs per device family - the base property and the S350 use 0, eufyCam 3 and\n * the Professional models use 5, and battery doorbells have both (0 = \"Auto / Low Encoding\",\n * 5 = \"Auto / High Encoding\") - so the value must be resolved through the label, not hardcoded.\n */\nconst VIDEO_STREAMING_QUALITY_AUTO_LABEL = 'Auto';\n\nexport class euSec extends Adapter {\n private eufy!: EufySecurity;\n /*private downloadEvent: {\n [index: string]: NodeJS.Timeout;\n } = {};*/\n\n private persistentFile: string = 'adapter.json';\n private persistentDriverFile: string = 'driver.json';\n private logger!: ioBrokerLogger;\n private persistentData: PersistentData = {\n version: '',\n };\n private captchaId: string | null = null;\n private verify_code = false;\n private skipInit = false;\n private go2rtcProcess: childProcess.ChildProcess | undefined = undefined;\n private go2rtcRestartTimeout: ioBroker.Timeout | undefined = undefined;\n private go2rtcRestarts = 0;\n private terminating = false;\n\n public constructor(options: Partial<AdapterOptions> = {}) {\n super({\n ...options,\n name: 'eusec',\n });\n\n this.on('ready', this.onReady.bind(this));\n this.on('stateChange', this.onStateChange.bind(this));\n // this.on(\"objectChange\", this.onObjectChange.bind(this));\n this.on('message', this.onMessage.bind(this));\n this.on('unload', this.onUnload.bind(this));\n\n // Safety net, registered once: onUnload does not run on every way out (uncaught exception),\n // and a surviving go2rtc would hold the configured ports against the next start.\n process.on('exit', () => this.go2rtcProcess?.kill());\n }\n\n public restartAdapter(): void {\n this.skipInit = true;\n this.restart();\n }\n\n /**\n * Is called when databases are connected and adapter received configuration.\n */\n private async onReady(): Promise<void> {\n this.logger = new ioBrokerLogger(this.log);\n\n await this.setObjectNotExistsAsync('verify_code', {\n type: 'state',\n common: {\n name: '2FA verification code',\n type: 'string',\n role: 'state',\n read: true,\n write: true,\n },\n native: {},\n });\n await this.setObjectNotExistsAsync('received_captcha_html', {\n type: 'state',\n common: {\n name: 'Received captcha image HTML',\n type: 'string',\n role: 'state',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setObjectNotExistsAsync('captcha', {\n type: 'state',\n common: {\n name: 'Enter captcha',\n type: 'string',\n role: 'state',\n read: true,\n write: true,\n },\n native: {},\n });\n await this.setObjectNotExistsAsync('info', {\n type: 'channel',\n common: {\n name: 'info',\n },\n native: {},\n });\n await this.setObjectNotExistsAsync('info.connection', {\n type: 'state',\n common: {\n name: 'Global connection',\n type: 'boolean',\n role: 'indicator.connection',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setStateAsync('info.connection', { val: false, ack: true });\n await this.setObjectNotExistsAsync('info.push_connection', {\n type: 'state',\n common: {\n name: 'Push notification connection',\n type: 'boolean',\n role: 'indicator.connection',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setStateAsync('info.push_connection', { val: false, ack: true });\n await this.setObjectNotExistsAsync('info.mqtt_connection', {\n type: 'state',\n common: {\n name: 'MQTT connection',\n type: 'boolean',\n role: 'indicator.connection',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setStateAsync('info.mqtt_connection', { val: false, ack: true });\n\n try {\n const connection = await this.getStatesAsync('*.connection');\n if (connection) {\n Object.keys(connection).forEach(async id => {\n await this.setStateAsync(id, { val: false, ack: true });\n });\n }\n } catch (error) {\n this.logger.error('Reset connection states - Error', error);\n }\n\n try {\n const sensorList = [\n PropertyName.DeviceMotionDetected,\n PropertyName.DevicePersonDetected,\n PropertyName.DeviceSoundDetected,\n PropertyName.DeviceCryingDetected,\n PropertyName.DevicePetDetected,\n PropertyName.DeviceRinging,\n ];\n for (const sensorName of sensorList) {\n const sensors = await this.getStatesAsync(`*.${convertCamelCaseToSnakeCase(sensorName)}`);\n if (sensors) {\n Object.keys(sensors).forEach(async id => {\n await this.setStateAsync(id, { val: false, ack: true });\n });\n }\n }\n } catch (error) {\n this.logger.error('Reset sensor states - Error', error);\n }\n\n try {\n if (await this.fileExistsAsync(this.namespace, this.persistentFile)) {\n const fileContent = await this.readFileAsync(this.namespace, this.persistentFile);\n this.persistentData = JSON.parse(fileContent.file.toString('utf8')) as PersistentData;\n }\n } catch (error) {\n this.logger.debug('No adapter stored data from last exit found.', error);\n }\n\n let persistentDriverData = '{}';\n try {\n if (await this.fileExistsAsync(this.namespace, this.persistentDriverFile)) {\n const fileContent = await this.readFileAsync(this.namespace, this.persistentDriverFile);\n persistentDriverData = fileContent.file.toString('utf8');\n }\n } catch (error) {\n this.logger.debug('No driver stored data from last exit found.', error);\n }\n\n this.subscribeStates('verify_code');\n this.subscribeStates('captcha');\n\n // The --security-revert=CVE-2023-46809 workaround that used to be applied here is gone:\n // it was only ever needed on node 20.11.1 and later, and node 22 - the minimum this\n // adapter declares in \"engines\" - rejects the flag outright (\"Attempt to revert an unknown\n // CVE\", exit code 12), which keeps the adapter process from starting at all. Removing a\n // flag left over from an older installation therefore cannot be done from in here; that is\n // what the cleanupCveFix.js postinstall script is for, which runs in a plain node process.\n const hosts = await this.getForeignObjectsAsync('system.host.*', 'host');\n if (hosts !== undefined && hosts !== null && Object.values(hosts).length !== 0) {\n if (this.config.hostname === '') {\n this.config.hostname = Object.values(hosts)[0].native.os.hostname;\n }\n }\n\n if (!this.skipInit) {\n const systemConfig = await this.getForeignObjectAsync('system.config');\n let countryCode = undefined;\n let languageCode = undefined;\n if (systemConfig) {\n countryCode = getCountryCode(systemConfig.common.country!, 'en');\n if (isValidLanguageCode(systemConfig.common.language)) {\n languageCode = systemConfig.common.language;\n }\n }\n if (this.config.country !== 'iobroker') {\n countryCode = this.config.country;\n }\n\n // Handling adapter version update\n try {\n if (this.persistentData.version !== this.version) {\n const currentVersion = Number.parseFloat(removeLastChar(this.version!, '.'));\n const previousVersion =\n this.persistentData.version !== '' && this.persistentData.version !== undefined\n ? Number.parseFloat(removeLastChar(this.persistentData.version, '.'))\n : 0;\n this.logger.debug(\n `Handling of adapter update - currentVersion: ${currentVersion} previousVersion: ${previousVersion}`,\n );\n\n if (previousVersion < currentVersion) {\n await handleUpdate(this, this.logger, previousVersion, currentVersion);\n this.persistentData.version = this.version!;\n await this.writePersistentData();\n }\n }\n } catch (error) {\n this.logger.error(`Handling of adapter update - Error:`, error);\n }\n\n let connectionType = P2PConnectionType.QUICKEST;\n if (this.config.p2pConnectionType === 'only_local') {\n connectionType = P2PConnectionType.ONLY_LOCAL;\n }\n\n if (this.config.username !== '' && this.config.password !== '') {\n const config: EufySecurityConfig = {\n username: this.config.username,\n password: this.config.password,\n country: countryCode,\n language: languageCode,\n persistentData: persistentDriverData,\n eventDurationSeconds: this.config.eventDuration,\n p2pConnectionSetup: connectionType,\n pollingIntervalMinutes: this.config.pollingInterval,\n acceptInvitations: this.config.acceptInvitations,\n logging: {\n level:\n this.log.level === 'silly'\n ? LogLevel.Trace\n : this.log.level === 'debug'\n ? LogLevel.Debug\n : this.log.level === 'info'\n ? LogLevel.Info\n : this.log.level === 'warn'\n ? LogLevel.Warn\n : this.log.level === 'error'\n ? LogLevel.Error\n : LogLevel.Info,\n },\n };\n\n // Must happen before initialize(), the first API call is made during login.\n applyEufyApiCompatibility(message => this.logger.info(message));\n\n this.eufy = await EufySecurity.initialize(config, this.logger);\n this.eufy.on('persistent data', (data: string) => this.onPersistentData(data));\n this.eufy.on('station added', (station: Station) => this.onStationAdded(station));\n this.eufy.on('device added', (device: Device) => this.onDeviceAdded(device));\n this.eufy.on('station removed', (station: Station) => this.onStationRemoved(station));\n this.eufy.on('device removed', (device: Device) => this.onDeviceRemoved(device));\n this.eufy.on('push message', messages => this.handlePushNotification(messages));\n this.eufy.on('push connect', () => this.onPushConnect());\n this.eufy.on('push close', () => this.onPushClose());\n this.eufy.on('mqtt connect', () => this.onMQTTConnect());\n this.eufy.on('mqtt close', () => this.onMQTTClose());\n this.eufy.on('connect', () => this.onConnect());\n this.eufy.on('close', () => this.onClose());\n\n this.eufy.on('device property changed', (device: Device, name: string, value: PropertyValue) =>\n this.onDevicePropertyChanged(device, name, value),\n );\n\n this.eufy.on('station command result', (station: Station, result: CommandResult) =>\n this.onStationCommandResult(station, result),\n );\n //this.eufy.on(\"station download start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationDownloadStart(station, device, metadata, videostream, audiostream));\n //this.eufy.on(\"station download finish\", (station: Station, device: Device) => this.onStationDownloadFinish(station, device));\n this.eufy.on(\n 'station livestream start',\n (\n station: Station,\n device: Device,\n metadata: StreamMetadata,\n videostream: Readable,\n audiostream: Readable,\n ) => this.onStationLivestreamStart(station, device, metadata, videostream, audiostream),\n );\n this.eufy.on('station livestream stop', (station: Station, device: Device) =>\n this.onStationLivestreamStop(station, device),\n );\n this.eufy.on('station rtsp url', (station: Station, device: Device, value: string) =>\n this.onStationRTSPUrl(station, device, value),\n );\n this.eufy.on('station property changed', (station: Station, name: string, value: PropertyValue) =>\n this.onStationPropertyChanged(station, name, value),\n );\n this.eufy.on('station connect', (station: Station) => this.onStationConnect(station));\n this.eufy.on('station close', (station: Station) => this.onStationClose(station));\n this.eufy.on('tfa request', () => this.onTFARequest());\n this.eufy.on('captcha request', (captchaId: string, captcha: string) =>\n this.onCaptchaRequest(captchaId, captcha),\n );\n this.eufy.setCameraMaxLivestreamDuration(this.config.maxLivestreamDuration);\n\n await this.eufy.connect();\n\n if (pathToGo2rtc) {\n const go2rtcConfig: {\n [index: string]: {\n [index: string]: string | number | null;\n };\n } = {\n api: {\n listen: `:${this.config.go2rtc_api_port}`,\n },\n rtsp: {\n listen: `:${this.config.go2rtc_rtsp_port}`,\n },\n srtp: {\n listen: `:${this.config.go2rtc_srtp_port}`,\n },\n webrtc: {\n listen: `:${this.config.go2rtc_webrtc_port}`,\n },\n ffmpeg: {\n bin: pathToFfmpeg !== '' && pathToFfmpeg !== undefined ? pathToFfmpeg : 'ffmpeg',\n },\n streams: {},\n /*\"log\": {\n \"level\": \"debug\", // default level\n \"api\": \"debug\",\n \"exec\": \"debug\",\n \"ngrok\": \"debug\",\n \"rtsp\": \"debug\",\n \"streams\": \"debug\",\n \"webrtc\": \"debug\",\n }*/\n };\n if (this.config.go2rtc_rtsp_username !== '' && this.config.go2rtc_rtsp_password !== '') {\n go2rtcConfig.rtsp.username = this.config.go2rtc_rtsp_username;\n go2rtcConfig.rtsp.password = this.config.go2rtc_rtsp_password;\n }\n for (const device of await this.eufy.getDevices()) {\n go2rtcConfig.streams[device.getSerial()] = null;\n }\n this.startGo2rtc(JSON.stringify(go2rtcConfig));\n }\n }\n // Delete cunknown channels without childs\n const channels = await this.getChannelsAsync();\n for (const channel of channels) {\n if (channel.common.name === 'unknown') {\n const states = await this.getStatesAsync(`${channel._id}.*`);\n if (Object.keys(states).length === 0) {\n await this.delObjectAsync(channel._id);\n }\n }\n }\n }\n }\n\n /**\n * Starts go2rtc and keeps it running. Without this, a crashed go2rtc was only reported with\n * this.log.info() and never restarted, so every livestream failed until the adapter itself was\n * restarted - at the default log level \"info\" the reason was not even visible.\n *\n * @param go2rtcConfig The serialized go2rtc configuration\n */\n private startGo2rtc(go2rtcConfig: string): void {\n if (!pathToGo2rtc || this.terminating) {\n return;\n }\n\n const startedAt = Date.now();\n const go2rtc = childProcess.spawn(pathToGo2rtc, ['-config', go2rtcConfig], {\n shell: false,\n detached: false,\n windowsHide: true,\n });\n this.go2rtcProcess = go2rtc;\n\n go2rtc.on('error', error => {\n this.log.error(`go2rtc error: ${error}`);\n });\n go2rtc.stdout.setEncoding('utf8');\n go2rtc.stdout.on('data', data => {\n this.log.info(`go2rtc: ${data}`);\n });\n go2rtc.stderr.setEncoding('utf8');\n go2rtc.stderr.on('data', data => {\n this.log.error(`go2rtc error: ${data}`);\n });\n go2rtc.on('close', exitcode => {\n this.go2rtcProcess = undefined;\n if (this.terminating) {\n this.log.info(`go2rtc terminated with exitcode ${exitcode}`);\n return;\n }\n // A process that ran for a while was healthy - do not let an old crash shorten the\n // backoff of an unrelated one much later.\n if (Date.now() - startedAt >= GO2RTC_HEALTHY_RUNTIME) {\n this.go2rtcRestarts = 0;\n }\n const delay = Math.min(GO2RTC_RESTART_DELAY_MAX, GO2RTC_RESTART_DELAY_MIN * 2 ** this.go2rtcRestarts);\n this.go2rtcRestarts++;\n this.log.error(\n `go2rtc terminated unexpectedly with exitcode ${exitcode} - livestreaming is unavailable, restarting in ${delay / 1000}s`,\n );\n this.go2rtcRestartTimeout = this.setTimeout(() => {\n this.go2rtcRestartTimeout = undefined;\n this.startGo2rtc(go2rtcConfig);\n }, delay);\n });\n }\n\n private stopGo2rtc(): void {\n if (this.go2rtcRestartTimeout) {\n this.clearTimeout(this.go2rtcRestartTimeout);\n this.go2rtcRestartTimeout = undefined;\n }\n if (this.go2rtcProcess) {\n this.go2rtcProcess.kill();\n this.go2rtcProcess = undefined;\n }\n }\n\n public async writePersistentData(): Promise<void> {\n try {\n await this.writeFileAsync(this.namespace, this.persistentFile, JSON.stringify(this.persistentData));\n } catch (error) {\n this.logger.error(`writePersistentData() - Error: ${error as Error}`);\n }\n }\n\n private onPersistentData(data: string): void {\n this.writeFileAsync(this.namespace, this.persistentDriverFile, data).catch(error => {\n this.logger.error(`writePersistentDriverData() - Error: ${error}`);\n });\n }\n\n /**\n * Is called when the adapter shuts down - callback has to be called under any circumstances!\n *\n * @param callback\n */\n private async onUnload(callback: () => void): Promise<void> {\n try {\n // Before anything else, so the exit of go2rtc is not mistaken for a crash and restarted\n // into a shutting down adapter.\n this.terminating = true;\n this.stopGo2rtc();\n\n await this.writePersistentData();\n\n if (this.eufy) {\n if (this.eufy.isConnected()) {\n await this.setStateAsync('info.connection', { val: false, ack: true }).catch();\n }\n this.eufy.removeAllListeners();\n this.eufy.close();\n }\n\n callback();\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n callback();\n }\n }\n\n // If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.\n // You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`.\n // /**\n // * Is called if a subscribed object changes\n // */\n // private onObjectChange(id: string, obj: ioBroker.Object | null | undefined): void {\n // if (obj) {\n // // The object was changed\n // this.log.info(`object ${id} changed: ${JSON.stringify(obj)}`);\n // } else {\n // // The object was deleted\n // this.log.info(`object ${id} deleted`);\n // }\n // }\n\n /**\n * Is called if a subscribed state changes\n *\n * @param id\n * @param state\n */\n private async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise<void> {\n if (state) {\n // don't do anything if the state is acked\n if (!id || state.ack) {\n this.logger.debug(\n `state ${id} changed: ${state.val} (ack = ${state.ack}) was already acknowledged, ignore it...`,\n );\n return;\n }\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);\n\n const values = id.split('.');\n const station_sn = values[2];\n const device_type = values[3];\n\n if (station_sn == 'verify_code') {\n if (this.eufy && this.verify_code) {\n this.logger.info(`Verification code received, send it. (verify_code: ${state.val})`);\n await this.eufy.connect({ verifyCode: state.val as string } as LoginOptions);\n this.verify_code = false;\n await this.delStateAsync(id);\n }\n } else if (station_sn == 'captcha') {\n if (this.eufy && this.captchaId) {\n this.logger.info(`Captcha received, send it. (captcha: ${state.val})`);\n await this.eufy.connect({\n captcha: {\n captchaCode: state.val as string,\n captchaId: this.captchaId,\n },\n } as LoginOptions);\n this.captchaId = null;\n await this.delStateAsync(id);\n await this.delStateAsync('received_captcha_html');\n }\n } else if (device_type == 'station') {\n try {\n const station_state_name = values[4];\n if (this.eufy) {\n const obj = await this.getObjectAsync(id);\n if (obj) {\n if (obj.native.name !== undefined) {\n await this.eufy.setStationProperty(station_sn, obj.native.name, state.val);\n return;\n }\n }\n\n const station = await this.eufy.getStation(station_sn);\n switch (station_state_name) {\n case StationStateID.REBOOT:\n station.rebootHUB();\n break;\n case StationStateID.TRIGGER_ALARM_SOUND:\n station.triggerStationAlarmSound(this.config.alarmSoundDuration);\n break;\n case StationStateID.RESET_ALARM_SOUND:\n station.resetStationAlarmSound();\n break;\n }\n }\n } catch (error) {\n this.logger.error(`station - Error:`, error);\n }\n } else {\n try {\n const device_sn = values[4];\n const obj = await this.getObjectAsync(id);\n if (obj) {\n if (obj.native.name !== undefined) {\n try {\n await this.eufy.setDeviceProperty(\n device_sn,\n obj.native.name,\n obj.common.type === 'object' ? JSON.parse(state.val as string) : state.val,\n );\n } catch (error) {\n this.logger.error(\n `Error in setting property value (property: ${obj.native.name} value: ${state.val})`,\n error,\n );\n }\n return;\n }\n }\n\n const device_state_name = values[5];\n const station = await this.eufy.getStation(station_sn);\n const device = await this.eufy.getDevice(device_sn);\n\n switch (device_state_name) {\n case DeviceStateID.START_STREAM:\n await this.startLivestream(device_sn);\n break;\n case DeviceStateID.STOP_STREAM:\n await this.stopLivestream(device_sn);\n break;\n case DeviceStateID.TRIGGER_ALARM_SOUND:\n station.triggerDeviceAlarmSound(device, this.config.alarmSoundDuration);\n break;\n case DeviceStateID.RESET_ALARM_SOUND:\n station.resetDeviceAlarmSound(device);\n break;\n case DeviceStateID.ROTATE_360:\n station.panAndTilt(device, PanTiltDirection.ROTATE360);\n break;\n case DeviceStateID.PAN_LEFT:\n station.panAndTilt(device, PanTiltDirection.LEFT);\n break;\n case DeviceStateID.PAN_RIGHT:\n station.panAndTilt(device, PanTiltDirection.RIGHT);\n break;\n case DeviceStateID.TILT_UP:\n station.panAndTilt(device, PanTiltDirection.UP);\n break;\n case DeviceStateID.TILT_DOWN:\n station.panAndTilt(device, PanTiltDirection.DOWN);\n break;\n case DeviceStateID.CALIBRATE:\n if (device.isLock()) {\n station.calibrateLock(device);\n } else {\n station.calibrate(device);\n }\n break;\n case DeviceStateID.UNLOCK:\n station.unlock(device);\n break;\n case DeviceStateID.SET_DEFAULT_ANGLE:\n station.setDefaultAngle(device);\n break;\n case DeviceStateID.SET_PRIVACY_ANGLE:\n station.setPrivacyAngle(device);\n break;\n case DeviceStateID.OPEN_BOX:\n station.open(device);\n break;\n }\n } catch (error) {\n this.logger.error(`cameras - Error:`, error);\n }\n }\n } else {\n // The state was deleted\n this.logger.debug(`state ${id} deleted`);\n }\n }\n\n /**\n * Some message was sent to this instance over the message box. Used by email, pushover, text2speech, ...\n * Using this method requires the \"common.message\" property to be set to true in io-package.json\n *\n * @param obj\n */\n private async onMessage(obj: ioBroker.Message): Promise<void> {\n if (typeof obj === 'object' && obj.message) {\n try {\n if (obj.command === 'quickResponse') {\n this.log.debug(`quickResponse command - message: ${JSON.stringify(obj.message)}`);\n if (\n typeof obj.message === 'object' &&\n typeof obj.message.station_sn === 'string' &&\n obj.message.station_sn !== '' &&\n typeof obj.message.device_sn === 'string' &&\n obj.message.device_sn !== '' &&\n typeof obj.message.voice_id === 'number'\n ) {\n try {\n const station = await this.eufy.getStation(obj.message.station_sn);\n const device = await this.eufy.getDevice(obj.message.device_sn);\n\n if (device.hasCommand(CommandName.DeviceQuickResponse)) {\n station.quickResponse(device, obj.message.voice_id);\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: true, // because of back compatibility\n sent: true,\n result: 'quickResponse command sent',\n },\n obj.callback,\n );\n }\n } else {\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: 'quickResponse command not supported by specified device',\n },\n obj.callback,\n );\n }\n }\n } catch (error) {\n if (error instanceof StationNotFoundError) {\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: \"quickResponse command not sent because specified station doesn't exists\",\n },\n obj.callback,\n );\n }\n } else if (error instanceof DeviceNotFoundError) {\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: \"quickResponse command not sent because specified device doesn't exists\",\n },\n obj.callback,\n );\n }\n } else {\n throw error;\n }\n }\n } else {\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: 'quickResponse command not sent because some required parameters are missing',\n },\n obj.callback,\n );\n }\n }\n } else if (obj.command === 'getQuickResponseVoices') {\n this.log.debug(`getQuickResponseVoices command - message: ${JSON.stringify(obj.message)}`);\n if (\n typeof obj.message === 'object' &&\n typeof obj.message.device_sn === 'string' &&\n obj.message.device_sn !== ''\n ) {\n const voices = await this.eufy.getApi().getVoices(obj.message.device_sn);\n\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: true, // because of back compatibility\n sent: true,\n result: voices,\n },\n obj.callback,\n );\n }\n } else {\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: 'getQuickResponseVoices command not sent because some required parameters are missing',\n },\n obj.callback,\n );\n }\n }\n } else if (obj.command === 'snooze') {\n this.log.debug(`snooze command - message: ${JSON.stringify(obj.message)}`);\n if (\n typeof obj.message === 'object' &&\n typeof obj.message.station_sn === 'string' &&\n obj.message.station_sn !== '' &&\n typeof obj.message.device_sn === 'string' &&\n obj.message.device_sn !== '' &&\n typeof obj.message.snooze_time === 'number' &&\n (obj.message.snooze_chime === undefined || typeof obj.message.snooze_chime === 'boolean') &&\n (obj.message.snooze_homebase === undefined ||\n typeof obj.message.snooze_homebase === 'boolean') &&\n (obj.message.snooze_motion === undefined || typeof obj.message.snooze_motion === 'boolean')\n ) {\n try {\n const station = await this.eufy.getStation(obj.message.station_sn);\n const device = await this.eufy.getDevice(obj.message.device_sn);\n\n if (device.hasCommand(CommandName.DeviceSnooze)) {\n station.snooze(device, {\n snooze_time: obj.message.snooze_time,\n snooze_chime: obj.message.snooze_chime,\n snooze_homebase: obj.message.snooze_homebase,\n snooze_motion: obj.message.snooze_motion,\n });\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: true, // because of back compatibility\n sent: true,\n result: 'snooze command sent',\n },\n obj.callback,\n );\n }\n } else {\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: 'snooze command not supported by specified device',\n },\n obj.callback,\n );\n }\n }\n } catch (error) {\n if (error instanceof StationNotFoundError) {\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: \"snooze command not sent because specified station doesn't exists\",\n },\n obj.callback,\n );\n }\n } else if (error instanceof DeviceNotFoundError) {\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: \"snooze command not sent because specified device doesn't exists\",\n },\n obj.callback,\n );\n }\n } else {\n throw error;\n }\n }\n } else {\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: 'snooze command not sent because some required parameters are missing',\n },\n obj.callback,\n );\n }\n }\n } else if (obj.command === 'chime') {\n this.log.debug(`snooze command - message: ${JSON.stringify(obj.message)}`);\n if (\n typeof obj.message === 'object' &&\n typeof obj.message.station_sn === 'string' &&\n obj.message.station_sn !== '' &&\n (obj.message.ringtone === undefined || typeof obj.message.ringtone === 'number')\n ) {\n try {\n const station = await this.eufy.getStation(obj.message.station_sn);\n\n if (station.hasCommand(CommandName.StationChime)) {\n station.chimeHomebase(\n obj.message.ringtone !== undefined && typeof obj.message.ringtone === 'number'\n ? obj.message.ringtone\n : 0,\n );\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: true, // because of back compatibility\n sent: true,\n result: 'chime command sent',\n },\n obj.callback,\n );\n }\n } else {\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: 'chime command not supported by specified station',\n },\n obj.callback,\n );\n }\n }\n\n if (obj.callback) {\n this.sendTo(obj.from, obj.command, 'chime command sent', obj.callback);\n }\n } catch (error) {\n if (error instanceof StationNotFoundError) {\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: \"snooze command not sent because specified station doesn't exists\",\n },\n obj.callback,\n );\n }\n } else {\n throw error;\n }\n }\n }\n } else if (obj.command === 'pollRefresh') {\n this.log.debug(`pollRefresh command`);\n await this.eufy.refreshCloudData();\n\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: true, // because of back compatibility\n sent: true,\n result: 'pollRefresh command sent',\n },\n obj.callback,\n );\n }\n } else {\n const errorMessage = `Received unknown message: ${JSON.stringify(obj.message)}`;\n this.log.warn(errorMessage);\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: errorMessage,\n },\n obj.callback,\n );\n }\n }\n } catch (error) {\n const errorMessage = `Error during processing of received message: ${error instanceof Error ? `${error.name} - ${error.message}` : (error as Error)}`;\n this.log.error(errorMessage);\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n sended: false, // because of back compatibility\n sent: false,\n result: errorMessage,\n },\n obj.callback,\n );\n }\n }\n }\n }\n\n private getStateCommon(property: PropertyMetadataAny): ioBroker.StateCommon {\n const state: ioBroker.StateCommon = {\n name: property.label!,\n type: property.type,\n role: 'state',\n read: property.readable,\n write: property.writeable,\n def:\n property.type === 'object' && typeof property.default === 'object'\n ? JSON.stringify(property.default)\n : property.default,\n };\n switch (property.type) {\n case 'number': {\n const numberProperty = property as PropertyMetadataNumeric;\n state.min = numberProperty.min;\n state.max = numberProperty.max;\n state.states = numberProperty.states;\n state.unit = numberProperty.unit;\n state.step = numberProperty.steps;\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : 'value';\n break;\n }\n case 'string': {\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : 'text';\n break;\n }\n case 'boolean': {\n state.role =\n RoleMapping[property.name] !== undefined\n ? RoleMapping[property.name]\n : property.writeable\n ? 'switch.enable'\n : 'state';\n break;\n }\n }\n return state;\n }\n\n private async createAndSetState(device: Device | Station, property: PropertyMetadataAny): Promise<void> {\n if (property.name !== PropertyName.Type && property.name !== PropertyName.DeviceStationSN) {\n const state = this.getStateCommon(property);\n const id: string = device.getStateID(convertCamelCaseToSnakeCase(property.name));\n const obj = await this.getObjectAsync(id);\n if (obj) {\n let changed = false;\n if (obj.native.name !== undefined && obj.native.name !== property.name) {\n obj.native.name = property.name;\n changed = true;\n }\n if (obj.native.key !== undefined && obj.native.key !== property.key) {\n obj.native.key = property.key;\n changed = true;\n }\n if (obj.native.commandId !== undefined && obj.native.commandId !== property.commandId) {\n obj.native.commandId = property.commandId;\n changed = true;\n }\n if (obj.common !== undefined && !util.isDeepStrictEqual(obj.common, state)) {\n changed = true;\n }\n if (changed) {\n const propertyMetadata = device.getPropertiesMetadata()[property.name];\n if (propertyMetadata !== undefined) {\n const newState = this.getStateCommon(propertyMetadata);\n obj.common = newState;\n }\n await this.setObjectAsync(id, obj);\n }\n } else {\n await this.setObjectNotExistsAsync(id, {\n type: 'state',\n common: state,\n native: {\n key: property.key,\n commandId: property.commandId,\n name: property.name,\n },\n });\n }\n const value = device.getPropertyValue(property.name);\n if (value !== undefined) {\n await setStateChangedAsync(\n this,\n id,\n (property.type === 'string' || property.type === 'object') && typeof value === 'object'\n ? JSON.stringify(value)\n : value,\n );\n }\n }\n }\n\n private async onDeviceAdded(device: Device): Promise<void> {\n this.logger.debug(`onDeviceAdded - device: ${device.getSerial()}`);\n\n await this.setObjectNotExistsAsync(device.getStateID('', 0), {\n type: 'channel',\n common: {\n name: device.getStateChannel(),\n },\n native: {},\n });\n\n await this.setObjectNotExistsAsync(device.getStateID('', 1), {\n type: 'device',\n common: {\n name: device.getName(),\n },\n native: {},\n });\n\n const metadata = device.getPropertiesMetadata();\n for (const property of Object.values(metadata)) {\n if (property.name !== PropertyName.DevicePicture) {\n await this.createAndSetState(device, property);\n }\n }\n\n if (device.hasProperty(PropertyName.DevicePicture)) {\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_URL), {\n type: 'state',\n common: {\n name: 'Picture URL',\n type: 'string',\n role: 'url',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_HTML), {\n type: 'state',\n common: {\n name: 'Picture HTML image',\n type: 'string',\n role: 'html',\n read: true,\n write: false,\n },\n native: {},\n });\n }\n\n if (device.hasCommand(CommandName.DeviceTriggerAlarmSound)) {\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TRIGGER_ALARM_SOUND), {\n type: 'state',\n common: {\n name: 'Trigger Alarm Sound',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RESET_ALARM_SOUND), {\n type: 'state',\n common: {\n name: 'Reset Alarm Sound',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n }\n if (device.hasCommand(CommandName.DevicePanAndTilt)) {\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_LEFT), {\n type: 'state',\n common: {\n name: 'Pan Left',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_RIGHT), {\n type: 'state',\n common: {\n name: 'Pan Right',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.ROTATE_360), {\n type: 'state',\n common: {\n name: 'Rotate 360\u00B0',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_UP), {\n type: 'state',\n common: {\n name: 'Tilt Up',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_DOWN), {\n type: 'state',\n common: {\n name: 'Tilt Down',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n }\n if (device.hasCommand(CommandName.DeviceLockCalibration)) {\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\n type: 'state',\n common: {\n name: 'Calibrate Lock',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n }\n if (device.hasCommand(CommandName.DeviceUnlock)) {\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.UNLOCK), {\n type: 'state',\n common: {\n name: 'Unlock',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n }\n if (device.hasCommand(CommandName.DeviceSetDefaultAngle)) {\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_DEFAULT_ANGLE), {\n type: 'state',\n common: {\n name: 'Set Default Angle',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n }\n if (device.hasCommand(CommandName.DeviceSetPrivacyAngle)) {\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_PRIVACY_ANGLE), {\n type: 'state',\n common: {\n name: 'Set Default Angle',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n }\n if (device.hasCommand(CommandName.DeviceCalibrate)) {\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\n type: 'state',\n common: {\n name: 'Calibrate',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n }\n if (device.hasCommand(CommandName.DeviceOpen)) {\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.OPEN_BOX), {\n type: 'state',\n common: {\n name: 'Open Box',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n }\n if (device.hasCommand(CommandName.DeviceStartLivestream)) {\n // Start Stream\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.START_STREAM), {\n type: 'state',\n common: {\n name: 'Start stream',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n\n // Stop Stream\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.STOP_STREAM), {\n type: 'state',\n common: {\n name: 'Stop stream',\n type: 'boolean',\n role: 'button.stop',\n read: false,\n write: true,\n },\n native: {},\n });\n\n // Livestream URL\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM), {\n type: 'state',\n common: {\n name: 'Livestream URL',\n type: 'string',\n role: 'url',\n read: true,\n write: false,\n },\n native: {},\n });\n\n // Livestream RTSP URL\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), {\n type: 'state',\n common: {\n name: 'Livestream RTSP URL',\n type: 'string',\n role: 'url',\n read: true,\n write: false,\n },\n native: {},\n });\n }\n\n if (device.hasProperty(PropertyName.DeviceRTSPStream)) {\n // RTSP Stream URL\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL), {\n type: 'state',\n common: {\n name: 'RTSP stream URL',\n type: 'string',\n role: 'url',\n read: true,\n write: false,\n },\n native: {},\n });\n }\n\n //TODO: Deactivated because the decryption of the download has changed.\n /*if (device.hasCommand(CommandName.DeviceStartDownload)) {\n // Last event video URL\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), {\n type: \"state\",\n common: {\n name: \"Last event video URL\",\n type: \"string\",\n role: \"url\",\n read: true,\n write: false,\n def: \"\"\n },\n native: {},\n });\n\n // Last event picture URL\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), {\n type: \"state\",\n common: {\n name: \"Last event picture URL\",\n type: \"string\",\n role: \"url\",\n read: true,\n write: false,\n def: \"\"\n },\n native: {},\n });\n\n // Last event picture HTML image\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), {\n type: \"state\",\n common: {\n name: \"Last event picture HTML image\",\n type: \"string\",\n role: \"html\",\n read: true,\n write: false,\n def: \"\"\n },\n native: {},\n });\n }*/\n }\n\n private onDeviceRemoved(device: Device): void {\n this.delObjectAsync(device.getStateID('', 0), { recursive: true }).catch(error => {\n this.logger.error(`Error deleting states of removed device`, error);\n });\n removeFiles(\n this as unknown as ioBroker.Adapter,\n device.getStationSerial(),\n DataLocation.LAST_EVENT,\n device.getSerial(),\n ).catch(error => {\n this.logger.error(`Error deleting fs contents of removed device`, error);\n });\n }\n\n private async onStationAdded(station: Station): Promise<void> {\n this.subscribeStates(`${station.getStateID('', 0)}.*`);\n\n await this.setObjectNotExistsAsync(station.getStateID('', 0), {\n type: 'device',\n common: {\n name: station.getName(),\n },\n native: {},\n });\n\n await this.setObjectNotExistsAsync(station.getStateID('', 1), {\n type: 'channel',\n common: {\n name: station.getStateChannel(),\n },\n native: {},\n });\n\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\n type: 'state',\n common: {\n name: 'Connection',\n type: 'boolean',\n role: 'indicator.connection',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\n\n const metadata = station.getPropertiesMetadata();\n for (const property of Object.values(metadata)) {\n await this.createAndSetState(station, property);\n }\n\n // Reboot station\n if (station.hasCommand(CommandName.StationReboot)) {\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.REBOOT), {\n type: 'state',\n common: {\n name: 'Reboot station',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n }\n // Alarm Sound\n if (station.hasCommand(CommandName.StationTriggerAlarmSound)) {\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.TRIGGER_ALARM_SOUND), {\n type: 'state',\n common: {\n name: 'Trigger Alarm Sound',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.RESET_ALARM_SOUND), {\n type: 'state',\n common: {\n name: 'Reset Alarm Sound',\n type: 'boolean',\n role: 'button.start',\n read: false,\n write: true,\n },\n native: {},\n });\n }\n }\n\n private onStationRemoved(station: Station): void {\n this.delObjectAsync(station.getStateID('', 0), { recursive: true }).catch(error => {\n this.logger.error(`Error deleting states of removed station`, error);\n });\n this.delFileAsync(this.namespace, station.getSerial()).catch(error => {\n this.logger.error(`Error deleting fs contents of removed station`, error);\n });\n }\n\n /*private async downloadEventVideo(device: Device, event_time: number, full_path: string | undefined, cipher_id: number | undefined): Promise<void> {\n this.logger.debug(`Device: ${device.getSerial()} full_path: ${full_path} cipher_id: ${cipher_id}`);\n try {\n if (!isEmpty(full_path) && cipher_id !== undefined) {\n const station = await this.eufy.getStation(device.getStationSerial());\n\n if (station !== undefined) {\n if (this.downloadEvent[device.getSerial()])\n clearTimeout(this.downloadEvent[device.getSerial()]);\n\n let videoLength = getVideoClipLength(device);\n const time_passed = (new Date().getTime() - new Date(event_time).getTime()) / 1000;\n\n if (time_passed >= videoLength)\n videoLength = 1;\n else\n videoLength = videoLength - time_passed;\n\n this.logger.info(`Downloading video event for device ${device.getSerial()} in ${videoLength} seconds...`);\n this.downloadEvent[device.getSerial()] = setTimeout(async () => {\n station.startDownload(device, full_path!, cipher_id);\n }, videoLength * 1000);\n }\n }\n } catch (error) {\n this.logger.error(`Device: ${device.getSerial()} - Error`, error);\n }\n }*/\n\n private handlePushNotification(message: PushMessage): void {\n try {\n if (message.device_sn !== undefined) {\n //TODO: Deactivated because the decryption of the download has changed.\n /*const device: Device = await this.eufy.getDevice(message.device_sn);\n if ((message.push_count === 1 || message.push_count === undefined) && (message.file_path !== undefined && message.file_path !== \"\" && message.cipher !== undefined))\n if (this.config.autoDownloadVideo)\n await this.downloadEventVideo(device, message.event_time, message.file_path, message.cipher);*/\n }\n } catch (error) {\n if (error instanceof DeviceNotFoundError) {\n //Do nothing\n } else {\n this.logger.error('Handling push notification - Error', error);\n }\n }\n }\n\n private async onConnect(): Promise<void> {\n await this.setObjectNotExistsAsync('info', {\n type: 'channel',\n common: {\n name: 'info',\n },\n native: {},\n });\n await this.setObjectNotExistsAsync('info.connection', {\n type: 'state',\n common: {\n name: 'Global connection',\n type: 'boolean',\n role: 'indicator.connection',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setStateAsync('info.connection', { val: true, ack: true });\n\n const stations = await this.eufy.getStations();\n const stationSerials: string[] = [];\n for (const station of stations) {\n stationSerials.push(station.getSerial());\n }\n const devices = await this.eufy.getDevices();\n const deviceSerials: string[] = [];\n for (const device of devices) {\n deviceSerials.push(device.getSerial());\n }\n\n // Delete obsolete stations\n try {\n const allDevices = await this.getDevicesAsync();\n const reg = new RegExp(`^${this.namespace}\\\\.[0-9A-Z]+$`);\n for (const id of allDevices) {\n if (id._id.match(reg)) {\n const serial = id._id.replace(`${this.namespace}.`, '');\n if (!stationSerials.includes(serial)) {\n await this.delObjectAsync(id._id, { recursive: true });\n }\n }\n }\n } catch (error) {\n this.log.error(`Delete obsolete stations ERROR - ${JSON.stringify(error)}`);\n }\n\n // Delete obsolete devices\n try {\n const allDevices = await this.getDevicesAsync();\n const reg = new RegExp(`^${this.namespace}\\\\.[0-9A-Z]+\\\\.[a-z]+\\\\.[0-9A-Z]+$`);\n for (const id of allDevices) {\n if (id._id.match(reg)) {\n const values = id._id.split('.');\n const stateChannel = values[3];\n const serial = values[4];\n if (\n !deviceSerials.includes(serial) ||\n (deviceSerials.includes(serial) &&\n devices[deviceSerials.indexOf(serial)].getStateChannel() !== 'unknown' &&\n stateChannel === 'unknown')\n ) {\n await this.delObjectAsync(id._id, { recursive: true });\n }\n }\n }\n } catch (error) {\n this.log.error(`Delete obsolete devices ERROR - ${JSON.stringify(error)}`);\n }\n\n // Delete obsolete properties\n try {\n const all = await this.getStatesAsync('*');\n if (all) {\n Object.keys(all).forEach(async stateid => {\n const object = await this.getObjectAsync(stateid);\n if (object?.native?.name !== undefined) {\n const tmp = stateid.split('.');\n if (tmp.length >= 5) {\n const stationSerial = tmp[2];\n const deviceSerial = tmp[4];\n\n if (deviceSerial.match(/^[A-Z0-9]+/)) {\n // Device\n try {\n const device = await this.eufy.getDevice(deviceSerial);\n if (!device.hasProperty(object.native.name)) {\n await this.delObjectAsync(stateid);\n }\n } catch (error) {\n if (error instanceof DeviceNotFoundError) {\n // ignore\n } else {\n this.log.error(\n `Delete obsolete properties ERROR - device - ${JSON.stringify(error)}`,\n );\n }\n }\n } else {\n // Station\n try {\n const station = await this.eufy.getStation(stationSerial);\n if (!station.hasProperty(object.native.name)) {\n await this.delObjectAsync(stateid);\n }\n } catch (error) {\n if (error instanceof StationNotFoundError) {\n // ignore\n } else {\n this.log.error(\n `Delete obsolete properties ERROR - station - ${JSON.stringify(error)}`,\n );\n }\n }\n }\n }\n }\n });\n }\n } catch (error) {\n this.log.error(`Delete obsolete properties ERROR - ${JSON.stringify(error)}`);\n }\n\n // Delete obsolete directories/files\n try {\n const contents = await this.readDirAsync(this.namespace, '');\n for (const content of contents.filter(fn => fn.file.match('^T[0-9A-Z]+$') !== null && fn.isDir)) {\n if (!stationSerials.includes(content.file)) {\n await this.delFileAsync(this.namespace, content.file);\n } else {\n const dirContents = await this.readDirAsync(this.namespace, content.file);\n for (const dir of dirContents.filter(\n fn => Object.values(DataLocation).includes(fn.file) && fn.isDir,\n )) {\n const files = await this.readDirAsync(this.namespace, path.join(content.file, dir.file));\n let deletedFiles = 0;\n for (const file of files.filter(\n fn => !deviceSerials.includes(fn.file.substring(0, 16)) && !fn.isDir,\n )) {\n await this.delFileAsync(this.namespace, path.join(content.file, dir.file, file.file));\n deletedFiles++;\n }\n if (deletedFiles === files.length) {\n await this.delFileAsync(this.namespace, path.join(content.file, dir.file));\n }\n }\n }\n }\n } catch (error) {\n this.log.error(`Delete obsolete directories/files ERROR - ${error as Error}`);\n }\n }\n\n private async onClose(): Promise<void> {\n await this.setStateAsync('info.connection', { val: false, ack: true }).catch();\n }\n\n public getPersistentData(): PersistentData {\n return this.persistentData;\n }\n\n private async onPushConnect(): Promise<void> {\n await this.setObjectNotExistsAsync('info', {\n type: 'channel',\n common: {\n name: 'info',\n },\n native: {},\n });\n await this.setObjectNotExistsAsync('info.push_connection', {\n type: 'state',\n common: {\n name: 'Push notification connection',\n type: 'boolean',\n role: 'indicator.connection',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setStateAsync('info.push_connection', { val: true, ack: true });\n }\n\n private async onPushClose(): Promise<void> {\n await this.setObjectNotExistsAsync('info', {\n type: 'channel',\n common: {\n name: 'info',\n },\n native: {},\n });\n await this.setObjectNotExistsAsync('info.push_connection', {\n type: 'state',\n common: {\n name: 'Push notification connection',\n type: 'boolean',\n role: 'indicator.connection',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setStateAsync('info.push_connection', { val: false, ack: true });\n }\n\n private async onMQTTConnect(): Promise<void> {\n await this.setObjectNotExistsAsync('info', {\n type: 'channel',\n common: {\n name: 'info',\n },\n native: {},\n });\n await this.setObjectNotExistsAsync('info.mqtt_connection', {\n type: 'state',\n common: {\n name: 'MQTT connection',\n type: 'boolean',\n role: 'indicator.connection',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setStateAsync('info.mqtt_connection', { val: true, ack: true });\n }\n\n private async onMQTTClose(): Promise<void> {\n await this.setObjectNotExistsAsync('info', {\n type: 'channel',\n common: {\n name: 'info',\n },\n native: {},\n });\n await this.setObjectNotExistsAsync('info.mqtt_connection', {\n type: 'state',\n common: {\n name: 'MQTT connection',\n type: 'boolean',\n role: 'indicator.connection',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setStateAsync('info.mqtt_connection', { val: false, ack: true });\n }\n\n private onStationCommandResult(station: Station, result: CommandResult): void {\n if (\n (result.return_code !== 0 &&\n result.command_type !== CommandType.P2P_QUERY_STATUS_IN_LOCK &&\n result.command_type !== CommandType.CMD_STORAGE_INFO_HB3 &&\n result.command_type !== CommandType.CMD_SDINFO_EX) ||\n (result.return_code !== 0 &&\n result.return_code !== ErrorCode.ERROR_DEV_BUSY &&\n result.command_type === CommandType.CMD_STORAGE_INFO_HB3)\n ) {\n this.logger.error(\n `Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${ErrorCode[result.return_code]} (${result.return_code})`,\n );\n } else if (\n result.return_code !== 0 &&\n result.return_code !== TFCardStatus.REMOVE &&\n result.return_code !== TFCardStatus.BUSY &&\n result.command_type === CommandType.CMD_SDINFO_EX\n ) {\n this.logger.error(\n `Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${TFCardStatus[result.return_code]} (${result.return_code})`,\n );\n }\n }\n\n private async onStationPropertyChanged(station: Station, name: string, value: PropertyValue): Promise<void> {\n const states = await this.getStatesAsync(`${station.getStateID('', 1)}.*`);\n for (const state in states) {\n const obj = await this.getObjectAsync(state);\n if (obj) {\n if (obj.native.name !== undefined && obj.native.name === name) {\n await setStateChangedAsync(\n this,\n state,\n (obj.common.type === 'string' || obj.common.type === 'object') && typeof value === 'object'\n ? JSON.stringify(value)\n : value,\n );\n return;\n }\n }\n }\n this.logger.debug(\n `onStationPropertyChanged(): Property \"${name}\" not implemented in this adapter (station: ${station.getSerial()} value: ${JSON.stringify(value)})`,\n );\n }\n\n private async onDevicePropertyChanged(device: Device, name: string, value: PropertyValue): Promise<void> {\n const states = await this.getStatesAsync(`${device.getStateID('', 1)}.*`);\n for (const state in states) {\n const obj = await this.getObjectAsync(state);\n if (obj) {\n if (obj.native.name !== undefined && obj.native.name === name) {\n await setStateChangedAsync(\n this,\n state,\n (obj.common.type === 'string' || obj.common.type === 'object') && typeof value === 'object'\n ? JSON.stringify(value)\n : value,\n );\n switch (name) {\n case PropertyName.DeviceRTSPStream:\n if ((value as boolean) === false) {\n await this.delStateAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL));\n }\n break;\n }\n return;\n }\n }\n }\n if (name === PropertyName.DevicePicture) {\n try {\n const picture = value as Picture;\n const fileName = `${device.getSerial()}.${picture.type.ext}`;\n const filePath = path.join(device.getStationSerial(), DataLocation.LAST_EVENT);\n if (!(await this.fileExistsAsync(this.namespace, filePath))) {\n await this.mkdirAsync(this.namespace, filePath);\n }\n await this.writeFileAsync(this.namespace, path.join(filePath, fileName), picture.data);\n\n await this.setStateAsync(\n device.getStateID(DeviceStateID.PICTURE_URL),\n `/files/${this.namespace}/${device.getStationSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}.${picture.type.ext}`,\n true,\n );\n await setStateChangedAsync(\n this,\n device.getStateID(DeviceStateID.PICTURE_HTML),\n getImageAsHTML(picture.data, picture.type.mime),\n );\n } catch (err) {\n const error = ensureError(err);\n this.logger.error('onDevicePropertyChanged - Property picture - Error', error);\n }\n } else {\n this.logger.debug(\n `onDevicePropertyChanged(): Property \"${name}\" not implemented in this adapter (device: ${device.getSerial()} value: ${JSON.stringify(value)})`,\n );\n }\n }\n\n /**\n * Tells whether a device streams at the \"Auto\" quality, where the camera is free to change the\n * resolution mid-stream. The numeric value of \"Auto\" is not the same for every device family,\n * so it is resolved through the state label of the property metadata.\n *\n * @param device The device to check\n * @returns true if the streaming quality is one of the \"Auto\" settings\n */\n private isVideoStreamingQualityAuto(device: Device): boolean {\n if (!device.hasProperty(PropertyName.DeviceVideoStreamingQuality)) {\n return false;\n }\n try {\n const metadata = device.getPropertyMetadata(\n PropertyName.DeviceVideoStreamingQuality,\n ) as PropertyMetadataNumeric;\n const value = device.getPropertyValue(PropertyName.DeviceVideoStreamingQuality);\n const label = metadata?.states?.[value as number];\n return typeof label === 'string' && label.startsWith(VIDEO_STREAMING_QUALITY_AUTO_LABEL);\n } catch (error) {\n // Only feeds a warning - it must never keep a livestream from starting.\n this.logger.debug(`Device: ${device.getSerial()} - Could not determine the video streaming quality`, error);\n return false;\n }\n }\n\n private async startLivestream(device_sn: string): Promise<void> {\n try {\n const device = await this.eufy.getDevice(device_sn);\n const station = await this.eufy.getStation(device.getStationSerial());\n\n if (station.isConnected() || station.isEnergySavingDevice()) {\n if (!station.isLiveStreaming(device)) {\n if (this.isVideoStreamingQualityAuto(device)) {\n // Measured on a T84A1: 2048x1536 -> 800x600 -> 1600x1200 within 20 seconds.\n // Every switch is a new SPS, and go2rtc does not hand out a new MSE init\n // segment for it, so browsers keep decoding against the old one.\n this.logger.warn(\n `The video streaming quality of device ${device_sn} is set to \"Auto\". The camera may change the resolution while the stream is running, which browsers using MSE cannot follow (green picture or artifacts). Set a fixed quality if you see this.`,\n );\n }\n await this.eufy.startStationLivestream(device_sn);\n } else {\n this.logger.warn(\n `The stream for the device ${device_sn} cannot be started, because it is already streaming!`,\n );\n }\n } else {\n this.logger.warn(\n `The stream for the device ${device_sn} cannot be started, because there is no connection to station ${station.getSerial()}!`,\n );\n }\n } catch (error) {\n this.logger.error('Start livestream - Error', error);\n }\n }\n\n private async stopLivestream(device_sn: string): Promise<void> {\n try {\n const device = await this.eufy.getDevice(device_sn);\n const station = await this.eufy.getStation(device.getStationSerial());\n if (device.isCamera()) {\n const camera = device as Camera;\n if (\n (await this.eufy.isStationConnected(device.getStationSerial())) &&\n station.isLiveStreaming(camera)\n ) {\n await this.eufy.stopStationLivestream(device_sn);\n } else {\n this.logger.warn(\n `The stream for the device ${device_sn} cannot be stopped, because it isn't streaming!`,\n );\n }\n }\n } catch (error) {\n this.logger.error('Stop livestream - Error', error);\n }\n }\n\n private async onStationLivestreamStart(\n station: Station,\n device: Device,\n metadata: StreamMetadata,\n videostream: Readable,\n audiostream: Readable,\n ): Promise<void> {\n try {\n await this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM), {\n val: `${this.config.https ? 'https' : 'http'}://${this.config.hostname}:${this.config.go2rtc_api_port}/stream.html?src=${device.getSerial()}`,\n ack: true,\n });\n await this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), {\n val: `rtsp://${this.config.hostname}:${this.config.go2rtc_rtsp_port}/${device.getSerial()}`,\n ack: true,\n });\n //await ffmpegStreamToGo2rtc(this.config, this.namespace, device.getSerial(), metadata, videostream, audiostream, this.logger);\n const results = await streamToGo2rtc(\n device.getSerial(),\n videostream,\n audiostream,\n this.logger,\n this.config,\n this.namespace,\n metadata,\n );\n if (streamToGo2rtcFailed(results)) {\n // streamToGo2rtc() settles instead of rejecting, so a broken pipeline never reached\n // the catch below, and the camera kept streaming into nothing until it timed out.\n this.logger.warn(\n `Station: ${station.getSerial()} Device: ${device.getSerial()} - Streaming to go2rtc failed - Stopping livestream...`,\n );\n await this.eufy.stopStationLivestream(device.getSerial()).catch(error => {\n this.logger.error(\n `Station: ${station.getSerial()} Device: ${device.getSerial()} - Error during stopping livestream...`,\n error,\n );\n });\n }\n } catch (error) {\n this.logger.error(\n `Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Stopping livestream...`,\n error,\n );\n this.eufy.stopStationLivestream(device.getSerial()).catch(error => {\n this.logger.error(\n `Station: ${station.getSerial()} Device: ${device.getSerial()} - Error during stopping livestream...`,\n error,\n );\n });\n }\n }\n\n private async onStationLivestreamStop(_station: Station, device: Device): Promise<void> {\n try {\n await this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM));\n await this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP));\n } catch (error) {\n this.log.error(`Cannot delete: ${error as Error}`);\n }\n }\n\n /*private async onStationDownloadFinish(_station: Station, _device: Device): Promise<void> {\n //this.logger.trace(`Station: ${station.getSerial()} channel: ${channel}`);\n }*/\n\n /*private async onStationDownloadStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise<void> {\n try {\n //TODO: Deactivated because the decryption of the download has changed.\n await removeFiles(this, station.getSerial(), DataLocation.TEMP, device.getSerial()).catch();\n const file_path = getDataFilePath(this, station.getSerial(), DataLocation.TEMP, `${device.getSerial()}${STREAM_FILE_NAME_EXT}`);\n\n await ffmpegStreamToHls(this.config, this.namespace, metadata, videostream, audiostream, file_path, this.logger)\n .then(async () => {\n if (fse.pathExistsSync(file_path)) {\n await removeFiles(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\n return true;\n }\n return false;\n })\n .then(async (result) => {\n if (result)\n await moveFiles(this, station.getSerial(), device.getSerial(), DataLocation.TEMP, DataLocation.LAST_EVENT);\n return result;\n })\n .then(async (result) => {\n if (result) {\n const filename_without_ext = getDataFilePath(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\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\");\n if (fse.pathExistsSync(`${filename_without_ext}${STREAM_FILE_NAME_EXT}`))\n await ffmpegPreviewImage(this.config, `${filename_without_ext}${STREAM_FILE_NAME_EXT}`, `${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`, this.logger)\n .then(() => {\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\");\n try {\n if (fse.existsSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`)) {\n const image_data = getImageAsHTML(fse.readFileSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`));\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), \"Last event picture HTML image\", image_data, \"html\");\n }\n } catch (error) {\n this.logger.error(`Station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\n }\n })\n .catch((error) => {\n this.logger.error(`ffmpegPreviewImage - station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\n });\n }\n })\n .catch(async (error) => {\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\n await this.eufy.cancelStationDownload(device.getSerial());\n });\n } catch(error) {\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\n await this.eufy.cancelStationDownload(device.getSerial());\n }\n }*/\n\n private async onStationRTSPUrl(station: Station, device: Device, value: string): Promise<void> {\n await setStateChangedAsync(this, device.getStateID(DeviceStateID.RTSP_STREAM_URL), value);\n }\n\n private async onStationConnect(station: Station): Promise<void> {\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\n type: 'state',\n common: {\n name: 'Connection',\n type: 'boolean',\n role: 'indicator.connection',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: true, ack: true });\n }\n\n private async onStationClose(station: Station): Promise<void> {\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\n type: 'state',\n common: {\n name: 'Connection',\n type: 'boolean',\n role: 'indicator.connection',\n read: true,\n write: false,\n },\n native: {},\n });\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\n\n // A station that dropped cannot be feeding go2rtc anymore. Leaving the livestream states\n // in place points every consumer at a producer that no longer exists.\n try {\n for (const device of await this.eufy.getDevicesFromStation(station.getSerial())) {\n await this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM)).catch(() => {\n /* not streaming */\n });\n await this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP)).catch(() => {\n /* not streaming */\n });\n }\n } catch (error) {\n this.logger.error(`Station: ${station.getSerial()} - Error while clearing livestream states`, error);\n }\n }\n\n private onTFARequest(): void {\n this.logger.warn(\n `Two factor authentication request received, please enter valid verification code in state ${this.namespace}.verify_code`,\n );\n this.verify_code = true;\n }\n\n private async onCaptchaRequest(captchaId: string, captcha: string): Promise<void> {\n this.captchaId = captchaId;\n this.logger.warn(\n `Captcha authentication request received, please enter valid captcha in state ${this.namespace}.captcha`,\n );\n this.logger.warn(`Captcha: <img src=\"${captcha}\">`);\n await this.setStateAsync('received_captcha_html', { val: `<img src=\"${captcha}\">`, ack: true });\n }\n}\n\nif (require.main !== module) {\n // Export the constructor in compact mode\n module.exports = (options: Partial<AdapterOptions> | undefined) => new euSec(options);\n} else {\n // otherwise start the instance directly\n (() => new euSec())();\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["getCountryCode", "isValidLanguageCode", "pathToGo2rtc", "pathToFfmpeg", "childProcess", "util", "error"]
|
|
7
7
|
}
|