diff --git a/README.md b/README.md index c6add56..6f68920 100644 --- a/README.md +++ b/README.md @@ -159,6 +159,16 @@ Best is to set the adapter to Debug log mode (see [here](https://bropat.github.i ## Changelog +### 1.2.0 (2023-11-04) + +* (bropat) Requires node version >= 18 +* (bropat) Added support for SmartTrack Link (T87B0) and SmartTrack Card (T87B2) +* (bropat) Added support for SoloCam S220 (T8134) +* (bropat) Fixed livestream issue +* (bropat) Updated version of the package go2rtc-static (1.8.1) +* (bropat) Updated version of the package eufy-security-client (2.9.0) +* (bropat) Further details can be found in the changelog of eufy-security-client (2.9.0) + ### 1.1.2 (2023-08-31) * (bropat) Updated version of the package eufy-security-client (2.8.1) diff --git a/build/lib/video.js b/build/lib/video.js index 0acf906..c9e38e4 100644 --- a/build/lib/video.js +++ b/build/lib/video.js @@ -62,6 +62,8 @@ const _UniversalStream = class { } this.server = import_net.default.createServer(onSocket); this.server.listen(sockpath); + this.server.on("error", () => { + }); } close() { if (this.server) @@ -183,7 +185,6 @@ const ffmpegStreamToGo2rtc = (config, namespace, camera, metadata, videoStream, try { if (import_ffmpeg_static.default) { import_fluent_ffmpeg.default.setFfmpegPath(import_ffmpeg_static.default); - log.warn("ffmpegStreamToGo2rtc(): Started"); videoStream.on("error", (error) => { log.error("ffmpegStreamToGo2rtc(): Videostream Error", error); }); @@ -197,7 +198,6 @@ const ffmpegStreamToGo2rtc = (config, namespace, camera, metadata, videoStream, const options = [ "-rtsp_transport tcp", "-sc_threshold 0", - `-g ${metadata.videoFPS}`, "-fflags genpts+nobuffer+flush_packets" ]; switch (metadata.videoCodec) { @@ -215,13 +215,20 @@ const ffmpegStreamToGo2rtc = (config, namespace, camera, metadata, videoStream, } const command = (0, import_fluent_ffmpeg.default)().withProcessOptions({ detached: true - }).input(uVideoStream.url).inputFormat(videoFormat).inputFps(metadata.videoFPS).videoCodec("copy"); + }).input(uVideoStream.url).inputFormat(videoFormat); + if (metadata.videoFPS > 0) { + options.push(`-g ${metadata.videoFPS}`); + command.inputFps(metadata.videoFPS); + } + command.videoCodec("copy"); if (audioFormat !== "") { command.input(uAudioStream.url).inputFormat(audioFormat).audioCodec("opus"); } else { log.warn(`ffmpegStreamToGo2rtc(): Not support audio codec or unknown audio codec (${import_eufy_security_client.AudioCodec[metadata.audioCodec]})`); } - command.output(`rtsp://localhost:${config.go2rtc_rtsp_port}/${camera}`).outputFormat("rtsp").addOptions(options).on("error", function(err, stdout, stderr) { + command.output(`rtsp://localhost:${config.go2rtc_rtsp_port}/${camera}`).outputFormat("rtsp").addOptions(options).on("start", (commandline) => { + log.debug(`ffmpegStreamToGo2rtc(): commandline: ${commandline}`); + }).on("error", function(err, stdout, stderr) { log.error(`ffmpegStreamToGo2rtc(): An error occurred: ${err.message}`); log.error(`ffmpegStreamToGo2rtc(): ffmpeg output: ${stdout}`); diff --git a/build/lib/video.js.map b/build/lib/video.js.map index 7595f09..726ef37 100644 --- a/build/lib/video.js.map +++ b/build/lib/video.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../src/lib/video.ts"], - "sourcesContent": ["import net from \"net\";\r\nimport path from \"path\";\r\nimport ffmpeg from \"@bropat/fluent-ffmpeg\";\r\nimport pathToFfmpeg from \"ffmpeg-static\";\r\nimport { Readable } from \"stream\";\r\nimport { StreamMetadata, AudioCodec, VideoCodec } from \"eufy-security-client\";\r\nimport { tmpdir } from \"os\";\r\nimport fse from \"fs-extra\";\r\n\r\nimport { ioBrokerLogger } from \"./log\";\r\nimport { lowestUnusedNumber } from \"./utils\";\r\n\r\nclass UniversalStream {\r\n\r\n public url: string;\r\n private static socks = new Set();\r\n private server: net.Server;\r\n private sock_id: number;\r\n\r\n constructor (namespace: string, onSocket: ((socket: net.Socket) => void) | undefined) {\r\n let sockpath = \"\";\r\n\r\n const unique_sock_id = lowestUnusedNumber([...UniversalStream.socks], 1);\r\n UniversalStream.socks.add(unique_sock_id);\r\n this.sock_id = unique_sock_id;\r\n\r\n if (process.platform === \"win32\") {\r\n const pipePrefix = \"\\\\\\\\.\\\\pipe\\\\\";\r\n const pipeName = `node-webrtc.${namespace}.${unique_sock_id}.sock`;\r\n\r\n sockpath = path.join(pipePrefix, pipeName);\r\n this.url = sockpath;\r\n }\r\n else {\r\n const pipeName = `${namespace}.${unique_sock_id}.sock`;\r\n sockpath = path.join(tmpdir(), pipeName);\r\n this.url = \"unix:\" + sockpath;\r\n\r\n try {\r\n if (fse.existsSync(sockpath))\r\n fse.unlinkSync(sockpath);\r\n } catch(error) {\r\n }\r\n }\r\n\r\n this.server = net.createServer(onSocket);\r\n this.server.listen(sockpath);\r\n }\r\n\r\n public close(): void {\r\n if (this.server)\r\n this.server.close();\r\n UniversalStream.socks.delete(this.sock_id);\r\n }\r\n\r\n}\r\n\r\nexport const StreamInput = function(namespace: string, stream: NodeJS.ReadableStream): UniversalStream {\r\n return new UniversalStream(namespace, (socket: net.Socket) => stream.pipe(socket, { end: true }))\r\n}\r\n\r\nexport const StreamOutput = function(namespace: string, stream: NodeJS.WritableStream): UniversalStream {\r\n return new UniversalStream(namespace, (socket: net.Socket) => socket.pipe(stream, { end: true }))\r\n}\r\n\r\nexport const ffmpegPreviewImage = (config: ioBroker.AdapterConfig, input:string, output: string, log: ioBrokerLogger, skip_seconds = 2.0): Promise => {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n })\r\n .addOptions([\r\n `-ss ${skip_seconds}`,\r\n \"-frames:v 1\"\r\n ])\r\n .input(input)\r\n .inputFormat(\"hls\")\r\n .outputFormat(\"image2\")\r\n .output(output)\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`ffmpegPreviewImage(): An error occurred: ${err.message}`);\r\n log.error(`ffmpegPreviewImage(): ffmpeg output:\\n${stdout}`);\r\n log.error(`ffmpegPreviewImage(): ffmpeg stderr:\\n${stderr}`);\r\n reject(err);\r\n })\r\n .on(\"end\", () => {\r\n log.debug(\"ffmpegPreviewImage(): Preview image generated!\");\r\n resolve();\r\n })\r\n .run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`ffmpegPreviewImage(): Error: ${error}`);\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\nexport const ffmpegStreamToHls = (config: ioBroker.AdapterConfig, namespace: string, metadata: StreamMetadata, videoStream: Readable, audioStream: Readable, output: string, log: ioBrokerLogger): Promise => {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n videoStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToHls(): Videostream Error\", error);\r\n });\r\n\r\n audioStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToHls(): Audiostream Error\", error);\r\n });\r\n\r\n const uVideoStream = StreamInput(namespace, videoStream);\r\n const uAudioStream = StreamInput(namespace, audioStream);\r\n\r\n let videoFormat = \"h264\";\r\n let audioFormat = \"\";\r\n const options: string[] = [\r\n \"-hls_init_time 0\",\r\n \"-hls_time 2\",\r\n \"-hls_segment_type mpegts\",\r\n //\"-start_number 1\",\r\n \"-sc_threshold 0\",\r\n `-g ${metadata.videoFPS}`,\r\n \"-fflags genpts+nobuffer+flush_packets\",\r\n //\"-flush_packets 1\",\r\n \"-hls_playlist_type event\"\r\n //\"-hls_flags split_by_time\"\r\n ];\r\n\r\n switch(metadata.videoCodec) {\r\n case VideoCodec.H264:\r\n videoFormat = \"h264\";\r\n break;\r\n case VideoCodec.H265:\r\n videoFormat = \"hevc\";\r\n break;\r\n }\r\n\r\n switch(metadata.audioCodec) {\r\n case AudioCodec.AAC:\r\n audioFormat = \"aac\";\r\n break;\r\n }\r\n\r\n const command = ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n })\r\n .input(uVideoStream.url)\r\n .inputFormat(videoFormat)\r\n .inputFps(metadata.videoFPS);\r\n if (audioFormat !== \"\") {\r\n command.input(uAudioStream.url)\r\n .inputFormat(audioFormat)\r\n .videoCodec(\"copy\")\r\n .audioCodec(\"copy\");\r\n options.push(\"-absf aac_adtstoasc\");\r\n } else {\r\n log.warn(`ffmpegStreamToHls(): Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`);\r\n }\r\n command.output(output)\r\n .addOptions(options)\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`ffmpegStreamToHls(): An error occurred: ${err.message}`);\r\n log.error(`ffmpegStreamToHls(): ffmpeg output:\\n${stdout}`);\r\n log.error(`ffmpegStreamToHls(): ffmpeg stderr:\\n${stderr}`);\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n reject(err);\r\n })\r\n .on(\"end\", () => {\r\n log.debug(\"ffmpegStreamToHls(): Processing finished!\");\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n resolve();\r\n });\r\n command.run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`ffmpegStreamToHls(): Error: ${error}`);\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\nexport const ffmpegStreamToGo2rtc = (config: ioBroker.AdapterConfig, namespace: string, camera: string, metadata: StreamMetadata, videoStream: Readable, audioStream: Readable, log: ioBrokerLogger): Promise => {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n log.warn(\"ffmpegStreamToGo2rtc(): Started\");\r\n\r\n videoStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToGo2rtc(): Videostream Error\", error);\r\n });\r\n\r\n audioStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToGo2rtc(): Audiostream Error\", error);\r\n });\r\n\r\n //TODO: For debugging purposes\r\n /*const outputFile = path.resolve(__dirname, \"../../test-stream.dump\");\r\n videoStream.pipe(fse.createWriteStream(outputFile)).on(\"finish\", () => {\r\n log.debug(\"videoStream dump finished!\");\r\n log.info(\"Manually test the output by running# ffplay output/test-stream.dump\");\r\n });*/\r\n\r\n const uVideoStream = StreamInput(namespace, videoStream);\r\n const uAudioStream = StreamInput(namespace, audioStream);\r\n\r\n let videoFormat = \"h264\";\r\n let audioFormat = \"\";\r\n const options: string[] = [\r\n \"-rtsp_transport tcp\",\r\n \"-sc_threshold 0\",\r\n `-g ${metadata.videoFPS}`,\r\n \"-fflags genpts+nobuffer+flush_packets\",\r\n //\"-rtpflags latm\",\r\n ];\r\n\r\n switch(metadata.videoCodec) {\r\n case VideoCodec.H264:\r\n videoFormat = \"h264\";\r\n break;\r\n case VideoCodec.H265:\r\n videoFormat = \"hevc\";\r\n break;\r\n }\r\n\r\n switch(metadata.audioCodec) {\r\n case AudioCodec.AAC:\r\n audioFormat = \"aac\";\r\n break;\r\n }\r\n\r\n const command = ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n })\r\n .input(uVideoStream.url)\r\n .inputFormat(videoFormat)\r\n .inputFps(metadata.videoFPS)\r\n .videoCodec(\"copy\");\r\n if (audioFormat !== \"\") {\r\n command.input(uAudioStream.url)\r\n .inputFormat(audioFormat)\r\n //.audioCodec(\"copy\");\r\n //.audioCodec(\"aac\");\r\n .audioCodec(\"opus\");\r\n } else {\r\n log.warn(`ffmpegStreamToGo2rtc(): Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`);\r\n }\r\n command.output(`rtsp://localhost:${config.go2rtc_rtsp_port}/${camera}`)\r\n .outputFormat(\"rtsp\")\r\n .addOptions(options)\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`ffmpegStreamToGo2rtc(): An error occurred: ${err.message}`);\r\n log.error(`ffmpegStreamToGo2rtc(): ffmpeg output:\\n${stdout}`);\r\n log.error(`ffmpegStreamToGo2rtc(): ffmpeg stderr:\\n${stderr}`);\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n reject(err);\r\n })\r\n .on(\"end\", () => {\r\n log.debug(\"ffmpegStreamToGo2rtc(): Processing finished!\");\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n resolve();\r\n });\r\n command.run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`ffmpegStreamToGo2rtc(): Error: ${error}`);\r\n reject(error);\r\n }\r\n });\r\n}\r\n"], - "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAgB;AAChB,kBAAiB;AACjB,2BAAmB;AACnB,2BAAyB;AAEzB,kCAAuD;AACvD,gBAAuB;AACvB,sBAAgB;AAGhB,mBAAmC;AAEnC,MAAM,mBAAN,MAAsB;AAAA,EAOlB,YAAa,WAAmB,UAAsD;AAClF,QAAI,WAAW;AAEf,UAAM,qBAAiB,iCAAmB,CAAC,GAAG,iBAAgB,KAAK,GAAG,CAAC;AACvE,qBAAgB,MAAM,IAAI,cAAc;AACxC,SAAK,UAAU;AAEf,QAAI,QAAQ,aAAa,SAAS;AAC9B,YAAM,aAAa;AACnB,YAAM,WAAW,eAAe,aAAa;AAE7C,iBAAW,YAAAA,QAAK,KAAK,YAAY,QAAQ;AACzC,WAAK,MAAM;AAAA,IACf,OACK;AACD,YAAM,WAAW,GAAG,aAAa;AACjC,iBAAW,YAAAA,QAAK,SAAK,kBAAO,GAAG,QAAQ;AACvC,WAAK,MAAM,UAAU;AAErB,UAAI;AACA,YAAI,gBAAAC,QAAI,WAAW,QAAQ;AACvB,0BAAAA,QAAI,WAAW,QAAQ;AAAA,MAC/B,SAAQ,OAAN;AAAA,MACF;AAAA,IACJ;AAEA,SAAK,SAAS,WAAAC,QAAI,aAAa,QAAQ;AACvC,SAAK,OAAO,OAAO,QAAQ;AAAA,EAC/B;AAAA,EAEO,QAAc;AACjB,QAAI,KAAK;AACL,WAAK,OAAO,MAAM;AACtB,qBAAgB,MAAM,OAAO,KAAK,OAAO;AAAA,EAC7C;AAEJ;AA3CA,IAAM,kBAAN;AAAM,gBAGa,QAAQ,oBAAI,IAAY;AA0CpC,MAAM,cAAc,SAAS,WAAmB,QAAgD;AACnG,SAAO,IAAI,gBAAgB,WAAW,CAAC,WAAuB,OAAO,KAAK,QAAQ,EAAE,KAAK,KAAK,CAAC,CAAC;AACpG;AAEO,MAAM,eAAe,SAAS,WAAmB,QAAgD;AACpG,SAAO,IAAI,gBAAgB,WAAW,CAAC,WAAuB,OAAO,KAAK,QAAQ,EAAE,KAAK,KAAK,CAAC,CAAC;AACpG;AAEO,MAAM,qBAAqB,CAAC,QAAgC,OAAc,QAAgB,KAAqB,eAAe,MAAuB;AACxJ,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,QAAI;AACA,UAAI,qBAAAC,SAAc;AACd,6BAAAC,QAAO,cAAc,qBAAAD,OAAY;AAEjC,iCAAAC,SAAO,EACF,mBAAmB;AAAA,UAChB,UAAU;AAAA,QACd,CAAC,EACA,WAAW;AAAA,UACR,OAAO;AAAA,UACP;AAAA,QACJ,CAAC,EACA,MAAM,KAAK,EACX,YAAY,KAAK,EACjB,aAAa,QAAQ,EACrB,OAAO,MAAM,EACb,GAAG,SAAS,SAAS,KAAK,QAAQ,QAAQ;AACvC,cAAI,MAAM,4CAA4C,IAAI,SAAS;AACnE,cAAI,MAAM;AAAA,EAAyC,QAAQ;AAC3D,cAAI,MAAM;AAAA,EAAyC,QAAQ;AAC3D,iBAAO,GAAG;AAAA,QACd,CAAC,EACA,GAAG,OAAO,MAAM;AACb,cAAI,MAAM,gDAAgD;AAC1D,kBAAQ;AAAA,QACZ,CAAC,EACA,IAAI;AAAA,MACb,OAAO;AACH,eAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC/C;AAAA,IACJ,SAAS,OAAP;AACE,UAAI,MAAM,gCAAgC,OAAO;AACjD,aAAO,KAAK;AAAA,IAChB;AAAA,EACJ,CAAC;AACL;AAEO,MAAM,oBAAoB,CAAC,QAAgC,WAAmB,UAA0B,aAAuB,aAAuB,QAAgB,QAAuC;AAChN,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,QAAI;AACA,UAAI,qBAAAD,SAAc;AACd,6BAAAC,QAAO,cAAc,qBAAAD,OAAY;AAEjC,oBAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,cAAI,MAAM,0CAA0C,KAAK;AAAA,QAC7D,CAAC;AAED,oBAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,cAAI,MAAM,0CAA0C,KAAK;AAAA,QAC7D,CAAC;AAED,cAAM,eAAe,YAAY,WAAW,WAAW;AACvD,cAAM,eAAe,YAAY,WAAW,WAAW;AAEvD,YAAI,cAAc;AAClB,YAAI,cAAc;AAClB,cAAM,UAAoB;AAAA,UACtB;AAAA,UACA;AAAA,UACA;AAAA,UAEA;AAAA,UACA,MAAM,SAAS;AAAA,UACf;AAAA,UAEA;AAAA,QAEJ;AAEA,gBAAO,SAAS,YAAY;AAAA,UACxB,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,UACJ,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,QACR;AAEA,gBAAO,SAAS,YAAY;AAAA,UACxB,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,QACR;AAEA,cAAM,cAAU,qBAAAC,SAAO,EAClB,mBAAmB;AAAA,UAChB,UAAU;AAAA,QACd,CAAC,EACA,MAAM,aAAa,GAAG,EACtB,YAAY,WAAW,EACvB,SAAS,SAAS,QAAQ;AAC/B,YAAI,gBAAgB,IAAI;AACpB,kBAAQ,MAAM,aAAa,GAAG,EACzB,YAAY,WAAW,EACvB,WAAW,MAAM,EACjB,WAAW,MAAM;AACtB,kBAAQ,KAAK,qBAAqB;AAAA,QACtC,OAAO;AACH,cAAI,KAAK,wEAAwE,uCAAW,SAAS,cAAc;AAAA,QACvH;AACA,gBAAQ,OAAO,MAAM,EAChB,WAAW,OAAO,EAClB,GAAG,SAAS,SAAS,KAAK,QAAQ,QAAQ;AACvC,cAAI,MAAM,2CAA2C,IAAI,SAAS;AAClE,cAAI,MAAM;AAAA,EAAwC,QAAQ;AAC1D,cAAI,MAAM;AAAA,EAAwC,QAAQ;AAC1D,uBAAa,MAAM;AACnB,uBAAa,MAAM;AACnB,iBAAO,GAAG;AAAA,QACd,CAAC,EACA,GAAG,OAAO,MAAM;AACb,cAAI,MAAM,2CAA2C;AACrD,uBAAa,MAAM;AACnB,uBAAa,MAAM;AACnB,kBAAQ;AAAA,QACZ,CAAC;AACL,gBAAQ,IAAI;AAAA,MAChB,OAAO;AACH,eAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC/C;AAAA,IACJ,SAAS,OAAP;AACE,UAAI,MAAM,+BAA+B,OAAO;AAChD,aAAO,KAAK;AAAA,IAChB;AAAA,EACJ,CAAC;AACL;AAEO,MAAM,uBAAuB,CAAC,QAAgC,WAAmB,QAAgB,UAA0B,aAAuB,aAAuB,QAAuC;AACnN,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,QAAI;AACA,UAAI,qBAAAD,SAAc;AACd,6BAAAC,QAAO,cAAc,qBAAAD,OAAY;AAEjC,YAAI,KAAK,iCAAiC;AAE1C,oBAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,cAAI,MAAM,6CAA6C,KAAK;AAAA,QAChE,CAAC;AAED,oBAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,cAAI,MAAM,6CAA6C,KAAK;AAAA,QAChE,CAAC;AASD,cAAM,eAAe,YAAY,WAAW,WAAW;AACvD,cAAM,eAAe,YAAY,WAAW,WAAW;AAEvD,YAAI,cAAc;AAClB,YAAI,cAAc;AAClB,cAAM,UAAoB;AAAA,UACtB;AAAA,UACA;AAAA,UACA,MAAM,SAAS;AAAA,UACf;AAAA,QAEJ;AAEA,gBAAO,SAAS,YAAY;AAAA,UACxB,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,UACJ,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,QACR;AAEA,gBAAO,SAAS,YAAY;AAAA,UACxB,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,QACR;AAEA,cAAM,cAAU,qBAAAC,SAAO,EAClB,mBAAmB;AAAA,UAChB,UAAU;AAAA,QACd,CAAC,EACA,MAAM,aAAa,GAAG,EACtB,YAAY,WAAW,EACvB,SAAS,SAAS,QAAQ,EAC1B,WAAW,MAAM;AACtB,YAAI,gBAAgB,IAAI;AACpB,kBAAQ,MAAM,aAAa,GAAG,EACzB,YAAY,WAAW,EAGvB,WAAW,MAAM;AAAA,QAC1B,OAAO;AACH,cAAI,KAAK,2EAA2E,uCAAW,SAAS,cAAc;AAAA,QAC1H;AACA,gBAAQ,OAAO,oBAAoB,OAAO,oBAAoB,QAAQ,EACjE,aAAa,MAAM,EACnB,WAAW,OAAO,EAClB,GAAG,SAAS,SAAS,KAAK,QAAQ,QAAQ;AACvC,cAAI,MAAM,8CAA8C,IAAI,SAAS;AACrE,cAAI,MAAM;AAAA,EAA2C,QAAQ;AAC7D,cAAI,MAAM;AAAA,EAA2C,QAAQ;AAC7D,uBAAa,MAAM;AACnB,uBAAa,MAAM;AACnB,iBAAO,GAAG;AAAA,QACd,CAAC,EACA,GAAG,OAAO,MAAM;AACb,cAAI,MAAM,8CAA8C;AACxD,uBAAa,MAAM;AACnB,uBAAa,MAAM;AACnB,kBAAQ;AAAA,QACZ,CAAC;AACL,gBAAQ,IAAI;AAAA,MAChB,OAAO;AACH,eAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC/C;AAAA,IACJ,SAAS,OAAP;AACE,UAAI,MAAM,kCAAkC,OAAO;AACnD,aAAO,KAAK;AAAA,IAChB;AAAA,EACJ,CAAC;AACL;", + "sourcesContent": ["import net from \"net\";\r\nimport path from \"path\";\r\nimport ffmpeg from \"@bropat/fluent-ffmpeg\";\r\nimport pathToFfmpeg from \"ffmpeg-static\";\r\nimport { Readable } from \"stream\";\r\nimport { StreamMetadata, AudioCodec, VideoCodec } from \"eufy-security-client\";\r\nimport { tmpdir } from \"os\";\r\nimport fse from \"fs-extra\";\r\n\r\nimport { ioBrokerLogger } from \"./log\";\r\nimport { lowestUnusedNumber } from \"./utils\";\r\n\r\nclass UniversalStream {\r\n\r\n public url: string;\r\n private static socks = new Set();\r\n private server: net.Server;\r\n private sock_id: number;\r\n\r\n constructor (namespace: string, onSocket: ((socket: net.Socket) => void) | undefined) {\r\n let sockpath = \"\";\r\n\r\n const unique_sock_id = lowestUnusedNumber([...UniversalStream.socks], 1);\r\n UniversalStream.socks.add(unique_sock_id);\r\n this.sock_id = unique_sock_id;\r\n\r\n if (process.platform === \"win32\") {\r\n const pipePrefix = \"\\\\\\\\.\\\\pipe\\\\\";\r\n const pipeName = `node-webrtc.${namespace}.${unique_sock_id}.sock`;\r\n\r\n sockpath = path.join(pipePrefix, pipeName);\r\n this.url = sockpath;\r\n }\r\n else {\r\n const pipeName = `${namespace}.${unique_sock_id}.sock`;\r\n sockpath = path.join(tmpdir(), pipeName);\r\n this.url = \"unix:\" + sockpath;\r\n\r\n try {\r\n if (fse.existsSync(sockpath))\r\n fse.unlinkSync(sockpath);\r\n } catch(error) {\r\n }\r\n }\r\n\r\n this.server = net.createServer(onSocket);\r\n this.server.listen(sockpath);\r\n this.server.on(\"error\", () => {});\r\n }\r\n\r\n public close(): void {\r\n if (this.server)\r\n this.server.close();\r\n UniversalStream.socks.delete(this.sock_id);\r\n }\r\n\r\n}\r\n\r\nexport const StreamInput = function(namespace: string, stream: NodeJS.ReadableStream): UniversalStream {\r\n return new UniversalStream(namespace, (socket: net.Socket) => stream.pipe(socket, { end: true }))\r\n}\r\n\r\nexport const StreamOutput = function(namespace: string, stream: NodeJS.WritableStream): UniversalStream {\r\n return new UniversalStream(namespace, (socket: net.Socket) => socket.pipe(stream, { end: true }))\r\n}\r\n\r\nexport const ffmpegPreviewImage = (config: ioBroker.AdapterConfig, input:string, output: string, log: ioBrokerLogger, skip_seconds = 2.0): Promise => {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n })\r\n .addOptions([\r\n `-ss ${skip_seconds}`,\r\n \"-frames:v 1\"\r\n ])\r\n .input(input)\r\n .inputFormat(\"hls\")\r\n .outputFormat(\"image2\")\r\n .output(output)\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`ffmpegPreviewImage(): An error occurred: ${err.message}`);\r\n log.error(`ffmpegPreviewImage(): ffmpeg output:\\n${stdout}`);\r\n log.error(`ffmpegPreviewImage(): ffmpeg stderr:\\n${stderr}`);\r\n reject(err);\r\n })\r\n .on(\"end\", () => {\r\n log.debug(\"ffmpegPreviewImage(): Preview image generated!\");\r\n resolve();\r\n })\r\n .run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`ffmpegPreviewImage(): Error: ${error}`);\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\nexport const ffmpegStreamToHls = (config: ioBroker.AdapterConfig, namespace: string, metadata: StreamMetadata, videoStream: Readable, audioStream: Readable, output: string, log: ioBrokerLogger): Promise => {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n videoStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToHls(): Videostream Error\", error);\r\n });\r\n\r\n audioStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToHls(): Audiostream Error\", error);\r\n });\r\n\r\n const uVideoStream = StreamInput(namespace, videoStream);\r\n const uAudioStream = StreamInput(namespace, audioStream);\r\n\r\n let videoFormat = \"h264\";\r\n let audioFormat = \"\";\r\n const options: string[] = [\r\n \"-hls_init_time 0\",\r\n \"-hls_time 2\",\r\n \"-hls_segment_type mpegts\",\r\n //\"-start_number 1\",\r\n \"-sc_threshold 0\",\r\n `-g ${metadata.videoFPS}`,\r\n \"-fflags genpts+nobuffer+flush_packets\",\r\n //\"-flush_packets 1\",\r\n \"-hls_playlist_type event\"\r\n //\"-hls_flags split_by_time\"\r\n ];\r\n\r\n switch(metadata.videoCodec) {\r\n case VideoCodec.H264:\r\n videoFormat = \"h264\";\r\n break;\r\n case VideoCodec.H265:\r\n videoFormat = \"hevc\";\r\n break;\r\n }\r\n\r\n switch(metadata.audioCodec) {\r\n case AudioCodec.AAC:\r\n audioFormat = \"aac\";\r\n break;\r\n }\r\n\r\n const command = ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n })\r\n .input(uVideoStream.url)\r\n .inputFormat(videoFormat)\r\n .inputFps(metadata.videoFPS);\r\n if (audioFormat !== \"\") {\r\n command.input(uAudioStream.url)\r\n .inputFormat(audioFormat)\r\n .videoCodec(\"copy\")\r\n .audioCodec(\"copy\");\r\n options.push(\"-absf aac_adtstoasc\");\r\n } else {\r\n log.warn(`ffmpegStreamToHls(): Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`);\r\n }\r\n command.output(output)\r\n .addOptions(options)\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`ffmpegStreamToHls(): An error occurred: ${err.message}`);\r\n log.error(`ffmpegStreamToHls(): ffmpeg output:\\n${stdout}`);\r\n log.error(`ffmpegStreamToHls(): ffmpeg stderr:\\n${stderr}`);\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n reject(err);\r\n })\r\n .on(\"end\", () => {\r\n log.debug(\"ffmpegStreamToHls(): Processing finished!\");\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n resolve();\r\n });\r\n command.run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`ffmpegStreamToHls(): Error: ${error}`);\r\n reject(error);\r\n }\r\n });\r\n}\r\n\r\nexport const ffmpegStreamToGo2rtc = (config: ioBroker.AdapterConfig, namespace: string, camera: string, metadata: StreamMetadata, videoStream: Readable, audioStream: Readable, log: ioBrokerLogger): Promise => {\r\n return new Promise((resolve, reject) => {\r\n try {\r\n if (pathToFfmpeg) {\r\n ffmpeg.setFfmpegPath(pathToFfmpeg);\r\n\r\n videoStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToGo2rtc(): Videostream Error\", error);\r\n });\r\n\r\n audioStream.on(\"error\", (error) => {\r\n log.error(\"ffmpegStreamToGo2rtc(): Audiostream Error\", error);\r\n });\r\n\r\n //TODO: For debugging purposes\r\n /*const outputFile = path.resolve(__dirname, \"../../test-stream.dump\");\r\n videoStream.pipe(fse.createWriteStream(outputFile)).on(\"finish\", () => {\r\n log.debug(\"videoStream dump finished!\");\r\n log.info(\"Manually test the output by running# ffplay output/test-stream.dump\");\r\n });*/\r\n\r\n const uVideoStream = StreamInput(namespace, videoStream);\r\n const uAudioStream = StreamInput(namespace, audioStream);\r\n\r\n let videoFormat = \"h264\";\r\n let audioFormat = \"\";\r\n const options: string[] = [\r\n \"-rtsp_transport tcp\",\r\n \"-sc_threshold 0\",\r\n \"-fflags genpts+nobuffer+flush_packets\",\r\n //\"-rtpflags latm\",\r\n ];\r\n\r\n switch(metadata.videoCodec) {\r\n case VideoCodec.H264:\r\n videoFormat = \"h264\";\r\n break;\r\n case VideoCodec.H265:\r\n videoFormat = \"hevc\";\r\n break;\r\n }\r\n\r\n switch(metadata.audioCodec) {\r\n case AudioCodec.AAC:\r\n audioFormat = \"aac\";\r\n break;\r\n }\r\n\r\n const command = ffmpeg()\r\n .withProcessOptions({\r\n detached: true\r\n })\r\n .input(uVideoStream.url)\r\n .inputFormat(videoFormat);\r\n if (metadata.videoFPS > 0 ) {\r\n options.push(`-g ${metadata.videoFPS}`);\r\n command.inputFps(metadata.videoFPS);\r\n }\r\n command.videoCodec(\"copy\");\r\n if (audioFormat !== \"\") {\r\n command.input(uAudioStream.url)\r\n .inputFormat(audioFormat)\r\n //.audioCodec(\"copy\");\r\n //.audioCodec(\"aac\");\r\n .audioCodec(\"opus\");\r\n } else {\r\n log.warn(`ffmpegStreamToGo2rtc(): Not support audio codec or unknown audio codec (${AudioCodec[metadata.audioCodec]})`);\r\n }\r\n command.output(`rtsp://localhost:${config.go2rtc_rtsp_port}/${camera}`)\r\n .outputFormat(\"rtsp\")\r\n .addOptions(options)\r\n .on(\"start\", (commandline) => {\r\n log.debug(`ffmpegStreamToGo2rtc(): commandline: ${commandline}`);\r\n })\r\n .on(\"error\", function(err, stdout, stderr) {\r\n log.error(`ffmpegStreamToGo2rtc(): An error occurred: ${err.message}`);\r\n log.error(`ffmpegStreamToGo2rtc(): ffmpeg output:\\n${stdout}`);\r\n log.error(`ffmpegStreamToGo2rtc(): ffmpeg stderr:\\n${stderr}`);\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n reject(err);\r\n })\r\n .on(\"end\", () => {\r\n log.debug(\"ffmpegStreamToGo2rtc(): Processing finished!\");\r\n uVideoStream.close();\r\n uAudioStream.close();\r\n resolve();\r\n });\r\n command.run();\r\n } else {\r\n reject(new Error(\"ffmpeg binary not found\"));\r\n }\r\n } catch (error) {\r\n log.error(`ffmpegStreamToGo2rtc(): Error: ${error}`);\r\n reject(error);\r\n }\r\n });\r\n}\r\n"], + "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAgB;AAChB,kBAAiB;AACjB,2BAAmB;AACnB,2BAAyB;AAEzB,kCAAuD;AACvD,gBAAuB;AACvB,sBAAgB;AAGhB,mBAAmC;AAEnC,MAAM,mBAAN,MAAsB;AAAA,EAOlB,YAAa,WAAmB,UAAsD;AAClF,QAAI,WAAW;AAEf,UAAM,qBAAiB,iCAAmB,CAAC,GAAG,iBAAgB,KAAK,GAAG,CAAC;AACvE,qBAAgB,MAAM,IAAI,cAAc;AACxC,SAAK,UAAU;AAEf,QAAI,QAAQ,aAAa,SAAS;AAC9B,YAAM,aAAa;AACnB,YAAM,WAAW,eAAe,aAAa;AAE7C,iBAAW,YAAAA,QAAK,KAAK,YAAY,QAAQ;AACzC,WAAK,MAAM;AAAA,IACf,OACK;AACD,YAAM,WAAW,GAAG,aAAa;AACjC,iBAAW,YAAAA,QAAK,SAAK,kBAAO,GAAG,QAAQ;AACvC,WAAK,MAAM,UAAU;AAErB,UAAI;AACA,YAAI,gBAAAC,QAAI,WAAW,QAAQ;AACvB,0BAAAA,QAAI,WAAW,QAAQ;AAAA,MAC/B,SAAQ,OAAN;AAAA,MACF;AAAA,IACJ;AAEA,SAAK,SAAS,WAAAC,QAAI,aAAa,QAAQ;AACvC,SAAK,OAAO,OAAO,QAAQ;AAC3B,SAAK,OAAO,GAAG,SAAS,MAAM;AAAA,IAAC,CAAC;AAAA,EACpC;AAAA,EAEO,QAAc;AACjB,QAAI,KAAK;AACL,WAAK,OAAO,MAAM;AACtB,qBAAgB,MAAM,OAAO,KAAK,OAAO;AAAA,EAC7C;AAEJ;AA5CA,IAAM,kBAAN;AAAM,gBAGa,QAAQ,oBAAI,IAAY;AA2CpC,MAAM,cAAc,SAAS,WAAmB,QAAgD;AACnG,SAAO,IAAI,gBAAgB,WAAW,CAAC,WAAuB,OAAO,KAAK,QAAQ,EAAE,KAAK,KAAK,CAAC,CAAC;AACpG;AAEO,MAAM,eAAe,SAAS,WAAmB,QAAgD;AACpG,SAAO,IAAI,gBAAgB,WAAW,CAAC,WAAuB,OAAO,KAAK,QAAQ,EAAE,KAAK,KAAK,CAAC,CAAC;AACpG;AAEO,MAAM,qBAAqB,CAAC,QAAgC,OAAc,QAAgB,KAAqB,eAAe,MAAuB;AACxJ,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,QAAI;AACA,UAAI,qBAAAC,SAAc;AACd,6BAAAC,QAAO,cAAc,qBAAAD,OAAY;AAEjC,iCAAAC,SAAO,EACF,mBAAmB;AAAA,UAChB,UAAU;AAAA,QACd,CAAC,EACA,WAAW;AAAA,UACR,OAAO;AAAA,UACP;AAAA,QACJ,CAAC,EACA,MAAM,KAAK,EACX,YAAY,KAAK,EACjB,aAAa,QAAQ,EACrB,OAAO,MAAM,EACb,GAAG,SAAS,SAAS,KAAK,QAAQ,QAAQ;AACvC,cAAI,MAAM,4CAA4C,IAAI,SAAS;AACnE,cAAI,MAAM;AAAA,EAAyC,QAAQ;AAC3D,cAAI,MAAM;AAAA,EAAyC,QAAQ;AAC3D,iBAAO,GAAG;AAAA,QACd,CAAC,EACA,GAAG,OAAO,MAAM;AACb,cAAI,MAAM,gDAAgD;AAC1D,kBAAQ;AAAA,QACZ,CAAC,EACA,IAAI;AAAA,MACb,OAAO;AACH,eAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC/C;AAAA,IACJ,SAAS,OAAP;AACE,UAAI,MAAM,gCAAgC,OAAO;AACjD,aAAO,KAAK;AAAA,IAChB;AAAA,EACJ,CAAC;AACL;AAEO,MAAM,oBAAoB,CAAC,QAAgC,WAAmB,UAA0B,aAAuB,aAAuB,QAAgB,QAAuC;AAChN,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,QAAI;AACA,UAAI,qBAAAD,SAAc;AACd,6BAAAC,QAAO,cAAc,qBAAAD,OAAY;AAEjC,oBAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,cAAI,MAAM,0CAA0C,KAAK;AAAA,QAC7D,CAAC;AAED,oBAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,cAAI,MAAM,0CAA0C,KAAK;AAAA,QAC7D,CAAC;AAED,cAAM,eAAe,YAAY,WAAW,WAAW;AACvD,cAAM,eAAe,YAAY,WAAW,WAAW;AAEvD,YAAI,cAAc;AAClB,YAAI,cAAc;AAClB,cAAM,UAAoB;AAAA,UACtB;AAAA,UACA;AAAA,UACA;AAAA,UAEA;AAAA,UACA,MAAM,SAAS;AAAA,UACf;AAAA,UAEA;AAAA,QAEJ;AAEA,gBAAO,SAAS,YAAY;AAAA,UACxB,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,UACJ,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,QACR;AAEA,gBAAO,SAAS,YAAY;AAAA,UACxB,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,QACR;AAEA,cAAM,cAAU,qBAAAC,SAAO,EAClB,mBAAmB;AAAA,UAChB,UAAU;AAAA,QACd,CAAC,EACA,MAAM,aAAa,GAAG,EACtB,YAAY,WAAW,EACvB,SAAS,SAAS,QAAQ;AAC/B,YAAI,gBAAgB,IAAI;AACpB,kBAAQ,MAAM,aAAa,GAAG,EACzB,YAAY,WAAW,EACvB,WAAW,MAAM,EACjB,WAAW,MAAM;AACtB,kBAAQ,KAAK,qBAAqB;AAAA,QACtC,OAAO;AACH,cAAI,KAAK,wEAAwE,uCAAW,SAAS,cAAc;AAAA,QACvH;AACA,gBAAQ,OAAO,MAAM,EAChB,WAAW,OAAO,EAClB,GAAG,SAAS,SAAS,KAAK,QAAQ,QAAQ;AACvC,cAAI,MAAM,2CAA2C,IAAI,SAAS;AAClE,cAAI,MAAM;AAAA,EAAwC,QAAQ;AAC1D,cAAI,MAAM;AAAA,EAAwC,QAAQ;AAC1D,uBAAa,MAAM;AACnB,uBAAa,MAAM;AACnB,iBAAO,GAAG;AAAA,QACd,CAAC,EACA,GAAG,OAAO,MAAM;AACb,cAAI,MAAM,2CAA2C;AACrD,uBAAa,MAAM;AACnB,uBAAa,MAAM;AACnB,kBAAQ;AAAA,QACZ,CAAC;AACL,gBAAQ,IAAI;AAAA,MAChB,OAAO;AACH,eAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC/C;AAAA,IACJ,SAAS,OAAP;AACE,UAAI,MAAM,+BAA+B,OAAO;AAChD,aAAO,KAAK;AAAA,IAChB;AAAA,EACJ,CAAC;AACL;AAEO,MAAM,uBAAuB,CAAC,QAAgC,WAAmB,QAAgB,UAA0B,aAAuB,aAAuB,QAAuC;AACnN,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACpC,QAAI;AACA,UAAI,qBAAAD,SAAc;AACd,6BAAAC,QAAO,cAAc,qBAAAD,OAAY;AAEjC,oBAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,cAAI,MAAM,6CAA6C,KAAK;AAAA,QAChE,CAAC;AAED,oBAAY,GAAG,SAAS,CAAC,UAAU;AAC/B,cAAI,MAAM,6CAA6C,KAAK;AAAA,QAChE,CAAC;AASD,cAAM,eAAe,YAAY,WAAW,WAAW;AACvD,cAAM,eAAe,YAAY,WAAW,WAAW;AAEvD,YAAI,cAAc;AAClB,YAAI,cAAc;AAClB,cAAM,UAAoB;AAAA,UACtB;AAAA,UACA;AAAA,UACA;AAAA,QAEJ;AAEA,gBAAO,SAAS,YAAY;AAAA,UACxB,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,UACJ,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,QACR;AAEA,gBAAO,SAAS,YAAY;AAAA,UACxB,KAAK,uCAAW;AACZ,0BAAc;AACd;AAAA,QACR;AAEA,cAAM,cAAU,qBAAAC,SAAO,EAClB,mBAAmB;AAAA,UAChB,UAAU;AAAA,QACd,CAAC,EACA,MAAM,aAAa,GAAG,EACtB,YAAY,WAAW;AAC5B,YAAI,SAAS,WAAW,GAAI;AACxB,kBAAQ,KAAK,MAAM,SAAS,UAAU;AACtC,kBAAQ,SAAS,SAAS,QAAQ;AAAA,QACtC;AACA,gBAAQ,WAAW,MAAM;AACzB,YAAI,gBAAgB,IAAI;AACpB,kBAAQ,MAAM,aAAa,GAAG,EACzB,YAAY,WAAW,EAGvB,WAAW,MAAM;AAAA,QAC1B,OAAO;AACH,cAAI,KAAK,2EAA2E,uCAAW,SAAS,cAAc;AAAA,QAC1H;AACA,gBAAQ,OAAO,oBAAoB,OAAO,oBAAoB,QAAQ,EACjE,aAAa,MAAM,EACnB,WAAW,OAAO,EAClB,GAAG,SAAS,CAAC,gBAAgB;AAC1B,cAAI,MAAM,wCAAwC,aAAa;AAAA,QACnE,CAAC,EACA,GAAG,SAAS,SAAS,KAAK,QAAQ,QAAQ;AACvC,cAAI,MAAM,8CAA8C,IAAI,SAAS;AACrE,cAAI,MAAM;AAAA,EAA2C,QAAQ;AAC7D,cAAI,MAAM;AAAA,EAA2C,QAAQ;AAC7D,uBAAa,MAAM;AACnB,uBAAa,MAAM;AACnB,iBAAO,GAAG;AAAA,QACd,CAAC,EACA,GAAG,OAAO,MAAM;AACb,cAAI,MAAM,8CAA8C;AACxD,uBAAa,MAAM;AACnB,uBAAa,MAAM;AACnB,kBAAQ;AAAA,QACZ,CAAC;AACL,gBAAQ,IAAI;AAAA,MAChB,OAAO;AACH,eAAO,IAAI,MAAM,yBAAyB,CAAC;AAAA,MAC/C;AAAA,IACJ,SAAS,OAAP;AACE,UAAI,MAAM,kCAAkC,OAAO;AACnD,aAAO,KAAK;AAAA,IAChB;AAAA,EACJ,CAAC;AACL;", "names": ["path", "fse", "net", "pathToFfmpeg", "ffmpeg"] } diff --git a/build/main.js b/build/main.js index bcc3c27..826fcba 100644 --- a/build/main.js +++ b/build/main.js @@ -1174,13 +1174,12 @@ class euSec extends utils.Adapter { try { this.setStateAsync(device.getStateID(import_types.DeviceStateID.LIVESTREAM), { val: `${this.config.https ? "https" : "http"}://${this.config.hostname}:${this.config.go2rtc_api_port}/stream.html?src=${device.getSerial()}`, ack: true }); this.setStateAsync(device.getStateID(import_types.DeviceStateID.LIVESTREAM_RTSP), { val: `rtsp://${this.config.hostname}:${this.config.go2rtc_rtsp_port}/${device.getSerial()}`, ack: true }); - await (0, import_video.ffmpegStreamToGo2rtc)(this.config, this.namespace, device.getSerial(), metadata, videostream, audiostream, this.logger).catch(async (error) => { - this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Stopping livestream...`, error); - await this.eufy.stopStationLivestream(device.getSerial()); - }); + await (0, import_video.ffmpegStreamToGo2rtc)(this.config, this.namespace, device.getSerial(), metadata, videostream, audiostream, this.logger); } catch (error) { this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Stopping livestream...`, error); - await this.eufy.stopStationLivestream(device.getSerial()); + this.eufy.stopStationLivestream(device.getSerial()).catch(async (error2) => { + this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error during stopping livestream...`, error2); + }); } } onStationLivestreamStop(_station, device) { diff --git a/build/main.js.map b/build/main.js.map index 22e4c52..523f181 100644 --- a/build/main.js.map +++ b/build/main.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../src/main.ts"], - "sourcesContent": ["/*\r\n * Created with @iobroker/create-adapter v2.5.0\r\n */\r\n\r\n// The adapter-core module gives you access to the core ioBroker functions\r\n// you need to create an adapter\r\nimport * as utils from \"@iobroker/adapter-core\";\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nimport { strict } from \"assert\";\r\nimport * as path from \"path\";\r\nimport { Camera, Device, Station, PushMessage, P2PConnectionType, EufySecurity, EufySecurityConfig, CommandResult, CommandType, ErrorCode, PropertyValue, PropertyName, StreamMetadata, PropertyMetadataNumeric, PropertyMetadataAny, CommandName, PanTiltDirection, DeviceNotFoundError, LoginOptions, Picture, StationNotFoundError, ensureError } from \"eufy-security-client\";\r\nimport { getAlpha2Code as getCountryCode } from \"i18n-iso-countries\"\r\nimport { isValid as isValidLanguageCode } from \"@cospired/i18n-iso-languages\"\r\nimport fse from \"fs-extra\";\r\nimport { Readable } from \"stream\";\r\nimport util from \"util\";\r\nimport childProcess from \"child_process\";\r\nimport pathToGo2rtc from \"go2rtc-static\";\r\nimport os from \"os\";\r\n\r\n//import * as Interface from \"./lib/interfaces\"\r\nimport { DeviceStateID, DataLocation, RoleMapping, StationStateID } from \"./lib/types\";\r\nimport { convertCamelCaseToSnakeCase, getImageAsHTML, handleUpdate, removeFiles, removeLastChar, setStateChangedAsync } from \"./lib/utils\";\r\nimport { PersistentData } from \"./lib/interfaces\";\r\nimport { ioBrokerLogger } from \"./lib/log\";\r\nimport { ffmpegStreamToGo2rtc } from \"./lib/video\";\r\n\r\n// Augment the adapter.config object with the actual types\r\n// TODO: delete this in the next version\r\n/*declare global {\r\n // eslint-disable-next-line @typescript-eslint/no-namespace\r\n namespace ioBroker {\r\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\r\n interface AdapterConfig extends Interface.AdapterConfig{\r\n // Define the shape of your options here (recommended)\r\n // Or use a catch-all approach\r\n //[key: string]: any;\r\n }\r\n }\r\n}*/\r\n\r\nclass euSec extends utils.Adapter {\r\n\r\n private eufy!: EufySecurity;\r\n /*private downloadEvent: {\r\n [index: string]: NodeJS.Timeout;\r\n } = {};*/\r\n\r\n private persistentFile: string;\r\n private logger!: ioBrokerLogger;\r\n private persistentData: PersistentData = {\r\n version: \"\"\r\n };\r\n private captchaId: string | null = null;\r\n private verify_code = false;\r\n\r\n public constructor(options: Partial = {}) {\r\n super({\r\n ...options,\r\n name: \"eusec\",\r\n });\r\n const data_dir = utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter);\r\n this.persistentFile = path.join(data_dir, \"adapter.json\");\r\n\r\n if (!fse.existsSync(data_dir))\r\n fse.mkdirSync(data_dir);\r\n\r\n this.on(\"ready\", this.onReady.bind(this));\r\n this.on(\"stateChange\", this.onStateChange.bind(this));\r\n // this.on(\"objectChange\", this.onObjectChange.bind(this));\r\n // this.on(\"message\", this.onMessage.bind(this));\r\n this.on(\"unload\", this.onUnload.bind(this));\r\n }\r\n\r\n /**\r\n * Is called when databases are connected and adapter received configuration.\r\n */\r\n private async onReady(): Promise {\r\n\r\n this.logger = new ioBrokerLogger(this.log as ioBroker.Logger);\r\n\r\n await this.setObjectNotExistsAsync(\"verify_code\", {\r\n type: \"state\",\r\n common: {\r\n name: \"2FA verification code\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"received_captcha_html\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Received captcha image HTML\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"captcha\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Enter captcha\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Global connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: false, ack: true });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: false, ack: true });\r\n\r\n try {\r\n const connection = await this.getStatesAsync(\"*.connection\");\r\n if (connection)\r\n Object.keys(connection).forEach(async id => {\r\n await this.setStateAsync(id, { val: false, ack: true });\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Reset connection states - Error\", error);\r\n }\r\n\r\n try {\r\n const sensorList = [\r\n PropertyName.DeviceMotionDetected,\r\n PropertyName.DevicePersonDetected,\r\n PropertyName.DeviceSoundDetected,\r\n PropertyName.DeviceCryingDetected,\r\n PropertyName.DevicePetDetected,\r\n PropertyName.DeviceRinging\r\n ];\r\n for(const sensorName of sensorList) {\r\n const sensors = await this.getStatesAsync(`*.${convertCamelCaseToSnakeCase(sensorName)}`);\r\n if (sensors)\r\n Object.keys(sensors).forEach(async id => {\r\n await this.setStateAsync(id, { val: false, ack: true });\r\n });\r\n }\r\n } catch (error) {\r\n this.logger.error(\"Reset sensor states - Error\", error);\r\n }\r\n\r\n try {\r\n if (fse.statSync(this.persistentFile).isFile()) {\r\n const fileContent = fse.readFileSync(this.persistentFile, \"utf8\");\r\n this.persistentData = JSON.parse(fileContent) as PersistentData;\r\n }\r\n } catch (error) {\r\n this.logger.debug(\"No stored data from last exit found.\", error);\r\n }\r\n\r\n this.subscribeStates(\"verify_code\");\r\n this.subscribeStates(\"captcha\");\r\n\r\n const systemConfig = await this.getForeignObjectAsync(\"system.config\");\r\n let countryCode = undefined;\r\n let languageCode = undefined;\r\n if (systemConfig) {\r\n countryCode = getCountryCode(systemConfig.common.country, \"en\");\r\n if (isValidLanguageCode(systemConfig.common.language))\r\n languageCode = systemConfig.common.language;\r\n }\r\n\r\n if (this.config.hostname === \"\") {\r\n this.config.hostname = os.hostname();\r\n }\r\n\r\n // Handling adapter version update\r\n try {\r\n if (this.persistentData.version !== this.version) {\r\n const currentVersion = Number.parseFloat(removeLastChar(this.version!, \".\"));\r\n const previousVersion = this.persistentData.version !== \"\" && this.persistentData.version !== undefined ? Number.parseFloat(removeLastChar(this.persistentData.version, \".\")) : 0;\r\n this.logger.debug(`Handling of adapter update - currentVersion: ${currentVersion} previousVersion: ${previousVersion}`);\r\n\r\n if (previousVersion < currentVersion) {\r\n await handleUpdate(this as unknown as ioBroker.Adapter, this.logger, previousVersion);\r\n this.persistentData.version = this.version!;\r\n this.writePersistentData();\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`Handling of adapter update - Error:`, error);\r\n }\r\n\r\n let connectionType = P2PConnectionType.QUICKEST;\r\n if (this.config.p2pConnectionType === \"only_local\") {\r\n connectionType = P2PConnectionType.ONLY_LOCAL;\r\n }\r\n\r\n const config: EufySecurityConfig = {\r\n username: this.config.username,\r\n password: this.config.password,\r\n country: countryCode,\r\n language: languageCode,\r\n persistentDir: utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter),\r\n eventDurationSeconds: this.config.eventDuration,\r\n p2pConnectionSetup: connectionType,\r\n pollingIntervalMinutes: this.config.pollingInterval,\r\n acceptInvitations: this.config.acceptInvitations,\r\n };\r\n\r\n this.eufy = await EufySecurity.initialize(config, this.logger);\r\n this.eufy.on(\"station added\", (station: Station) => this.onStationAdded(station));\r\n this.eufy.on(\"device added\", (device: Device) => this.onDeviceAdded(device));\r\n this.eufy.on(\"station removed\", (station: Station) => this.onStationRemoved(station));\r\n this.eufy.on(\"device removed\", (device: Device) => this.onDeviceRemoved(device));\r\n this.eufy.on(\"push message\", (messages) => this.handlePushNotification(messages));\r\n this.eufy.on(\"push connect\", () => this.onPushConnect());\r\n this.eufy.on(\"push close\", () => this.onPushClose());\r\n this.eufy.on(\"mqtt connect\", () => this.onMQTTConnect());\r\n this.eufy.on(\"mqtt close\", () => this.onMQTTClose());\r\n this.eufy.on(\"connect\", () => this.onConnect());\r\n this.eufy.on(\"close\", () => this.onClose());\r\n\r\n this.eufy.on(\"device property changed\", (device: Device, name: string, value: PropertyValue) => this.onDevicePropertyChanged(device, name, value));\r\n\r\n this.eufy.on(\"station command result\", (station: Station, result: CommandResult) => this.onStationCommandResult(station, result));\r\n //this.eufy.on(\"station download start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationDownloadStart(station, device, metadata, videostream, audiostream));\r\n //this.eufy.on(\"station download finish\", (station: Station, device: Device) => this.onStationDownloadFinish(station, device));\r\n this.eufy.on(\"station livestream start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationLivestreamStart(station, device, metadata, videostream, audiostream));\r\n this.eufy.on(\"station livestream stop\", (station: Station, device: Device) => this.onStationLivestreamStop(station, device));\r\n this.eufy.on(\"station rtsp url\", (station: Station, device: Device, value: string) => this.onStationRTSPUrl(station, device, value));\r\n this.eufy.on(\"station property changed\", (station: Station, name: string, value: PropertyValue) => this.onStationPropertyChanged(station, name, value));\r\n this.eufy.on(\"station connect\", (station: Station) => this.onStationConnect(station));\r\n this.eufy.on(\"station close\", (station: Station) => this.onStationClose(station));\r\n this.eufy.on(\"tfa request\", () => this.onTFARequest());\r\n this.eufy.on(\"captcha request\", (captchaId: string, captcha: string) => this.onCaptchaRequest(captchaId, captcha));\r\n this.eufy.setCameraMaxLivestreamDuration(this.config.maxLivestreamDuration);\r\n\r\n await this.eufy.connect();\r\n\r\n if (pathToGo2rtc) {\r\n const go2rtcConfig: {\r\n [index: string]: {\r\n [index: string]: string | number | null\r\n }\r\n } = {\r\n \"api\": {\r\n \"listen\": `:${this.config.go2rtc_api_port}`\r\n },\r\n \"rtsp\": {\r\n \"listen\": `:${this.config.go2rtc_rtsp_port}`\r\n },\r\n \"srtp\": {\r\n \"listen\": `:${this.config.go2rtc_srtp_port}`\r\n },\r\n \"webrtc\": {\r\n \"listen\": `:${this.config.go2rtc_webrtc_port}`\r\n },\r\n \"streams\": {}\r\n };\r\n if (this.config.go2rtc_rtsp_username !== \"\" && this.config.go2rtc_rtsp_password !== \"\") {\r\n go2rtcConfig.rtsp.username = this.config.go2rtc_rtsp_username;\r\n go2rtcConfig.rtsp.password = this.config.go2rtc_rtsp_password;\r\n }\r\n for (const device of await this.eufy.getDevices()) {\r\n go2rtcConfig.streams[device.getSerial()] = null;\r\n }\r\n const go2rtc = childProcess.spawn(pathToGo2rtc, [\"-config\", JSON.stringify(go2rtcConfig)], { shell: false, detached: false, windowsHide: true });\r\n go2rtc.on(\"error\", (error) => {\r\n this.log.error(`go2rtc error: ${error}`);\r\n });\r\n go2rtc.stdout.setEncoding(\"utf8\");\r\n go2rtc.stdout.on(\"data\", (data) => {\r\n this.log.info(`go2rtc started: ${data}`);\r\n });\r\n go2rtc.stderr.setEncoding(\"utf8\");\r\n go2rtc.stderr.on(\"data\", (data) => {\r\n this.log.error(`go2rtc error: ${data}`);\r\n });\r\n go2rtc.on(\"close\", (exitcode) => {\r\n this.log.info(`go2rtc terminated with exitcode ${exitcode}`);\r\n });\r\n process.on(\"exit\", () => {\r\n go2rtc.kill();\r\n });\r\n }\r\n }\r\n\r\n public writePersistentData(): void {\r\n try {\r\n fse.writeFileSync(this.persistentFile, JSON.stringify(this.persistentData));\r\n } catch (error) {\r\n this.logger.error(`writePersistentData() - Error: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Is called when adapter shuts down - callback has to be called under any circumstances!\r\n */\r\n private async onUnload(callback: () => void): Promise {\r\n try {\r\n\r\n this.writePersistentData();\r\n\r\n if (this.eufy) {\r\n if (this.eufy.isConnected())\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true }).catch();\r\n this.eufy.removeAllListeners();\r\n this.eufy.close();\r\n }\r\n\r\n callback();\r\n } catch (e) {\r\n callback();\r\n }\r\n }\r\n\r\n // If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.\r\n // You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`.\r\n // /**\r\n // * Is called if a subscribed object changes\r\n // */\r\n // private onObjectChange(id: string, obj: ioBroker.Object | null | undefined): void {\r\n // if (obj) {\r\n // // The object was changed\r\n // this.log.info(`object ${id} changed: ${JSON.stringify(obj)}`);\r\n // } else {\r\n // // The object was deleted\r\n // this.log.info(`object ${id} deleted`);\r\n // }\r\n // }\r\n\r\n /**\r\n * Is called if a subscribed state changes\r\n */\r\n private async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise {\r\n if (state) {\r\n\r\n // don't do anything if the state is acked\r\n if (!id || state.ack) {\r\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack}) was already acknowledged, ignore it...`);\r\n return;\r\n }\r\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);\r\n\r\n const values = id.split(\".\");\r\n const station_sn = values[2];\r\n const device_type = values[3];\r\n\r\n if (station_sn == \"verify_code\") {\r\n if (this.eufy && this.verify_code) {\r\n this.logger.info(`Verification code received, send it. (verify_code: ${state.val})`);\r\n await this.eufy.connect({ verifyCode: state.val as string } as LoginOptions);\r\n this.verify_code = false;\r\n await this.delStateAsync(id);\r\n }\r\n } else if (station_sn == \"captcha\") {\r\n if (this.eufy && this.captchaId) {\r\n this.logger.info(`Captcha received, send it. (captcha: ${state.val})`);\r\n await this.eufy.connect({\r\n captcha: {\r\n captchaCode: state.val as string,\r\n captchaId: this.captchaId\r\n }\r\n } as LoginOptions);\r\n this.captchaId = null;\r\n await this.delStateAsync(id);\r\n await this.delStateAsync(\"received_captcha_html\");\r\n }\r\n } else if (device_type == \"station\") {\r\n try {\r\n const station_state_name = values[4];\r\n if (this.eufy) {\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n if (obj.native.name !== undefined) {\r\n await this.eufy.setStationProperty(station_sn, obj.native.name, state.val);\r\n return;\r\n }\r\n }\r\n\r\n const station = await this.eufy.getStation(station_sn);\r\n switch(station_state_name) {\r\n case StationStateID.REBOOT:\r\n await station.rebootHUB();\r\n break;\r\n case StationStateID.TRIGGER_ALARM_SOUND:\r\n await station.triggerStationAlarmSound(this.config.alarmSoundDuration);\r\n break;\r\n case StationStateID.RESET_ALARM_SOUND:\r\n await station.resetStationAlarmSound();\r\n break;\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`station - Error:`, error);\r\n }\r\n } else {\r\n try {\r\n const device_sn = values[4];\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n if (obj.native.name !== undefined) {\r\n try {\r\n await this.eufy.setDeviceProperty(device_sn, obj.native.name, obj.common.type === \"object\" ? JSON.parse(state.val as string) : state.val);\r\n } catch (error) {\r\n this.logger.error(`Error in setting property value (property: ${obj.native.name} value: ${state.val})`, error);\r\n }\r\n return;\r\n }\r\n }\r\n\r\n const device_state_name = values[5];\r\n const station = await this.eufy.getStation(station_sn);\r\n const device = await this.eufy.getDevice(device_sn);\r\n\r\n switch(device_state_name) {\r\n case DeviceStateID.START_STREAM:\r\n await this.startLivestream(device_sn);\r\n break;\r\n case DeviceStateID.STOP_STREAM:\r\n await this.stopLivestream(device_sn);\r\n break;\r\n case DeviceStateID.TRIGGER_ALARM_SOUND:\r\n await station.triggerDeviceAlarmSound(device, this.config.alarmSoundDuration);\r\n break;\r\n case DeviceStateID.RESET_ALARM_SOUND:\r\n await station.resetDeviceAlarmSound(device);\r\n break;\r\n case DeviceStateID.ROTATE_360:\r\n await station.panAndTilt(device, PanTiltDirection.ROTATE360);\r\n break;\r\n case DeviceStateID.PAN_LEFT:\r\n await station.panAndTilt(device, PanTiltDirection.LEFT);\r\n break;\r\n case DeviceStateID.PAN_RIGHT:\r\n await station.panAndTilt(device, PanTiltDirection.RIGHT);\r\n break;\r\n case DeviceStateID.TILT_UP:\r\n await station.panAndTilt(device, PanTiltDirection.UP);\r\n break;\r\n case DeviceStateID.TILT_DOWN:\r\n await station.panAndTilt(device, PanTiltDirection.DOWN);\r\n break;\r\n case DeviceStateID.CALIBRATE:\r\n if (device.isLock()) {\r\n await station.calibrateLock(device);\r\n } else {\r\n await station.calibrate(device);\r\n }\r\n break;\r\n case DeviceStateID.UNLOCK:\r\n await station.unlock(device);\r\n break;\r\n case DeviceStateID.SET_DEFAULT_ANGLE:\r\n await station.setDefaultAngle(device);\r\n break;\r\n case DeviceStateID.SET_PRIVACY_ANGLE:\r\n await station.setPrivacyAngle(device);\r\n break;\r\n }\r\n } catch (error) {\r\n this.logger.error(`cameras - Error:`, error);\r\n }\r\n }\r\n } else {\r\n // The state was deleted\r\n this.logger.debug(`state ${id} deleted`);\r\n }\r\n }\r\n\r\n // If you need to accept messages in your adapter, uncomment the following block and the corresponding line in the constructor.\r\n // /**\r\n // * Some message was sent to this instance over message box. Used by email, pushover, text2speech, ...\r\n // * Using this method requires \"common.message\" property to be set to true in io-package.json\r\n // */\r\n // private onMessage(obj: ioBroker.Message): void {\r\n // if (typeof obj === \"object\" && obj.message) {\r\n // if (obj.command === \"send\") {\r\n // // e.g. send email or pushover or whatever\r\n // this.log.info(\"send command\");\r\n\r\n // // Send response in callback if required\r\n // if (obj.callback) this.sendTo(obj.from, obj.command, \"Message received\", obj.callback);\r\n // }\r\n // }\r\n // }\r\n\r\n private getStateCommon(property: PropertyMetadataAny): ioBroker.StateCommon {\r\n const state: ioBroker.StateCommon = {\r\n name: property.label!,\r\n type: property.type,\r\n role: \"state\",\r\n read: property.readable,\r\n write: property.writeable,\r\n def: property.default\r\n };\r\n switch (property.type) {\r\n case \"number\": {\r\n const numberProperty = property as PropertyMetadataNumeric;\r\n state.min = numberProperty.min;\r\n state.max = numberProperty.max;\r\n state.states = numberProperty.states;\r\n state.unit = numberProperty.unit;\r\n state.step = numberProperty.steps;\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : \"value\";\r\n break;\r\n }\r\n case \"string\": {\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : \"text\";\r\n break;\r\n }\r\n case \"boolean\": {\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : (property.writeable ? \"switch.enable\" : \"state\");\r\n break;\r\n }\r\n }\r\n return state;\r\n }\r\n\r\n private async createAndSetState(device: Device | Station, property: PropertyMetadataAny): Promise {\r\n if (property.name !== PropertyName.Type && property.name !== PropertyName.DeviceStationSN) {\r\n const state = this.getStateCommon(property);\r\n const id: string = device.getStateID(convertCamelCaseToSnakeCase(property.name));\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n let changed = false;\r\n if (obj.native.name !== undefined && obj.native.name !== property.name) {\r\n obj.native.name = property.name;\r\n changed = true;\r\n }\r\n if (obj.native.key !== undefined && obj.native.key !== property.key) {\r\n obj.native.key = property.key;\r\n changed = true;\r\n }\r\n if (obj.native.commandId !== undefined && obj.native.commandId !== property.commandId) {\r\n obj.native.commandId = property.commandId;\r\n changed = true;\r\n }\r\n if (obj.common !== undefined && !util.isDeepStrictEqual(obj.common, state)) {\r\n changed = true;\r\n }\r\n if (changed) {\r\n const propertyMetadata = device.getPropertiesMetadata()[property.name];\r\n if (propertyMetadata !== undefined) {\r\n const newState = this.getStateCommon(propertyMetadata);\r\n obj.common = newState;\r\n }\r\n await this.setObjectAsync(id, obj);\r\n }\r\n } else {\r\n await this.setObjectNotExistsAsync(id, {\r\n type: \"state\",\r\n common: state,\r\n native: {\r\n key: property.key,\r\n commandId: property.commandId,\r\n name: property.name,\r\n },\r\n });\r\n }\r\n const value = device.getPropertyValue(property.name);\r\n if (value !== undefined)\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, id, (property.type === \"string\" || property.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n }\r\n }\r\n\r\n private async onDeviceAdded(device: Device): Promise {\r\n this.logger.debug(`onDeviceAdded - device: ${device.getSerial()}`);\r\n\r\n await this.setObjectNotExistsAsync(device.getStateID(\"\", 0), {\r\n type: \"channel\",\r\n common: {\r\n name: device.getStateChannel()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(device.getStateID(\"\", 1), {\r\n type: \"device\",\r\n common: {\r\n name: device.getName()\r\n },\r\n native: {},\r\n });\r\n\r\n const metadata = device.getPropertiesMetadata();\r\n for(const property of Object.values(metadata)) {\r\n if (property.name !== PropertyName.DevicePicture)\r\n this.createAndSetState(device, property);\r\n }\r\n\r\n if (device.hasProperty(PropertyName.DevicePicture)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Picture URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_HTML), {\r\n type: \"state\",\r\n common: {\r\n name: \"Picture HTML image\",\r\n type: \"string\",\r\n role: \"html\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n if (device.hasCommand(CommandName.DeviceTriggerAlarmSound)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TRIGGER_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Trigger Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RESET_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reset Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DevicePanAndTilt)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_LEFT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Pan Left\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_RIGHT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Pan Right\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.ROTATE_360), {\r\n type: \"state\",\r\n common: {\r\n name: \"Rotate 360\u00B0\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_UP), {\r\n type: \"state\",\r\n common: {\r\n name: \"Tilt Up\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_DOWN), {\r\n type: \"state\",\r\n common: {\r\n name: \"Tilt Down\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceLockCalibration)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Calibrate Lock\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceUnlock)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.UNLOCK), {\r\n type: \"state\",\r\n common: {\r\n name: \"Unlock\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceSetDefaultAngle)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_DEFAULT_ANGLE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Set Default Angle\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceSetPrivacyAngle)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_PRIVACY_ANGLE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Set Default Angle\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceCalibrate)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Calibrate\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceStartLivestream)) {\r\n // Start Stream\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.START_STREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Start stream\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n\r\n // Stop Stream\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.STOP_STREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Stop stream\",\r\n type: \"boolean\",\r\n role: \"button.stop\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n\r\n // Livestream URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Livestream URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n\r\n // Livestream RTSP URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), {\r\n type: \"state\",\r\n common: {\r\n name: \"Livestream RTSP URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n if (device.hasProperty(PropertyName.DeviceRTSPStream)) {\r\n // RTSP Stream URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"RTSP stream URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n /*if (device.hasCommand(CommandName.DeviceStartDownload)) {\r\n // Last event video URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event video URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n\r\n // Last event picture URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event picture URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n\r\n // Last event picture HTML image\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event picture HTML image\",\r\n type: \"string\",\r\n role: \"html\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n }*/\r\n }\r\n\r\n private async onDeviceRemoved(device: Device): Promise {\r\n this.delObjectAsync(device.getStateID(\"\", 0), { recursive: true }).catch((error) => {\r\n this.logger.error(`Error deleting states of removed device`, error);\r\n });\r\n removeFiles(this as unknown as ioBroker.Adapter, device.getStationSerial(), DataLocation.LAST_EVENT, device.getSerial()).catch((error) => {\r\n this.logger.error(`Error deleting fs contents of removed device`, error);\r\n });\r\n }\r\n\r\n private async onStationAdded(station: Station): Promise {\r\n this.subscribeStates(`${station.getStateID(\"\", 0)}.*`);\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(\"\", 0), {\r\n type: \"device\",\r\n common: {\r\n name: station.getName()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(\"\", 1), {\r\n type: \"channel\",\r\n common: {\r\n name: station.getStateChannel()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\r\n\r\n const metadata = station.getPropertiesMetadata();\r\n for(const property of Object.values(metadata)) {\r\n this.createAndSetState(station, property);\r\n }\r\n\r\n // Reboot station\r\n if (station.hasCommand(CommandName.StationReboot)) {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.REBOOT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reboot station\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n // Alarm Sound\r\n if (station.hasCommand(CommandName.StationTriggerAlarmSound)) {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.TRIGGER_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Trigger Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.RESET_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reset Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n }\r\n\r\n private async onStationRemoved(station: Station): Promise {\r\n this.delObjectAsync(station.getStateID(\"\", 0), { recursive: true }).catch((error) => {\r\n this.logger.error(`Error deleting states of removed station`, error);\r\n });\r\n fse.remove(path.join(utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter), station.getSerial())).catch((error) => {\r\n this.logger.error(`Error deleting fs contents of removed station`, error);\r\n });\r\n }\r\n\r\n /*private async downloadEventVideo(device: Device, event_time: number, full_path: string | undefined, cipher_id: number | undefined): Promise {\r\n this.logger.debug(`Device: ${device.getSerial()} full_path: ${full_path} cipher_id: ${cipher_id}`);\r\n try {\r\n if (!isEmpty(full_path) && cipher_id !== undefined) {\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n\r\n if (station !== undefined) {\r\n if (this.downloadEvent[device.getSerial()])\r\n clearTimeout(this.downloadEvent[device.getSerial()]);\r\n\r\n let videoLength = getVideoClipLength(device);\r\n const time_passed = (new Date().getTime() - new Date(event_time).getTime()) / 1000;\r\n\r\n if (time_passed >= videoLength)\r\n videoLength = 1;\r\n else\r\n videoLength = videoLength - time_passed;\r\n\r\n this.logger.info(`Downloading video event for device ${device.getSerial()} in ${videoLength} seconds...`);\r\n this.downloadEvent[device.getSerial()] = setTimeout(async () => {\r\n station.startDownload(device, full_path!, cipher_id);\r\n }, videoLength * 1000);\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`Device: ${device.getSerial()} - Error`, error);\r\n }\r\n }*/\r\n\r\n private async handlePushNotification(message: PushMessage): Promise {\r\n try {\r\n if (message.device_sn !== undefined) {\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n /*const device: Device = await this.eufy.getDevice(message.device_sn);\r\n if ((message.push_count === 1 || message.push_count === undefined) && (message.file_path !== undefined && message.file_path !== \"\" && message.cipher !== undefined))\r\n if (this.config.autoDownloadVideo)\r\n await this.downloadEventVideo(device, message.event_time, message.file_path, message.cipher);*/\r\n }\r\n } catch (error) {\r\n if (error instanceof DeviceNotFoundError) {\r\n //Do nothing\r\n } else {\r\n this.logger.error(\"Handling push notification - Error\", error);\r\n }\r\n }\r\n }\r\n\r\n private async onConnect(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Global connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.connection\", { val: true, ack: true });\r\n\r\n const stations = await this.eufy.getStations();\r\n const stationSerials: string[] = [];\r\n for(const station of stations) {\r\n stationSerials.push(station.getSerial());\r\n }\r\n const devices = await this.eufy.getDevices();\r\n const deviceSerials: string[] = [];\r\n for(const device of devices) {\r\n deviceSerials.push(device.getSerial());\r\n }\r\n\r\n // Delete obsolete stations\r\n try {\r\n const allDevices = await this.getDevicesAsync();\r\n const reg = new RegExp(`^${this.namespace}\\.[0-9A-Z]+$`);\r\n for (const id of allDevices) {\r\n if (id._id.match(reg)) {\r\n const serial = id._id.replace(`${this.namespace}.`, \"\");\r\n if (!stationSerials.includes(serial)) {\r\n await this.delObjectAsync(id._id, { recursive: true });\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete stations ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete devices\r\n try {\r\n const allDevices = await this.getDevicesAsync();\r\n const reg = new RegExp(`^${this.namespace}\\.[0-9A-Z]+\\.[a-z]+\\.[0-9A-Z]+$`);\r\n for (const id of allDevices) {\r\n if (id._id.match(reg)) {\r\n const serial = id._id.split(\".\")[4];\r\n if (!deviceSerials.includes(serial)) {\r\n await this.delObjectAsync(id._id, { recursive: true });\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete devices ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete properties\r\n try {\r\n const all = await this.getStatesAsync(\"*\");\r\n if (all) {\r\n Object.keys(all).forEach(async (stateid) => {\r\n const object = await this.getObjectAsync(stateid);\r\n if (object?.native?.name !== undefined) {\r\n const tmp = stateid.split(\".\");\r\n if (tmp.length >= 5) {\r\n const stationSerial = tmp[2];\r\n const deviceSerial = tmp[4];\r\n\r\n if (deviceSerial.match(/^[A-Z0-9]+/)) {\r\n // Device\r\n try {\r\n const device = await this.eufy.getDevice(deviceSerial);\r\n if (!device.hasProperty(object.native.name)) {\r\n this.delObjectAsync(stateid);\r\n }\r\n } catch (error) {\r\n if (error instanceof DeviceNotFoundError) {\r\n } else {\r\n this.log.error(`Delete obsolete properties ERROR - device - ${JSON.stringify(error)}`);\r\n }\r\n }\r\n } else {\r\n // Station\r\n try {\r\n const station = await this.eufy.getStation(stationSerial);\r\n if (!station.hasProperty(object.native.name)) {\r\n this.delObjectAsync(stateid);\r\n }\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n } else {\r\n this.log.error(`Delete obsolete properties ERROR - station - ${JSON.stringify(error)}`);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete properties ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete directories/files\r\n new Promise(async (resolve, reject) => {\r\n try {\r\n const dir_path = path.join(utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter));\r\n if (fse.existsSync(dir_path)) {\r\n for (const content of fse.readdirSync(dir_path).filter(fn => fn.match(\"^T[0-9A-Z]+$\") !== null)) {\r\n if (!stationSerials.includes(content)) {\r\n fse.removeSync(path.join(dir_path, content));\r\n } else {\r\n for (const dir of fse.readdirSync(path.join(dir_path, content))) {\r\n if (dir === DataLocation.LIVESTREAM || dir === DataLocation.LAST_LIVESTREAM || dir === DataLocation.TEMP) {\r\n fse.removeSync(path.join(dir_path, content, dir));\r\n } else {\r\n const files = fse.readdirSync(path.join(dir_path, content, dir));\r\n let deletedFiles = 0;\r\n for (const file of files) {\r\n if (!deviceSerials.includes(file.substring(0, 16))) {\r\n fse.removeSync(path.join(dir_path, content, dir, file));\r\n deletedFiles++;\r\n }\r\n }\r\n if (deletedFiles === files.length) {\r\n fse.removeSync(path.join(dir_path, content, dir));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n resolve();\r\n } catch (error) {\r\n reject(error);\r\n }\r\n }).catch(error => {\r\n this.log.error(`Delete obsolete directories/files ERROR - ${JSON.stringify(error)}`);\r\n });\r\n }\r\n\r\n private async onClose(): Promise {\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true }).catch();\r\n }\r\n\r\n public getPersistentData(): PersistentData {\r\n return this.persistentData;\r\n }\r\n\r\n private async onPushConnect(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: true, ack: true });\r\n }\r\n\r\n private async onPushClose(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: false, ack: true });\r\n }\r\n\r\n private async onMQTTConnect(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: true, ack: true });\r\n }\r\n\r\n private async onMQTTClose(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: false, ack: true });\r\n }\r\n\r\n private async onStationCommandResult(station: Station, result: CommandResult): Promise {\r\n if (result.return_code !== 0 && result.command_type === CommandType.CMD_START_REALTIME_MEDIA) {\r\n this.logger.debug(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${ErrorCode[result.return_code]} (${result.return_code}) fallback to RTMP livestream...`);\r\n try {\r\n const device = await this.eufy.getStationDevice(station.getSerial(), result.channel);\r\n if (device.isCamera())\r\n this.eufy.startCloudLivestream(device.getSerial());\r\n } catch (error) {\r\n this.logger.error(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} RTMP fallback failed - Error ${error}`);\r\n }\r\n } else if (result.return_code !== 0 && result.command_type !== CommandType.P2P_QUERY_STATUS_IN_LOCK) {\r\n this.logger.error(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${ErrorCode[result.return_code]} (${result.return_code})`);\r\n }\r\n }\r\n\r\n private async onStationPropertyChanged(station: Station, name: string, value: PropertyValue): Promise {\r\n const states = await this.getStatesAsync(`${station.getStateID(\"\", 1)}.*`);\r\n for (const state in states) {\r\n const obj = await this.getObjectAsync(state);\r\n if (obj) {\r\n if (obj.native.name !== undefined && obj.native.name === name) {\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, state, (obj.common.type === \"string\" || obj.common.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n return;\r\n }\r\n }\r\n }\r\n this.logger.debug(`onStationPropertyChanged(): Property \"${name}\" not implemented in this adapter (station: ${station.getSerial()} value: ${JSON.stringify(value)})`);\r\n }\r\n\r\n private async onDevicePropertyChanged(device: Device, name: string, value: PropertyValue): Promise {\r\n const states = await this.getStatesAsync(`${device.getStateID(\"\", 1)}.*`);\r\n for (const state in states) {\r\n const obj = await this.getObjectAsync(state);\r\n if (obj) {\r\n if (obj.native.name !== undefined && obj.native.name === name) {\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, state, (obj.common.type === \"string\" || obj.common.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n switch(name) {\r\n case PropertyName.DeviceRTSPStream:\r\n if (value as boolean === false) {\r\n this.delStateAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL));\r\n }\r\n break;\r\n }\r\n return;\r\n }\r\n }\r\n }\r\n if (name === PropertyName.DevicePicture) {\r\n try {\r\n const picture = value as Picture;\r\n const fileName = `${device.getSerial()}.${picture.type.ext}`;\r\n const filePath = path.join(utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter), device.getStationSerial(), DataLocation.LAST_EVENT);\r\n\r\n if (!fse.existsSync(filePath)) {\r\n fse.mkdirSync(filePath, {mode: 0o775, recursive: true});\r\n }\r\n\r\n await fse.writeFile(path.join(filePath, fileName), picture.data);\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.PICTURE_URL), `/${this.namespace}/${device.getStationSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}.${picture.type.ext}`);\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.PICTURE_HTML), getImageAsHTML(picture.data, picture.type.mime));\r\n } catch (err) {\r\n const error = ensureError(err);\r\n this.logger.error(\"onDevicePropertyChanged - Property picture - Error\", error);\r\n }\r\n } else {\r\n this.logger.debug(`onDevicePropertyChanged(): Property \"${name}\" not implemented in this adapter (device: ${device.getSerial()} value: ${JSON.stringify(value)})`);\r\n }\r\n }\r\n\r\n private async startLivestream(device_sn: string): Promise {\r\n try {\r\n const device = await this.eufy.getDevice(device_sn);\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n\r\n if (station.isConnected() || station.isEnergySavingDevice()) {\r\n if (!station.isLiveStreaming(device)) {\r\n this.eufy.startStationLivestream(device_sn);\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be started, because it is already streaming!`);\r\n }\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be started, because there is no connection to station ${station.getSerial()}!`);\r\n }\r\n } catch (error) {\r\n this.logger.error(\"Start livestream - Error\", error);\r\n }\r\n }\r\n\r\n private async stopLivestream(device_sn: string): Promise {\r\n try {\r\n const device = await this.eufy.getDevice(device_sn);\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n if (device.isCamera()) {\r\n const camera = device as Camera;\r\n if (await this.eufy.isStationConnected(device.getStationSerial()) && station.isLiveStreaming(camera)) {\r\n await this.eufy.stopStationLivestream(device_sn);\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be stopped, because it isn't streaming!`);\r\n }\r\n }\r\n\r\n } catch (error) {\r\n this.logger.error(\"Stop livestream - Error\", error);\r\n }\r\n }\r\n\r\n private async onStationLivestreamStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise {\r\n try {\r\n this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM), { val: `${this.config.https ? \"https\" : \"http\"}://${this.config.hostname}:${this.config.go2rtc_api_port}/stream.html?src=${device.getSerial()}`, ack: true });\r\n this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), { val: `rtsp://${this.config.hostname}:${this.config.go2rtc_rtsp_port}/${device.getSerial()}`, ack: true });\r\n await ffmpegStreamToGo2rtc(this.config, this.namespace, device.getSerial(), metadata, videostream, audiostream, this.logger)\r\n .catch(async (error) => {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Stopping livestream...`, error);\r\n await this.eufy.stopStationLivestream(device.getSerial());\r\n });\r\n } catch(error) {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Stopping livestream...`, error);\r\n await this.eufy.stopStationLivestream(device.getSerial());\r\n }\r\n }\r\n\r\n private onStationLivestreamStop(_station: Station, device: Device): void {\r\n this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM));\r\n this.delStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP));\r\n }\r\n\r\n /*private async onStationDownloadFinish(_station: Station, _device: Device): Promise {\r\n //this.logger.trace(`Station: ${station.getSerial()} channel: ${channel}`);\r\n }*/\r\n\r\n /*private async onStationDownloadStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise {\r\n try {\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n await removeFiles(this, station.getSerial(), DataLocation.TEMP, device.getSerial()).catch();\r\n const file_path = getDataFilePath(this, station.getSerial(), DataLocation.TEMP, `${device.getSerial()}${STREAM_FILE_NAME_EXT}`);\r\n\r\n await ffmpegStreamToHls(this.config, this.namespace, metadata, videostream, audiostream, file_path, this.logger)\r\n .then(async () => {\r\n if (fse.pathExistsSync(file_path)) {\r\n await removeFiles(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\r\n return true;\r\n }\r\n return false;\r\n })\r\n .then(async (result) => {\r\n if (result)\r\n await moveFiles(this, station.getSerial(), device.getSerial(), DataLocation.TEMP, DataLocation.LAST_EVENT);\r\n return result;\r\n })\r\n .then(async (result) => {\r\n if (result) {\r\n const filename_without_ext = getDataFilePath(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), \"Last captured video URL\", `/${this.namespace}/${station.getSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}${STREAM_FILE_NAME_EXT}`, \"url\");\r\n if (fse.pathExistsSync(`${filename_without_ext}${STREAM_FILE_NAME_EXT}`))\r\n await ffmpegPreviewImage(this.config, `${filename_without_ext}${STREAM_FILE_NAME_EXT}`, `${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`, this.logger)\r\n .then(() => {\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), \"Last event picture URL\", `/${this.namespace}/${station.getSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}${IMAGE_FILE_JPEG_EXT}`, \"url\");\r\n try {\r\n if (fse.existsSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`)) {\r\n const image_data = getImageAsHTML(fse.readFileSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`));\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), \"Last event picture HTML image\", image_data, \"html\");\r\n }\r\n } catch (error) {\r\n this.logger.error(`Station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\r\n }\r\n })\r\n .catch((error) => {\r\n this.logger.error(`ffmpegPreviewImage - station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\r\n });\r\n }\r\n })\r\n .catch(async (error) => {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\r\n await this.eufy.cancelStationDownload(device.getSerial());\r\n });\r\n } catch(error) {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\r\n await this.eufy.cancelStationDownload(device.getSerial());\r\n }\r\n }*/\r\n\r\n private onStationRTSPUrl(station: Station, device: Device, value: string): void {\r\n setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.RTSP_STREAM_URL), value);\r\n }\r\n\r\n private async onStationConnect(station: Station): Promise {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: true, ack: true });\r\n }\r\n\r\n private async onStationClose(station: Station): Promise {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\r\n }\r\n\r\n private onTFARequest(): void {\r\n this.logger.warn(`Two factor authentication request received, please enter valid verification code in state ${this.namespace}.verify_code`);\r\n this.verify_code= true;\r\n }\r\n\r\n private onCaptchaRequest(captchaId: string, captcha: string): void {\r\n this.captchaId = captchaId;\r\n this.logger.warn(`Captcha authentication request received, please enter valid captcha in state ${this.namespace}.captcha`);\r\n this.logger.warn(`Captcha: `);\r\n this.setStateAsync(\"received_captcha_html\", { val: ``, ack: true });\r\n }\r\n\r\n}\r\n\r\nif (require.main !== module) {\r\n // Export the constructor in compact mode\r\n module.exports = (options: Partial | undefined) => new euSec(options);\r\n} else {\r\n // otherwise start the instance directly\r\n (() => new euSec())();\r\n}"], - "mappings": "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", - "names": ["fse", "getCountryCode", "isValidLanguageCode", "os", "pathToGo2rtc", "childProcess", "util"] + "sourcesContent": ["/*\r\n * Created with @iobroker/create-adapter v2.5.0\r\n */\r\n\r\n// The adapter-core module gives you access to the core ioBroker functions\r\n// you need to create an adapter\r\nimport * as utils from \"@iobroker/adapter-core\";\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nimport { strict } from \"assert\";\r\nimport * as path from \"path\";\r\nimport { Camera, Device, Station, PushMessage, P2PConnectionType, EufySecurity, EufySecurityConfig, CommandResult, CommandType, ErrorCode, PropertyValue, PropertyName, StreamMetadata, PropertyMetadataNumeric, PropertyMetadataAny, CommandName, PanTiltDirection, DeviceNotFoundError, LoginOptions, Picture, StationNotFoundError, ensureError } from \"eufy-security-client\";\r\nimport { getAlpha2Code as getCountryCode } from \"i18n-iso-countries\"\r\nimport { isValid as isValidLanguageCode } from \"@cospired/i18n-iso-languages\"\r\nimport fse from \"fs-extra\";\r\nimport { Readable } from \"stream\";\r\nimport util from \"util\";\r\nimport childProcess from \"child_process\";\r\nimport pathToGo2rtc from \"go2rtc-static\";\r\nimport os from \"os\";\r\n\r\n//import * as Interface from \"./lib/interfaces\"\r\nimport { DeviceStateID, DataLocation, RoleMapping, StationStateID } from \"./lib/types\";\r\nimport { convertCamelCaseToSnakeCase, getImageAsHTML, handleUpdate, removeFiles, removeLastChar, setStateChangedAsync } from \"./lib/utils\";\r\nimport { PersistentData } from \"./lib/interfaces\";\r\nimport { ioBrokerLogger } from \"./lib/log\";\r\nimport { ffmpegStreamToGo2rtc } from \"./lib/video\";\r\n\r\n// Augment the adapter.config object with the actual types\r\n// TODO: delete this in the next version\r\n/*declare global {\r\n // eslint-disable-next-line @typescript-eslint/no-namespace\r\n namespace ioBroker {\r\n // eslint-disable-next-line @typescript-eslint/no-empty-interface\r\n interface AdapterConfig extends Interface.AdapterConfig{\r\n // Define the shape of your options here (recommended)\r\n // Or use a catch-all approach\r\n //[key: string]: any;\r\n }\r\n }\r\n}*/\r\n\r\nclass euSec extends utils.Adapter {\r\n\r\n private eufy!: EufySecurity;\r\n /*private downloadEvent: {\r\n [index: string]: NodeJS.Timeout;\r\n } = {};*/\r\n\r\n private persistentFile: string;\r\n private logger!: ioBrokerLogger;\r\n private persistentData: PersistentData = {\r\n version: \"\"\r\n };\r\n private captchaId: string | null = null;\r\n private verify_code = false;\r\n\r\n public constructor(options: Partial = {}) {\r\n super({\r\n ...options,\r\n name: \"eusec\",\r\n });\r\n const data_dir = utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter);\r\n this.persistentFile = path.join(data_dir, \"adapter.json\");\r\n\r\n if (!fse.existsSync(data_dir))\r\n fse.mkdirSync(data_dir);\r\n\r\n this.on(\"ready\", this.onReady.bind(this));\r\n this.on(\"stateChange\", this.onStateChange.bind(this));\r\n // this.on(\"objectChange\", this.onObjectChange.bind(this));\r\n // this.on(\"message\", this.onMessage.bind(this));\r\n this.on(\"unload\", this.onUnload.bind(this));\r\n }\r\n\r\n /**\r\n * Is called when databases are connected and adapter received configuration.\r\n */\r\n private async onReady(): Promise {\r\n\r\n this.logger = new ioBrokerLogger(this.log as ioBroker.Logger);\r\n\r\n await this.setObjectNotExistsAsync(\"verify_code\", {\r\n type: \"state\",\r\n common: {\r\n name: \"2FA verification code\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"received_captcha_html\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Received captcha image HTML\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"captcha\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Enter captcha\",\r\n type: \"string\",\r\n role: \"state\",\r\n read: true,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Global connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: false, ack: true });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: false, ack: true });\r\n\r\n try {\r\n const connection = await this.getStatesAsync(\"*.connection\");\r\n if (connection)\r\n Object.keys(connection).forEach(async id => {\r\n await this.setStateAsync(id, { val: false, ack: true });\r\n });\r\n } catch (error) {\r\n this.logger.error(\"Reset connection states - Error\", error);\r\n }\r\n\r\n try {\r\n const sensorList = [\r\n PropertyName.DeviceMotionDetected,\r\n PropertyName.DevicePersonDetected,\r\n PropertyName.DeviceSoundDetected,\r\n PropertyName.DeviceCryingDetected,\r\n PropertyName.DevicePetDetected,\r\n PropertyName.DeviceRinging\r\n ];\r\n for(const sensorName of sensorList) {\r\n const sensors = await this.getStatesAsync(`*.${convertCamelCaseToSnakeCase(sensorName)}`);\r\n if (sensors)\r\n Object.keys(sensors).forEach(async id => {\r\n await this.setStateAsync(id, { val: false, ack: true });\r\n });\r\n }\r\n } catch (error) {\r\n this.logger.error(\"Reset sensor states - Error\", error);\r\n }\r\n\r\n try {\r\n if (fse.statSync(this.persistentFile).isFile()) {\r\n const fileContent = fse.readFileSync(this.persistentFile, \"utf8\");\r\n this.persistentData = JSON.parse(fileContent) as PersistentData;\r\n }\r\n } catch (error) {\r\n this.logger.debug(\"No stored data from last exit found.\", error);\r\n }\r\n\r\n this.subscribeStates(\"verify_code\");\r\n this.subscribeStates(\"captcha\");\r\n\r\n const systemConfig = await this.getForeignObjectAsync(\"system.config\");\r\n let countryCode = undefined;\r\n let languageCode = undefined;\r\n if (systemConfig) {\r\n countryCode = getCountryCode(systemConfig.common.country, \"en\");\r\n if (isValidLanguageCode(systemConfig.common.language))\r\n languageCode = systemConfig.common.language;\r\n }\r\n\r\n if (this.config.hostname === \"\") {\r\n this.config.hostname = os.hostname();\r\n }\r\n\r\n // Handling adapter version update\r\n try {\r\n if (this.persistentData.version !== this.version) {\r\n const currentVersion = Number.parseFloat(removeLastChar(this.version!, \".\"));\r\n const previousVersion = this.persistentData.version !== \"\" && this.persistentData.version !== undefined ? Number.parseFloat(removeLastChar(this.persistentData.version, \".\")) : 0;\r\n this.logger.debug(`Handling of adapter update - currentVersion: ${currentVersion} previousVersion: ${previousVersion}`);\r\n\r\n if (previousVersion < currentVersion) {\r\n await handleUpdate(this as unknown as ioBroker.Adapter, this.logger, previousVersion);\r\n this.persistentData.version = this.version!;\r\n this.writePersistentData();\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`Handling of adapter update - Error:`, error);\r\n }\r\n\r\n let connectionType = P2PConnectionType.QUICKEST;\r\n if (this.config.p2pConnectionType === \"only_local\") {\r\n connectionType = P2PConnectionType.ONLY_LOCAL;\r\n }\r\n\r\n const config: EufySecurityConfig = {\r\n username: this.config.username,\r\n password: this.config.password,\r\n country: countryCode,\r\n language: languageCode,\r\n persistentDir: utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter),\r\n eventDurationSeconds: this.config.eventDuration,\r\n p2pConnectionSetup: connectionType,\r\n pollingIntervalMinutes: this.config.pollingInterval,\r\n acceptInvitations: this.config.acceptInvitations,\r\n };\r\n\r\n this.eufy = await EufySecurity.initialize(config, this.logger);\r\n this.eufy.on(\"station added\", (station: Station) => this.onStationAdded(station));\r\n this.eufy.on(\"device added\", (device: Device) => this.onDeviceAdded(device));\r\n this.eufy.on(\"station removed\", (station: Station) => this.onStationRemoved(station));\r\n this.eufy.on(\"device removed\", (device: Device) => this.onDeviceRemoved(device));\r\n this.eufy.on(\"push message\", (messages) => this.handlePushNotification(messages));\r\n this.eufy.on(\"push connect\", () => this.onPushConnect());\r\n this.eufy.on(\"push close\", () => this.onPushClose());\r\n this.eufy.on(\"mqtt connect\", () => this.onMQTTConnect());\r\n this.eufy.on(\"mqtt close\", () => this.onMQTTClose());\r\n this.eufy.on(\"connect\", () => this.onConnect());\r\n this.eufy.on(\"close\", () => this.onClose());\r\n\r\n this.eufy.on(\"device property changed\", (device: Device, name: string, value: PropertyValue) => this.onDevicePropertyChanged(device, name, value));\r\n\r\n this.eufy.on(\"station command result\", (station: Station, result: CommandResult) => this.onStationCommandResult(station, result));\r\n //this.eufy.on(\"station download start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationDownloadStart(station, device, metadata, videostream, audiostream));\r\n //this.eufy.on(\"station download finish\", (station: Station, device: Device) => this.onStationDownloadFinish(station, device));\r\n this.eufy.on(\"station livestream start\", (station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable) => this.onStationLivestreamStart(station, device, metadata, videostream, audiostream));\r\n this.eufy.on(\"station livestream stop\", (station: Station, device: Device) => this.onStationLivestreamStop(station, device));\r\n this.eufy.on(\"station rtsp url\", (station: Station, device: Device, value: string) => this.onStationRTSPUrl(station, device, value));\r\n this.eufy.on(\"station property changed\", (station: Station, name: string, value: PropertyValue) => this.onStationPropertyChanged(station, name, value));\r\n this.eufy.on(\"station connect\", (station: Station) => this.onStationConnect(station));\r\n this.eufy.on(\"station close\", (station: Station) => this.onStationClose(station));\r\n this.eufy.on(\"tfa request\", () => this.onTFARequest());\r\n this.eufy.on(\"captcha request\", (captchaId: string, captcha: string) => this.onCaptchaRequest(captchaId, captcha));\r\n this.eufy.setCameraMaxLivestreamDuration(this.config.maxLivestreamDuration);\r\n\r\n await this.eufy.connect();\r\n\r\n if (pathToGo2rtc) {\r\n const go2rtcConfig: {\r\n [index: string]: {\r\n [index: string]: string | number | null\r\n }\r\n } = {\r\n \"api\": {\r\n \"listen\": `:${this.config.go2rtc_api_port}`\r\n },\r\n \"rtsp\": {\r\n \"listen\": `:${this.config.go2rtc_rtsp_port}`\r\n },\r\n \"srtp\": {\r\n \"listen\": `:${this.config.go2rtc_srtp_port}`\r\n },\r\n \"webrtc\": {\r\n \"listen\": `:${this.config.go2rtc_webrtc_port}`\r\n },\r\n \"streams\": {}\r\n };\r\n if (this.config.go2rtc_rtsp_username !== \"\" && this.config.go2rtc_rtsp_password !== \"\") {\r\n go2rtcConfig.rtsp.username = this.config.go2rtc_rtsp_username;\r\n go2rtcConfig.rtsp.password = this.config.go2rtc_rtsp_password;\r\n }\r\n for (const device of await this.eufy.getDevices()) {\r\n go2rtcConfig.streams[device.getSerial()] = null;\r\n }\r\n const go2rtc = childProcess.spawn(pathToGo2rtc, [\"-config\", JSON.stringify(go2rtcConfig)], { shell: false, detached: false, windowsHide: true });\r\n go2rtc.on(\"error\", (error) => {\r\n this.log.error(`go2rtc error: ${error}`);\r\n });\r\n go2rtc.stdout.setEncoding(\"utf8\");\r\n go2rtc.stdout.on(\"data\", (data) => {\r\n this.log.info(`go2rtc started: ${data}`);\r\n });\r\n go2rtc.stderr.setEncoding(\"utf8\");\r\n go2rtc.stderr.on(\"data\", (data) => {\r\n this.log.error(`go2rtc error: ${data}`);\r\n });\r\n go2rtc.on(\"close\", (exitcode) => {\r\n this.log.info(`go2rtc terminated with exitcode ${exitcode}`);\r\n });\r\n process.on(\"exit\", () => {\r\n go2rtc.kill();\r\n });\r\n }\r\n }\r\n\r\n public writePersistentData(): void {\r\n try {\r\n fse.writeFileSync(this.persistentFile, JSON.stringify(this.persistentData));\r\n } catch (error) {\r\n this.logger.error(`writePersistentData() - Error: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Is called when adapter shuts down - callback has to be called under any circumstances!\r\n */\r\n private async onUnload(callback: () => void): Promise {\r\n try {\r\n\r\n this.writePersistentData();\r\n\r\n if (this.eufy) {\r\n if (this.eufy.isConnected())\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true }).catch();\r\n this.eufy.removeAllListeners();\r\n this.eufy.close();\r\n }\r\n\r\n callback();\r\n } catch (e) {\r\n callback();\r\n }\r\n }\r\n\r\n // If you need to react to object changes, uncomment the following block and the corresponding line in the constructor.\r\n // You also need to subscribe to the objects with `this.subscribeObjects`, similar to `this.subscribeStates`.\r\n // /**\r\n // * Is called if a subscribed object changes\r\n // */\r\n // private onObjectChange(id: string, obj: ioBroker.Object | null | undefined): void {\r\n // if (obj) {\r\n // // The object was changed\r\n // this.log.info(`object ${id} changed: ${JSON.stringify(obj)}`);\r\n // } else {\r\n // // The object was deleted\r\n // this.log.info(`object ${id} deleted`);\r\n // }\r\n // }\r\n\r\n /**\r\n * Is called if a subscribed state changes\r\n */\r\n private async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise {\r\n if (state) {\r\n\r\n // don't do anything if the state is acked\r\n if (!id || state.ack) {\r\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack}) was already acknowledged, ignore it...`);\r\n return;\r\n }\r\n this.logger.debug(`state ${id} changed: ${state.val} (ack = ${state.ack})`);\r\n\r\n const values = id.split(\".\");\r\n const station_sn = values[2];\r\n const device_type = values[3];\r\n\r\n if (station_sn == \"verify_code\") {\r\n if (this.eufy && this.verify_code) {\r\n this.logger.info(`Verification code received, send it. (verify_code: ${state.val})`);\r\n await this.eufy.connect({ verifyCode: state.val as string } as LoginOptions);\r\n this.verify_code = false;\r\n await this.delStateAsync(id);\r\n }\r\n } else if (station_sn == \"captcha\") {\r\n if (this.eufy && this.captchaId) {\r\n this.logger.info(`Captcha received, send it. (captcha: ${state.val})`);\r\n await this.eufy.connect({\r\n captcha: {\r\n captchaCode: state.val as string,\r\n captchaId: this.captchaId\r\n }\r\n } as LoginOptions);\r\n this.captchaId = null;\r\n await this.delStateAsync(id);\r\n await this.delStateAsync(\"received_captcha_html\");\r\n }\r\n } else if (device_type == \"station\") {\r\n try {\r\n const station_state_name = values[4];\r\n if (this.eufy) {\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n if (obj.native.name !== undefined) {\r\n await this.eufy.setStationProperty(station_sn, obj.native.name, state.val);\r\n return;\r\n }\r\n }\r\n\r\n const station = await this.eufy.getStation(station_sn);\r\n switch(station_state_name) {\r\n case StationStateID.REBOOT:\r\n await station.rebootHUB();\r\n break;\r\n case StationStateID.TRIGGER_ALARM_SOUND:\r\n await station.triggerStationAlarmSound(this.config.alarmSoundDuration);\r\n break;\r\n case StationStateID.RESET_ALARM_SOUND:\r\n await station.resetStationAlarmSound();\r\n break;\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`station - Error:`, error);\r\n }\r\n } else {\r\n try {\r\n const device_sn = values[4];\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n if (obj.native.name !== undefined) {\r\n try {\r\n await this.eufy.setDeviceProperty(device_sn, obj.native.name, obj.common.type === \"object\" ? JSON.parse(state.val as string) : state.val);\r\n } catch (error) {\r\n this.logger.error(`Error in setting property value (property: ${obj.native.name} value: ${state.val})`, error);\r\n }\r\n return;\r\n }\r\n }\r\n\r\n const device_state_name = values[5];\r\n const station = await this.eufy.getStation(station_sn);\r\n const device = await this.eufy.getDevice(device_sn);\r\n\r\n switch(device_state_name) {\r\n case DeviceStateID.START_STREAM:\r\n await this.startLivestream(device_sn);\r\n break;\r\n case DeviceStateID.STOP_STREAM:\r\n await this.stopLivestream(device_sn);\r\n break;\r\n case DeviceStateID.TRIGGER_ALARM_SOUND:\r\n await station.triggerDeviceAlarmSound(device, this.config.alarmSoundDuration);\r\n break;\r\n case DeviceStateID.RESET_ALARM_SOUND:\r\n await station.resetDeviceAlarmSound(device);\r\n break;\r\n case DeviceStateID.ROTATE_360:\r\n await station.panAndTilt(device, PanTiltDirection.ROTATE360);\r\n break;\r\n case DeviceStateID.PAN_LEFT:\r\n await station.panAndTilt(device, PanTiltDirection.LEFT);\r\n break;\r\n case DeviceStateID.PAN_RIGHT:\r\n await station.panAndTilt(device, PanTiltDirection.RIGHT);\r\n break;\r\n case DeviceStateID.TILT_UP:\r\n await station.panAndTilt(device, PanTiltDirection.UP);\r\n break;\r\n case DeviceStateID.TILT_DOWN:\r\n await station.panAndTilt(device, PanTiltDirection.DOWN);\r\n break;\r\n case DeviceStateID.CALIBRATE:\r\n if (device.isLock()) {\r\n await station.calibrateLock(device);\r\n } else {\r\n await station.calibrate(device);\r\n }\r\n break;\r\n case DeviceStateID.UNLOCK:\r\n await station.unlock(device);\r\n break;\r\n case DeviceStateID.SET_DEFAULT_ANGLE:\r\n await station.setDefaultAngle(device);\r\n break;\r\n case DeviceStateID.SET_PRIVACY_ANGLE:\r\n await station.setPrivacyAngle(device);\r\n break;\r\n }\r\n } catch (error) {\r\n this.logger.error(`cameras - Error:`, error);\r\n }\r\n }\r\n } else {\r\n // The state was deleted\r\n this.logger.debug(`state ${id} deleted`);\r\n }\r\n }\r\n\r\n // If you need to accept messages in your adapter, uncomment the following block and the corresponding line in the constructor.\r\n // /**\r\n // * Some message was sent to this instance over message box. Used by email, pushover, text2speech, ...\r\n // * Using this method requires \"common.message\" property to be set to true in io-package.json\r\n // */\r\n // private onMessage(obj: ioBroker.Message): void {\r\n // if (typeof obj === \"object\" && obj.message) {\r\n // if (obj.command === \"send\") {\r\n // // e.g. send email or pushover or whatever\r\n // this.log.info(\"send command\");\r\n\r\n // // Send response in callback if required\r\n // if (obj.callback) this.sendTo(obj.from, obj.command, \"Message received\", obj.callback);\r\n // }\r\n // }\r\n // }\r\n\r\n private getStateCommon(property: PropertyMetadataAny): ioBroker.StateCommon {\r\n const state: ioBroker.StateCommon = {\r\n name: property.label!,\r\n type: property.type,\r\n role: \"state\",\r\n read: property.readable,\r\n write: property.writeable,\r\n def: property.default\r\n };\r\n switch (property.type) {\r\n case \"number\": {\r\n const numberProperty = property as PropertyMetadataNumeric;\r\n state.min = numberProperty.min;\r\n state.max = numberProperty.max;\r\n state.states = numberProperty.states;\r\n state.unit = numberProperty.unit;\r\n state.step = numberProperty.steps;\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : \"value\";\r\n break;\r\n }\r\n case \"string\": {\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : \"text\";\r\n break;\r\n }\r\n case \"boolean\": {\r\n state.role = RoleMapping[property.name] !== undefined ? RoleMapping[property.name] : (property.writeable ? \"switch.enable\" : \"state\");\r\n break;\r\n }\r\n }\r\n return state;\r\n }\r\n\r\n private async createAndSetState(device: Device | Station, property: PropertyMetadataAny): Promise {\r\n if (property.name !== PropertyName.Type && property.name !== PropertyName.DeviceStationSN) {\r\n const state = this.getStateCommon(property);\r\n const id: string = device.getStateID(convertCamelCaseToSnakeCase(property.name));\r\n const obj = await this.getObjectAsync(id);\r\n if (obj) {\r\n let changed = false;\r\n if (obj.native.name !== undefined && obj.native.name !== property.name) {\r\n obj.native.name = property.name;\r\n changed = true;\r\n }\r\n if (obj.native.key !== undefined && obj.native.key !== property.key) {\r\n obj.native.key = property.key;\r\n changed = true;\r\n }\r\n if (obj.native.commandId !== undefined && obj.native.commandId !== property.commandId) {\r\n obj.native.commandId = property.commandId;\r\n changed = true;\r\n }\r\n if (obj.common !== undefined && !util.isDeepStrictEqual(obj.common, state)) {\r\n changed = true;\r\n }\r\n if (changed) {\r\n const propertyMetadata = device.getPropertiesMetadata()[property.name];\r\n if (propertyMetadata !== undefined) {\r\n const newState = this.getStateCommon(propertyMetadata);\r\n obj.common = newState;\r\n }\r\n await this.setObjectAsync(id, obj);\r\n }\r\n } else {\r\n await this.setObjectNotExistsAsync(id, {\r\n type: \"state\",\r\n common: state,\r\n native: {\r\n key: property.key,\r\n commandId: property.commandId,\r\n name: property.name,\r\n },\r\n });\r\n }\r\n const value = device.getPropertyValue(property.name);\r\n if (value !== undefined)\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, id, (property.type === \"string\" || property.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n }\r\n }\r\n\r\n private async onDeviceAdded(device: Device): Promise {\r\n this.logger.debug(`onDeviceAdded - device: ${device.getSerial()}`);\r\n\r\n await this.setObjectNotExistsAsync(device.getStateID(\"\", 0), {\r\n type: \"channel\",\r\n common: {\r\n name: device.getStateChannel()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(device.getStateID(\"\", 1), {\r\n type: \"device\",\r\n common: {\r\n name: device.getName()\r\n },\r\n native: {},\r\n });\r\n\r\n const metadata = device.getPropertiesMetadata();\r\n for(const property of Object.values(metadata)) {\r\n if (property.name !== PropertyName.DevicePicture)\r\n this.createAndSetState(device, property);\r\n }\r\n\r\n if (device.hasProperty(PropertyName.DevicePicture)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Picture URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PICTURE_HTML), {\r\n type: \"state\",\r\n common: {\r\n name: \"Picture HTML image\",\r\n type: \"string\",\r\n role: \"html\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n if (device.hasCommand(CommandName.DeviceTriggerAlarmSound)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TRIGGER_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Trigger Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RESET_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reset Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DevicePanAndTilt)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_LEFT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Pan Left\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.PAN_RIGHT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Pan Right\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.ROTATE_360), {\r\n type: \"state\",\r\n common: {\r\n name: \"Rotate 360\u00B0\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_UP), {\r\n type: \"state\",\r\n common: {\r\n name: \"Tilt Up\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.TILT_DOWN), {\r\n type: \"state\",\r\n common: {\r\n name: \"Tilt Down\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceLockCalibration)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Calibrate Lock\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceUnlock)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.UNLOCK), {\r\n type: \"state\",\r\n common: {\r\n name: \"Unlock\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceSetDefaultAngle)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_DEFAULT_ANGLE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Set Default Angle\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceSetPrivacyAngle)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.SET_PRIVACY_ANGLE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Set Default Angle\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceCalibrate)) {\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.CALIBRATE), {\r\n type: \"state\",\r\n common: {\r\n name: \"Calibrate\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n if (device.hasCommand(CommandName.DeviceStartLivestream)) {\r\n // Start Stream\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.START_STREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Start stream\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n\r\n // Stop Stream\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.STOP_STREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Stop stream\",\r\n type: \"boolean\",\r\n role: \"button.stop\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n\r\n // Livestream URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM), {\r\n type: \"state\",\r\n common: {\r\n name: \"Livestream URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n\r\n // Livestream RTSP URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), {\r\n type: \"state\",\r\n common: {\r\n name: \"Livestream RTSP URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n if (device.hasProperty(PropertyName.DeviceRTSPStream)) {\r\n // RTSP Stream URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"RTSP stream URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false\r\n },\r\n native: {},\r\n });\r\n }\r\n\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n /*if (device.hasCommand(CommandName.DeviceStartDownload)) {\r\n // Last event video URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event video URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n\r\n // Last event picture URL\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event picture URL\",\r\n type: \"string\",\r\n role: \"url\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n\r\n // Last event picture HTML image\r\n await this.setObjectNotExistsAsync(device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), {\r\n type: \"state\",\r\n common: {\r\n name: \"Last event picture HTML image\",\r\n type: \"string\",\r\n role: \"html\",\r\n read: true,\r\n write: false,\r\n def: \"\"\r\n },\r\n native: {},\r\n });\r\n }*/\r\n }\r\n\r\n private async onDeviceRemoved(device: Device): Promise {\r\n this.delObjectAsync(device.getStateID(\"\", 0), { recursive: true }).catch((error) => {\r\n this.logger.error(`Error deleting states of removed device`, error);\r\n });\r\n removeFiles(this as unknown as ioBroker.Adapter, device.getStationSerial(), DataLocation.LAST_EVENT, device.getSerial()).catch((error) => {\r\n this.logger.error(`Error deleting fs contents of removed device`, error);\r\n });\r\n }\r\n\r\n private async onStationAdded(station: Station): Promise {\r\n this.subscribeStates(`${station.getStateID(\"\", 0)}.*`);\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(\"\", 0), {\r\n type: \"device\",\r\n common: {\r\n name: station.getName()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(\"\", 1), {\r\n type: \"channel\",\r\n common: {\r\n name: station.getStateChannel()\r\n },\r\n native: {},\r\n });\r\n\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\r\n\r\n const metadata = station.getPropertiesMetadata();\r\n for(const property of Object.values(metadata)) {\r\n this.createAndSetState(station, property);\r\n }\r\n\r\n // Reboot station\r\n if (station.hasCommand(CommandName.StationReboot)) {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.REBOOT), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reboot station\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n // Alarm Sound\r\n if (station.hasCommand(CommandName.StationTriggerAlarmSound)) {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.TRIGGER_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Trigger Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.RESET_ALARM_SOUND), {\r\n type: \"state\",\r\n common: {\r\n name: \"Reset Alarm Sound\",\r\n type: \"boolean\",\r\n role: \"button.start\",\r\n read: false,\r\n write: true,\r\n },\r\n native: {},\r\n });\r\n }\r\n }\r\n\r\n private async onStationRemoved(station: Station): Promise {\r\n this.delObjectAsync(station.getStateID(\"\", 0), { recursive: true }).catch((error) => {\r\n this.logger.error(`Error deleting states of removed station`, error);\r\n });\r\n fse.remove(path.join(utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter), station.getSerial())).catch((error) => {\r\n this.logger.error(`Error deleting fs contents of removed station`, error);\r\n });\r\n }\r\n\r\n /*private async downloadEventVideo(device: Device, event_time: number, full_path: string | undefined, cipher_id: number | undefined): Promise {\r\n this.logger.debug(`Device: ${device.getSerial()} full_path: ${full_path} cipher_id: ${cipher_id}`);\r\n try {\r\n if (!isEmpty(full_path) && cipher_id !== undefined) {\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n\r\n if (station !== undefined) {\r\n if (this.downloadEvent[device.getSerial()])\r\n clearTimeout(this.downloadEvent[device.getSerial()]);\r\n\r\n let videoLength = getVideoClipLength(device);\r\n const time_passed = (new Date().getTime() - new Date(event_time).getTime()) / 1000;\r\n\r\n if (time_passed >= videoLength)\r\n videoLength = 1;\r\n else\r\n videoLength = videoLength - time_passed;\r\n\r\n this.logger.info(`Downloading video event for device ${device.getSerial()} in ${videoLength} seconds...`);\r\n this.downloadEvent[device.getSerial()] = setTimeout(async () => {\r\n station.startDownload(device, full_path!, cipher_id);\r\n }, videoLength * 1000);\r\n }\r\n }\r\n } catch (error) {\r\n this.logger.error(`Device: ${device.getSerial()} - Error`, error);\r\n }\r\n }*/\r\n\r\n private async handlePushNotification(message: PushMessage): Promise {\r\n try {\r\n if (message.device_sn !== undefined) {\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n /*const device: Device = await this.eufy.getDevice(message.device_sn);\r\n if ((message.push_count === 1 || message.push_count === undefined) && (message.file_path !== undefined && message.file_path !== \"\" && message.cipher !== undefined))\r\n if (this.config.autoDownloadVideo)\r\n await this.downloadEventVideo(device, message.event_time, message.file_path, message.cipher);*/\r\n }\r\n } catch (error) {\r\n if (error instanceof DeviceNotFoundError) {\r\n //Do nothing\r\n } else {\r\n this.logger.error(\"Handling push notification - Error\", error);\r\n }\r\n }\r\n }\r\n\r\n private async onConnect(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Global connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.connection\", { val: true, ack: true });\r\n\r\n const stations = await this.eufy.getStations();\r\n const stationSerials: string[] = [];\r\n for(const station of stations) {\r\n stationSerials.push(station.getSerial());\r\n }\r\n const devices = await this.eufy.getDevices();\r\n const deviceSerials: string[] = [];\r\n for(const device of devices) {\r\n deviceSerials.push(device.getSerial());\r\n }\r\n\r\n // Delete obsolete stations\r\n try {\r\n const allDevices = await this.getDevicesAsync();\r\n const reg = new RegExp(`^${this.namespace}\\.[0-9A-Z]+$`);\r\n for (const id of allDevices) {\r\n if (id._id.match(reg)) {\r\n const serial = id._id.replace(`${this.namespace}.`, \"\");\r\n if (!stationSerials.includes(serial)) {\r\n await this.delObjectAsync(id._id, { recursive: true });\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete stations ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete devices\r\n try {\r\n const allDevices = await this.getDevicesAsync();\r\n const reg = new RegExp(`^${this.namespace}\\.[0-9A-Z]+\\.[a-z]+\\.[0-9A-Z]+$`);\r\n for (const id of allDevices) {\r\n if (id._id.match(reg)) {\r\n const serial = id._id.split(\".\")[4];\r\n if (!deviceSerials.includes(serial)) {\r\n await this.delObjectAsync(id._id, { recursive: true });\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete devices ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete properties\r\n try {\r\n const all = await this.getStatesAsync(\"*\");\r\n if (all) {\r\n Object.keys(all).forEach(async (stateid) => {\r\n const object = await this.getObjectAsync(stateid);\r\n if (object?.native?.name !== undefined) {\r\n const tmp = stateid.split(\".\");\r\n if (tmp.length >= 5) {\r\n const stationSerial = tmp[2];\r\n const deviceSerial = tmp[4];\r\n\r\n if (deviceSerial.match(/^[A-Z0-9]+/)) {\r\n // Device\r\n try {\r\n const device = await this.eufy.getDevice(deviceSerial);\r\n if (!device.hasProperty(object.native.name)) {\r\n this.delObjectAsync(stateid);\r\n }\r\n } catch (error) {\r\n if (error instanceof DeviceNotFoundError) {\r\n } else {\r\n this.log.error(`Delete obsolete properties ERROR - device - ${JSON.stringify(error)}`);\r\n }\r\n }\r\n } else {\r\n // Station\r\n try {\r\n const station = await this.eufy.getStation(stationSerial);\r\n if (!station.hasProperty(object.native.name)) {\r\n this.delObjectAsync(stateid);\r\n }\r\n } catch (error) {\r\n if (error instanceof StationNotFoundError) {\r\n } else {\r\n this.log.error(`Delete obsolete properties ERROR - station - ${JSON.stringify(error)}`);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n });\r\n }\r\n } catch (error) {\r\n this.log.error(`Delete obsolete properties ERROR - ${JSON.stringify(error)}`);\r\n }\r\n\r\n // Delete obsolete directories/files\r\n new Promise(async (resolve, reject) => {\r\n try {\r\n const dir_path = path.join(utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter));\r\n if (fse.existsSync(dir_path)) {\r\n for (const content of fse.readdirSync(dir_path).filter(fn => fn.match(\"^T[0-9A-Z]+$\") !== null)) {\r\n if (!stationSerials.includes(content)) {\r\n fse.removeSync(path.join(dir_path, content));\r\n } else {\r\n for (const dir of fse.readdirSync(path.join(dir_path, content))) {\r\n if (dir === DataLocation.LIVESTREAM || dir === DataLocation.LAST_LIVESTREAM || dir === DataLocation.TEMP) {\r\n fse.removeSync(path.join(dir_path, content, dir));\r\n } else {\r\n const files = fse.readdirSync(path.join(dir_path, content, dir));\r\n let deletedFiles = 0;\r\n for (const file of files) {\r\n if (!deviceSerials.includes(file.substring(0, 16))) {\r\n fse.removeSync(path.join(dir_path, content, dir, file));\r\n deletedFiles++;\r\n }\r\n }\r\n if (deletedFiles === files.length) {\r\n fse.removeSync(path.join(dir_path, content, dir));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n resolve();\r\n } catch (error) {\r\n reject(error);\r\n }\r\n }).catch(error => {\r\n this.log.error(`Delete obsolete directories/files ERROR - ${JSON.stringify(error)}`);\r\n });\r\n }\r\n\r\n private async onClose(): Promise {\r\n await this.setStateAsync(\"info.connection\", { val: false, ack: true }).catch();\r\n }\r\n\r\n public getPersistentData(): PersistentData {\r\n return this.persistentData;\r\n }\r\n\r\n private async onPushConnect(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: true, ack: true });\r\n }\r\n\r\n private async onPushClose(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.push_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"Push notification connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.push_connection\", { val: false, ack: true });\r\n }\r\n\r\n private async onMQTTConnect(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: true, ack: true });\r\n }\r\n\r\n private async onMQTTClose(): Promise {\r\n await this.setObjectNotExistsAsync(\"info\", {\r\n type: \"channel\",\r\n common: {\r\n name: \"info\"\r\n },\r\n native: {},\r\n });\r\n await this.setObjectNotExistsAsync(\"info.mqtt_connection\", {\r\n type: \"state\",\r\n common: {\r\n name: \"MQTT connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(\"info.mqtt_connection\", { val: false, ack: true });\r\n }\r\n\r\n private async onStationCommandResult(station: Station, result: CommandResult): Promise {\r\n if (result.return_code !== 0 && result.command_type === CommandType.CMD_START_REALTIME_MEDIA) {\r\n this.logger.debug(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${ErrorCode[result.return_code]} (${result.return_code}) fallback to RTMP livestream...`);\r\n try {\r\n const device = await this.eufy.getStationDevice(station.getSerial(), result.channel);\r\n if (device.isCamera())\r\n this.eufy.startCloudLivestream(device.getSerial());\r\n } catch (error) {\r\n this.logger.error(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} RTMP fallback failed - Error ${error}`);\r\n }\r\n } else if (result.return_code !== 0 && result.command_type !== CommandType.P2P_QUERY_STATUS_IN_LOCK) {\r\n this.logger.error(`Station: ${station.getSerial()} command ${CommandType[result.command_type]} failed with error: ${ErrorCode[result.return_code]} (${result.return_code})`);\r\n }\r\n }\r\n\r\n private async onStationPropertyChanged(station: Station, name: string, value: PropertyValue): Promise {\r\n const states = await this.getStatesAsync(`${station.getStateID(\"\", 1)}.*`);\r\n for (const state in states) {\r\n const obj = await this.getObjectAsync(state);\r\n if (obj) {\r\n if (obj.native.name !== undefined && obj.native.name === name) {\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, state, (obj.common.type === \"string\" || obj.common.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n return;\r\n }\r\n }\r\n }\r\n this.logger.debug(`onStationPropertyChanged(): Property \"${name}\" not implemented in this adapter (station: ${station.getSerial()} value: ${JSON.stringify(value)})`);\r\n }\r\n\r\n private async onDevicePropertyChanged(device: Device, name: string, value: PropertyValue): Promise {\r\n const states = await this.getStatesAsync(`${device.getStateID(\"\", 1)}.*`);\r\n for (const state in states) {\r\n const obj = await this.getObjectAsync(state);\r\n if (obj) {\r\n if (obj.native.name !== undefined && obj.native.name === name) {\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, state, (obj.common.type === \"string\" || obj.common.type === \"object\") && typeof value === \"object\" ? JSON.stringify(value) : value);\r\n switch(name) {\r\n case PropertyName.DeviceRTSPStream:\r\n if (value as boolean === false) {\r\n this.delStateAsync(device.getStateID(DeviceStateID.RTSP_STREAM_URL));\r\n }\r\n break;\r\n }\r\n return;\r\n }\r\n }\r\n }\r\n if (name === PropertyName.DevicePicture) {\r\n try {\r\n const picture = value as Picture;\r\n const fileName = `${device.getSerial()}.${picture.type.ext}`;\r\n const filePath = path.join(utils.getAbsoluteInstanceDataDir(this as unknown as ioBroker.Adapter), device.getStationSerial(), DataLocation.LAST_EVENT);\r\n\r\n if (!fse.existsSync(filePath)) {\r\n fse.mkdirSync(filePath, {mode: 0o775, recursive: true});\r\n }\r\n\r\n await fse.writeFile(path.join(filePath, fileName), picture.data);\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.PICTURE_URL), `/${this.namespace}/${device.getStationSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}.${picture.type.ext}`);\r\n await setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.PICTURE_HTML), getImageAsHTML(picture.data, picture.type.mime));\r\n } catch (err) {\r\n const error = ensureError(err);\r\n this.logger.error(\"onDevicePropertyChanged - Property picture - Error\", error);\r\n }\r\n } else {\r\n this.logger.debug(`onDevicePropertyChanged(): Property \"${name}\" not implemented in this adapter (device: ${device.getSerial()} value: ${JSON.stringify(value)})`);\r\n }\r\n }\r\n\r\n private async startLivestream(device_sn: string): Promise {\r\n try {\r\n const device = await this.eufy.getDevice(device_sn);\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n\r\n if (station.isConnected() || station.isEnergySavingDevice()) {\r\n if (!station.isLiveStreaming(device)) {\r\n this.eufy.startStationLivestream(device_sn);\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be started, because it is already streaming!`);\r\n }\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be started, because there is no connection to station ${station.getSerial()}!`);\r\n }\r\n } catch (error) {\r\n this.logger.error(\"Start livestream - Error\", error);\r\n }\r\n }\r\n\r\n private async stopLivestream(device_sn: string): Promise {\r\n try {\r\n const device = await this.eufy.getDevice(device_sn);\r\n const station = await this.eufy.getStation(device.getStationSerial());\r\n if (device.isCamera()) {\r\n const camera = device as Camera;\r\n if (await this.eufy.isStationConnected(device.getStationSerial()) && station.isLiveStreaming(camera)) {\r\n await this.eufy.stopStationLivestream(device_sn);\r\n } else {\r\n this.logger.warn(`The stream for the device ${device_sn} cannot be stopped, because it isn't streaming!`);\r\n }\r\n }\r\n\r\n } catch (error) {\r\n this.logger.error(\"Stop livestream - Error\", error);\r\n }\r\n }\r\n\r\n private async onStationLivestreamStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise {\r\n try {\r\n this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM), { val: `${this.config.https ? \"https\" : \"http\"}://${this.config.hostname}:${this.config.go2rtc_api_port}/stream.html?src=${device.getSerial()}`, ack: true });\r\n this.setStateAsync(device.getStateID(DeviceStateID.LIVESTREAM_RTSP), { val: `rtsp://${this.config.hostname}:${this.config.go2rtc_rtsp_port}/${device.getSerial()}`, ack: true });\r\n await ffmpegStreamToGo2rtc(this.config, this.namespace, device.getSerial(), metadata, videostream, audiostream, this.logger);\r\n } catch(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 {\r\n //this.logger.trace(`Station: ${station.getSerial()} channel: ${channel}`);\r\n }*/\r\n\r\n /*private async onStationDownloadStart(station: Station, device: Device, metadata: StreamMetadata, videostream: Readable, audiostream: Readable): Promise {\r\n try {\r\n //TODO: Deactivated because the decryption of the download has changed.\r\n await removeFiles(this, station.getSerial(), DataLocation.TEMP, device.getSerial()).catch();\r\n const file_path = getDataFilePath(this, station.getSerial(), DataLocation.TEMP, `${device.getSerial()}${STREAM_FILE_NAME_EXT}`);\r\n\r\n await ffmpegStreamToHls(this.config, this.namespace, metadata, videostream, audiostream, file_path, this.logger)\r\n .then(async () => {\r\n if (fse.pathExistsSync(file_path)) {\r\n await removeFiles(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\r\n return true;\r\n }\r\n return false;\r\n })\r\n .then(async (result) => {\r\n if (result)\r\n await moveFiles(this, station.getSerial(), device.getSerial(), DataLocation.TEMP, DataLocation.LAST_EVENT);\r\n return result;\r\n })\r\n .then(async (result) => {\r\n if (result) {\r\n const filename_without_ext = getDataFilePath(this, station.getSerial(), DataLocation.LAST_EVENT, device.getSerial());\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_VIDEO_URL), \"Last captured video URL\", `/${this.namespace}/${station.getSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}${STREAM_FILE_NAME_EXT}`, \"url\");\r\n if (fse.pathExistsSync(`${filename_without_ext}${STREAM_FILE_NAME_EXT}`))\r\n await ffmpegPreviewImage(this.config, `${filename_without_ext}${STREAM_FILE_NAME_EXT}`, `${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`, this.logger)\r\n .then(() => {\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_URL), \"Last event picture URL\", `/${this.namespace}/${station.getSerial()}/${DataLocation.LAST_EVENT}/${device.getSerial()}${IMAGE_FILE_JPEG_EXT}`, \"url\");\r\n try {\r\n if (fse.existsSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`)) {\r\n const image_data = getImageAsHTML(fse.readFileSync(`${filename_without_ext}${IMAGE_FILE_JPEG_EXT}`));\r\n setStateAsync(this, device.getStateID(DeviceStateID.LAST_EVENT_PIC_HTML), \"Last event picture HTML image\", image_data, \"html\");\r\n }\r\n } catch (error) {\r\n this.logger.error(`Station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\r\n }\r\n })\r\n .catch((error) => {\r\n this.logger.error(`ffmpegPreviewImage - station: ${station.getSerial()} device: ${device.getSerial()} - Error`, error);\r\n });\r\n }\r\n })\r\n .catch(async (error) => {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\r\n await this.eufy.cancelStationDownload(device.getSerial());\r\n });\r\n } catch(error) {\r\n this.logger.error(`Station: ${station.getSerial()} Device: ${device.getSerial()} - Error - Cancelling download...`, error);\r\n await this.eufy.cancelStationDownload(device.getSerial());\r\n }\r\n }*/\r\n\r\n private onStationRTSPUrl(station: Station, device: Device, value: string): void {\r\n setStateChangedAsync(this as unknown as ioBroker.Adapter, device.getStateID(DeviceStateID.RTSP_STREAM_URL), value);\r\n }\r\n\r\n private async onStationConnect(station: Station): Promise {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: true, ack: true });\r\n }\r\n\r\n private async onStationClose(station: Station): Promise {\r\n await this.setObjectNotExistsAsync(station.getStateID(StationStateID.CONNECTION), {\r\n type: \"state\",\r\n common: {\r\n name: \"Connection\",\r\n type: \"boolean\",\r\n role: \"indicator.connection\",\r\n read: true,\r\n write: false,\r\n },\r\n native: {},\r\n });\r\n await this.setStateAsync(station.getStateID(StationStateID.CONNECTION), { val: false, ack: true });\r\n }\r\n\r\n private onTFARequest(): void {\r\n this.logger.warn(`Two factor authentication request received, please enter valid verification code in state ${this.namespace}.verify_code`);\r\n this.verify_code= true;\r\n }\r\n\r\n private onCaptchaRequest(captchaId: string, captcha: string): void {\r\n this.captchaId = captchaId;\r\n this.logger.warn(`Captcha authentication request received, please enter valid captcha in state ${this.namespace}.captcha`);\r\n this.logger.warn(`Captcha: `);\r\n this.setStateAsync(\"received_captcha_html\", { val: ``, ack: true });\r\n }\r\n\r\n}\r\n\r\nif (require.main !== module) {\r\n // Export the constructor in compact mode\r\n module.exports = (options: Partial | undefined) => new euSec(options);\r\n} else {\r\n // otherwise start the instance directly\r\n (() => new euSec())();\r\n}"], + "mappings": "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", + "names": ["fse", "getCountryCode", "isValidLanguageCode", "os", "pathToGo2rtc", "childProcess", "util", "error"] } diff --git a/docs/_coverpage.md b/docs/_coverpage.md index 1dbe75e..3086739 100644 --- a/docs/_coverpage.md +++ b/docs/_coverpage.md @@ -1,6 +1,6 @@ ![logo](_media/ioBroker.euSec.png) -# ioBroker.euSec 1.1.2 +# ioBroker.euSec 1.2.0 > An [ioBroker](https://www.iobroker.net) adapter that uses the [eufy-security-client](https://github.com/bropat/eufy-security-client) library to comunicate with Eufy devices diff --git a/io-package.json b/io-package.json index ae3ad69..54cd578 100644 --- a/io-package.json +++ b/io-package.json @@ -1,8 +1,21 @@ { "common": { "name": "eusec", - "version": "1.1.2", + "version": "1.2.0", "news": { + "1.2.0": { + "en": "Requires node version >= 18\nAdded support for SmartTrack Link (T87B0) and SmartTrack Card (T87B2)\nAdded support for SoloCam S220 (T8134)\nUpdated version of the package go2rtc-static (1.8.1)\nUpdated version of the package eufy-security-client (2.9.0)\n", + "uk": "Requires node version >= 18\nAdded support for SmartTrack Link (T87B0) and SmartTrack Card (T87B2)\nAdded support for SoloCam S220 (T8134)\nUpdated version of the package go2rtc-static (1.8.1)\nUpdated version of the package eufy-security-client (2.9.0)\n", + "de": "Erfordert Node-Version >= 18\nUnterstützung für SmartTrack Link (T87B0) und SmartTrack Card (T87B2)\nUnterstützung für SoloCam S220 (T8134)\nAktualisierte Version des Pakets go2rtc-static (1.8.1)\nAktualisierte Version des Pakets eufy-security-client (2.9.0)\n", + "ru": "Требуется версия node >= 18\nДобавлена поддержка SmartTrack Link (T87B0) и SmartTrack Card (T87B2)\nДобавлена поддержка SoloCam S220 (T8134)\nОбновлена версия пакета go2rtc-static (1.8.1)\nОбновлена версия пакета eufy-security-client (2.9.0)\n", + "pt": "Requer node versão >= 18\nSuporte adicionado para SmartTrack Link (T87B0) e SmartTrack Card (T87B2)\nSuporte adicionado para SoloCam S220 (T8134)\nVersão atualizada do pacote go2rtc-static (1.8.1)\nVersão atualizada do pacote eufy-security-client (2.9.0)\n", + "nl": "Vereist node versie >= 18\nOndersteuning toegevoegd voor SmartTrack Link (T87B0) en SmartTrack Card (T87B2)\nOndersteuning toegevoegd voor SoloCam S220 (T8134)\nBijgewerkte versie van het pakket go2rtc-static (1.8.1)\nBijgewerkte versie van het pakket eufy-security-client (2.9.0)\n", + "fr": "Nécessite une version de node >= 18\nAjout de la prise en charge de SmartTrack Link (T87B0) et SmartTrack Card (T87B2)\nAjout de la prise en charge de SoloCam S220 (T8134)\nVersion mise à jour du paquet go2rtc-static (1.8.1)\nVersion mise à jour du paquet eufy-security-client (2.9.0)\n", + "it": "Richiede la versione di node >= 18\nAggiunto supporto per SmartTrack Link (T87B0) e SmartTrack Card (T87B2)\nAggiunto supporto per SoloCam S220 (T8134)\nVersione aggiornata del pacchetto go2rtc-static (1.8.1)\nVersione aggiornata del pacchetto eufy-security-client (2.9.0)\n", + "es": "Requiere node versión >= 18\nAgregado soporte para SmartTrack Link (T87B0) y SmartTrack Card (T87B2)\nAgregado soporte para SoloCam S220 (T8134)\nVersión actualizada del paquete go2rtc-static (1.8.1)\nVersión actualizada del paquete eufy-security-client (2.9.0)\n", + "pl": "Wymaga node w wersji >= 18\nDodano obsługę SmartTrack Link (T87B0) i SmartTrack Card (T87B2)\nDodano obsługę SoloCam S220 (T8134)\nZaktualizowano wersję pakietu go2rtc-static (1.8.1)\nZaktualizowano wersję pakietu eufy-security-client (2.9.0)\n", + "zh-cn": "要求 node 版本 >= 18\n添加了对智能跟踪链接(T87B0)和智能跟踪卡(T87B2)的支持\n添加了对 SoloCam S220 (T8134) 的支持\n软件包 go2rtc-static 的更新版本 (1.8.1)\n软件包 eufy-security-client 的更新版本 (2.9.0)\n" + }, "1.1.2": { "en": "Updated version of the package eufy-security-client (2.8.1)\n", "uk": "Updated version of the package eufy-security-client (2.8.1)\n", @@ -41,19 +54,6 @@ "es": "Añadido soporte para Wired Wall Light Cam S100 (T84A1; #332)\nAñadido soporte para Garage-Control Cam (T8452)\nSolucionados los problemas #316, #342, #347, #353\nVersión actualizada del paquete go2rtc-static (1.6.2)\nVersión actualizada del paquete eufy-security-client (2.7.1)\n", "pl": "Dodano obsługę Wired Wall Light Cam S100 (T84A1; #332).\nDodano obsługę Garage-Control Cam (T8452)\nNaprawiono błędy #316, #342, #347, #353\nZaktualizowana wersja pakietu go2rtc-static (1.6.2)\nZaktualizowana wersja pakietu eufy-security-client (2.7.1)\n", "zh-cn": "已添加对 Wired Wall Light Cam S100(T84A1;#332)的支持\n已添加对 Garage-Control Cam(T8452)的支持\n修复了 #316、#342、#347 和 #353 号问题\n包 go2rtc-static (1.6.2) 的更新版本\n包 eufy-security-client (2.7.1) 的更新版本\n" - }, - "1.0.0": { - "en": "Notification pictures are supported again\nImplemented new livestream support using go2rtc (WebRTC/MSE, rtsp)\nFixed issue #323\nUpdated version of the package eufy-security-client (2.6.2)\n", - "uk": "Notification pictures are supported again\nImplemented new livestream support using go2rtc (WebRTC/MSE, rtsp)\nFixed issue #323\nUpdated version of the package eufy-security-client (2.6.2)\n", - "de": "Benachrichtigungsbilder werden wieder unterstützt\nNeue Livestream-Unterstützung mit go2rtc implementiert (WebRTC/MSE, rtsp)\nProblem #323 behoben\nVersion des Pakets eufy-security-client (2.6.2) aktualisiert\n", - "ru": "Изображения уведомлений снова поддерживаются\nРеализована новая поддержка livestream с использованием go2rtc (WebRTC/MSE, rtsp)\nИсправлена проблема №323\nОбновленная версия пакета eufy-security-client (2.6.2)\n", - "pt": "As imagens de notificação são novamente suportadas\nImplementação de um novo suporte de transmissão em directo utilizando go2rtc (WebRTC/MSE, rtsp)\nEdição fixa #323\nVersão atualizada do pacote eufy-security-client (2.6.2)\n", - "nl": "Meldingsfoto's worden weer ondersteund\nNieuwe livestreamondersteuning geïmplementeerd met go2rtc (WebRTC/MSE, rtsp).\nProbleem #323 opgelost\nBijgewerkte versie van het pakket eufy-security-client (2.6.2)\n", - "fr": "Les images de notification sont à nouveau prises en charge\nMise en place d'un nouveau support pour le livestream en utilisant go2rtc (WebRTC/MSE, rtsp)\nCorrection du problème n°323\nVersion mise à jour du paquet eufy-security-client (2.6.2)\n", - "it": "Le immagini di notifica sono nuovamente supportate\nImplementato nuovo livestream utilizzando go2rtc (WebRTC/MSE, rtsp)\nRisolto il problema #323\nAggiornata la versione del pacchetto eufy-security-client (2.6.2)\n", - "es": "Las imágenes de notificación vuelven a ser compatibles\nImplementado nuevo soporte livestream usando go2rtc (WebRTC/MSE, rtsp)\nCorregido el problema #323\nVersión actualizada del paquete eufy-security-client (2.6.2)\n", - "pl": "Obrazy powiadomień są ponownie obsługiwane\nWdrożono nową obsługę transmisji na żywo przy użyciu go2rtc (WebRTC/MSE, rtsp).\nNaprawiono błąd #323\nZaktualizowana wersja pakietu eufy-security-client (2.6.2)\n", - "zh-cn": "再次支持通知图片\n使用go2rtc(WebRTC/MSE,rtsp)实施新的现场直播支持。\n修正了问题#323\n包 eufy-security-client (2.6.2) 的更新版本\n" } }, "titleLang": { diff --git a/package-lock.json b/package-lock.json index 5e37837..bd2fa2c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,23 +1,23 @@ { "name": "iobroker.eusec", - "version": "1.1.2", + "version": "1.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "iobroker.eusec", - "version": "1.1.2", + "version": "1.2.0", "license": "MIT", "dependencies": { "@bropat/fluent-ffmpeg": "^2.1.3", "@cospired/i18n-iso-languages": "^4.1.0", - "@iobroker/adapter-core": "^3.0.3", - "eufy-security-client": "^2.8.1", + "@iobroker/adapter-core": "^3.0.4", + "eufy-security-client": "^2.9.0", "ffmpeg-static": "^5.2.0", "fs-extra": "^11.1.1", - "go2rtc-static": "^1.6.2", + "go2rtc-static": "^1.8.1", "got": "^11.8.6", - "i18n-iso-countries": "^7.6.0", + "i18n-iso-countries": "^7.7.0", "mime": "^3.0.0", "ts-log": "^2.2.5" }, @@ -25,33 +25,33 @@ "@alcalzone/release-script": "^3.6.0", "@iobroker/adapter-dev": "^1.2.0", "@iobroker/testing": "^4.1.0", - "@types/chai": "^4.3.5", - "@types/chai-as-promised": "^7.1.5", - "@types/express": "^4.17.17", - "@types/ffmpeg-static": "^3.0.1", - "@types/fs-extra": "^11.0.1", - "@types/mime": "^3.0.1", - "@types/mocha": "^10.0.1", - "@types/node": "^16.18.46", - "@types/proxyquire": "^1.3.28", - "@types/sinon": "^10.0.16", - "@types/sinon-chai": "^3.2.9", - "@typescript-eslint/eslint-plugin": "^6.5.0", - "@typescript-eslint/parser": "^6.5.0", - "chai": "^4.3.8", + "@types/chai": "^4.3.9", + "@types/chai-as-promised": "^7.1.7", + "@types/express": "^4.17.20", + "@types/ffmpeg-static": "^3.0.2", + "@types/fs-extra": "^11.0.3", + "@types/mime": "^3.0.3", + "@types/mocha": "^10.0.3", + "@types/node": "^18.18.8", + "@types/proxyquire": "^1.3.30", + "@types/sinon": "^17.0.0", + "@types/sinon-chai": "^3.2.11", + "@typescript-eslint/eslint-plugin": "^6.9.1", + "@typescript-eslint/parser": "^6.9.1", + "chai": "^4.3.10", "chai-as-promised": "^7.1.1", - "eslint": "^8.48.0", + "eslint": "^8.53.0", "mocha": "^10.2.0", "proxyquire": "^2.1.3", - "rimraf": "^5.0.1", - "sinon": "^15.2.0", + "rimraf": "^5.0.5", + "sinon": "^17.0.1", "sinon-chai": "^3.7.0", "source-map-support": "^0.5.21", "ts-node": "^10.9.1", "typescript": "5.2.2" }, "engines": { - "node": ">=16.9.0" + "node": ">=18.0.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -404,9 +404,9 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", + "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -427,9 +427,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", - "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz", + "integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -654,12 +654,12 @@ "dev": true }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" }, @@ -681,15 +681,18 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "node_modules/@iobroker/adapter-core": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@iobroker/adapter-core/-/adapter-core-3.0.3.tgz", - "integrity": "sha512-SZmL69BtUXitnTbidNjlljQKB6CbkBLK9+Tqo/NMsOqHb1RmhPCNKhO4F5o8jc0dW0J6d4VArXryUkL7Ru0WpA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@iobroker/adapter-core/-/adapter-core-3.0.4.tgz", + "integrity": "sha512-QsSeIkOa+zEVdIQ0kc0GcfsnQC+pTWWkixotdG4naKuaLUwMWK7xP0UyUEUiaHfPG3KqyZxwIxQR9HMENvvIYQ==", + "engines": { + "npm": ">=7.0.0" + }, "peerDependencies": { "@iobroker/types": "^5.0.11" } @@ -1152,15 +1155,15 @@ } }, "node_modules/@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.9.tgz", + "integrity": "sha512-69TtiDzu0bcmKQv3yg1Zx409/Kd7r0b5F1PfpYJfSHzLGtB53547V4u+9iqKYsTu/O2ai6KTb0TInNpvuQ3qmg==", "dev": true }, "node_modules/@types/chai-as-promised": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz", - "integrity": "sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.7.tgz", + "integrity": "sha512-APucaP5rlmTRYKtRA6FE5QPP87x76ejw5t5guRJ4y5OgMnwtsvigw7HHhKZlx2MGXLeZd6R/GNZR/IqDHcbtQw==", "dev": true, "dependencies": { "@types/chai": "*" @@ -1176,9 +1179,9 @@ } }, "node_modules/@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.20.tgz", + "integrity": "sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw==", "dev": true, "dependencies": { "@types/body-parser": "*", @@ -1199,15 +1202,15 @@ } }, "node_modules/@types/ffmpeg-static": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/ffmpeg-static/-/ffmpeg-static-3.0.1.tgz", - "integrity": "sha512-hEJdQMv/g1olk9qTiWqh23BfbKsDKE6Tc7DilNJWF1MgZsU9fYOPKrgQ448vfT7aP2Yt5re9vgJDVv9TXEoTyQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/ffmpeg-static/-/ffmpeg-static-3.0.2.tgz", + "integrity": "sha512-hEgrO6mk9OkBAEGLh5fqnW7LXVcTHGWncVPVgeroTvD+X95xd0Q6Mpd7hI96B1yzh0oTEKgTzR98FX7V54UNuw==", "dev": true }, "node_modules/@types/fs-extra": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.1.tgz", - "integrity": "sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.3.tgz", + "integrity": "sha512-sF59BlXtUdzEAL1u0MSvuzWd7PdZvZEtnaVkzX5mjpdWTJ8brG0jUqve3jPCzSzvAKKMHTG8F8o/WMQLtleZdQ==", "dev": true, "dependencies": { "@types/jsonfile": "*", @@ -1230,9 +1233,9 @@ "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" }, "node_modules/@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", + "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", "dev": true }, "node_modules/@types/jsonfile": { @@ -1281,9 +1284,9 @@ "dev": true }, "node_modules/@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.3.tgz", + "integrity": "sha512-i8MBln35l856k5iOhKk2XJ4SeAWg75mLIpZB4v6imOagKL6twsukBZGDMNhdOVk7yRFTMPpfILocMos59Q1otQ==", "dev": true }, "node_modules/@types/minimatch": { @@ -1293,20 +1296,23 @@ "dev": true }, "node_modules/@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.3.tgz", + "integrity": "sha512-RsOPImTriV/OE4A9qKjMtk2MnXiuLLbcO3nCXK+kvq4nr0iMfFgpjaX3MPLb6f7+EL1FGSelYvuJMV6REH+ZPQ==", "dev": true }, "node_modules/@types/node": { - "version": "16.18.46", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.46.tgz", - "integrity": "sha512-Mnq3O9Xz52exs3mlxMcQuA7/9VFe/dXcrgAyfjLkABIqxXKOgBRjyazTxUbjsxDa4BP7hhPliyjVTP9RDP14xg==" + "version": "18.18.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.8.tgz", + "integrity": "sha512-OLGBaaK5V3VRBS1bAkMVP2/W9B+H8meUfl866OrMNQqt7wDgdpWPp5o6gmIc9pB+lIQHSq4ZL8ypeH1vPxcPaQ==", + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/proxyquire": { - "version": "1.3.28", - "resolved": "https://registry.npmjs.org/@types/proxyquire/-/proxyquire-1.3.28.tgz", - "integrity": "sha512-SQaNzWQ2YZSr7FqAyPPiA3FYpux2Lqh3HWMZQk47x3xbMCqgC/w0dY3dw9rGqlweDDkrySQBcaScXWeR+Yb11Q==", + "version": "1.3.30", + "resolved": "https://registry.npmjs.org/@types/proxyquire/-/proxyquire-1.3.30.tgz", + "integrity": "sha512-erD15isFDzHMfeQC09DMjGeI0G6pJm7r5R7X/CxnEEe6tEp7N4r6xLYhTptdzne8zMz+2+5wJzrefCMvbmV/Fg==", "dev": true }, "node_modules/@types/qs": { @@ -1322,9 +1328,9 @@ "dev": true }, "node_modules/@types/readable-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.2.tgz", - "integrity": "sha512-hhzOsMEISZ+mX1l+01F0duYt9wHEbCGmjARed0PcQoVS5zAdu7u5YbWYuNGhw09M1MgGr3kfsto+ut/MnAdKqA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.4.tgz", + "integrity": "sha512-NSAiePj3Iq3kBArfpUWRNX/mRw8DibYD6YhNCIJDfUP/iIOQYsNJgtHyjpbuZlcbL7TxILS8qYjY/nXXvtcFQg==", "dependencies": { "@types/node": "*", "safe-buffer": "~5.1.1" @@ -1354,9 +1360,9 @@ } }, "node_modules/@types/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", "dev": true }, "node_modules/@types/serve-static": { @@ -1370,18 +1376,18 @@ } }, "node_modules/@types/sinon": { - "version": "10.0.16", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.16.tgz", - "integrity": "sha512-j2Du5SYpXZjJVJtXBokASpPRj+e2z+VUhCPHmM6WMfe3dpHu6iVKJMU6AiBcMp/XTAYnEj6Wc1trJUWwZ0QaAQ==", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.0.tgz", + "integrity": "sha512-oN4AeDMFCeNZrAffCjhLcwwVymRZL2c9mljUmhPnd0eiM06d4ELDg0Q0TSvnZXrCIFlSA859qIdcfu1HapswPQ==", "dev": true, "dependencies": { "@types/sinonjs__fake-timers": "*" } }, "node_modules/@types/sinon-chai": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.9.tgz", - "integrity": "sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ==", + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.11.tgz", + "integrity": "sha512-1C5SBFzwn9hjiMr1xfqbULcSI9qXVpkGZT/LYbbd3jWiTo2MSvA+iFfwODlSoAXGeCgBw6S509dxy8zSIacr3Q==", "dev": true, "dependencies": { "@types/chai": "*", @@ -1395,24 +1401,24 @@ "dev": true }, "node_modules/@types/ws": { - "version": "8.5.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", - "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.8.tgz", + "integrity": "sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg==", "dependencies": { "@types/node": "*" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", - "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", + "integrity": "sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/type-utils": "6.5.0", - "@typescript-eslint/utils": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/type-utils": "6.9.1", + "@typescript-eslint/utils": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -1438,15 +1444,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", - "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.1.tgz", + "integrity": "sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4" }, "engines": { @@ -1466,13 +1472,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", - "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", + "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0" + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1483,13 +1489,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", - "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.1.tgz", + "integrity": "sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/utils": "6.5.0", + "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/utils": "6.9.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -1510,9 +1516,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", - "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", + "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -1523,13 +1529,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", - "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", + "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1550,17 +1556,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", - "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.1.tgz", + "integrity": "sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/typescript-estree": "6.9.1", "semver": "^7.5.4" }, "engines": { @@ -1575,12 +1581,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", - "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", + "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/types": "6.9.1", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -1591,6 +1597,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -1994,18 +2006,18 @@ } }, "node_modules/chai": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.8.tgz", - "integrity": "sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==", + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", "dev": true, "dependencies": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" }, "engines": { "node": ">=4" @@ -2040,10 +2052,13 @@ } }, "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, "engines": { "node": "*" } @@ -2189,14 +2204,14 @@ } }, "node_modules/crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" }, "node_modules/date-and-time": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-3.0.2.tgz", - "integrity": "sha512-MOqlRertOQmQI7ySbz6dKLM7Rxm9dgcPuBI9IL7NVe0UGqHPK+6hWSKVhLrVHxlSgQQtocE2R7+HFOf5aMz8vw==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-3.0.3.tgz", + "integrity": "sha512-CmHCeTixc3KA5pcLTVs9JCFhmJMFTBsmSsgHnNed4YDNw9yUOrjjRn3zALy8eMgqmTO+4U8k5jl1peC7IoezfA==" }, "node_modules/debug": { "version": "4.3.4", @@ -2240,9 +2255,9 @@ } }, "node_modules/deep-eql": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz", - "integrity": "sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "dependencies": { "type-detect": "^4.0.0" @@ -2277,7 +2292,7 @@ "node_modules/diacritics": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/diacritics/-/diacritics-1.3.0.tgz", - "integrity": "sha1-PvqHMj67hj5mls67AILUj/PW96E=" + "integrity": "sha512-wlwEkqcsaxvPJML+rDh/2iS824jbREk6DUMUKkEaSlxdYHeS43cClJtsWglvw2RfeXGm6ohKDqsXteJ5sP5enA==" }, "node_modules/diff": { "version": "5.0.0", @@ -2871,18 +2886,19 @@ } }, "node_modules/eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", - "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz", + "integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.48.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.53.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -3037,19 +3053,19 @@ } }, "node_modules/eufy-security-client": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eufy-security-client/-/eufy-security-client-2.8.1.tgz", - "integrity": "sha512-EbqOJZnFEqq0ruNN2KTh/rW4xubQdNnGA6uu65dnLPEU9uE9ZoRxXEP2hDDn9HVNxmGbWHmOuT5rNlDI1OvkUQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/eufy-security-client/-/eufy-security-client-2.9.0.tgz", + "integrity": "sha512-EdESEUj82JaZRKjUXwl1VCXBnJ9CA3UYHL9SU1nCDHZNPuSWlYmkfyqk0LZJRdTEOe3SVb9RZ+5O2dhpo3wASw==", "dependencies": { "@cospired/i18n-iso-languages": "^4.1.0", - "crypto-js": "^4.1.1", - "date-and-time": "^3.0.2", + "crypto-js": "^4.2.0", + "date-and-time": "^3.0.3", "fs-extra": "^11.1.1", "got": "^11.8.6", - "i18n-iso-countries": "^7.6.0", + "i18n-iso-countries": "^7.7.0", "image-type": "^4.1.0", "long": "^5.2.3", - "mqtt": "^5.0.4", + "mqtt": "^5.1.4", "node-rsa": "^1.1.1", "node-schedule": "^2.1.1", "p-throttle": "^4.1.1", @@ -3060,7 +3076,7 @@ "ts-log": "^2.2.5" }, "engines": { - "node": ">=16.9.0" + "node": ">=18.0.0" } }, "node_modules/eufy-security-client/node_modules/protobufjs": { @@ -3331,6 +3347,34 @@ } } }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -3420,9 +3464,9 @@ } }, "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true, "engines": { "node": "*" @@ -3497,9 +3541,9 @@ } }, "node_modules/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3544,17 +3588,40 @@ "dev": true }, "node_modules/go2rtc-static": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/go2rtc-static/-/go2rtc-static-1.6.2.tgz", - "integrity": "sha512-pzm5cZkulntXBfQx+N7/d30qfMwJ/l0KZzVuvXeNefWu+swEAV/xM5RCwhfT1GPraa/F8Ds1IrCMD0v/w5Vsjg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/go2rtc-static/-/go2rtc-static-1.8.1.tgz", + "integrity": "sha512-KHeTObZIYFNABAkNuTxfvOclV5an47LJRK4VMFBMJ69VN1mmCj1/4TRxVkWWpcH3Ovqg1phl2OXL0DCU+PDVsw==", "hasInstallScript": true, "dependencies": { "got": "^11.8.6", - "https-proxy-agent": "^5.0.1", + "https-proxy-agent": "^7.0.2", "progress": "^2.0.3" }, "engines": { - "node": ">=14.18.0" + "node": ">=18.0.0" + } + }, + "node_modules/go2rtc-static/node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/go2rtc-static/node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" } }, "node_modules/google-auth-library": { @@ -3860,9 +3927,9 @@ } }, "node_modules/i18n-iso-countries": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/i18n-iso-countries/-/i18n-iso-countries-7.6.0.tgz", - "integrity": "sha512-HPKjOUKS0BkjiY4ayrsuFbu7Ock++pXLs+FAOYl4WfTL5L0ploEH68fiRAP6Zev5g/jvMFt54KcPGJcb942wbg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/i18n-iso-countries/-/i18n-iso-countries-7.7.0.tgz", + "integrity": "sha512-07zMatrSsR1Z+cnxW//7s14Xf4v5g6U6ORHPaH8+Ox4uPqV+y46Uq78veYV8H1DKTr76EfdjSeaTxHpnaYq+bw==", "dependencies": { "diacritics": "1.3.0" }, @@ -4077,9 +4144,9 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "node_modules/jackspeak": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz", - "integrity": "sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", "dev": true, "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -4517,9 +4584,9 @@ } }, "node_modules/minipass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", - "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -4685,12 +4752,12 @@ "dev": true }, "node_modules/mqtt": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.0.4.tgz", - "integrity": "sha512-Ao+DA4QYzIFXTQPIF0WKJfeHM2BV0kbP1xt/POPyJY2dQ02dscUJonh94NG9/aw0Fbk2L8Ex0YxobDSKUyQvcQ==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.1.4.tgz", + "integrity": "sha512-rmwV8WL5Wud2EEs4b0pKlTksLZGOW4ATdS+hN2H/VK5pC6PWEZQ3KGjbUJRwjIOD0pggu7VZSQ746NqWhabD+A==", "dependencies": { - "@types/readable-stream": "^4.0.1", - "@types/ws": "^8.5.5", + "@types/readable-stream": "^4.0.4", + "@types/ws": "^8.5.8", "commist": "^3.2.0", "concat-stream": "^2.0.0", "debug": "^4.3.4", @@ -4698,13 +4765,13 @@ "help-me": "^4.2.0", "lru-cache": "^7.18.3", "minimist": "^1.2.8", - "mqtt-packet": "^8.2.0", + "mqtt-packet": "^8.2.1", "number-allocator": "^1.0.14", "readable-stream": "^4.4.2", "reinterval": "^1.1.0", "rfdc": "^1.3.0", "split2": "^4.2.0", - "ws": "^8.13.0" + "ws": "^8.14.2" }, "bin": { "mqtt": "build/bin/mqtt.js", @@ -4716,9 +4783,9 @@ } }, "node_modules/mqtt-packet": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-8.2.0.tgz", - "integrity": "sha512-21Vo7XdRXUw2qhdTfk8GeOl2jtb8Dkwd4dKxn/epvf37mxTxHodvBJoozTPZGVwh57JXlsh2ChsaxMsAfqxp+A==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-8.2.1.tgz", + "integrity": "sha512-vrHHjwhmuxzQIe3fJWoOLQHF4H5FETUrQGYD5g1qGfEmpjkQUkPONfygA0cI8Wtb3IUCfu66WmZiVSCgGm8oUw==", "dependencies": { "bl": "^5.0.0", "debug": "^4.1.1", @@ -4799,9 +4866,9 @@ "dev": true }, "node_modules/nise": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", - "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz", + "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==", "dev": true, "dependencies": { "@sinonjs/commons": "^2.0.0", @@ -5068,13 +5135,13 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", - "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "dependencies": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -5084,9 +5151,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz", - "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", "dev": true, "engines": { "node": "14 || >=16.14" @@ -5283,9 +5350,9 @@ } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -5470,15 +5537,15 @@ "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, "node_modules/rimraf": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", - "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, "dependencies": { - "glob": "^10.2.5" + "glob": "^10.3.7" }, "bin": { - "rimraf": "dist/cjs/src/bin.js" + "rimraf": "dist/esm/bin.mjs" }, "engines": { "node": ">=14" @@ -5496,36 +5563,20 @@ "balanced-match": "^1.0.0" } }, - "node_modules/rimraf/node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/rimraf/node_modules/glob": { - "version": "10.2.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.7.tgz", - "integrity": "sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA==", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", + "jackspeak": "^2.3.5", "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" }, "bin": { - "glob": "dist/cjs/src/bin.js" + "glob": "dist/esm/bin.mjs" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -5535,9 +5586,9 @@ } }, "node_modules/rimraf/node_modules/minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -5549,18 +5600,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rimraf/node_modules/signal-exit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -5685,16 +5724,16 @@ "dev": true }, "node_modules/sinon": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz", - "integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", "dev": true, "dependencies": { "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^10.3.0", + "@sinonjs/fake-timers": "^11.2.2", "@sinonjs/samsam": "^8.0.0", "diff": "^5.1.0", - "nise": "^5.1.4", + "nise": "^5.1.5", "supports-color": "^7.2.0" }, "funding": { @@ -5722,9 +5761,9 @@ } }, "node_modules/sinon/node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, "dependencies": { "@sinonjs/commons": "^3.0.0" @@ -6160,6 +6199,11 @@ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -6274,9 +6318,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", "engines": { "node": ">=10.0.0" }, @@ -6679,9 +6723,9 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.3.tgz", + "integrity": "sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -6696,9 +6740,9 @@ } }, "@eslint/js": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", - "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz", + "integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==", "dev": true }, "@esm2cjs/execa": { @@ -6849,12 +6893,12 @@ } }, "@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.13.tgz", + "integrity": "sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", + "@humanwhocodes/object-schema": "^2.0.1", "debug": "^4.1.1", "minimatch": "^3.0.5" } @@ -6866,15 +6910,15 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz", + "integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==", "dev": true }, "@iobroker/adapter-core": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@iobroker/adapter-core/-/adapter-core-3.0.3.tgz", - "integrity": "sha512-SZmL69BtUXitnTbidNjlljQKB6CbkBLK9+Tqo/NMsOqHb1RmhPCNKhO4F5o8jc0dW0J6d4VArXryUkL7Ru0WpA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@iobroker/adapter-core/-/adapter-core-3.0.4.tgz", + "integrity": "sha512-QsSeIkOa+zEVdIQ0kc0GcfsnQC+pTWWkixotdG4naKuaLUwMWK7xP0UyUEUiaHfPG3KqyZxwIxQR9HMENvvIYQ==", "requires": {} }, "@iobroker/adapter-dev": { @@ -7254,15 +7298,15 @@ } }, "@types/chai": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.5.tgz", - "integrity": "sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==", + "version": "4.3.9", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.9.tgz", + "integrity": "sha512-69TtiDzu0bcmKQv3yg1Zx409/Kd7r0b5F1PfpYJfSHzLGtB53547V4u+9iqKYsTu/O2ai6KTb0TInNpvuQ3qmg==", "dev": true }, "@types/chai-as-promised": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz", - "integrity": "sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.7.tgz", + "integrity": "sha512-APucaP5rlmTRYKtRA6FE5QPP87x76ejw5t5guRJ4y5OgMnwtsvigw7HHhKZlx2MGXLeZd6R/GNZR/IqDHcbtQw==", "dev": true, "requires": { "@types/chai": "*" @@ -7278,9 +7322,9 @@ } }, "@types/express": { - "version": "4.17.17", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz", - "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==", + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.20.tgz", + "integrity": "sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw==", "dev": true, "requires": { "@types/body-parser": "*", @@ -7301,15 +7345,15 @@ } }, "@types/ffmpeg-static": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/ffmpeg-static/-/ffmpeg-static-3.0.1.tgz", - "integrity": "sha512-hEJdQMv/g1olk9qTiWqh23BfbKsDKE6Tc7DilNJWF1MgZsU9fYOPKrgQ448vfT7aP2Yt5re9vgJDVv9TXEoTyQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/ffmpeg-static/-/ffmpeg-static-3.0.2.tgz", + "integrity": "sha512-hEgrO6mk9OkBAEGLh5fqnW7LXVcTHGWncVPVgeroTvD+X95xd0Q6Mpd7hI96B1yzh0oTEKgTzR98FX7V54UNuw==", "dev": true }, "@types/fs-extra": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.1.tgz", - "integrity": "sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.3.tgz", + "integrity": "sha512-sF59BlXtUdzEAL1u0MSvuzWd7PdZvZEtnaVkzX5mjpdWTJ8brG0jUqve3jPCzSzvAKKMHTG8F8o/WMQLtleZdQ==", "dev": true, "requires": { "@types/jsonfile": "*", @@ -7332,9 +7376,9 @@ "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" }, "@types/json-schema": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", - "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.14.tgz", + "integrity": "sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw==", "dev": true }, "@types/jsonfile": { @@ -7383,9 +7427,9 @@ "dev": true }, "@types/mime": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", - "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.3.tgz", + "integrity": "sha512-i8MBln35l856k5iOhKk2XJ4SeAWg75mLIpZB4v6imOagKL6twsukBZGDMNhdOVk7yRFTMPpfILocMos59Q1otQ==", "dev": true }, "@types/minimatch": { @@ -7395,20 +7439,23 @@ "dev": true }, "@types/mocha": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.1.tgz", - "integrity": "sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.3.tgz", + "integrity": "sha512-RsOPImTriV/OE4A9qKjMtk2MnXiuLLbcO3nCXK+kvq4nr0iMfFgpjaX3MPLb6f7+EL1FGSelYvuJMV6REH+ZPQ==", "dev": true }, "@types/node": { - "version": "16.18.46", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.46.tgz", - "integrity": "sha512-Mnq3O9Xz52exs3mlxMcQuA7/9VFe/dXcrgAyfjLkABIqxXKOgBRjyazTxUbjsxDa4BP7hhPliyjVTP9RDP14xg==" + "version": "18.18.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.8.tgz", + "integrity": "sha512-OLGBaaK5V3VRBS1bAkMVP2/W9B+H8meUfl866OrMNQqt7wDgdpWPp5o6gmIc9pB+lIQHSq4ZL8ypeH1vPxcPaQ==", + "requires": { + "undici-types": "~5.26.4" + } }, "@types/proxyquire": { - "version": "1.3.28", - "resolved": "https://registry.npmjs.org/@types/proxyquire/-/proxyquire-1.3.28.tgz", - "integrity": "sha512-SQaNzWQ2YZSr7FqAyPPiA3FYpux2Lqh3HWMZQk47x3xbMCqgC/w0dY3dw9rGqlweDDkrySQBcaScXWeR+Yb11Q==", + "version": "1.3.30", + "resolved": "https://registry.npmjs.org/@types/proxyquire/-/proxyquire-1.3.30.tgz", + "integrity": "sha512-erD15isFDzHMfeQC09DMjGeI0G6pJm7r5R7X/CxnEEe6tEp7N4r6xLYhTptdzne8zMz+2+5wJzrefCMvbmV/Fg==", "dev": true }, "@types/qs": { @@ -7424,9 +7471,9 @@ "dev": true }, "@types/readable-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.2.tgz", - "integrity": "sha512-hhzOsMEISZ+mX1l+01F0duYt9wHEbCGmjARed0PcQoVS5zAdu7u5YbWYuNGhw09M1MgGr3kfsto+ut/MnAdKqA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.4.tgz", + "integrity": "sha512-NSAiePj3Iq3kBArfpUWRNX/mRw8DibYD6YhNCIJDfUP/iIOQYsNJgtHyjpbuZlcbL7TxILS8qYjY/nXXvtcFQg==", "requires": { "@types/node": "*", "safe-buffer": "~5.1.1" @@ -7458,9 +7505,9 @@ } }, "@types/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ==", "dev": true }, "@types/serve-static": { @@ -7474,18 +7521,18 @@ } }, "@types/sinon": { - "version": "10.0.16", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.16.tgz", - "integrity": "sha512-j2Du5SYpXZjJVJtXBokASpPRj+e2z+VUhCPHmM6WMfe3dpHu6iVKJMU6AiBcMp/XTAYnEj6Wc1trJUWwZ0QaAQ==", + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.0.tgz", + "integrity": "sha512-oN4AeDMFCeNZrAffCjhLcwwVymRZL2c9mljUmhPnd0eiM06d4ELDg0Q0TSvnZXrCIFlSA859qIdcfu1HapswPQ==", "dev": true, "requires": { "@types/sinonjs__fake-timers": "*" } }, "@types/sinon-chai": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.9.tgz", - "integrity": "sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ==", + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.11.tgz", + "integrity": "sha512-1C5SBFzwn9hjiMr1xfqbULcSI9qXVpkGZT/LYbbd3jWiTo2MSvA+iFfwODlSoAXGeCgBw6S509dxy8zSIacr3Q==", "dev": true, "requires": { "@types/chai": "*", @@ -7499,24 +7546,24 @@ "dev": true }, "@types/ws": { - "version": "8.5.5", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", - "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.8.tgz", + "integrity": "sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg==", "requires": { "@types/node": "*" } }, "@typescript-eslint/eslint-plugin": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.5.0.tgz", - "integrity": "sha512-2pktILyjvMaScU6iK3925uvGU87E+N9rh372uGZgiMYwafaw9SXq86U04XPq3UH6tzRvNgBsub6x2DacHc33lw==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.9.1.tgz", + "integrity": "sha512-w0tiiRc9I4S5XSXXrMHOWgHgxbrBn1Ro+PmiYhSg2ZVdxrAJtQgzU5o2m1BfP6UOn7Vxcc6152vFjQfmZR4xEg==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/type-utils": "6.5.0", - "@typescript-eslint/utils": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/type-utils": "6.9.1", + "@typescript-eslint/utils": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -7526,54 +7573,54 @@ } }, "@typescript-eslint/parser": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.5.0.tgz", - "integrity": "sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.9.1.tgz", + "integrity": "sha512-C7AK2wn43GSaCUZ9do6Ksgi2g3mwFkMO3Cis96kzmgudoVaKyt62yNzJOktP0HDLb/iO2O0n2lBOzJgr6Q/cyg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.5.0.tgz", - "integrity": "sha512-A8hZ7OlxURricpycp5kdPTH3XnjG85UpJS6Fn4VzeoH4T388gQJ/PGP4ole5NfKt4WDVhmLaQ/dBLNDC4Xl/Kw==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.9.1.tgz", + "integrity": "sha512-38IxvKB6NAne3g/+MyXMs2Cda/Sz+CEpmm+KLGEM8hx/CvnSRuw51i8ukfwB/B/sESdeTGet1NH1Wj7I0YXswg==", "dev": true, "requires": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0" + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1" } }, "@typescript-eslint/type-utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.5.0.tgz", - "integrity": "sha512-f7OcZOkRivtujIBQ4yrJNIuwyCQO1OjocVqntl9dgSIZAdKqicj3xFDqDOzHDlGCZX990LqhLQXWRnQvsapq8A==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.9.1.tgz", + "integrity": "sha512-eh2oHaUKCK58qIeYp19F5V5TbpM52680sB4zNSz29VBQPTWIlE/hCj5P5B1AChxECe/fmZlspAWFuRniep1Skg==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "6.5.0", - "@typescript-eslint/utils": "6.5.0", + "@typescript-eslint/typescript-estree": "6.9.1", + "@typescript-eslint/utils": "6.9.1", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" } }, "@typescript-eslint/types": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.5.0.tgz", - "integrity": "sha512-eqLLOEF5/lU8jW3Bw+8auf4lZSbbljHR2saKnYqON12G/WsJrGeeDHWuQePoEf9ro22+JkbPfWQwKEC5WwLQ3w==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.9.1.tgz", + "integrity": "sha512-BUGslGOb14zUHOUmDB2FfT6SI1CcZEJYfF3qFwBeUrU6srJfzANonwRYHDpLBuzbq3HaoF2XL2hcr01c8f8OaQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.5.0.tgz", - "integrity": "sha512-q0rGwSe9e5Kk/XzliB9h2LBc9tmXX25G0833r7kffbl5437FPWb2tbpIV9wAATebC/018pGa9fwPDuvGN+LxWQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.9.1.tgz", + "integrity": "sha512-U+mUylTHfcqeO7mLWVQ5W/tMLXqVpRv61wm9ZtfE5egz7gtnmqVIw9ryh0mgIlkKk9rZLY3UHygsBSdB9/ftyw==", "dev": true, "requires": { - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/visitor-keys": "6.5.0", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/visitor-keys": "6.9.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -7582,30 +7629,36 @@ } }, "@typescript-eslint/utils": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.5.0.tgz", - "integrity": "sha512-9nqtjkNykFzeVtt9Pj6lyR9WEdd8npPhhIPM992FWVkZuS6tmxHfGVnlUcjpUP2hv8r4w35nT33mlxd+Be1ACQ==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.9.1.tgz", + "integrity": "sha512-L1T0A5nFdQrMVunpZgzqPL6y2wVreSyHhKGZryS6jrEN7bD9NplVAyMryUhXsQ4TWLnZmxc2ekar/lSGIlprCA==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.5.0", - "@typescript-eslint/types": "6.5.0", - "@typescript-eslint/typescript-estree": "6.5.0", + "@typescript-eslint/scope-manager": "6.9.1", + "@typescript-eslint/types": "6.9.1", + "@typescript-eslint/typescript-estree": "6.9.1", "semver": "^7.5.4" } }, "@typescript-eslint/visitor-keys": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.5.0.tgz", - "integrity": "sha512-yCB/2wkbv3hPsh02ZS8dFQnij9VVQXJMN/gbQsaaY+zxALkZnxa/wagvLEFsAWMPv7d7lxQmNsIzGU1w/T/WyA==", + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.9.1.tgz", + "integrity": "sha512-MUaPUe/QRLEffARsmNfmpghuQkW436DvESW+h+M52w0coICHRfD6Np9/K6PdACwnrq1HmuLl+cSPZaJmeVPkSw==", "dev": true, "requires": { - "@typescript-eslint/types": "6.5.0", + "@typescript-eslint/types": "6.9.1", "eslint-visitor-keys": "^3.4.1" } }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -7902,18 +7955,18 @@ } }, "chai": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.8.tgz", - "integrity": "sha512-vX4YvVVtxlfSZ2VecZgFUTU5qPCYsobVI2O9FmwEXBhDigYGQA6jRXCycIs1yJnnWbZ6/+a2zNIF5DfVCcJBFQ==", + "version": "4.3.10", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.10.tgz", + "integrity": "sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==", "dev": true, "requires": { "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", "pathval": "^1.1.1", - "type-detect": "^4.0.5" + "type-detect": "^4.0.8" } }, "chai-as-promised": { @@ -7936,10 +7989,13 @@ } }, "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "requires": { + "get-func-name": "^2.0.2" + } }, "chokidar": { "version": "3.5.3", @@ -8053,14 +8109,14 @@ } }, "crypto-js": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz", - "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" }, "date-and-time": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-3.0.2.tgz", - "integrity": "sha512-MOqlRertOQmQI7ySbz6dKLM7Rxm9dgcPuBI9IL7NVe0UGqHPK+6hWSKVhLrVHxlSgQQtocE2R7+HFOf5aMz8vw==" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-3.0.3.tgz", + "integrity": "sha512-CmHCeTixc3KA5pcLTVs9JCFhmJMFTBsmSsgHnNed4YDNw9yUOrjjRn3zALy8eMgqmTO+4U8k5jl1peC7IoezfA==" }, "debug": { "version": "4.3.4", @@ -8086,9 +8142,9 @@ } }, "deep-eql": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz", - "integrity": "sha512-gT18+YW4CcW/DBNTwAmqTtkJh7f9qqScu2qFVlx7kCoeY9tlBu9cUcr7+I+Z/noG8INehS3xQgLpTtd/QUTn4w==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", + "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", "dev": true, "requires": { "type-detect": "^4.0.0" @@ -8114,7 +8170,7 @@ "diacritics": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/diacritics/-/diacritics-1.3.0.tgz", - "integrity": "sha1-PvqHMj67hj5mls67AILUj/PW96E=" + "integrity": "sha512-wlwEkqcsaxvPJML+rDh/2iS824jbREk6DUMUKkEaSlxdYHeS43cClJtsWglvw2RfeXGm6ohKDqsXteJ5sP5enA==" }, "diff": { "version": "5.0.0", @@ -8468,18 +8524,19 @@ } }, "eslint": { - "version": "8.48.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", - "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", + "version": "8.53.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz", + "integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "8.48.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/eslintrc": "^2.1.3", + "@eslint/js": "8.53.0", + "@humanwhocodes/config-array": "^0.11.13", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -8587,19 +8644,19 @@ "dev": true }, "eufy-security-client": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eufy-security-client/-/eufy-security-client-2.8.1.tgz", - "integrity": "sha512-EbqOJZnFEqq0ruNN2KTh/rW4xubQdNnGA6uu65dnLPEU9uE9ZoRxXEP2hDDn9HVNxmGbWHmOuT5rNlDI1OvkUQ==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/eufy-security-client/-/eufy-security-client-2.9.0.tgz", + "integrity": "sha512-EdESEUj82JaZRKjUXwl1VCXBnJ9CA3UYHL9SU1nCDHZNPuSWlYmkfyqk0LZJRdTEOe3SVb9RZ+5O2dhpo3wASw==", "requires": { "@cospired/i18n-iso-languages": "^4.1.0", - "crypto-js": "^4.1.1", - "date-and-time": "^3.0.2", + "crypto-js": "^4.2.0", + "date-and-time": "^3.0.3", "fs-extra": "^11.1.1", "got": "^11.8.6", - "i18n-iso-countries": "^7.6.0", + "i18n-iso-countries": "^7.7.0", "image-type": "^4.1.0", "long": "^5.2.3", - "mqtt": "^5.0.4", + "mqtt": "^5.1.4", "node-rsa": "^1.1.1", "node-schedule": "^2.1.1", "p-throttle": "^4.1.1", @@ -8811,6 +8868,24 @@ "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", "dev": true }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "dependencies": { + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + } + } + }, "form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -8878,9 +8953,9 @@ "dev": true }, "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", "dev": true }, "get-intrinsic": { @@ -8936,9 +9011,9 @@ } }, "globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -8971,13 +9046,32 @@ "dev": true }, "go2rtc-static": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/go2rtc-static/-/go2rtc-static-1.6.2.tgz", - "integrity": "sha512-pzm5cZkulntXBfQx+N7/d30qfMwJ/l0KZzVuvXeNefWu+swEAV/xM5RCwhfT1GPraa/F8Ds1IrCMD0v/w5Vsjg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/go2rtc-static/-/go2rtc-static-1.8.1.tgz", + "integrity": "sha512-KHeTObZIYFNABAkNuTxfvOclV5an47LJRK4VMFBMJ69VN1mmCj1/4TRxVkWWpcH3Ovqg1phl2OXL0DCU+PDVsw==", "requires": { "got": "^11.8.6", - "https-proxy-agent": "^5.0.1", + "https-proxy-agent": "^7.0.2", "progress": "^2.0.3" + }, + "dependencies": { + "agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "requires": { + "debug": "^4.3.4" + } + }, + "https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "requires": { + "agent-base": "^7.0.2", + "debug": "4" + } + } } }, "google-auth-library": { @@ -9216,9 +9310,9 @@ "dev": true }, "i18n-iso-countries": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/i18n-iso-countries/-/i18n-iso-countries-7.6.0.tgz", - "integrity": "sha512-HPKjOUKS0BkjiY4ayrsuFbu7Ock++pXLs+FAOYl4WfTL5L0ploEH68fiRAP6Zev5g/jvMFt54KcPGJcb942wbg==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/i18n-iso-countries/-/i18n-iso-countries-7.7.0.tgz", + "integrity": "sha512-07zMatrSsR1Z+cnxW//7s14Xf4v5g6U6ORHPaH8+Ox4uPqV+y46Uq78veYV8H1DKTr76EfdjSeaTxHpnaYq+bw==", "requires": { "diacritics": "1.3.0" } @@ -9365,9 +9459,9 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "jackspeak": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.2.1.tgz", - "integrity": "sha512-MXbxovZ/Pm42f6cDIDkl3xpwv1AGwObKwfmjs2nQePiy85tP3fatofl3FC1aBsOtP/6fq5SbtgHwWcMsLP+bDw==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", "dev": true, "requires": { "@isaacs/cliui": "^8.0.2", @@ -9715,9 +9809,9 @@ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" }, "minipass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", - "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true }, "mkdirp": { @@ -9845,12 +9939,12 @@ "dev": true }, "mqtt": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.0.4.tgz", - "integrity": "sha512-Ao+DA4QYzIFXTQPIF0WKJfeHM2BV0kbP1xt/POPyJY2dQ02dscUJonh94NG9/aw0Fbk2L8Ex0YxobDSKUyQvcQ==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.1.4.tgz", + "integrity": "sha512-rmwV8WL5Wud2EEs4b0pKlTksLZGOW4ATdS+hN2H/VK5pC6PWEZQ3KGjbUJRwjIOD0pggu7VZSQ746NqWhabD+A==", "requires": { - "@types/readable-stream": "^4.0.1", - "@types/ws": "^8.5.5", + "@types/readable-stream": "^4.0.4", + "@types/ws": "^8.5.8", "commist": "^3.2.0", "concat-stream": "^2.0.0", "debug": "^4.3.4", @@ -9858,13 +9952,13 @@ "help-me": "^4.2.0", "lru-cache": "^7.18.3", "minimist": "^1.2.8", - "mqtt-packet": "^8.2.0", + "mqtt-packet": "^8.2.1", "number-allocator": "^1.0.14", "readable-stream": "^4.4.2", "reinterval": "^1.1.0", "rfdc": "^1.3.0", "split2": "^4.2.0", - "ws": "^8.13.0" + "ws": "^8.14.2" }, "dependencies": { "concat-stream": { @@ -9913,9 +10007,9 @@ } }, "mqtt-packet": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-8.2.0.tgz", - "integrity": "sha512-21Vo7XdRXUw2qhdTfk8GeOl2jtb8Dkwd4dKxn/epvf37mxTxHodvBJoozTPZGVwh57JXlsh2ChsaxMsAfqxp+A==", + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-8.2.1.tgz", + "integrity": "sha512-vrHHjwhmuxzQIe3fJWoOLQHF4H5FETUrQGYD5g1qGfEmpjkQUkPONfygA0cI8Wtb3IUCfu66WmZiVSCgGm8oUw==", "requires": { "bl": "^5.0.0", "debug": "^4.1.1", @@ -9940,9 +10034,9 @@ "dev": true }, "nise": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", - "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz", + "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==", "dev": true, "requires": { "@sinonjs/commons": "^2.0.0", @@ -10134,19 +10228,19 @@ "dev": true }, "path-scurry": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", - "integrity": "sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "requires": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "dependencies": { "lru-cache": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz", - "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", + "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==", "dev": true } } @@ -10297,9 +10391,9 @@ } }, "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, "qs": { @@ -10435,12 +10529,12 @@ "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, "rimraf": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.1.tgz", - "integrity": "sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", + "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", "dev": true, "requires": { - "glob": "^10.2.5" + "glob": "^10.3.7" }, "dependencies": { "brace-expansion": { @@ -10452,43 +10546,27 @@ "balanced-match": "^1.0.0" } }, - "foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - } - }, "glob": { - "version": "10.2.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.2.7.tgz", - "integrity": "sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA==", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, "requires": { "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", + "jackspeak": "^2.3.5", "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2", - "path-scurry": "^1.7.0" + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" } }, "minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "requires": { "brace-expansion": "^2.0.1" } - }, - "signal-exit": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz", - "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==", - "dev": true } } }, @@ -10572,16 +10650,16 @@ "dev": true }, "sinon": { - "version": "15.2.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.2.0.tgz", - "integrity": "sha512-nPS85arNqwBXaIsFCkolHjGIkFo+Oxu9vbgmBJizLAhqe6P2o3Qmj3KCUoRkfhHtvgDhZdWD3risLHAUJ8npjw==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", "dev": true, "requires": { "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^10.3.0", + "@sinonjs/fake-timers": "^11.2.2", "@sinonjs/samsam": "^8.0.0", "diff": "^5.1.0", - "nise": "^5.1.4", + "nise": "^5.1.5", "supports-color": "^7.2.0" }, "dependencies": { @@ -10595,9 +10673,9 @@ } }, "@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, "requires": { "@sinonjs/commons": "^3.0.0" @@ -10943,6 +11021,11 @@ "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", "dev": true }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -11032,9 +11115,9 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", + "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", "requires": {} }, "xmlcreate": { diff --git a/package.json b/package.json index 8832b63..a74f199 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "iobroker.eusec", - "version": "1.1.2", + "version": "1.2.0", "description": "ioBroker adapter that integrates Eufy-Security cameras with stations", "author": { "name": "bropat", @@ -20,18 +20,18 @@ "url": "https://github.com/bropat/ioBroker.eusec" }, "engines": { - "node": ">=16.9.0" + "node": ">=18.0.0" }, "dependencies": { "@bropat/fluent-ffmpeg": "^2.1.3", "@cospired/i18n-iso-languages": "^4.1.0", - "@iobroker/adapter-core": "^3.0.3", - "eufy-security-client": "^2.8.1", + "@iobroker/adapter-core": "^3.0.4", + "eufy-security-client": "^2.9.0", "ffmpeg-static": "^5.2.0", "fs-extra": "^11.1.1", - "go2rtc-static": "^1.6.2", + "go2rtc-static": "^1.8.1", "got": "^11.8.6", - "i18n-iso-countries": "^7.6.0", + "i18n-iso-countries": "^7.7.0", "mime": "^3.0.0", "ts-log": "^2.2.5" }, @@ -39,26 +39,26 @@ "@iobroker/adapter-dev": "^1.2.0", "@alcalzone/release-script": "^3.6.0", "@iobroker/testing": "^4.1.0", - "@types/chai": "^4.3.5", - "@types/chai-as-promised": "^7.1.5", - "@types/express": "^4.17.17", - "@types/ffmpeg-static": "^3.0.1", - "@types/fs-extra": "^11.0.1", - "@types/mime": "^3.0.1", - "@types/mocha": "^10.0.1", - "@types/node": "^16.18.46", - "@types/proxyquire": "^1.3.28", - "@types/sinon": "^10.0.16", - "@types/sinon-chai": "^3.2.9", - "@typescript-eslint/eslint-plugin": "^6.5.0", - "@typescript-eslint/parser": "^6.5.0", - "chai": "^4.3.8", + "@types/chai": "^4.3.9", + "@types/chai-as-promised": "^7.1.7", + "@types/express": "^4.17.20", + "@types/ffmpeg-static": "^3.0.2", + "@types/fs-extra": "^11.0.3", + "@types/mime": "^3.0.3", + "@types/mocha": "^10.0.3", + "@types/node": "^18.18.8", + "@types/proxyquire": "^1.3.30", + "@types/sinon": "^17.0.0", + "@types/sinon-chai": "^3.2.11", + "@typescript-eslint/eslint-plugin": "^6.9.1", + "@typescript-eslint/parser": "^6.9.1", + "chai": "^4.3.10", "chai-as-promised": "^7.1.1", - "eslint": "^8.48.0", + "eslint": "^8.53.0", "mocha": "^10.2.0", "proxyquire": "^2.1.3", - "rimraf": "^5.0.1", - "sinon": "^15.2.0", + "rimraf": "^5.0.5", + "sinon": "^17.0.1", "sinon-chai": "^3.7.0", "source-map-support": "^0.5.21", "ts-node": "^10.9.1",