@homebridge-eufy-security/eufy-security-client 3.7.2-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/.prettierignore/342/200/216 +8 -0
  2. package/.prettierrc +11 -0
  3. package/LICENSE +21 -0
  4. package/README.md +970 -0
  5. package/build/error.d.ts +138 -0
  6. package/build/error.js +190 -0
  7. package/build/error.js.map +1 -0
  8. package/build/eufysecurity.d.ts +180 -0
  9. package/build/eufysecurity.js +3148 -0
  10. package/build/eufysecurity.js.map +1 -0
  11. package/build/http/api.d.ts +119 -0
  12. package/build/http/api.js +1877 -0
  13. package/build/http/api.js.map +1 -0
  14. package/build/http/cache.d.ts +8 -0
  15. package/build/http/cache.js +34 -0
  16. package/build/http/cache.js.map +1 -0
  17. package/build/http/const.d.ts +8 -0
  18. package/build/http/const.js +3054 -0
  19. package/build/http/const.js.map +1 -0
  20. package/build/http/device.d.ts +490 -0
  21. package/build/http/device.js +5256 -0
  22. package/build/http/device.js.map +1 -0
  23. package/build/http/error.d.ts +73 -0
  24. package/build/http/error.js +101 -0
  25. package/build/http/error.js.map +1 -0
  26. package/build/http/index.d.ts +10 -0
  27. package/build/http/index.js +30 -0
  28. package/build/http/index.js.map +1 -0
  29. package/build/http/interfaces.d.ts +248 -0
  30. package/build/http/interfaces.js +3 -0
  31. package/build/http/interfaces.js.map +1 -0
  32. package/build/http/models.d.ts +608 -0
  33. package/build/http/models.js +3 -0
  34. package/build/http/models.js.map +1 -0
  35. package/build/http/parameter.d.ts +7 -0
  36. package/build/http/parameter.js +119 -0
  37. package/build/http/parameter.js.map +1 -0
  38. package/build/http/station.d.ts +382 -0
  39. package/build/http/station.js +15735 -0
  40. package/build/http/station.js.map +1 -0
  41. package/build/http/types.d.ts +1358 -0
  42. package/build/http/types.js +10333 -0
  43. package/build/http/types.js.map +1 -0
  44. package/build/http/utils.d.ts +89 -0
  45. package/build/http/utils.js +916 -0
  46. package/build/http/utils.js.map +1 -0
  47. package/build/index.d.ts +8 -0
  48. package/build/index.js +29 -0
  49. package/build/index.js.map +1 -0
  50. package/build/interfaces.d.ts +147 -0
  51. package/build/interfaces.js +7 -0
  52. package/build/interfaces.js.map +1 -0
  53. package/build/logging.d.ts +36 -0
  54. package/build/logging.js +119 -0
  55. package/build/logging.js.map +1 -0
  56. package/build/mqtt/interface.d.ts +6 -0
  57. package/build/mqtt/interface.js +3 -0
  58. package/build/mqtt/interface.js.map +1 -0
  59. package/build/mqtt/model.d.ts +24 -0
  60. package/build/mqtt/model.js +3 -0
  61. package/build/mqtt/model.js.map +1 -0
  62. package/build/mqtt/mqtt-eufy.crt +79 -0
  63. package/build/mqtt/proto/lock.proto +33 -0
  64. package/build/mqtt/service.d.ts +28 -0
  65. package/build/mqtt/service.js +196 -0
  66. package/build/mqtt/service.js.map +1 -0
  67. package/build/p2p/ble.d.ts +59 -0
  68. package/build/p2p/ble.js +281 -0
  69. package/build/p2p/ble.js.map +1 -0
  70. package/build/p2p/error.d.ts +49 -0
  71. package/build/p2p/error.js +69 -0
  72. package/build/p2p/error.js.map +1 -0
  73. package/build/p2p/index.d.ts +8 -0
  74. package/build/p2p/index.js +28 -0
  75. package/build/p2p/index.js.map +1 -0
  76. package/build/p2p/interfaces.d.ts +423 -0
  77. package/build/p2p/interfaces.js +3 -0
  78. package/build/p2p/interfaces.js.map +1 -0
  79. package/build/p2p/models.d.ts +295 -0
  80. package/build/p2p/models.js +3 -0
  81. package/build/p2p/models.js.map +1 -0
  82. package/build/p2p/session.d.ts +186 -0
  83. package/build/p2p/session.js +3737 -0
  84. package/build/p2p/session.js.map +1 -0
  85. package/build/p2p/talkback.d.ts +8 -0
  86. package/build/p2p/talkback.js +23 -0
  87. package/build/p2p/talkback.js.map +1 -0
  88. package/build/p2p/types.d.ts +1164 -0
  89. package/build/p2p/types.js +1219 -0
  90. package/build/p2p/types.js.map +1 -0
  91. package/build/p2p/utils.d.ts +72 -0
  92. package/build/p2p/utils.js +865 -0
  93. package/build/p2p/utils.js.map +1 -0
  94. package/build/push/client.d.ts +49 -0
  95. package/build/push/client.js +344 -0
  96. package/build/push/client.js.map +1 -0
  97. package/build/push/error.d.ts +73 -0
  98. package/build/push/error.js +101 -0
  99. package/build/push/error.js.map +1 -0
  100. package/build/push/index.d.ts +6 -0
  101. package/build/push/index.js +26 -0
  102. package/build/push/index.js.map +1 -0
  103. package/build/push/interfaces.d.ts +19 -0
  104. package/build/push/interfaces.js +3 -0
  105. package/build/push/interfaces.js.map +1 -0
  106. package/build/push/models.d.ts +328 -0
  107. package/build/push/models.js +38 -0
  108. package/build/push/models.js.map +1 -0
  109. package/build/push/parser.d.ts +25 -0
  110. package/build/push/parser.js +231 -0
  111. package/build/push/parser.js.map +1 -0
  112. package/build/push/proto/checkin.proto +266 -0
  113. package/build/push/proto/mcs.proto +328 -0
  114. package/build/push/service.d.ts +46 -0
  115. package/build/push/service.js +965 -0
  116. package/build/push/service.js.map +1 -0
  117. package/build/push/types.d.ts +220 -0
  118. package/build/push/types.js +244 -0
  119. package/build/push/types.js.map +1 -0
  120. package/build/push/utils.d.ts +7 -0
  121. package/build/push/utils.js +116 -0
  122. package/build/push/utils.js.map +1 -0
  123. package/build/utils.d.ts +115 -0
  124. package/build/utils.js +438 -0
  125. package/build/utils.js.map +1 -0
  126. package/eslint.config.mts +68 -0
  127. package/jest.config.js +14 -0
  128. package/package.json +85 -0
  129. package/scripts/cut_release.sh +31 -0
@@ -0,0 +1,3148 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.EufySecurity = void 0;
40
+ const tiny_typed_emitter_1 = require("tiny-typed-emitter");
41
+ const fs_1 = require("fs");
42
+ const path = __importStar(require("path"));
43
+ const events_1 = __importDefault(require("events"));
44
+ const api_1 = require("./http/api");
45
+ const station_1 = require("./http/station");
46
+ const types_1 = require("./http/types");
47
+ const service_1 = require("./push/service");
48
+ const device_1 = require("./http/device");
49
+ const types_2 = require("./p2p/types");
50
+ const utils_1 = require("./utils");
51
+ const error_1 = require("./error");
52
+ const _1 = require(".");
53
+ const error_2 = require("./http/error");
54
+ const types_3 = require("./push/types");
55
+ const service_2 = require("./mqtt/service");
56
+ const utils_2 = require("./http/utils");
57
+ const logging_1 = require("./logging");
58
+ const typescript_logging_1 = require("typescript-logging");
59
+ const utils_3 = require("./p2p/utils");
60
+ class EufySecurity extends tiny_typed_emitter_1.TypedEmitter {
61
+ config;
62
+ api;
63
+ houses = {};
64
+ stations = {};
65
+ devices = {};
66
+ P2P_REFRESH_INTERVAL_MIN = 720;
67
+ cameraMaxLivestreamSeconds = 30;
68
+ cameraStationLivestreamTimeout = new Map();
69
+ pushService;
70
+ mqttService;
71
+ pushCloudRegistered = false;
72
+ pushCloudChecked = false;
73
+ persistentFile;
74
+ persistentData = {
75
+ country: "",
76
+ openudid: "",
77
+ serial_number: "",
78
+ push_credentials: undefined,
79
+ push_persistentIds: [],
80
+ login_hash: "",
81
+ version: "",
82
+ httpApi: undefined,
83
+ };
84
+ connected = false;
85
+ retries = 0;
86
+ refreshEufySecurityCloudTimeout;
87
+ refreshEufySecurityP2PTimeout = {};
88
+ deviceSnoozeTimeout = {};
89
+ loadingEmitter = new events_1.default();
90
+ stationsLoaded = (0, utils_1.waitForEvent)(this.loadingEmitter, "stations loaded");
91
+ devicesLoaded = (0, utils_1.waitForEvent)(this.loadingEmitter, "devices loaded");
92
+ constructor(config, log = logging_1.dummyLogger) {
93
+ super();
94
+ this.config = config;
95
+ logging_1.InternalLogger.logger = log;
96
+ }
97
+ static async initialize(config, log = logging_1.dummyLogger) {
98
+ const eufySecurity = new EufySecurity(config, log);
99
+ await eufySecurity._initializeInternals();
100
+ return eufySecurity;
101
+ }
102
+ async _initializeInternals() {
103
+ if (this.config.logging) {
104
+ if (this.config.logging.level !== undefined &&
105
+ typeof this.config.logging.level === "number" &&
106
+ Object.values(typescript_logging_1.LogLevel).includes(this.config.logging.level))
107
+ (0, logging_1.setLoggingLevel)("all", this.config.logging.level);
108
+ if (this.config.logging.categories !== undefined && Array.isArray(this.config.logging.categories)) {
109
+ for (const category of this.config.logging.categories) {
110
+ if (typeof category === "object" &&
111
+ "category" in category &&
112
+ "level" in category &&
113
+ typeof category.level === "number" &&
114
+ Object.values(typescript_logging_1.LogLevel).includes(category.level) &&
115
+ typeof category.category === "string" &&
116
+ ["main", "http", "p2p", "push", "mqtt"].includes(category.category.toLowerCase())) {
117
+ (0, logging_1.setLoggingLevel)(category.category.toLocaleLowerCase(), category.level);
118
+ }
119
+ }
120
+ }
121
+ }
122
+ if (this.config.country === undefined) {
123
+ this.config.country = "US";
124
+ }
125
+ else {
126
+ this.config.country = this.config.country.toUpperCase();
127
+ }
128
+ if (this.config.language === undefined) {
129
+ this.config.language = "en";
130
+ }
131
+ if (this.config.eventDurationSeconds === undefined) {
132
+ this.config.eventDurationSeconds = 10;
133
+ }
134
+ if (this.config.p2pConnectionSetup === undefined) {
135
+ this.config.p2pConnectionSetup = types_2.P2PConnectionType.QUICKEST;
136
+ }
137
+ else if (!Object.values(types_2.P2PConnectionType).includes(this.config.p2pConnectionSetup)) {
138
+ this.config.p2pConnectionSetup = types_2.P2PConnectionType.QUICKEST;
139
+ }
140
+ if (this.config.pollingIntervalMinutes === undefined) {
141
+ this.config.pollingIntervalMinutes = 10;
142
+ }
143
+ if (this.config.acceptInvitations === undefined) {
144
+ this.config.acceptInvitations = false;
145
+ }
146
+ if (this.config.enableEmbeddedPKCS1Support === undefined) {
147
+ this.config.enableEmbeddedPKCS1Support = false;
148
+ }
149
+ if (this.config.deviceConfig === undefined) {
150
+ this.config.deviceConfig = {
151
+ simultaneousDetections: true,
152
+ };
153
+ }
154
+ if (this.config.persistentDir === undefined) {
155
+ this.config.persistentDir = path.resolve(__dirname, "../../..");
156
+ }
157
+ else if (!(0, fs_1.existsSync)(this.config.persistentDir)) {
158
+ this.config.persistentDir = path.resolve(__dirname, "../../..");
159
+ }
160
+ if (this.config.persistentData) {
161
+ this.persistentData = JSON.parse(this.config.persistentData);
162
+ }
163
+ else {
164
+ this.persistentFile = path.join(this.config.persistentDir, "persistent.json");
165
+ }
166
+ try {
167
+ if (!this.config.persistentData && (0, fs_1.statSync)(this.persistentFile).isFile()) {
168
+ const fileContent = (0, fs_1.readFileSync)(this.persistentFile, "utf8");
169
+ this.persistentData = JSON.parse(fileContent);
170
+ }
171
+ }
172
+ catch (err) {
173
+ const error = (0, error_1.ensureError)(err);
174
+ logging_1.rootMainLogger.debug("No stored data from last exit found", { error: (0, utils_1.getError)(error) });
175
+ }
176
+ logging_1.rootMainLogger.debug("Loaded persistent data", { persistentData: this.persistentData });
177
+ try {
178
+ if (this.persistentData.version !== _1.libVersion) {
179
+ const currentVersion = Number.parseFloat((0, utils_1.removeLastChar)(_1.libVersion, "."));
180
+ const previousVersion = this.persistentData.version !== "" && this.persistentData.version !== undefined
181
+ ? Number.parseFloat((0, utils_1.removeLastChar)(this.persistentData.version, "."))
182
+ : 0;
183
+ logging_1.rootMainLogger.debug("Handling of driver update", {
184
+ currentVersion: currentVersion,
185
+ previousVersion: previousVersion,
186
+ });
187
+ if (previousVersion < currentVersion) {
188
+ this.persistentData = (0, utils_1.handleUpdate)(this.persistentData, previousVersion);
189
+ this.persistentData.version = _1.libVersion;
190
+ }
191
+ }
192
+ }
193
+ catch (err) {
194
+ const error = (0, error_1.ensureError)(err);
195
+ logging_1.rootMainLogger.error("Handling update - Error", { error: (0, utils_1.getError)(error) });
196
+ }
197
+ if (this.config.trustedDeviceName === undefined || this.config.trustedDeviceName === "") {
198
+ if (this.persistentData.fallbackTrustedDeviceName !== undefined) {
199
+ this.config.trustedDeviceName = this.persistentData.fallbackTrustedDeviceName;
200
+ }
201
+ else {
202
+ this.persistentData.fallbackTrustedDeviceName = (0, utils_2.getRandomPhoneModel)();
203
+ this.config.trustedDeviceName = this.persistentData.fallbackTrustedDeviceName;
204
+ }
205
+ }
206
+ if (this.persistentData.login_hash && this.persistentData.login_hash != "") {
207
+ logging_1.rootMainLogger.debug("Load previous login_hash", { login_hash: this.persistentData.login_hash });
208
+ if ((0, utils_1.md5)(`${this.config.username}:${this.config.password}`) != this.persistentData.login_hash) {
209
+ logging_1.rootMainLogger.info("Authentication properties changed, invalidate saved cloud token.");
210
+ this.persistentData.cloud_token = "";
211
+ this.persistentData.cloud_token_expiration = 0;
212
+ this.persistentData.httpApi = undefined;
213
+ }
214
+ }
215
+ else {
216
+ this.persistentData.cloud_token = "";
217
+ this.persistentData.cloud_token_expiration = 0;
218
+ this.persistentData.httpApi = undefined;
219
+ }
220
+ if (this.persistentData.country !== undefined &&
221
+ this.persistentData.country !== "" &&
222
+ this.persistentData.country !== this.config.country) {
223
+ logging_1.rootMainLogger.info("Country property changed, invalidate saved cloud token.");
224
+ this.persistentData.cloud_token = "";
225
+ this.persistentData.cloud_token_expiration = 0;
226
+ this.persistentData.httpApi = undefined;
227
+ }
228
+ if (this.persistentData.httpApi !== undefined &&
229
+ (this.persistentData.httpApi.clientPrivateKey === undefined ||
230
+ this.persistentData.httpApi.clientPrivateKey === "" ||
231
+ this.persistentData.httpApi.serverPublicKey === undefined ||
232
+ this.persistentData.httpApi.serverPublicKey === "")) {
233
+ logging_1.rootMainLogger.debug("Incomplete persistent data for v2 encrypted cloud api communication. Invalidate authenticated session data.");
234
+ this.persistentData.cloud_token = "";
235
+ this.persistentData.cloud_token_expiration = 0;
236
+ this.persistentData.httpApi = undefined;
237
+ }
238
+ this.api = await api_1.HTTPApi.initialize(this.config.country, this.config.username, this.config.password, this.persistentData.httpApi);
239
+ this.api.setLanguage(this.config.language);
240
+ this.api.setPhoneModel(this.config.trustedDeviceName);
241
+ this.api.on("houses", (houses) => this.handleHouses(houses));
242
+ this.api.on("hubs", (hubs) => this.handleHubs(hubs));
243
+ this.api.on("devices", (devices) => this.handleDevices(devices));
244
+ this.api.on("close", () => this.onAPIClose());
245
+ this.api.on("connect", () => this.onAPIConnect());
246
+ this.api.on("captcha request", (id, captcha) => this.onCaptchaRequest(id, captcha));
247
+ this.api.on("auth token invalidated", () => this.onAuthTokenInvalidated());
248
+ this.api.on("tfa request", () => this.onTfaRequest());
249
+ this.api.on("connection error", (error) => this.onAPIConnectionError(error));
250
+ if (this.persistentData.cloud_token &&
251
+ this.persistentData.cloud_token != "" &&
252
+ this.persistentData.cloud_token_expiration) {
253
+ logging_1.rootMainLogger.debug("Load previous token", {
254
+ token: this.persistentData.cloud_token,
255
+ tokenExpiration: this.persistentData.cloud_token_expiration,
256
+ persistentHttpApi: this.persistentData.httpApi,
257
+ });
258
+ this.api.setToken(this.persistentData.cloud_token);
259
+ this.api.setTokenExpiration(new Date(this.persistentData.cloud_token_expiration));
260
+ }
261
+ if (!this.persistentData.openudid || this.persistentData.openudid == "") {
262
+ this.persistentData.openudid = (0, utils_1.generateUDID)();
263
+ logging_1.rootMainLogger.debug("Generated new openudid", { openudid: this.persistentData.openudid });
264
+ }
265
+ this.api.setOpenUDID(this.persistentData.openudid);
266
+ if (!this.persistentData.serial_number || this.persistentData.serial_number == "") {
267
+ this.persistentData.serial_number = (0, utils_1.generateSerialnumber)(12);
268
+ logging_1.rootMainLogger.debug("Generated new serial_number", { serialnumber: this.persistentData.serial_number });
269
+ }
270
+ this.api.setSerialNumber(this.persistentData.serial_number);
271
+ this.pushService = await service_1.PushNotificationService.initialize();
272
+ this.pushService.on("connect", async (token) => {
273
+ this.pushCloudRegistered = await this.api.registerPushToken(token);
274
+ this.pushCloudChecked = await this.api.checkPushToken();
275
+ //TODO: Retry if failed with max retry to not lock account
276
+ if (this.pushCloudRegistered && this.pushCloudChecked) {
277
+ logging_1.rootMainLogger.info("Push notification connection successfully established");
278
+ this.emit("push connect");
279
+ }
280
+ else {
281
+ logging_1.rootMainLogger.info("Push notification connection closed");
282
+ this.emit("push close");
283
+ }
284
+ });
285
+ this.pushService.on("credential", (credentials) => {
286
+ this.savePushCredentials(credentials);
287
+ });
288
+ this.pushService.on("message", (message) => this.onPushMessage(message));
289
+ this.pushService.on("close", () => {
290
+ logging_1.rootMainLogger.info("Push notification connection closed");
291
+ this.emit("push close");
292
+ });
293
+ await this.initMQTT();
294
+ }
295
+ async initMQTT() {
296
+ this.mqttService = await service_2.MQTTService.init();
297
+ this.mqttService.on("connect", () => {
298
+ logging_1.rootMainLogger.info("MQTT connection successfully established");
299
+ this.emit("mqtt connect");
300
+ });
301
+ this.mqttService.on("close", () => {
302
+ logging_1.rootMainLogger.info("MQTT connection closed");
303
+ this.emit("mqtt close");
304
+ });
305
+ this.mqttService.on("lock message", (message) => {
306
+ this.getDevice(message.data.data.deviceSn)
307
+ .then((device) => {
308
+ device.processMQTTNotification(message.data.data, this.config.eventDurationSeconds);
309
+ })
310
+ .catch((err) => {
311
+ const error = (0, error_1.ensureError)(err);
312
+ if (!(error instanceof error_1.DeviceNotFoundError)) {
313
+ logging_1.rootMainLogger.error("Lock MQTT Message Error", { error: (0, utils_1.getError)(error) });
314
+ }
315
+ })
316
+ .finally(() => {
317
+ this.emit("mqtt lock message", message);
318
+ });
319
+ });
320
+ }
321
+ setLoggingLevel(category, level) {
322
+ if (typeof level === "number" &&
323
+ Object.values(typescript_logging_1.LogLevel).includes(level) &&
324
+ typeof category === "string" &&
325
+ ["all", "main", "http", "p2p", "push", "mqtt"].includes(category.toLowerCase())) {
326
+ (0, logging_1.setLoggingLevel)(category, level);
327
+ }
328
+ }
329
+ getLoggingLevel(category) {
330
+ if (typeof category === "string" &&
331
+ ["all", "main", "http", "p2p", "push", "mqtt"].includes(category.toLowerCase())) {
332
+ return (0, logging_1.getLoggingLevel)(category);
333
+ }
334
+ return -1;
335
+ }
336
+ setInternalLogger(logger) {
337
+ logging_1.InternalLogger.logger = logger;
338
+ }
339
+ getInternalLogger() {
340
+ return logging_1.InternalLogger.logger;
341
+ }
342
+ getPushService() {
343
+ return this.pushService;
344
+ }
345
+ addStation(station) {
346
+ const serial = station.getSerial();
347
+ if (serial && !Object.keys(this.stations).includes(serial)) {
348
+ this.stations[serial] = station;
349
+ this.emit("station added", station);
350
+ }
351
+ else {
352
+ logging_1.rootMainLogger.debug(`Station with this serial ${station.getSerial()} exists already and couldn't be added again!`);
353
+ }
354
+ }
355
+ removeStation(station) {
356
+ const serial = station.getSerial();
357
+ if (serial && Object.keys(this.stations).includes(serial)) {
358
+ delete this.stations[serial];
359
+ station.removeAllListeners();
360
+ if (station.isConnected())
361
+ station.close();
362
+ this.emit("station removed", station);
363
+ }
364
+ else {
365
+ logging_1.rootMainLogger.debug(`Station with this serial ${station.getSerial()} doesn't exists and couldn't be removed!`);
366
+ }
367
+ }
368
+ async updateStation(hub) {
369
+ if (this.stationsLoaded)
370
+ await this.stationsLoaded;
371
+ if (Object.keys(this.stations).includes(hub.station_sn)) {
372
+ this.stations[hub.station_sn].update(hub);
373
+ if (!this.stations[hub.station_sn].isConnected() &&
374
+ !this.stations[hub.station_sn].isEnergySavingDevice() &&
375
+ this.stations[hub.station_sn].isP2PConnectableDevice()) {
376
+ this.stations[hub.station_sn].setConnectionType(this.config.p2pConnectionSetup);
377
+ logging_1.rootMainLogger.debug(`Updating station cloud data - initiate station connection to get local data over p2p`, {
378
+ stationSN: hub.station_sn,
379
+ });
380
+ this.stations[hub.station_sn].connect();
381
+ }
382
+ }
383
+ else {
384
+ logging_1.rootMainLogger.debug(`Station with this serial ${hub.station_sn} doesn't exists and couldn't be updated!`);
385
+ }
386
+ }
387
+ addDevice(device) {
388
+ const serial = device.getSerial();
389
+ if (serial && !Object.keys(this.devices).includes(serial)) {
390
+ this.devices[serial] = device;
391
+ this.emit("device added", device);
392
+ if (device.isLock())
393
+ this.mqttService.subscribeLock(device.getSerial());
394
+ }
395
+ else {
396
+ logging_1.rootMainLogger.debug(`Device with this serial ${device.getSerial()} exists already and couldn't be added again!`);
397
+ }
398
+ }
399
+ removeDevice(device) {
400
+ const serial = device.getSerial();
401
+ if (serial && Object.keys(this.devices).includes(serial)) {
402
+ delete this.devices[serial];
403
+ device.removeAllListeners();
404
+ this.emit("device removed", device);
405
+ }
406
+ else {
407
+ logging_1.rootMainLogger.debug(`Device with this serial ${device.getSerial()} doesn't exists and couldn't be removed!`);
408
+ }
409
+ }
410
+ async updateDevice(device) {
411
+ if (this.devicesLoaded)
412
+ await this.devicesLoaded;
413
+ if (Object.keys(this.devices).includes(device.device_sn))
414
+ this.devices[device.device_sn].update(device);
415
+ else
416
+ logging_1.rootMainLogger.debug(`Device with this serial ${device.device_sn} doesn't exists and couldn't be updated!`);
417
+ }
418
+ async getDevices() {
419
+ if (this.devicesLoaded)
420
+ await this.devicesLoaded;
421
+ const arr = [];
422
+ Object.keys(this.devices).forEach((serialNumber) => {
423
+ arr.push(this.devices[serialNumber]);
424
+ });
425
+ return arr;
426
+ }
427
+ async getDevicesFromStation(stationSN) {
428
+ if (this.devicesLoaded)
429
+ await this.devicesLoaded;
430
+ const arr = [];
431
+ Object.keys(this.devices).forEach((serialNumber) => {
432
+ if (this.devices[serialNumber].getStationSerial() === stationSN)
433
+ arr.push(this.devices[serialNumber]);
434
+ });
435
+ return arr;
436
+ }
437
+ async getDevice(deviceSN) {
438
+ if (this.devicesLoaded)
439
+ await this.devicesLoaded;
440
+ if (Object.keys(this.devices).includes(deviceSN))
441
+ return this.devices[deviceSN];
442
+ throw new error_1.DeviceNotFoundError("Device doesn't exists", { context: { device: deviceSN } });
443
+ }
444
+ async getStationDevice(stationSN, channel) {
445
+ if (this.devicesLoaded)
446
+ await this.devicesLoaded;
447
+ for (const device of Object.values(this.devices)) {
448
+ if ((device.getStationSerial() === stationSN && device.getChannel() === channel) ||
449
+ (device.getStationSerial() === stationSN && device.getSerial() === stationSN)) {
450
+ return device;
451
+ }
452
+ }
453
+ throw new error_1.DeviceNotFoundError("No device with passed channel found on station", {
454
+ context: { station: stationSN, channel: channel },
455
+ });
456
+ }
457
+ async getStations() {
458
+ if (this.stationsLoaded)
459
+ await this.stationsLoaded;
460
+ const arr = [];
461
+ Object.keys(this.stations).forEach((serialNumber) => {
462
+ arr.push(this.stations[serialNumber]);
463
+ });
464
+ return arr;
465
+ }
466
+ async getStation(stationSN) {
467
+ if (this.stationsLoaded)
468
+ await this.stationsLoaded;
469
+ if (Object.keys(this.stations).includes(stationSN))
470
+ return this.stations[stationSN];
471
+ throw new error_1.StationNotFoundError("Station doesn't exists", { context: { station: stationSN } });
472
+ }
473
+ getApi() {
474
+ return this.api;
475
+ }
476
+ async connectToStation(stationSN, p2pConnectionType = types_2.P2PConnectionType.QUICKEST) {
477
+ const station = await this.getStation(stationSN);
478
+ if (station.isP2PConnectableDevice()) {
479
+ station.setConnectionType(p2pConnectionType);
480
+ logging_1.rootMainLogger.debug(`Explicit request for p2p connection to the station`, { stationSN: station.getSerial() });
481
+ await station.connect();
482
+ }
483
+ }
484
+ async isStationConnected(stationSN) {
485
+ const station = await this.getStation(stationSN);
486
+ return station.isConnected();
487
+ }
488
+ async isStationEnergySavingDevice(stationSN) {
489
+ const station = await this.getStation(stationSN);
490
+ return station.isEnergySavingDevice();
491
+ }
492
+ handleHouses(houses) {
493
+ logging_1.rootMainLogger.debug("Got houses", { houses: houses });
494
+ //TODO: Finish implementation
495
+ this.houses = houses;
496
+ }
497
+ handleHubs(hubs) {
498
+ logging_1.rootMainLogger.debug("Got hubs", { hubs: hubs });
499
+ const stationsSNs = Object.keys(this.stations);
500
+ const newStationsSNs = Object.keys(hubs);
501
+ const promises = [];
502
+ for (const hub of Object.values(hubs)) {
503
+ if (stationsSNs.includes(hub.station_sn)) {
504
+ this.updateStation(hub);
505
+ }
506
+ else {
507
+ if (this.stationsLoaded === undefined)
508
+ this.stationsLoaded = (0, utils_1.waitForEvent)(this.loadingEmitter, "stations loaded");
509
+ let ipAddress;
510
+ if (this.config.stationIPAddresses !== undefined) {
511
+ ipAddress = this.config.stationIPAddresses[hub.station_sn];
512
+ }
513
+ const station = station_1.Station.getInstance(this.api, hub, ipAddress, 0, this.config.enableEmbeddedPKCS1Support);
514
+ promises.push(station.then((station) => {
515
+ try {
516
+ station.on("connect", (station) => this.onStationConnect(station));
517
+ station.on("connection error", (station, error) => this.onStationConnectionError(station, error));
518
+ station.on("close", (station) => this.onStationClose(station));
519
+ station.on("raw device property changed", (deviceSN, params) => this.updateDeviceProperties(deviceSN, params));
520
+ station.on("livestream start", (station, channel, metadata, videostream, audiostream) => this.onStartStationLivestream(station, channel, metadata, videostream, audiostream));
521
+ station.on("livestream stop", (station, channel) => this.onStopStationLivestream(station, channel));
522
+ station.on("livestream error", (station, channel, error) => this.onErrorStationLivestream(station, channel, error));
523
+ station.on("download start", (station, channel, metadata, videoStream, audioStream) => this.onStationStartDownload(station, channel, metadata, videoStream, audioStream));
524
+ station.on("download finish", (station, channel) => this.onStationFinishDownload(station, channel));
525
+ station.on("command result", (station, result) => this.onStationCommandResult(station, result));
526
+ station.on("guard mode", (station, guardMode) => this.onStationGuardMode(station, guardMode));
527
+ station.on("current mode", (station, currentMode) => this.onStationCurrentMode(station, currentMode));
528
+ station.on("rtsp livestream start", (station, channel) => this.onStartStationRTSPLivestream(station, channel));
529
+ station.on("rtsp livestream stop", (station, channel) => this.onStopStationRTSPLivestream(station, channel));
530
+ station.on("rtsp url", (station, channel, value) => this.onStationRtspUrl(station, channel, value));
531
+ station.on("property changed", (station, name, value, ready) => this.onStationPropertyChanged(station, name, value, ready));
532
+ station.on("raw property changed", (station, type, value) => this.onStationRawPropertyChanged(station, type, value));
533
+ station.on("alarm event", (station, alarmEvent) => this.onStationAlarmEvent(station, alarmEvent));
534
+ station.on("runtime state", (station, channel, batteryLevel, temperature) => this.onStationRuntimeState(station, channel, batteryLevel, temperature));
535
+ station.on("charging state", (station, channel, chargeType, batteryLevel) => this.onStationChargingState(station, channel, chargeType, batteryLevel));
536
+ station.on("wifi rssi", (station, channel, rssi) => this.onStationWifiRssi(station, channel, rssi));
537
+ station.on("floodlight manual switch", (station, channel, enabled) => this.onFloodlightManualSwitch(station, channel, enabled));
538
+ station.on("alarm delay event", (station, alarmDelayEvent, alarmDelay) => this.onStationAlarmDelayEvent(station, alarmDelayEvent, alarmDelay));
539
+ station.on("talkback started", (station, channel, talkbackStream) => this.onStationTalkbackStart(station, channel, talkbackStream));
540
+ station.on("talkback stopped", (station, channel) => this.onStationTalkbackStop(station, channel));
541
+ station.on("talkback error", (station, channel, error) => this.onStationTalkbackError(station, channel, error));
542
+ station.on("alarm armed event", (station) => this.onStationAlarmArmedEvent(station));
543
+ station.on("alarm arm delay event", (station, armDelay) => this.onStationArmDelayEvent(station, armDelay));
544
+ station.on("secondary command result", (station, result) => this.onStationSecondaryCommandResult(station, result));
545
+ station.on("device shake alarm", (deviceSN, event) => this.onStationDeviceShakeAlarm(deviceSN, event));
546
+ station.on("device 911 alarm", (deviceSN, event) => this.onStationDevice911Alarm(deviceSN, event));
547
+ station.on("device jammed", (deviceSN) => this.onStationDeviceJammed(deviceSN));
548
+ station.on("device low battery", (deviceSN) => this.onStationDeviceLowBattery(deviceSN));
549
+ station.on("device wrong try-protect alarm", (deviceSN) => this.onStationDeviceWrongTryProtectAlarm(deviceSN));
550
+ station.on("device pin verified", (deviceSN, successfull) => this.onStationDevicePinVerified(deviceSN, successfull));
551
+ station.on("sd info ex", (station, sdStatus, sdCapacity, sdCapacityAvailable) => this.onStationSdInfoEx(station, sdStatus, sdCapacity, sdCapacityAvailable));
552
+ station.on("image download", (station, file, image) => this.onStationImageDownload(station, file, image));
553
+ station.on("database query latest", (station, returnCode, data) => this.onStationDatabaseQueryLatest(station, returnCode, data));
554
+ station.on("database query local", (station, returnCode, data) => this.onStationDatabaseQueryLocal(station, returnCode, data));
555
+ station.on("database query by date", (station, returnCode, data) => this.onStationDatabaseQueryByDate(station, returnCode, data));
556
+ station.on("database count by date", (station, returnCode, data) => this.onStationDatabaseCountByDate(station, returnCode, data));
557
+ station.on("database delete", (station, returnCode, failedIds) => this.onStationDatabaseDelete(station, returnCode, failedIds));
558
+ station.on("sensor status", (station, channel, status) => this.onStationSensorStatus(station, channel, status));
559
+ station.on("garage door status", (station, channel, doorId, status) => this.onStationGarageDoorStatus(station, channel, doorId, status));
560
+ station.on("storage info hb3", (station, channel, storageInfo) => this.onStorageInfoHb3(station, channel, storageInfo));
561
+ this.addStation(station);
562
+ station.initialize();
563
+ }
564
+ catch (err) {
565
+ const error = (0, error_1.ensureError)(err);
566
+ logging_1.rootMainLogger.error("HandleHubs Error", { error: (0, utils_1.getError)(error), stationSN: station.getSerial() });
567
+ }
568
+ return station;
569
+ }));
570
+ }
571
+ }
572
+ Promise.all(promises).then(() => {
573
+ this.loadingEmitter.emit("stations loaded");
574
+ this.stationsLoaded = undefined;
575
+ });
576
+ if (promises.length === 0) {
577
+ this.loadingEmitter.emit("stations loaded");
578
+ this.stationsLoaded = undefined;
579
+ }
580
+ for (const stationSN of stationsSNs) {
581
+ if (!newStationsSNs.includes(stationSN)) {
582
+ this.getStation(stationSN)
583
+ .then((station) => {
584
+ this.removeStation(station);
585
+ })
586
+ .catch((err) => {
587
+ const error = (0, error_1.ensureError)(err);
588
+ logging_1.rootMainLogger.error("Error removing station", { error: (0, utils_1.getError)(error), stationSN: stationSN });
589
+ });
590
+ }
591
+ }
592
+ }
593
+ refreshP2PData(station) {
594
+ if (station.isStation() ||
595
+ (device_1.Device.isCamera(station.getDeviceType()) && !device_1.Device.isWiredDoorbell(station.getDeviceType())) ||
596
+ device_1.Device.isSmartSafe(station.getDeviceType())) {
597
+ station.getCameraInfo();
598
+ }
599
+ if (device_1.Device.isLock(station.getDeviceType())) {
600
+ station.getLockParameters();
601
+ station.getLockStatus();
602
+ }
603
+ if (station.isStation() ||
604
+ (station.hasProperty(types_1.PropertyName.StationSdStatus) &&
605
+ station.getPropertyValue(types_1.PropertyName.StationSdStatus) !== types_2.TFCardStatus.REMOVE)) {
606
+ station.getStorageInfoEx();
607
+ }
608
+ }
609
+ onStationConnect(station) {
610
+ this.emit("station connect", station);
611
+ this.refreshP2PData(station);
612
+ if (this.refreshEufySecurityP2PTimeout[station.getSerial()] !== undefined) {
613
+ clearTimeout(this.refreshEufySecurityP2PTimeout[station.getSerial()]);
614
+ delete this.refreshEufySecurityP2PTimeout[station.getSerial()];
615
+ }
616
+ this.refreshEufySecurityP2PTimeout[station.getSerial()] = setTimeout(() => {
617
+ this.refreshP2PData(station);
618
+ }, this.P2P_REFRESH_INTERVAL_MIN * 60 * 1000);
619
+ }
620
+ onStationConnectionError(station, error) {
621
+ this.emit("station connection error", station, error);
622
+ }
623
+ onStationClose(station) {
624
+ this.emit("station close", station);
625
+ for (const device_sn of this.cameraStationLivestreamTimeout.keys()) {
626
+ this.getDevice(device_sn)
627
+ .then((device) => {
628
+ if (device !== null && device.getStationSerial() === station.getSerial()) {
629
+ clearTimeout(this.cameraStationLivestreamTimeout.get(device_sn));
630
+ this.cameraStationLivestreamTimeout.delete(device_sn);
631
+ }
632
+ })
633
+ .catch((err) => {
634
+ const error = (0, error_1.ensureError)(err);
635
+ logging_1.rootMainLogger.error(`Station close Error`, { error: (0, utils_1.getError)(error), stationSN: station.getSerial() });
636
+ });
637
+ }
638
+ }
639
+ handleDevices(devices) {
640
+ logging_1.rootMainLogger.debug("Got devices", { devices: devices });
641
+ const deviceSNs = Object.keys(this.devices);
642
+ const newDeviceSNs = Object.keys(devices);
643
+ const promises = [];
644
+ const deviceConfig = this.config.deviceConfig;
645
+ for (const device of Object.values(devices)) {
646
+ if (deviceSNs.includes(device.device_sn)) {
647
+ this.updateDevice(device);
648
+ }
649
+ else {
650
+ if (this.devicesLoaded === undefined)
651
+ this.devicesLoaded = (0, utils_1.waitForEvent)(this.loadingEmitter, "devices loaded");
652
+ let new_device;
653
+ if (device_1.Device.isIndoorCamera(device.device_type)) {
654
+ new_device = device_1.IndoorCamera.getInstance(this.api, device, deviceConfig);
655
+ }
656
+ else if (device_1.Device.isSoloCameras(device.device_type)) {
657
+ new_device = device_1.SoloCamera.getInstance(this.api, device, deviceConfig);
658
+ }
659
+ else if (device_1.Device.isLockWifiVideo(device.device_type)) {
660
+ new_device = device_1.DoorbellLock.getInstance(this.api, device, deviceConfig);
661
+ }
662
+ else if (device_1.Device.isBatteryDoorbell(device.device_type)) {
663
+ new_device = device_1.BatteryDoorbellCamera.getInstance(this.api, device, deviceConfig);
664
+ }
665
+ else if (device_1.Device.isWiredDoorbell(device.device_type) || device_1.Device.isWiredDoorbellDual(device.device_type)) {
666
+ new_device = device_1.WiredDoorbellCamera.getInstance(this.api, device, deviceConfig);
667
+ }
668
+ else if (device_1.Device.isFloodLight(device.device_type)) {
669
+ new_device = device_1.FloodlightCamera.getInstance(this.api, device, deviceConfig);
670
+ }
671
+ else if (device_1.Device.isWallLightCam(device.device_type)) {
672
+ new_device = device_1.WallLightCam.getInstance(this.api, device, deviceConfig);
673
+ }
674
+ else if (device_1.Device.isGarageCamera(device.device_type)) {
675
+ new_device = device_1.GarageCamera.getInstance(this.api, device, deviceConfig);
676
+ }
677
+ else if (device_1.Device.isSmartDrop(device.device_type)) {
678
+ new_device = device_1.SmartDrop.getInstance(this.api, device, deviceConfig);
679
+ }
680
+ else if (device_1.Device.isCamera(device.device_type)) {
681
+ new_device = device_1.Camera.getInstance(this.api, device, deviceConfig);
682
+ }
683
+ else if (device_1.Device.isLock(device.device_type)) {
684
+ new_device = device_1.Lock.getInstance(this.api, device, deviceConfig);
685
+ }
686
+ else if (device_1.Device.isMotionSensor(device.device_type)) {
687
+ new_device = device_1.MotionSensor.getInstance(this.api, device, deviceConfig);
688
+ }
689
+ else if (device_1.Device.isEntrySensor(device.device_type)) {
690
+ new_device = device_1.EntrySensor.getInstance(this.api, device, deviceConfig);
691
+ }
692
+ else if (device_1.Device.isKeyPad(device.device_type)) {
693
+ new_device = device_1.Keypad.getInstance(this.api, device, deviceConfig);
694
+ }
695
+ else if (device_1.Device.isSmartSafe(device.device_type)) {
696
+ new_device = device_1.SmartSafe.getInstance(this.api, device, deviceConfig);
697
+ }
698
+ else if (device_1.Device.isSmartTrack(device.device_type)) {
699
+ new_device = device_1.Tracker.getInstance(this.api, device, deviceConfig);
700
+ }
701
+ else if (device_1.Device.isLockKeypad(device.device_type)) {
702
+ new_device = device_1.LockKeypad.getInstance(this.api, device, deviceConfig);
703
+ }
704
+ else {
705
+ new_device = device_1.UnknownDevice.getInstance(this.api, device, deviceConfig);
706
+ }
707
+ promises.push(new_device.then((device) => {
708
+ try {
709
+ device.on("property changed", (device, name, value, ready) => this.onDevicePropertyChanged(device, name, value, ready));
710
+ device.on("raw property changed", (device, type, value) => this.onDeviceRawPropertyChanged(device, type, value));
711
+ device.on("crying detected", (device, state) => this.onDeviceCryingDetected(device, state));
712
+ device.on("sound detected", (device, state) => this.onDeviceSoundDetected(device, state));
713
+ device.on("pet detected", (device, state) => this.onDevicePetDetected(device, state));
714
+ device.on("vehicle detected", (device, state) => this.onDeviceVehicleDetected(device, state));
715
+ device.on("motion detected", (device, state) => this.onDeviceMotionDetected(device, state));
716
+ device.on("person detected", (device, state, person) => this.onDevicePersonDetected(device, state, person));
717
+ device.on("rings", (device, state) => this.onDeviceRings(device, state));
718
+ device.on("locked", (device, state) => this.onDeviceLocked(device, state));
719
+ device.on("open", (device, state) => this.onDeviceOpen(device, state));
720
+ device.on("ready", (device) => this.onDeviceReady(device));
721
+ device.on("package delivered", (device, state) => this.onDevicePackageDelivered(device, state));
722
+ device.on("package stranded", (device, state) => this.onDevicePackageStranded(device, state));
723
+ device.on("package taken", (device, state) => this.onDevicePackageTaken(device, state));
724
+ device.on("someone loitering", (device, state) => this.onDeviceSomeoneLoitering(device, state));
725
+ device.on("radar motion detected", (device, state) => this.onDeviceRadarMotionDetected(device, state));
726
+ device.on("911 alarm", (device, state, detail) => this.onDevice911Alarm(device, state, detail));
727
+ device.on("shake alarm", (device, state, detail) => this.onDeviceShakeAlarm(device, state, detail));
728
+ device.on("wrong try-protect alarm", (device, state) => this.onDeviceWrongTryProtectAlarm(device, state));
729
+ device.on("long time not close", (device, state) => this.onDeviceLongTimeNotClose(device, state));
730
+ device.on("low battery", (device, state) => this.onDeviceLowBattery(device, state));
731
+ device.on("jammed", (device, state) => this.onDeviceJammed(device, state));
732
+ device.on("stranger person detected", (device, state) => this.onDeviceStrangerPersonDetected(device, state));
733
+ device.on("dog detected", (device, state) => this.onDeviceDogDetected(device, state));
734
+ device.on("dog lick detected", (device, state) => this.onDeviceDogLickDetected(device, state));
735
+ device.on("dog poop detected", (device, state) => this.onDeviceDogPoopDetected(device, state));
736
+ device.on("tampering", (device, state) => this.onDeviceTampering(device, state));
737
+ device.on("low temperature", (device, state) => this.onDeviceLowTemperature(device, state));
738
+ device.on("high temperature", (device, state) => this.onDeviceHighTemperature(device, state));
739
+ device.on("pin incorrect", (device, state) => this.onDevicePinIncorrect(device, state));
740
+ device.on("lid stuck", (device, state) => this.onDeviceLidStuck(device, state));
741
+ device.on("battery fully charged", (device, state) => this.onDeviceBatteryFullyCharged(device, state));
742
+ this.addDevice(device);
743
+ device.initialize();
744
+ }
745
+ catch (err) {
746
+ const error = (0, error_1.ensureError)(err);
747
+ logging_1.rootMainLogger.error("HandleDevices Error", { error: (0, utils_1.getError)(error), deviceSN: device.getSerial() });
748
+ }
749
+ return device;
750
+ }));
751
+ }
752
+ }
753
+ Promise.all(promises).then((devices) => {
754
+ devices.forEach((device) => {
755
+ this.getStation(device.getStationSerial())
756
+ .then((station) => {
757
+ if (!station.isConnected() && station.isP2PConnectableDevice()) {
758
+ station.setConnectionType(this.config.p2pConnectionSetup);
759
+ logging_1.rootMainLogger.debug(`Initiate first station connection to get data over p2p`, {
760
+ stationSN: station.getSerial(),
761
+ });
762
+ station.connect();
763
+ }
764
+ })
765
+ .catch((err) => {
766
+ const error = (0, error_1.ensureError)(err);
767
+ logging_1.rootMainLogger.error("Error trying to connect to station afte device loaded", {
768
+ error: (0, utils_1.getError)(error),
769
+ deviceSN: device.getSerial(),
770
+ });
771
+ });
772
+ });
773
+ this.loadingEmitter.emit("devices loaded");
774
+ this.devicesLoaded = undefined;
775
+ });
776
+ if (promises.length === 0) {
777
+ this.loadingEmitter.emit("devices loaded");
778
+ this.devicesLoaded = undefined;
779
+ }
780
+ for (const deviceSN of deviceSNs) {
781
+ if (!newDeviceSNs.includes(deviceSN)) {
782
+ this.getDevice(deviceSN)
783
+ .then((device) => {
784
+ this.removeDevice(device);
785
+ })
786
+ .catch((err) => {
787
+ const error = (0, error_1.ensureError)(err);
788
+ logging_1.rootMainLogger.error("Error removing device", { error: (0, utils_1.getError)(error), deviceSN: deviceSN });
789
+ });
790
+ }
791
+ }
792
+ }
793
+ async refreshCloudData() {
794
+ if (this.config.acceptInvitations) {
795
+ await this.processInvitations().catch((err) => {
796
+ const error = (0, error_1.ensureError)(err);
797
+ logging_1.rootMainLogger.error("Error in processing invitations", { error: (0, utils_1.getError)(error) });
798
+ });
799
+ }
800
+ await this.api.refreshAllData().catch((err) => {
801
+ const error = (0, error_1.ensureError)(err);
802
+ logging_1.rootMainLogger.error("Error during API data refreshing", { error: (0, utils_1.getError)(error) });
803
+ });
804
+ if (this.refreshEufySecurityCloudTimeout !== undefined)
805
+ clearTimeout(this.refreshEufySecurityCloudTimeout);
806
+ if (this.config.pollingIntervalMinutes > 0)
807
+ this.refreshEufySecurityCloudTimeout = setTimeout(() => {
808
+ this.refreshCloudData();
809
+ }, this.config.pollingIntervalMinutes * 60 * 1000);
810
+ else
811
+ logging_1.rootMainLogger.info(`Automatic retrieval of data from the cloud has been deactivated (config pollingIntervalMinutes: ${this.config.pollingIntervalMinutes})`);
812
+ }
813
+ close() {
814
+ for (const device_sn of this.cameraStationLivestreamTimeout.keys()) {
815
+ this.stopStationLivestream(device_sn);
816
+ }
817
+ if (this.refreshEufySecurityCloudTimeout !== undefined)
818
+ clearTimeout(this.refreshEufySecurityCloudTimeout);
819
+ Object.keys(this.refreshEufySecurityP2PTimeout).forEach((station_sn) => {
820
+ clearTimeout(this.refreshEufySecurityP2PTimeout[station_sn]);
821
+ delete this.refreshEufySecurityP2PTimeout[station_sn];
822
+ });
823
+ Object.keys(this.deviceSnoozeTimeout).forEach((device_sn) => {
824
+ clearTimeout(this.deviceSnoozeTimeout[device_sn]);
825
+ delete this.deviceSnoozeTimeout[device_sn];
826
+ });
827
+ this.savePushPersistentIds();
828
+ this.pushService.close();
829
+ this.mqttService.close();
830
+ Object.values(this.stations).forEach((station) => {
831
+ station.close();
832
+ });
833
+ Object.values(this.devices).forEach((device) => {
834
+ device.destroy();
835
+ });
836
+ if (this.connected)
837
+ this.emit("close");
838
+ this.connected = false;
839
+ }
840
+ setCameraMaxLivestreamDuration(seconds) {
841
+ this.cameraMaxLivestreamSeconds = seconds;
842
+ }
843
+ getCameraMaxLivestreamDuration() {
844
+ return this.cameraMaxLivestreamSeconds;
845
+ }
846
+ async registerPushNotifications(credentials, persistentIds) {
847
+ if (credentials)
848
+ this.pushService.setCredentials(credentials);
849
+ if (persistentIds)
850
+ this.pushService.setPersistentIds(persistentIds);
851
+ this.pushService.open();
852
+ }
853
+ async connect(options) {
854
+ await this.api
855
+ .login(options)
856
+ .then(async () => {
857
+ if (options?.verifyCode) {
858
+ let trusted = false;
859
+ const trusted_devices = await this.api.listTrustDevice();
860
+ trusted_devices.forEach((trusted_device) => {
861
+ if (trusted_device.is_current_device === 1) {
862
+ trusted = true;
863
+ }
864
+ });
865
+ if (!trusted)
866
+ return await this.api.addTrustDevice(options?.verifyCode);
867
+ }
868
+ })
869
+ .catch((err) => {
870
+ const error = (0, error_1.ensureError)(err);
871
+ logging_1.rootMainLogger.error("Connect Error", { error: (0, utils_1.getError)(error), options: options });
872
+ });
873
+ }
874
+ getPushPersistentIds() {
875
+ return this.pushService.getPersistentIds();
876
+ }
877
+ updateDeviceProperties(deviceSN, values) {
878
+ this.getDevice(deviceSN)
879
+ .then((device) => {
880
+ device.updateRawProperties(values);
881
+ })
882
+ .catch((err) => {
883
+ const error = (0, error_1.ensureError)(err);
884
+ logging_1.rootMainLogger.error("Update device properties error", {
885
+ error: (0, utils_1.getError)(error),
886
+ deviceSN: deviceSN,
887
+ values: values,
888
+ });
889
+ });
890
+ }
891
+ async onAPIClose() {
892
+ if (this.refreshEufySecurityCloudTimeout !== undefined)
893
+ clearTimeout(this.refreshEufySecurityCloudTimeout);
894
+ this.connected = false;
895
+ this.emit("close");
896
+ if (this.retries < 3) {
897
+ this.retries++;
898
+ await this.connect();
899
+ }
900
+ else {
901
+ logging_1.rootMainLogger.error(`Tried to re-authenticate to Eufy cloud, but failed in the process. Manual intervention is required!`);
902
+ }
903
+ }
904
+ async onAPIConnect() {
905
+ this.connected = true;
906
+ this.retries = 0;
907
+ this.saveCloudToken();
908
+ await this.refreshCloudData();
909
+ this.emit("connect");
910
+ this.registerPushNotifications(this.persistentData.push_credentials, this.persistentData.push_persistentIds);
911
+ const loginData = this.api.getPersistentData();
912
+ if (loginData) {
913
+ this.mqttService.connect(loginData.user_id, this.persistentData.openudid, this.api.getAPIBase(), loginData.email);
914
+ }
915
+ else {
916
+ logging_1.rootMainLogger.warn("No login data recevied to initialize MQTT connection...");
917
+ }
918
+ }
919
+ onAPIConnectionError(error) {
920
+ this.emit("connection error", error);
921
+ }
922
+ async startStationLivestream(deviceSN) {
923
+ const device = await this.getDevice(deviceSN);
924
+ const station = await this.getStation(device.getStationSerial());
925
+ if (!device.hasCommand(types_1.CommandName.DeviceStartLivestream))
926
+ throw new error_1.NotSupportedError("This functionality is not implemented or supported by this device", {
927
+ context: { device: deviceSN, commandName: types_1.CommandName.DeviceStartLivestream },
928
+ });
929
+ const camera = device;
930
+ if (!station.isLiveStreaming(camera)) {
931
+ station.startLivestream(camera);
932
+ if (this.cameraMaxLivestreamSeconds > 0) {
933
+ this.cameraStationLivestreamTimeout.set(deviceSN, setTimeout(() => {
934
+ logging_1.rootMainLogger.info(`Stopping the station stream for the device ${deviceSN}, because we have reached the configured maximum stream timeout (${this.cameraMaxLivestreamSeconds} seconds)`);
935
+ this.stopStationLivestream(deviceSN);
936
+ }, this.cameraMaxLivestreamSeconds * 1000));
937
+ }
938
+ }
939
+ else {
940
+ logging_1.rootMainLogger.warn(`The station stream for the device ${deviceSN} cannot be started, because it is already streaming!`);
941
+ }
942
+ }
943
+ async stopStationLivestream(deviceSN) {
944
+ const device = await this.getDevice(deviceSN);
945
+ const station = await this.getStation(device.getStationSerial());
946
+ if (!device.hasCommand(types_1.CommandName.DeviceStopLivestream))
947
+ throw new error_1.NotSupportedError("This functionality is not implemented or supported by this device", {
948
+ context: { device: deviceSN, commandName: types_1.CommandName.DeviceStopLivestream },
949
+ });
950
+ if (station.isConnected() && station.isLiveStreaming(device)) {
951
+ station.stopLivestream(device);
952
+ }
953
+ else {
954
+ logging_1.rootMainLogger.warn(`The station stream for the device ${deviceSN} cannot be stopped, because it isn't streaming!`);
955
+ }
956
+ const timeout = this.cameraStationLivestreamTimeout.get(deviceSN);
957
+ if (timeout) {
958
+ clearTimeout(timeout);
959
+ this.cameraStationLivestreamTimeout.delete(deviceSN);
960
+ }
961
+ }
962
+ writePersistentData() {
963
+ this.persistentData.login_hash = (0, utils_1.md5)(`${this.config.username}:${this.config.password}`);
964
+ if (this.api.isConnected()) {
965
+ this.persistentData.httpApi = this.api?.getPersistentData();
966
+ this.persistentData.country = this.api?.getCountry();
967
+ }
968
+ try {
969
+ if (this.config.persistentData) {
970
+ this.emit("persistent data", JSON.stringify(this.persistentData));
971
+ }
972
+ else {
973
+ (0, fs_1.writeFileSync)(this.persistentFile, JSON.stringify(this.persistentData));
974
+ }
975
+ }
976
+ catch (err) {
977
+ const error = (0, error_1.ensureError)(err);
978
+ logging_1.rootMainLogger.error("WritePersistentData Error", { error: (0, utils_1.getError)(error) });
979
+ }
980
+ }
981
+ saveCloudToken() {
982
+ const token = this.api.getToken();
983
+ const token_expiration = this.api.getTokenExpiration();
984
+ if (!!token && !!token_expiration) {
985
+ logging_1.rootMainLogger.debug("Save cloud token and token expiration", {
986
+ token: token,
987
+ tokenExpiration: token_expiration,
988
+ });
989
+ this.persistentData.cloud_token = token;
990
+ this.persistentData.cloud_token_expiration = token_expiration.getTime();
991
+ this.writePersistentData();
992
+ }
993
+ }
994
+ savePushCredentials(credentials) {
995
+ this.persistentData.push_credentials = credentials;
996
+ this.writePersistentData();
997
+ }
998
+ savePushPersistentIds() {
999
+ this.persistentData.push_persistentIds = this.getPushPersistentIds();
1000
+ this.writePersistentData();
1001
+ }
1002
+ getVersion() {
1003
+ return _1.libVersion;
1004
+ }
1005
+ isPushConnected() {
1006
+ return this.pushService.isConnected();
1007
+ }
1008
+ isMQTTConnected() {
1009
+ return this.mqttService.isConnected();
1010
+ }
1011
+ isConnected() {
1012
+ return this.connected;
1013
+ }
1014
+ async processInvitations() {
1015
+ let refreshCloud = false;
1016
+ const invites = await this.api.getInvites().catch((err) => {
1017
+ const error = (0, error_1.ensureError)(err);
1018
+ logging_1.rootMainLogger.error("Error getting invites from cloud", { error: (0, utils_1.getError)(error) });
1019
+ return error;
1020
+ });
1021
+ if (Object.keys(invites).length > 0) {
1022
+ const confirmInvites = [];
1023
+ for (const invite of Object.values(invites)) {
1024
+ const devices = [];
1025
+ invite.devices.forEach((device) => {
1026
+ devices.push(device.device_sn);
1027
+ });
1028
+ if (devices.length > 0) {
1029
+ confirmInvites.push({
1030
+ invite_id: invite.invite_id,
1031
+ station_sn: invite.station_sn,
1032
+ device_sns: devices,
1033
+ });
1034
+ }
1035
+ }
1036
+ if (confirmInvites.length > 0) {
1037
+ const result = await this.api.confirmInvites(confirmInvites).catch((err) => {
1038
+ const error = (0, error_1.ensureError)(err);
1039
+ logging_1.rootMainLogger.error("Error in confirmation of invitations", {
1040
+ error: (0, utils_1.getError)(error),
1041
+ confirmInvites: confirmInvites,
1042
+ });
1043
+ return error;
1044
+ });
1045
+ if (result) {
1046
+ logging_1.rootMainLogger.info(`Accepted received invitations`, confirmInvites);
1047
+ refreshCloud = true;
1048
+ }
1049
+ }
1050
+ }
1051
+ const houseInvites = await this.api.getHouseInviteList().catch((err) => {
1052
+ const error = (0, error_1.ensureError)(err);
1053
+ logging_1.rootMainLogger.error("Error getting house invites from cloud", { error: (0, utils_1.getError)(error) });
1054
+ return error;
1055
+ });
1056
+ if (Object.keys(houseInvites).length > 0) {
1057
+ for (const invite of Object.values(houseInvites)) {
1058
+ const result = await this.api.confirmHouseInvite(invite.house_id, invite.id).catch((err) => {
1059
+ const error = (0, error_1.ensureError)(err);
1060
+ logging_1.rootMainLogger.error("Error in confirmation of house invitations", { error: (0, utils_1.getError)(error) });
1061
+ return error;
1062
+ });
1063
+ if (result) {
1064
+ logging_1.rootMainLogger.info(`Accepted received house invitation from ${invite.action_user_email}`, {
1065
+ invite: invite,
1066
+ });
1067
+ refreshCloud = true;
1068
+ }
1069
+ }
1070
+ }
1071
+ if (refreshCloud)
1072
+ this.refreshCloudData();
1073
+ }
1074
+ onPushMessage(message) {
1075
+ this.emit("push message", message);
1076
+ try {
1077
+ logging_1.rootMainLogger.debug("Received push message", { message: message });
1078
+ try {
1079
+ if ((message.type === types_3.ServerPushEvent.INVITE_DEVICE || message.type === types_3.ServerPushEvent.HOUSE_INVITE) &&
1080
+ this.config.acceptInvitations) {
1081
+ if (this.isConnected())
1082
+ this.processInvitations();
1083
+ }
1084
+ }
1085
+ catch (err) {
1086
+ const error = (0, error_1.ensureError)(err);
1087
+ logging_1.rootMainLogger.error(`Error processing server push notification for device invitation`, {
1088
+ error: (0, utils_1.getError)(error),
1089
+ message: message,
1090
+ });
1091
+ }
1092
+ try {
1093
+ if (message.type === types_3.ServerPushEvent.REMOVE_DEVICE ||
1094
+ message.type === types_3.ServerPushEvent.REMOVE_HOMEBASE ||
1095
+ message.type === types_3.ServerPushEvent.HOUSE_REMOVE) {
1096
+ if (this.isConnected())
1097
+ this.refreshCloudData();
1098
+ }
1099
+ }
1100
+ catch (err) {
1101
+ const error = (0, error_1.ensureError)(err);
1102
+ logging_1.rootMainLogger.error(`Error processing server push notification for device/station/house removal`, {
1103
+ error: (0, utils_1.getError)(error),
1104
+ message: message,
1105
+ });
1106
+ }
1107
+ this.getStations()
1108
+ .then((stations) => {
1109
+ stations.forEach((station) => {
1110
+ try {
1111
+ station.processPushNotification(message);
1112
+ }
1113
+ catch (err) {
1114
+ const error = (0, error_1.ensureError)(err);
1115
+ logging_1.rootMainLogger.error(`Error processing push notification for station`, {
1116
+ error: (0, utils_1.getError)(error),
1117
+ stationSN: station.getSerial(),
1118
+ message: message,
1119
+ });
1120
+ }
1121
+ });
1122
+ })
1123
+ .catch((err) => {
1124
+ const error = (0, error_1.ensureError)(err);
1125
+ logging_1.rootMainLogger.error("Process push notification for stations", { error: (0, utils_1.getError)(error), message: message });
1126
+ });
1127
+ this.getDevices()
1128
+ .then((devices) => {
1129
+ devices.forEach((device) => {
1130
+ this.getStation(device.getStationSerial())
1131
+ .then((station) => {
1132
+ try {
1133
+ device.processPushNotification(station, message, this.config.eventDurationSeconds);
1134
+ }
1135
+ catch (err) {
1136
+ const error = (0, error_1.ensureError)(err);
1137
+ logging_1.rootMainLogger.error(`Error processing push notification for device`, {
1138
+ error: (0, utils_1.getError)(error),
1139
+ deviceSN: device.getSerial(),
1140
+ message: message,
1141
+ });
1142
+ }
1143
+ })
1144
+ .catch((err) => {
1145
+ const error = (0, error_1.ensureError)(err);
1146
+ logging_1.rootMainLogger.error("Process push notification for devices loading station", {
1147
+ error: (0, utils_1.getError)(error),
1148
+ message: message,
1149
+ });
1150
+ });
1151
+ });
1152
+ })
1153
+ .catch((err) => {
1154
+ const error = (0, error_1.ensureError)(err);
1155
+ logging_1.rootMainLogger.error("Process push notification for devices", { error: (0, utils_1.getError)(error), message: message });
1156
+ });
1157
+ }
1158
+ catch (err) {
1159
+ const error = (0, error_1.ensureError)(err);
1160
+ logging_1.rootMainLogger.error("OnPushMessage Generic Error", { error: (0, utils_1.getError)(error), message: message });
1161
+ }
1162
+ }
1163
+ async startStationDownload(deviceSN, path, cipherID) {
1164
+ const device = await this.getDevice(deviceSN);
1165
+ const station = await this.getStation(device.getStationSerial());
1166
+ if (!device.hasCommand(types_1.CommandName.DeviceStartDownload))
1167
+ throw new error_1.NotSupportedError("This functionality is not implemented or supported by this device", {
1168
+ context: { device: deviceSN, commandName: types_1.CommandName.DeviceStartDownload, path: path, cipherID: cipherID },
1169
+ });
1170
+ if (!station.isDownloading(device)) {
1171
+ await station.startDownload(device, path, cipherID);
1172
+ }
1173
+ else {
1174
+ logging_1.rootMainLogger.warn(`The station is already downloading a video for the device ${deviceSN}!`);
1175
+ }
1176
+ }
1177
+ async cancelStationDownload(deviceSN) {
1178
+ const device = await this.getDevice(deviceSN);
1179
+ const station = await this.getStation(device.getStationSerial());
1180
+ if (!device.hasCommand(types_1.CommandName.DeviceCancelDownload))
1181
+ throw new error_1.NotSupportedError("This functionality is not implemented or supported by this device", {
1182
+ context: { device: deviceSN, commandName: types_1.CommandName.DeviceCancelDownload },
1183
+ });
1184
+ if (station.isConnected() && station.isDownloading(device)) {
1185
+ station.cancelDownload(device);
1186
+ }
1187
+ else {
1188
+ logging_1.rootMainLogger.warn(`The station isn't downloading a video for the device ${deviceSN}!`);
1189
+ }
1190
+ }
1191
+ getConfig() {
1192
+ return this.config;
1193
+ }
1194
+ async setDeviceProperty(deviceSN, name, value) {
1195
+ const device = await this.getDevice(deviceSN);
1196
+ const station = await this.getStation(device.getStationSerial());
1197
+ const metadata = device.getPropertyMetadata(name);
1198
+ value = (0, utils_1.parseValue)(metadata, value);
1199
+ switch (name) {
1200
+ case types_1.PropertyName.DeviceEnabled:
1201
+ station.enableDevice(device, value);
1202
+ break;
1203
+ case types_1.PropertyName.DeviceStatusLed:
1204
+ station.setStatusLed(device, value);
1205
+ break;
1206
+ case types_1.PropertyName.DeviceAutoNightvision:
1207
+ station.setAutoNightVision(device, value);
1208
+ break;
1209
+ case types_1.PropertyName.DeviceMotionDetection:
1210
+ station.setMotionDetection(device, value);
1211
+ break;
1212
+ case types_1.PropertyName.DeviceSoundDetection:
1213
+ station.setSoundDetection(device, value);
1214
+ break;
1215
+ case types_1.PropertyName.DevicePetDetection:
1216
+ station.setPetDetection(device, value);
1217
+ break;
1218
+ case types_1.PropertyName.DeviceRTSPStream:
1219
+ station.setRTSPStream(device, value);
1220
+ break;
1221
+ case types_1.PropertyName.DeviceAntitheftDetection:
1222
+ station.setAntiTheftDetection(device, value);
1223
+ break;
1224
+ case types_1.PropertyName.DeviceLocked:
1225
+ station.lockDevice(device, value);
1226
+ break;
1227
+ case types_1.PropertyName.DeviceWatermark:
1228
+ station.setWatermark(device, value);
1229
+ break;
1230
+ case types_1.PropertyName.DeviceLight:
1231
+ station.switchLight(device, value);
1232
+ break;
1233
+ case types_1.PropertyName.DeviceLightSettingsEnable:
1234
+ station.setFloodlightLightSettingsEnable(device, value);
1235
+ break;
1236
+ case types_1.PropertyName.DeviceLightSettingsBrightnessManual:
1237
+ station.setFloodlightLightSettingsBrightnessManual(device, value);
1238
+ break;
1239
+ case types_1.PropertyName.DeviceLightSettingsBrightnessMotion:
1240
+ station.setFloodlightLightSettingsBrightnessMotion(device, value);
1241
+ break;
1242
+ case types_1.PropertyName.DeviceLightSettingsBrightnessSchedule:
1243
+ station.setFloodlightLightSettingsBrightnessSchedule(device, value);
1244
+ break;
1245
+ case types_1.PropertyName.DeviceLightSettingsMotionTriggered:
1246
+ station.setFloodlightLightSettingsMotionTriggered(device, value);
1247
+ break;
1248
+ case types_1.PropertyName.DeviceLightSettingsMotionTriggeredDistance:
1249
+ station.setFloodlightLightSettingsMotionTriggeredDistance(device, value);
1250
+ break;
1251
+ case types_1.PropertyName.DeviceLightSettingsMotionTriggeredTimer:
1252
+ station.setFloodlightLightSettingsMotionTriggeredTimer(device, value);
1253
+ break;
1254
+ case types_1.PropertyName.DeviceMicrophone:
1255
+ station.setMicMute(device, value);
1256
+ break;
1257
+ case types_1.PropertyName.DeviceSpeaker:
1258
+ station.enableSpeaker(device, value);
1259
+ break;
1260
+ case types_1.PropertyName.DeviceSpeakerVolume:
1261
+ station.setSpeakerVolume(device, value);
1262
+ break;
1263
+ case types_1.PropertyName.DeviceAudioRecording:
1264
+ station.setAudioRecording(device, value);
1265
+ break;
1266
+ case types_1.PropertyName.DevicePowerSource:
1267
+ station.setPowerSource(device, value);
1268
+ break;
1269
+ case types_1.PropertyName.DevicePowerWorkingMode:
1270
+ station.setPowerWorkingMode(device, value);
1271
+ break;
1272
+ case types_1.PropertyName.DeviceRecordingEndClipMotionStops:
1273
+ station.setRecordingEndClipMotionStops(device, value);
1274
+ break;
1275
+ case types_1.PropertyName.DeviceRecordingClipLength:
1276
+ station.setRecordingClipLength(device, value);
1277
+ break;
1278
+ case types_1.PropertyName.DeviceRecordingRetriggerInterval:
1279
+ station.setRecordingRetriggerInterval(device, value);
1280
+ break;
1281
+ case types_1.PropertyName.DeviceVideoStreamingQuality:
1282
+ station.setVideoStreamingQuality(device, value);
1283
+ break;
1284
+ case types_1.PropertyName.DeviceVideoRecordingQuality:
1285
+ station.setVideoRecordingQuality(device, value);
1286
+ break;
1287
+ case types_1.PropertyName.DeviceMotionDetectionSensitivity:
1288
+ station.setMotionDetectionSensitivity(device, value);
1289
+ break;
1290
+ case types_1.PropertyName.DeviceMotionTracking:
1291
+ station.setMotionTracking(device, value);
1292
+ break;
1293
+ case types_1.PropertyName.DeviceMotionDetectionType:
1294
+ station.setMotionDetectionType(device, value);
1295
+ break;
1296
+ case types_1.PropertyName.DeviceMotionZone:
1297
+ station.setMotionZone(device, value);
1298
+ break;
1299
+ case types_1.PropertyName.DeviceVideoWDR:
1300
+ station.setWDR(device, value);
1301
+ break;
1302
+ case types_1.PropertyName.DeviceRingtoneVolume:
1303
+ station.setRingtoneVolume(device, value);
1304
+ break;
1305
+ case types_1.PropertyName.DeviceChimeIndoor:
1306
+ station.enableIndoorChime(device, value);
1307
+ break;
1308
+ case types_1.PropertyName.DeviceChimeHomebase:
1309
+ station.enableHomebaseChime(device, value);
1310
+ break;
1311
+ case types_1.PropertyName.DeviceChimeHomebaseRingtoneVolume:
1312
+ station.setHomebaseChimeRingtoneVolume(device, value);
1313
+ break;
1314
+ case types_1.PropertyName.DeviceChimeHomebaseRingtoneType:
1315
+ station.setHomebaseChimeRingtoneType(device, value);
1316
+ break;
1317
+ case types_1.PropertyName.DeviceNotificationType:
1318
+ station.setNotificationType(device, value);
1319
+ break;
1320
+ case types_1.PropertyName.DeviceNotificationPerson:
1321
+ if (device.isIndoorPanAndTiltCameraS350()) {
1322
+ station.setNotificationIndoor(device, types_1.IndoorS350NotificationTypes.HUMAN, value);
1323
+ }
1324
+ else if (device.isFloodLightT8425() || device.isCameraC35()) {
1325
+ station.setNotificationFloodlightT8425(device, types_1.FloodlightT8425NotificationTypes.HUMAN, value);
1326
+ }
1327
+ else {
1328
+ station.setNotificationPerson(device, value);
1329
+ }
1330
+ break;
1331
+ case types_1.PropertyName.DeviceNotificationPet:
1332
+ if (device.isIndoorPanAndTiltCameraS350()) {
1333
+ station.setNotificationIndoor(device, types_1.IndoorS350NotificationTypes.PET, value);
1334
+ }
1335
+ else if (device.isFloodLightT8425() || device.isCameraC35()) {
1336
+ station.setNotificationFloodlightT8425(device, types_1.FloodlightT8425NotificationTypes.PET, value);
1337
+ }
1338
+ else {
1339
+ station.setNotificationPet(device, value);
1340
+ }
1341
+ break;
1342
+ case types_1.PropertyName.DeviceNotificationAllOtherMotion:
1343
+ if (device.isIndoorPanAndTiltCameraS350()) {
1344
+ station.setNotificationIndoor(device, types_1.IndoorS350NotificationTypes.ALL_OTHER_MOTION, value);
1345
+ }
1346
+ else if (device.isFloodLightT8425() || device.isCameraC35()) {
1347
+ station.setNotificationFloodlightT8425(device, types_1.FloodlightT8425NotificationTypes.ALL_OTHER_MOTION, value);
1348
+ }
1349
+ else {
1350
+ station.setNotificationAllOtherMotion(device, value);
1351
+ }
1352
+ break;
1353
+ case types_1.PropertyName.DeviceNotificationAllSound:
1354
+ if (device.isIndoorPanAndTiltCameraS350()) {
1355
+ station.setNotificationIndoor(device, types_1.IndoorS350NotificationTypes.ALL_SOUND, value);
1356
+ }
1357
+ else {
1358
+ station.setNotificationAllSound(device, value);
1359
+ }
1360
+ break;
1361
+ case types_1.PropertyName.DeviceNotificationCrying:
1362
+ if (device.isIndoorPanAndTiltCameraS350()) {
1363
+ station.setNotificationIndoor(device, types_1.IndoorS350NotificationTypes.CRYING, value);
1364
+ }
1365
+ else {
1366
+ station.setNotificationCrying(device, value);
1367
+ }
1368
+ break;
1369
+ case types_1.PropertyName.DeviceNotificationVehicle:
1370
+ if (device.isFloodLightT8425() || device.isCameraC35()) {
1371
+ station.setNotificationFloodlightT8425(device, types_1.FloodlightT8425NotificationTypes.VEHICLE, value);
1372
+ }
1373
+ else {
1374
+ throw new error_2.InvalidPropertyError("Station has no writable property", {
1375
+ context: { station: station.getSerial(), propertyName: name, propertyValue: value },
1376
+ });
1377
+ }
1378
+ break;
1379
+ case types_1.PropertyName.DeviceNotificationMotion:
1380
+ station.setNotificationMotion(device, value);
1381
+ break;
1382
+ case types_1.PropertyName.DeviceNotificationRing:
1383
+ station.setNotificationRing(device, value);
1384
+ break;
1385
+ case types_1.PropertyName.DeviceChirpVolume:
1386
+ station.setChirpVolume(device, value);
1387
+ break;
1388
+ case types_1.PropertyName.DeviceChirpTone:
1389
+ station.setChirpTone(device, value);
1390
+ break;
1391
+ case types_1.PropertyName.DeviceVideoHDR:
1392
+ station.setHDR(device, value);
1393
+ break;
1394
+ case types_1.PropertyName.DeviceVideoDistortionCorrection:
1395
+ station.setDistortionCorrection(device, value);
1396
+ break;
1397
+ case types_1.PropertyName.DeviceVideoRingRecord:
1398
+ station.setRingRecord(device, value);
1399
+ break;
1400
+ case types_1.PropertyName.DeviceRotationSpeed:
1401
+ station.setPanAndTiltRotationSpeed(device, value);
1402
+ break;
1403
+ case types_1.PropertyName.DeviceNightvision:
1404
+ station.setNightVision(device, value);
1405
+ break;
1406
+ case types_1.PropertyName.DeviceMotionDetectionRange:
1407
+ station.setMotionDetectionRange(device, value);
1408
+ break;
1409
+ case types_1.PropertyName.DeviceMotionDetectionRangeStandardSensitivity:
1410
+ station.setMotionDetectionRangeStandardSensitivity(device, value);
1411
+ break;
1412
+ case types_1.PropertyName.DeviceMotionDetectionRangeAdvancedLeftSensitivity:
1413
+ station.setMotionDetectionRangeAdvancedLeftSensitivity(device, value);
1414
+ break;
1415
+ case types_1.PropertyName.DeviceMotionDetectionRangeAdvancedMiddleSensitivity:
1416
+ station.setMotionDetectionRangeAdvancedMiddleSensitivity(device, value);
1417
+ break;
1418
+ case types_1.PropertyName.DeviceMotionDetectionRangeAdvancedRightSensitivity:
1419
+ station.setMotionDetectionRangeAdvancedRightSensitivity(device, value);
1420
+ break;
1421
+ case types_1.PropertyName.DeviceMotionDetectionTestMode:
1422
+ station.setMotionDetectionTestMode(device, value);
1423
+ break;
1424
+ case types_1.PropertyName.DeviceMotionTrackingSensitivity:
1425
+ station.setMotionTrackingSensitivity(device, value);
1426
+ break;
1427
+ case types_1.PropertyName.DeviceMotionAutoCruise:
1428
+ station.setMotionAutoCruise(device, value);
1429
+ break;
1430
+ case types_1.PropertyName.DeviceMotionOutOfViewDetection:
1431
+ station.setMotionOutOfViewDetection(device, value);
1432
+ break;
1433
+ case types_1.PropertyName.DeviceLightSettingsColorTemperatureManual:
1434
+ station.setLightSettingsColorTemperatureManual(device, value);
1435
+ break;
1436
+ case types_1.PropertyName.DeviceLightSettingsColorTemperatureMotion:
1437
+ station.setLightSettingsColorTemperatureMotion(device, value);
1438
+ break;
1439
+ case types_1.PropertyName.DeviceLightSettingsColorTemperatureSchedule:
1440
+ station.setLightSettingsColorTemperatureSchedule(device, value);
1441
+ break;
1442
+ case types_1.PropertyName.DeviceLightSettingsMotionActivationMode:
1443
+ station.setLightSettingsMotionActivationMode(device, value);
1444
+ break;
1445
+ case types_1.PropertyName.DeviceVideoNightvisionImageAdjustment:
1446
+ station.setVideoNightvisionImageAdjustment(device, value);
1447
+ break;
1448
+ case types_1.PropertyName.DeviceVideoColorNightvision:
1449
+ station.setVideoColorNightvision(device, value);
1450
+ break;
1451
+ case types_1.PropertyName.DeviceAutoCalibration:
1452
+ station.setAutoCalibration(device, value);
1453
+ break;
1454
+ case types_1.PropertyName.DeviceAutoLock:
1455
+ station.setAutoLock(device, value);
1456
+ break;
1457
+ case types_1.PropertyName.DeviceAutoLockSchedule:
1458
+ station.setAutoLockSchedule(device, value);
1459
+ break;
1460
+ case types_1.PropertyName.DeviceAutoLockScheduleStartTime:
1461
+ station.setAutoLockScheduleStartTime(device, value);
1462
+ break;
1463
+ case types_1.PropertyName.DeviceAutoLockScheduleEndTime:
1464
+ station.setAutoLockScheduleEndTime(device, value);
1465
+ break;
1466
+ case types_1.PropertyName.DeviceAutoLockTimer:
1467
+ station.setAutoLockTimer(device, value);
1468
+ break;
1469
+ case types_1.PropertyName.DeviceOneTouchLocking:
1470
+ station.setOneTouchLocking(device, value);
1471
+ break;
1472
+ case types_1.PropertyName.DeviceSound:
1473
+ station.setSound(device, value);
1474
+ break;
1475
+ case types_1.PropertyName.DeviceNotification:
1476
+ station.setNotification(device, value);
1477
+ break;
1478
+ case types_1.PropertyName.DeviceNotificationLocked:
1479
+ station.setNotificationLocked(device, value);
1480
+ break;
1481
+ case types_1.PropertyName.DeviceNotificationUnlocked:
1482
+ station.setNotificationUnlocked(device, value);
1483
+ break;
1484
+ case types_1.PropertyName.DeviceScramblePasscode:
1485
+ station.setScramblePasscode(device, value);
1486
+ break;
1487
+ case types_1.PropertyName.DeviceWrongTryProtection:
1488
+ station.setWrongTryProtection(device, value);
1489
+ break;
1490
+ case types_1.PropertyName.DeviceWrongTryAttempts:
1491
+ station.setWrongTryAttempts(device, value);
1492
+ break;
1493
+ case types_1.PropertyName.DeviceWrongTryLockdownTime:
1494
+ station.setWrongTryLockdownTime(device, value);
1495
+ break;
1496
+ case types_1.PropertyName.DeviceLoiteringDetection:
1497
+ station.setLoiteringDetection(device, value);
1498
+ break;
1499
+ case types_1.PropertyName.DeviceLoiteringDetectionRange:
1500
+ station.setLoiteringDetectionRange(device, value);
1501
+ break;
1502
+ case types_1.PropertyName.DeviceLoiteringDetectionLength:
1503
+ station.setLoiteringDetectionLength(device, value);
1504
+ break;
1505
+ case types_1.PropertyName.DeviceLoiteringCustomResponseAutoVoiceResponse:
1506
+ station.setLoiteringCustomResponseAutoVoiceResponse(device, value);
1507
+ break;
1508
+ case types_1.PropertyName.DeviceLoiteringCustomResponseHomeBaseNotification:
1509
+ station.setLoiteringCustomResponseHomeBaseNotification(device, value);
1510
+ break;
1511
+ case types_1.PropertyName.DeviceLoiteringCustomResponsePhoneNotification:
1512
+ station.setLoiteringCustomResponsePhoneNotification(device, value);
1513
+ break;
1514
+ case types_1.PropertyName.DeviceLoiteringCustomResponseAutoVoiceResponseVoice:
1515
+ station.setLoiteringCustomResponseAutoVoiceResponseVoice(device, value);
1516
+ break;
1517
+ case types_1.PropertyName.DeviceLoiteringCustomResponseTimeFrom:
1518
+ station.setLoiteringCustomResponseTimeFrom(device, value);
1519
+ break;
1520
+ case types_1.PropertyName.DeviceLoiteringCustomResponseTimeTo:
1521
+ station.setLoiteringCustomResponseTimeTo(device, value);
1522
+ break;
1523
+ case types_1.PropertyName.DeviceMotionDetectionSensitivityMode:
1524
+ station.setMotionDetectionSensitivityMode(device, value);
1525
+ break;
1526
+ case types_1.PropertyName.DeviceMotionDetectionSensitivityStandard:
1527
+ station.setMotionDetectionSensitivityStandard(device, value);
1528
+ break;
1529
+ case types_1.PropertyName.DeviceMotionDetectionSensitivityAdvancedA:
1530
+ station.setMotionDetectionSensitivityAdvancedA(device, value);
1531
+ break;
1532
+ case types_1.PropertyName.DeviceMotionDetectionSensitivityAdvancedB:
1533
+ station.setMotionDetectionSensitivityAdvancedB(device, value);
1534
+ break;
1535
+ case types_1.PropertyName.DeviceMotionDetectionSensitivityAdvancedC:
1536
+ station.setMotionDetectionSensitivityAdvancedC(device, value);
1537
+ break;
1538
+ case types_1.PropertyName.DeviceMotionDetectionSensitivityAdvancedD:
1539
+ station.setMotionDetectionSensitivityAdvancedD(device, value);
1540
+ break;
1541
+ case types_1.PropertyName.DeviceMotionDetectionSensitivityAdvancedE:
1542
+ station.setMotionDetectionSensitivityAdvancedE(device, value);
1543
+ break;
1544
+ case types_1.PropertyName.DeviceMotionDetectionSensitivityAdvancedF:
1545
+ station.setMotionDetectionSensitivityAdvancedF(device, value);
1546
+ break;
1547
+ case types_1.PropertyName.DeviceMotionDetectionSensitivityAdvancedG:
1548
+ station.setMotionDetectionSensitivityAdvancedG(device, value);
1549
+ break;
1550
+ case types_1.PropertyName.DeviceMotionDetectionSensitivityAdvancedH:
1551
+ station.setMotionDetectionSensitivityAdvancedH(device, value);
1552
+ break;
1553
+ case types_1.PropertyName.DeviceDeliveryGuard:
1554
+ station.setDeliveryGuard(device, value);
1555
+ break;
1556
+ case types_1.PropertyName.DeviceDeliveryGuardPackageGuarding:
1557
+ station.setDeliveryGuardPackageGuarding(device, value);
1558
+ break;
1559
+ case types_1.PropertyName.DeviceDeliveryGuardPackageGuardingVoiceResponseVoice:
1560
+ station.setDeliveryGuardPackageGuardingVoiceResponseVoice(device, value);
1561
+ break;
1562
+ case types_1.PropertyName.DeviceDeliveryGuardPackageGuardingActivatedTimeFrom:
1563
+ station.setDeliveryGuardPackageGuardingActivatedTimeFrom(device, value);
1564
+ break;
1565
+ case types_1.PropertyName.DeviceDeliveryGuardPackageGuardingActivatedTimeTo:
1566
+ station.setDeliveryGuardPackageGuardingActivatedTimeTo(device, value);
1567
+ break;
1568
+ case types_1.PropertyName.DeviceDeliveryGuardUncollectedPackageAlert:
1569
+ station.setDeliveryGuardUncollectedPackageAlert(device, value);
1570
+ break;
1571
+ case types_1.PropertyName.DeviceDeliveryGuardPackageLiveCheckAssistance:
1572
+ station.setDeliveryGuardPackageLiveCheckAssistance(device, value);
1573
+ break;
1574
+ case types_1.PropertyName.DeviceDualCamWatchViewMode:
1575
+ station.setDualCamWatchViewMode(device, value);
1576
+ break;
1577
+ case types_1.PropertyName.DeviceRingAutoResponse:
1578
+ station.setRingAutoResponse(device, value);
1579
+ break;
1580
+ case types_1.PropertyName.DeviceRingAutoResponseVoiceResponse:
1581
+ station.setRingAutoResponseVoiceResponse(device, value);
1582
+ break;
1583
+ case types_1.PropertyName.DeviceRingAutoResponseVoiceResponseVoice:
1584
+ station.setRingAutoResponseVoiceResponseVoice(device, value);
1585
+ break;
1586
+ case types_1.PropertyName.DeviceRingAutoResponseTimeFrom:
1587
+ station.setRingAutoResponseTimeFrom(device, value);
1588
+ break;
1589
+ case types_1.PropertyName.DeviceRingAutoResponseTimeTo:
1590
+ station.setRingAutoResponseTimeTo(device, value);
1591
+ break;
1592
+ case types_1.PropertyName.DeviceNotificationRadarDetector:
1593
+ station.setNotificationRadarDetector(device, value);
1594
+ break;
1595
+ case types_1.PropertyName.DeviceSoundDetectionSensitivity:
1596
+ station.setSoundDetectionSensitivity(device, value);
1597
+ break;
1598
+ case types_1.PropertyName.DeviceContinuousRecording:
1599
+ station.setContinuousRecording(device, value);
1600
+ break;
1601
+ case types_1.PropertyName.DeviceContinuousRecordingType:
1602
+ station.setContinuousRecordingType(device, value);
1603
+ break;
1604
+ case types_1.PropertyName.DeviceDefaultAngle:
1605
+ station.enableDefaultAngle(device, value);
1606
+ break;
1607
+ case types_1.PropertyName.DeviceDefaultAngleIdleTime:
1608
+ station.setDefaultAngleIdleTime(device, value);
1609
+ break;
1610
+ case types_1.PropertyName.DeviceNotificationIntervalTime:
1611
+ station.setNotificationIntervalTime(device, value);
1612
+ break;
1613
+ case types_1.PropertyName.DeviceSoundDetectionRoundLook:
1614
+ station.setSoundDetectionRoundLook(device, value);
1615
+ break;
1616
+ case types_1.PropertyName.DeviceDeliveryGuardUncollectedPackageAlertTimeToCheck:
1617
+ station.setDeliveryGuardUncollectedPackageAlertTimeToCheck(device, value);
1618
+ break;
1619
+ case types_1.PropertyName.DeviceLeftOpenAlarm:
1620
+ case types_1.PropertyName.DeviceLeftOpenAlarmDuration:
1621
+ case types_1.PropertyName.DeviceDualUnlock:
1622
+ case types_1.PropertyName.DevicePowerSave:
1623
+ case types_1.PropertyName.DeviceInteriorBrightness:
1624
+ case types_1.PropertyName.DeviceInteriorBrightnessDuration:
1625
+ case types_1.PropertyName.DeviceTamperAlarm:
1626
+ case types_1.PropertyName.DeviceRemoteUnlock:
1627
+ case types_1.PropertyName.DeviceRemoteUnlockMasterPIN:
1628
+ case types_1.PropertyName.DeviceAlarmVolume:
1629
+ case types_1.PropertyName.DevicePromptVolume:
1630
+ case types_1.PropertyName.DeviceNotificationUnlockByKey:
1631
+ case types_1.PropertyName.DeviceNotificationUnlockByPIN:
1632
+ case types_1.PropertyName.DeviceNotificationUnlockByFingerprint:
1633
+ case types_1.PropertyName.DeviceNotificationUnlockByApp:
1634
+ case types_1.PropertyName.DeviceNotificationDualUnlock:
1635
+ case types_1.PropertyName.DeviceNotificationDualLock:
1636
+ case types_1.PropertyName.DeviceNotificationWrongTryProtect:
1637
+ case types_1.PropertyName.DeviceNotificationJammed:
1638
+ station.setSmartSafeParams(device, name, value);
1639
+ break;
1640
+ case types_1.PropertyName.DeviceVideoTypeStoreToNAS:
1641
+ station.setVideoTypeStoreToNAS(device, value);
1642
+ break;
1643
+ case types_1.PropertyName.DeviceMotionDetectionTypeHumanRecognition:
1644
+ station.setMotionDetectionTypeHB3(device, types_1.HB3DetectionTypes.HUMAN_RECOGNITION, value);
1645
+ break;
1646
+ case types_1.PropertyName.DeviceMotionDetectionTypeHuman:
1647
+ if (device.isWallLightCam()) {
1648
+ station.setMotionDetectionTypeHuman(device, value);
1649
+ }
1650
+ else if (device.isOutdoorPanAndTiltCamera()) {
1651
+ station.setMotionDetectionTypeHB3(device, types_1.T8170DetectionTypes.HUMAN_DETECTION, value);
1652
+ }
1653
+ else if (device.isSoloCameras()) {
1654
+ station.setMotionDetectionTypeHB3(device, types_1.SoloCameraDetectionTypes.HUMAN_DETECTION, value);
1655
+ }
1656
+ else if (device.isIndoorPanAndTiltCameraS350()) {
1657
+ station.setMotionDetectionTypeHB3(device, types_1.IndoorS350DetectionTypes.HUMAN_DETECTION, value);
1658
+ }
1659
+ else {
1660
+ station.setMotionDetectionTypeHB3(device, types_1.HB3DetectionTypes.HUMAN_DETECTION, value);
1661
+ }
1662
+ break;
1663
+ case types_1.PropertyName.DeviceMotionDetectionTypePet:
1664
+ if (device.isIndoorPanAndTiltCameraS350()) {
1665
+ station.setMotionDetectionTypeHB3(device, types_1.IndoorS350DetectionTypes.PET_DETECTION, value);
1666
+ }
1667
+ else if (device.isCameraC35()) {
1668
+ station.setMotionDetectionTypeHB3(device, types_1.EufyCamC35DetectionTypes.PET_DETECTION, value);
1669
+ }
1670
+ else {
1671
+ station.setMotionDetectionTypeHB3(device, types_1.HB3DetectionTypes.PET_DETECTION, value);
1672
+ }
1673
+ break;
1674
+ case types_1.PropertyName.DeviceMotionDetectionTypeVehicle:
1675
+ if (device.isOutdoorPanAndTiltCamera()) {
1676
+ station.setMotionDetectionTypeHB3(device, types_1.T8170DetectionTypes.VEHICLE_DETECTION, value);
1677
+ }
1678
+ else if (device.isCameraC35()) {
1679
+ station.setMotionDetectionTypeHB3(device, types_1.EufyCamC35DetectionTypes.VEHICLE_DETECTION, value);
1680
+ }
1681
+ else {
1682
+ station.setMotionDetectionTypeHB3(device, types_1.HB3DetectionTypes.VEHICLE_DETECTION, value);
1683
+ }
1684
+ break;
1685
+ case types_1.PropertyName.DeviceMotionDetectionTypeAllOtherMotions:
1686
+ if (device.isWallLightCam()) {
1687
+ station.setMotionDetectionTypeAllOtherMotions(device, value);
1688
+ }
1689
+ else if (device.isOutdoorPanAndTiltCamera()) {
1690
+ station.setMotionDetectionTypeHB3(device, types_1.T8170DetectionTypes.ALL_OTHER_MOTION, value);
1691
+ }
1692
+ else if (device.isSoloCameras() && !device.isCameraC35()) {
1693
+ station.setMotionDetectionTypeHB3(device, types_1.SoloCameraDetectionTypes.ALL_OTHER_MOTION, value);
1694
+ }
1695
+ else if (device.isIndoorPanAndTiltCameraS350()) {
1696
+ station.setMotionDetectionTypeHB3(device, types_1.IndoorS350DetectionTypes.ALL_OTHER_MOTION, value);
1697
+ }
1698
+ else if (device.isCameraC35()) {
1699
+ station.setMotionDetectionTypeHB3(device, types_1.EufyCamC35DetectionTypes.ALL_OTHER_MOTION, value);
1700
+ }
1701
+ else {
1702
+ station.setMotionDetectionTypeHB3(device, types_1.HB3DetectionTypes.ALL_OTHER_MOTION, value);
1703
+ }
1704
+ break;
1705
+ case types_1.PropertyName.DeviceLightSettingsManualLightingActiveMode:
1706
+ station.setLightSettingsManualLightingActiveMode(device, value);
1707
+ break;
1708
+ case types_1.PropertyName.DeviceLightSettingsManualDailyLighting:
1709
+ station.setLightSettingsManualDailyLighting(device, value);
1710
+ break;
1711
+ case types_1.PropertyName.DeviceLightSettingsManualColoredLighting:
1712
+ station.setLightSettingsManualColoredLighting(device, value);
1713
+ break;
1714
+ case types_1.PropertyName.DeviceLightSettingsManualDynamicLighting:
1715
+ station.setLightSettingsManualDynamicLighting(device, value);
1716
+ break;
1717
+ case types_1.PropertyName.DeviceLightSettingsMotionLightingActiveMode:
1718
+ station.setLightSettingsMotionLightingActiveMode(device, value);
1719
+ break;
1720
+ case types_1.PropertyName.DeviceLightSettingsMotionDailyLighting:
1721
+ station.setLightSettingsMotionDailyLighting(device, value);
1722
+ break;
1723
+ case types_1.PropertyName.DeviceLightSettingsMotionColoredLighting:
1724
+ station.setLightSettingsMotionColoredLighting(device, value);
1725
+ break;
1726
+ case types_1.PropertyName.DeviceLightSettingsMotionDynamicLighting:
1727
+ station.setLightSettingsMotionDynamicLighting(device, value);
1728
+ break;
1729
+ case types_1.PropertyName.DeviceLightSettingsScheduleLightingActiveMode:
1730
+ station.setLightSettingsScheduleLightingActiveMode(device, value);
1731
+ break;
1732
+ case types_1.PropertyName.DeviceLightSettingsScheduleDailyLighting:
1733
+ station.setLightSettingsScheduleDailyLighting(device, value);
1734
+ break;
1735
+ case types_1.PropertyName.DeviceLightSettingsScheduleColoredLighting:
1736
+ station.setLightSettingsScheduleColoredLighting(device, value);
1737
+ break;
1738
+ case types_1.PropertyName.DeviceLightSettingsScheduleDynamicLighting:
1739
+ station.setLightSettingsScheduleDynamicLighting(device, value);
1740
+ break;
1741
+ case types_1.PropertyName.DeviceLightSettingsColoredLightingColors:
1742
+ station.setLightSettingsColoredLightingColors(device, value);
1743
+ break;
1744
+ case types_1.PropertyName.DeviceLightSettingsDynamicLightingThemes:
1745
+ station.setLightSettingsDynamicLightingThemes(device, value);
1746
+ break;
1747
+ case types_1.PropertyName.DeviceDoorControlWarning:
1748
+ station.setDoorControlWarning(device, value);
1749
+ break;
1750
+ case types_1.PropertyName.DeviceDoor1Open:
1751
+ station.openDoor(device, value, 1);
1752
+ break;
1753
+ case types_1.PropertyName.DeviceDoor2Open:
1754
+ station.openDoor(device, value, 2);
1755
+ break;
1756
+ case types_1.PropertyName.DeviceLeftBehindAlarm: {
1757
+ const tracker = device;
1758
+ const result = await tracker.setLeftBehindAlarm(value);
1759
+ if (result) {
1760
+ device.updateProperty(name, value);
1761
+ }
1762
+ break;
1763
+ }
1764
+ case types_1.PropertyName.DeviceFindPhone: {
1765
+ const tracker = device;
1766
+ const result = await tracker.setFindPhone(value);
1767
+ if (result) {
1768
+ device.updateProperty(name, value);
1769
+ }
1770
+ break;
1771
+ }
1772
+ case types_1.PropertyName.DeviceTrackerType: {
1773
+ const tracker = device;
1774
+ const result = await tracker.setTrackerType(value);
1775
+ if (result) {
1776
+ device.updateProperty(name, value);
1777
+ }
1778
+ break;
1779
+ }
1780
+ case types_1.PropertyName.DeviceImageMirrored:
1781
+ station.setMirrorMode(device, value);
1782
+ break;
1783
+ case types_1.PropertyName.DeviceFlickerAdjustment:
1784
+ station.setFlickerAdjustment(device, value);
1785
+ break;
1786
+ case types_1.PropertyName.DeviceSoundDetectionType:
1787
+ station.setSoundDetectionType(device, value);
1788
+ break;
1789
+ case types_1.PropertyName.DeviceLeavingDetection:
1790
+ station.setLeavingDetection(device, value);
1791
+ break;
1792
+ case types_1.PropertyName.DeviceLeavingReactionNotification:
1793
+ station.setLeavingReactionNotification(device, value);
1794
+ break;
1795
+ case types_1.PropertyName.DeviceLeavingReactionStartTime:
1796
+ station.setLeavingReactionStartTime(device, value);
1797
+ break;
1798
+ case types_1.PropertyName.DeviceLeavingReactionEndTime:
1799
+ station.setLeavingReactionEndTime(device, value);
1800
+ break;
1801
+ case types_1.PropertyName.DeviceBeepVolume:
1802
+ station.setBeepVolume(device, value);
1803
+ break;
1804
+ case types_1.PropertyName.DeviceNightvisionOptimization:
1805
+ station.setNightvisionOptimization(device, value);
1806
+ break;
1807
+ case types_1.PropertyName.DeviceNightvisionOptimizationSide:
1808
+ station.setNightvisionOptimizationSide(device, value);
1809
+ break;
1810
+ case types_1.PropertyName.DeviceOpenMethod:
1811
+ station.setOpenMethod(device, value);
1812
+ break;
1813
+ case types_1.PropertyName.DeviceMotionActivatedPrompt:
1814
+ station.setMotionActivatedPrompt(device, value);
1815
+ break;
1816
+ default:
1817
+ if (!Object.values(types_1.PropertyName).includes(name))
1818
+ throw new error_1.ReadOnlyPropertyError("Property is read only", {
1819
+ context: { device: deviceSN, propertyName: name, propertyValue: value },
1820
+ });
1821
+ throw new error_2.InvalidPropertyError("Device has no writable property", {
1822
+ context: { device: deviceSN, propertyName: name, propertyValue: value },
1823
+ });
1824
+ }
1825
+ }
1826
+ async setStationProperty(stationSN, name, value) {
1827
+ const station = await this.getStation(stationSN);
1828
+ const metadata = station.getPropertyMetadata(name);
1829
+ value = (0, utils_1.parseValue)(metadata, value);
1830
+ switch (name) {
1831
+ case types_1.PropertyName.StationGuardMode:
1832
+ station.setGuardMode(value);
1833
+ break;
1834
+ case types_1.PropertyName.StationAlarmTone:
1835
+ station.setStationAlarmTone(value);
1836
+ break;
1837
+ case types_1.PropertyName.StationAlarmVolume:
1838
+ station.setStationAlarmRingtoneVolume(value);
1839
+ break;
1840
+ case types_1.PropertyName.StationPromptVolume:
1841
+ station.setStationPromptVolume(value);
1842
+ break;
1843
+ case types_1.PropertyName.StationNotificationSwitchModeApp:
1844
+ station.setStationNotificationSwitchMode(types_1.NotificationSwitchMode.APP, value);
1845
+ break;
1846
+ case types_1.PropertyName.StationNotificationSwitchModeGeofence:
1847
+ station.setStationNotificationSwitchMode(types_1.NotificationSwitchMode.GEOFENCE, value);
1848
+ break;
1849
+ case types_1.PropertyName.StationNotificationSwitchModeSchedule:
1850
+ station.setStationNotificationSwitchMode(types_1.NotificationSwitchMode.SCHEDULE, value);
1851
+ break;
1852
+ case types_1.PropertyName.StationNotificationSwitchModeKeypad:
1853
+ station.setStationNotificationSwitchMode(types_1.NotificationSwitchMode.KEYPAD, value);
1854
+ break;
1855
+ case types_1.PropertyName.StationNotificationStartAlarmDelay:
1856
+ station.setStationNotificationStartAlarmDelay(value);
1857
+ break;
1858
+ case types_1.PropertyName.StationTimeFormat:
1859
+ station.setStationTimeFormat(value);
1860
+ break;
1861
+ case types_1.PropertyName.StationSwitchModeWithAccessCode:
1862
+ station.setStationSwitchModeWithAccessCode(value);
1863
+ break;
1864
+ case types_1.PropertyName.StationAutoEndAlarm:
1865
+ station.setStationAutoEndAlarm(value);
1866
+ break;
1867
+ case types_1.PropertyName.StationTurnOffAlarmWithButton:
1868
+ station.setStationTurnOffAlarmWithButton(value);
1869
+ break;
1870
+ case types_1.PropertyName.StationCrossCameraTracking:
1871
+ station.setCrossCameraTracking(value);
1872
+ break;
1873
+ case types_1.PropertyName.StationContinuousTrackingTime:
1874
+ station.setContinuousTrackingTime(value);
1875
+ break;
1876
+ case types_1.PropertyName.StationTrackingAssistance:
1877
+ station.setTrackingAssistance(value);
1878
+ break;
1879
+ case types_1.PropertyName.StationCrossTrackingCameraList:
1880
+ station.setCrossTrackingCameraList(value);
1881
+ break;
1882
+ case types_1.PropertyName.StationCrossTrackingGroupList:
1883
+ station.setCrossTrackingGroupList(value);
1884
+ break;
1885
+ default:
1886
+ if (!Object.values(types_1.PropertyName).includes(name))
1887
+ throw new error_1.ReadOnlyPropertyError("Property is read only", {
1888
+ context: { station: stationSN, propertyName: name, propertyValue: value },
1889
+ });
1890
+ throw new error_2.InvalidPropertyError("Station has no writable property", {
1891
+ context: { station: stationSN, propertyName: name, propertyValue: value },
1892
+ });
1893
+ }
1894
+ }
1895
+ onStartStationLivestream(station, channel, metadata, videostream, audiostream) {
1896
+ this.getStationDevice(station.getSerial(), channel)
1897
+ .then((device) => {
1898
+ this.emit("station livestream start", station, device, metadata, videostream, audiostream);
1899
+ })
1900
+ .catch((err) => {
1901
+ const error = (0, error_1.ensureError)(err);
1902
+ logging_1.rootMainLogger.error(`Station start livestream error`, {
1903
+ error: (0, utils_1.getError)(error),
1904
+ stationSN: station.getSerial(),
1905
+ channel: channel,
1906
+ metadata: metadata,
1907
+ });
1908
+ });
1909
+ }
1910
+ onStopStationLivestream(station, channel) {
1911
+ this.getStationDevice(station.getSerial(), channel)
1912
+ .then((device) => {
1913
+ this.emit("station livestream stop", station, device);
1914
+ })
1915
+ .catch((err) => {
1916
+ const error = (0, error_1.ensureError)(err);
1917
+ logging_1.rootMainLogger.error(`Station stop livestream error`, {
1918
+ error: (0, utils_1.getError)(error),
1919
+ stationSN: station.getSerial(),
1920
+ channel: channel,
1921
+ });
1922
+ });
1923
+ }
1924
+ onErrorStationLivestream(station, channel, origError) {
1925
+ this.getStationDevice(station.getSerial(), channel)
1926
+ .then((device) => {
1927
+ station.stopLivestream(device);
1928
+ })
1929
+ .catch((err) => {
1930
+ const error = (0, error_1.ensureError)(err);
1931
+ logging_1.rootMainLogger.error(`Station livestream error`, {
1932
+ error: (0, utils_1.getError)(error),
1933
+ stationSN: station.getSerial(),
1934
+ channel: channel,
1935
+ origError: (0, utils_1.getError)(origError),
1936
+ });
1937
+ });
1938
+ }
1939
+ onStartStationRTSPLivestream(station, channel) {
1940
+ this.getStationDevice(station.getSerial(), channel)
1941
+ .then((device) => {
1942
+ this.emit("station rtsp livestream start", station, device);
1943
+ })
1944
+ .catch((err) => {
1945
+ const error = (0, error_1.ensureError)(err);
1946
+ logging_1.rootMainLogger.error(`Station start rtsp livestream error`, {
1947
+ error: (0, utils_1.getError)(error),
1948
+ stationSN: station.getSerial(),
1949
+ channel: channel,
1950
+ });
1951
+ });
1952
+ }
1953
+ onStopStationRTSPLivestream(station, channel) {
1954
+ this.getStationDevice(station.getSerial(), channel)
1955
+ .then((device) => {
1956
+ this.emit("station rtsp livestream stop", station, device);
1957
+ })
1958
+ .catch((err) => {
1959
+ const error = (0, error_1.ensureError)(err);
1960
+ logging_1.rootMainLogger.error(`Station stop rtsp livestream error`, {
1961
+ error: (0, utils_1.getError)(error),
1962
+ stationSN: station.getSerial(),
1963
+ channel: channel,
1964
+ });
1965
+ });
1966
+ }
1967
+ onStationStartDownload(station, channel, metadata, videoStream, audioStream) {
1968
+ this.getStationDevice(station.getSerial(), channel)
1969
+ .then((device) => {
1970
+ this.emit("station download start", station, device, metadata, videoStream, audioStream);
1971
+ })
1972
+ .catch((err) => {
1973
+ const error = (0, error_1.ensureError)(err);
1974
+ logging_1.rootMainLogger.error(`Station start download error`, {
1975
+ error: (0, utils_1.getError)(error),
1976
+ stationSN: station.getSerial(),
1977
+ channel: channel,
1978
+ metadata: metadata,
1979
+ });
1980
+ });
1981
+ }
1982
+ onStationFinishDownload(station, channel) {
1983
+ this.getStationDevice(station.getSerial(), channel)
1984
+ .then((device) => {
1985
+ this.emit("station download finish", station, device);
1986
+ })
1987
+ .catch((err) => {
1988
+ const error = (0, error_1.ensureError)(err);
1989
+ logging_1.rootMainLogger.error(`Station finish download error`, {
1990
+ error: (0, utils_1.getError)(error),
1991
+ stationSN: station.getSerial(),
1992
+ channel: channel,
1993
+ });
1994
+ });
1995
+ }
1996
+ onStationCommandResult(station, result) {
1997
+ this.emit("station command result", station, result);
1998
+ if (result.return_code === 0) {
1999
+ if (result.customData !== undefined && result.customData.onSuccess !== undefined) {
2000
+ try {
2001
+ result.customData.onSuccess();
2002
+ }
2003
+ catch (err) {
2004
+ const error = (0, error_1.ensureError)(err);
2005
+ logging_1.rootMainLogger.error(`Station command result - onSuccess callback error`, {
2006
+ error: (0, utils_1.getError)(error),
2007
+ stationSN: station.getSerial(),
2008
+ result: result,
2009
+ });
2010
+ }
2011
+ }
2012
+ this.getStationDevice(station.getSerial(), result.channel)
2013
+ .then((device) => {
2014
+ if ((result.customData !== undefined &&
2015
+ result.customData.property !== undefined &&
2016
+ !device.isLockWifiR10() &&
2017
+ !device.isLockWifiR20() &&
2018
+ !device.isSmartSafe() &&
2019
+ !device.isLockWifiT8506() &&
2020
+ !device.isLockWifiT8502() &&
2021
+ !device.isLockWifiT8510P() &&
2022
+ !device.isLockWifiT8520P() &&
2023
+ !device.isLockWifiT85L0()) ||
2024
+ (result.customData !== undefined &&
2025
+ result.customData.property !== undefined &&
2026
+ device.isSmartSafe() &&
2027
+ result.command_type !== types_2.CommandType.CMD_SMARTSAFE_SETTINGS) ||
2028
+ (result.customData !== undefined &&
2029
+ result.customData.property !== undefined &&
2030
+ (device.isLockWifiT8506() ||
2031
+ device.isLockWifiT8502() ||
2032
+ device.isLockWifiT8510P() ||
2033
+ device.isLockWifiT8520P() ||
2034
+ device.isLockWifiT85L0()) &&
2035
+ result.command_type !== types_2.CommandType.CMD_DOORLOCK_SET_PUSH_MODE)) {
2036
+ if (device.hasProperty(result.customData.property.name)) {
2037
+ const metadata = device.getPropertyMetadata(result.customData.property.name);
2038
+ if (typeof result.customData.property.value !== "object" || metadata.type === "object") {
2039
+ device.updateProperty(result.customData.property.name, result.customData.property.value);
2040
+ }
2041
+ }
2042
+ else if (station.hasProperty(result.customData.property.name)) {
2043
+ const metadata = station.getPropertyMetadata(result.customData.property.name);
2044
+ if (typeof result.customData.property.value !== "object" || metadata.type === "object") {
2045
+ station.updateProperty(result.customData.property.name, result.customData.property.value);
2046
+ }
2047
+ }
2048
+ }
2049
+ else if (result.customData !== undefined &&
2050
+ result.customData.command !== undefined &&
2051
+ result.customData.command.name === types_1.CommandName.DeviceSnooze) {
2052
+ const snoozeTime = result.customData.command.value !== undefined && result.customData.command.value.snooze_time !== undefined
2053
+ ? result.customData.command.value.snooze_time
2054
+ : 0;
2055
+ if (snoozeTime > 0) {
2056
+ device.updateProperty(types_1.PropertyName.DeviceSnooze, true);
2057
+ device.updateProperty(types_1.PropertyName.DeviceSnoozeTime, snoozeTime);
2058
+ }
2059
+ this.api
2060
+ .refreshAllData()
2061
+ .then(() => {
2062
+ const snoozeStartTime = device.getPropertyValue(types_1.PropertyName.DeviceSnoozeStartTime);
2063
+ const currentTime = Math.trunc(new Date().getTime() / 1000);
2064
+ let timeoutMS;
2065
+ if (snoozeStartTime !== undefined && snoozeStartTime !== 0) {
2066
+ timeoutMS = (snoozeStartTime + snoozeTime - currentTime) * 1000;
2067
+ }
2068
+ else {
2069
+ timeoutMS = snoozeTime * 1000;
2070
+ }
2071
+ this.deviceSnoozeTimeout[device.getSerial()] = setTimeout(() => {
2072
+ device.updateProperty(types_1.PropertyName.DeviceSnooze, false);
2073
+ device.updateProperty(types_1.PropertyName.DeviceSnoozeTime, 0);
2074
+ device.updateProperty(types_1.PropertyName.DeviceSnoozeStartTime, 0);
2075
+ if (device.hasProperty(types_1.PropertyName.DeviceSnoozeHomebase)) {
2076
+ device.updateProperty(types_1.PropertyName.DeviceSnoozeHomebase, false);
2077
+ }
2078
+ if (device.hasProperty(types_1.PropertyName.DeviceSnoozeMotion)) {
2079
+ device.updateProperty(types_1.PropertyName.DeviceSnoozeMotion, false);
2080
+ }
2081
+ if (device.hasProperty(types_1.PropertyName.DeviceSnoozeChime)) {
2082
+ device.updateProperty(types_1.PropertyName.DeviceSnoozeChime, false);
2083
+ }
2084
+ delete this.deviceSnoozeTimeout[device.getSerial()];
2085
+ }, timeoutMS);
2086
+ })
2087
+ .catch((err) => {
2088
+ const error = (0, error_1.ensureError)(err);
2089
+ logging_1.rootMainLogger.error("Error during API data refreshing", { error: (0, utils_1.getError)(error) });
2090
+ });
2091
+ }
2092
+ })
2093
+ .catch((err) => {
2094
+ const error = (0, error_1.ensureError)(err);
2095
+ if (error instanceof error_1.DeviceNotFoundError) {
2096
+ if (result.customData !== undefined && result.customData.property !== undefined) {
2097
+ station.updateProperty(result.customData.property.name, result.customData.property.value);
2098
+ }
2099
+ }
2100
+ else {
2101
+ logging_1.rootMainLogger.error(`Station command result error`, {
2102
+ error: (0, utils_1.getError)(error),
2103
+ stationSN: station.getSerial(),
2104
+ result: result,
2105
+ });
2106
+ }
2107
+ });
2108
+ if (station.isIntegratedDevice() &&
2109
+ result.command_type === types_2.CommandType.CMD_SET_ARMING &&
2110
+ station.isConnected() &&
2111
+ station.getDeviceType() !== types_1.DeviceType.DOORBELL) {
2112
+ station.getCameraInfo();
2113
+ }
2114
+ }
2115
+ else {
2116
+ if (result.customData !== undefined && result.customData.onFailure !== undefined) {
2117
+ try {
2118
+ result.customData.onFailure();
2119
+ }
2120
+ catch (err) {
2121
+ const error = (0, error_1.ensureError)(err);
2122
+ logging_1.rootMainLogger.error(`Station command result - onFailure callback error`, {
2123
+ error: (0, utils_1.getError)(error),
2124
+ stationSN: station.getSerial(),
2125
+ result: result,
2126
+ });
2127
+ }
2128
+ }
2129
+ }
2130
+ if (result.customData !== undefined && result.customData.command !== undefined) {
2131
+ const customValue = result.customData.command.value;
2132
+ switch (result.customData.command.name) {
2133
+ case types_1.CommandName.DeviceAddUser:
2134
+ this.getStationDevice(station.getSerial(), result.channel).then((device) => {
2135
+ switch (result.return_code) {
2136
+ case 0:
2137
+ this.emit("user added", device, customValue.username, customValue.schedule);
2138
+ break;
2139
+ case 4:
2140
+ this.emit("user error", device, customValue.username, new error_1.AddUserError("Passcode already used by another user, please choose a different one", {
2141
+ context: {
2142
+ device: device.getSerial(),
2143
+ username: customValue.username,
2144
+ schedule: customValue.schedule,
2145
+ },
2146
+ }));
2147
+ break;
2148
+ default:
2149
+ this.emit("user error", device, customValue.username, new error_1.AddUserError("Error creating user", {
2150
+ context: {
2151
+ device: device.getSerial(),
2152
+ username: customValue.username,
2153
+ schedule: customValue.schedule,
2154
+ returnode: result.return_code,
2155
+ },
2156
+ }));
2157
+ break;
2158
+ }
2159
+ });
2160
+ break;
2161
+ case types_1.CommandName.DeviceDeleteUser:
2162
+ this.getStationDevice(station.getSerial(), result.channel).then((device) => {
2163
+ switch (result.return_code) {
2164
+ case 0:
2165
+ this.api
2166
+ .deleteUser(device.getSerial(), customValue.shortUserId, device.getStationSerial())
2167
+ .then((result) => {
2168
+ if (result) {
2169
+ this.emit("user deleted", device, customValue.username);
2170
+ }
2171
+ else {
2172
+ this.emit("user error", device, customValue.username, new error_1.DeleteUserError("Error in deleting user through cloud api call", {
2173
+ context: {
2174
+ device: device.getSerial(),
2175
+ username: customValue.username,
2176
+ shortUserId: customValue.short_user_id,
2177
+ },
2178
+ }));
2179
+ }
2180
+ });
2181
+ break;
2182
+ default:
2183
+ this.emit("user error", device, customValue.username, new error_1.DeleteUserError("Error deleting user", {
2184
+ context: {
2185
+ device: device.getSerial(),
2186
+ username: customValue.username,
2187
+ shortUserId: customValue.short_user_id,
2188
+ returnCode: result.return_code,
2189
+ },
2190
+ }));
2191
+ break;
2192
+ }
2193
+ });
2194
+ break;
2195
+ case types_1.CommandName.DeviceUpdateUserPasscode:
2196
+ this.getStationDevice(station.getSerial(), result.channel).then((device) => {
2197
+ switch (result.return_code) {
2198
+ case 0:
2199
+ this.emit("user passcode updated", device, customValue.username);
2200
+ break;
2201
+ default:
2202
+ this.emit("user error", device, customValue.username, new error_1.UpdateUserPasscodeError("Error updating user passcode", {
2203
+ context: {
2204
+ device: device.getSerial(),
2205
+ username: customValue.username,
2206
+ returnCode: result.return_code,
2207
+ },
2208
+ }));
2209
+ break;
2210
+ }
2211
+ });
2212
+ break;
2213
+ case types_1.CommandName.DeviceUpdateUserSchedule:
2214
+ this.getStationDevice(station.getSerial(), result.channel).then((device) => {
2215
+ switch (result.return_code) {
2216
+ case 0:
2217
+ this.emit("user schedule updated", device, customValue.username, customValue.schedule);
2218
+ break;
2219
+ default:
2220
+ this.emit("user error", device, customValue.username, new error_1.UpdateUserScheduleError("Error updating user schedule", {
2221
+ context: {
2222
+ device: device.getSerial(),
2223
+ username: customValue.username,
2224
+ schedule: customValue.schedule,
2225
+ returnCode: result.return_code,
2226
+ },
2227
+ }));
2228
+ break;
2229
+ }
2230
+ });
2231
+ break;
2232
+ }
2233
+ }
2234
+ }
2235
+ onStationSecondaryCommandResult(station, result) {
2236
+ if (result.return_code === 0) {
2237
+ this.getStationDevice(station.getSerial(), result.channel)
2238
+ .then((device) => {
2239
+ if (result.customData !== undefined && result.customData.property !== undefined) {
2240
+ if (device.hasProperty(result.customData.property.name))
2241
+ device.updateProperty(result.customData.property.name, result.customData.property.value);
2242
+ else if (station.hasProperty(result.customData.property.name)) {
2243
+ station.updateProperty(result.customData.property.name, result.customData.property.value);
2244
+ }
2245
+ }
2246
+ })
2247
+ .catch((err) => {
2248
+ const error = (0, error_1.ensureError)(err);
2249
+ if (error instanceof error_1.DeviceNotFoundError) {
2250
+ if (result.customData !== undefined && result.customData.property !== undefined) {
2251
+ station.updateProperty(result.customData.property.name, result.customData.property.value);
2252
+ }
2253
+ }
2254
+ else {
2255
+ logging_1.rootMainLogger.error(`Station secondary command result error`, {
2256
+ error: (0, utils_1.getError)(error),
2257
+ stationSN: station.getSerial(),
2258
+ result: result,
2259
+ });
2260
+ }
2261
+ });
2262
+ }
2263
+ }
2264
+ onStationRtspUrl(station, channel, value) {
2265
+ this.getStationDevice(station.getSerial(), channel)
2266
+ .then((device) => {
2267
+ this.emit("station rtsp url", station, device, value);
2268
+ device.setCustomPropertyValue(types_1.PropertyName.DeviceRTSPStreamUrl, value);
2269
+ })
2270
+ .catch((err) => {
2271
+ const error = (0, error_1.ensureError)(err);
2272
+ logging_1.rootMainLogger.error(`Station rtsp url error`, {
2273
+ error: (0, utils_1.getError)(error),
2274
+ stationSN: station.getSerial(),
2275
+ channel: channel,
2276
+ url: value,
2277
+ });
2278
+ });
2279
+ }
2280
+ onStationGuardMode(station, guardMode) {
2281
+ this.emit("station guard mode", station, guardMode);
2282
+ }
2283
+ onStationCurrentMode(station, currentMode) {
2284
+ this.emit("station current mode", station, currentMode);
2285
+ }
2286
+ onStationPropertyChanged(station, name, value, ready) {
2287
+ if (ready && !name.startsWith("hidden-")) {
2288
+ this.emit("station property changed", station, name, value);
2289
+ }
2290
+ }
2291
+ onStationRawPropertyChanged(station, type, value) {
2292
+ this.emit("station raw property changed", station, type, value);
2293
+ }
2294
+ onStationAlarmEvent(station, alarmEvent) {
2295
+ this.emit("station alarm event", station, alarmEvent);
2296
+ }
2297
+ onStationAlarmDelayEvent(station, alarmDelayEvent, alarmDelay) {
2298
+ this.emit("station alarm delay event", station, alarmDelayEvent, alarmDelay);
2299
+ }
2300
+ onStationArmDelayEvent(station, armDelay) {
2301
+ this.emit("station alarm arm delay event", station, armDelay);
2302
+ }
2303
+ onStationAlarmArmedEvent(station) {
2304
+ this.emit("station alarm armed", station);
2305
+ }
2306
+ onDevicePropertyChanged(device, name, value, ready) {
2307
+ try {
2308
+ if (ready && !name.startsWith("hidden-")) {
2309
+ this.emit("device property changed", device, name, value);
2310
+ }
2311
+ if (name === types_1.PropertyName.DeviceRTSPStream &&
2312
+ value === true &&
2313
+ (device.getPropertyValue(types_1.PropertyName.DeviceRTSPStreamUrl) === undefined ||
2314
+ (device.getPropertyValue(types_1.PropertyName.DeviceRTSPStreamUrl) !== undefined &&
2315
+ device.getPropertyValue(types_1.PropertyName.DeviceRTSPStreamUrl) === ""))) {
2316
+ this.getStation(device.getStationSerial())
2317
+ .then((station) => {
2318
+ station.setRTSPStream(device, true);
2319
+ })
2320
+ .catch((err) => {
2321
+ const error = (0, error_1.ensureError)(err);
2322
+ logging_1.rootMainLogger.error(`Device property changed error - station enable rtsp`, {
2323
+ error: (0, utils_1.getError)(error),
2324
+ deviceSN: device.getSerial(),
2325
+ stationSN: device.getStationSerial(),
2326
+ propertyName: name,
2327
+ propertyValue: value,
2328
+ ready: ready,
2329
+ });
2330
+ });
2331
+ }
2332
+ else if (name === types_1.PropertyName.DeviceRTSPStream && value === false) {
2333
+ device.setCustomPropertyValue(types_1.PropertyName.DeviceRTSPStreamUrl, "");
2334
+ }
2335
+ else if (name === types_1.PropertyName.DevicePictureUrl && value !== "") {
2336
+ if (!(0, utils_1.isValidUrl)(value)) {
2337
+ this.getStation(device.getStationSerial())
2338
+ .then((station) => {
2339
+ if (station.hasCommand(types_1.CommandName.StationDownloadImage)) {
2340
+ station.downloadImage(value);
2341
+ }
2342
+ })
2343
+ .catch((err) => {
2344
+ const error = (0, error_1.ensureError)(err);
2345
+ logging_1.rootMainLogger.error(`Device property changed error - station download image`, {
2346
+ error: (0, utils_1.getError)(error),
2347
+ deviceSN: device.getSerial(),
2348
+ stationSN: device.getStationSerial(),
2349
+ propertyName: name,
2350
+ propertyValue: value,
2351
+ ready: ready,
2352
+ });
2353
+ });
2354
+ }
2355
+ }
2356
+ }
2357
+ catch (err) {
2358
+ const error = (0, error_1.ensureError)(err);
2359
+ logging_1.rootMainLogger.error(`Device property changed error`, {
2360
+ error: (0, utils_1.getError)(error),
2361
+ deviceSN: device.getSerial(),
2362
+ stationSN: device.getStationSerial(),
2363
+ propertyName: name,
2364
+ propertyValue: value,
2365
+ ready: ready,
2366
+ });
2367
+ }
2368
+ }
2369
+ onDeviceRawPropertyChanged(device, type, value) {
2370
+ this.emit("device raw property changed", device, type, value);
2371
+ }
2372
+ onDeviceCryingDetected(device, state) {
2373
+ this.emit("device crying detected", device, state);
2374
+ }
2375
+ onDeviceSoundDetected(device, state) {
2376
+ this.emit("device sound detected", device, state);
2377
+ }
2378
+ onDevicePetDetected(device, state) {
2379
+ this.emit("device pet detected", device, state);
2380
+ }
2381
+ onDeviceVehicleDetected(device, state) {
2382
+ this.emit("device vehicle detected", device, state);
2383
+ }
2384
+ onDeviceMotionDetected(device, state) {
2385
+ this.emit("device motion detected", device, state);
2386
+ }
2387
+ onDevicePersonDetected(device, state, person) {
2388
+ this.emit("device person detected", device, state, person);
2389
+ }
2390
+ onDeviceRings(device, state) {
2391
+ this.emit("device rings", device, state);
2392
+ }
2393
+ onDeviceLocked(device, state) {
2394
+ this.emit("device locked", device, state);
2395
+ }
2396
+ onDeviceOpen(device, state) {
2397
+ this.emit("device open", device, state);
2398
+ }
2399
+ onDevicePackageDelivered(device, state) {
2400
+ this.emit("device package delivered", device, state);
2401
+ }
2402
+ onDevicePackageStranded(device, state) {
2403
+ this.emit("device package stranded", device, state);
2404
+ }
2405
+ onDevicePackageTaken(device, state) {
2406
+ this.emit("device package taken", device, state);
2407
+ }
2408
+ onDeviceSomeoneLoitering(device, state) {
2409
+ this.emit("device someone loitering", device, state);
2410
+ }
2411
+ onDeviceRadarMotionDetected(device, state) {
2412
+ this.emit("device radar motion detected", device, state);
2413
+ }
2414
+ onDevice911Alarm(device, state, detail) {
2415
+ this.emit("device 911 alarm", device, state, detail);
2416
+ }
2417
+ onDeviceShakeAlarm(device, state, detail) {
2418
+ this.emit("device shake alarm", device, state, detail);
2419
+ }
2420
+ onDeviceWrongTryProtectAlarm(device, state) {
2421
+ this.emit("device wrong try-protect alarm", device, state);
2422
+ }
2423
+ onDeviceLongTimeNotClose(device, state) {
2424
+ this.emit("device long time not close", device, state);
2425
+ }
2426
+ onDeviceLowBattery(device, state) {
2427
+ this.emit("device low battery", device, state);
2428
+ }
2429
+ onDeviceJammed(device, state) {
2430
+ this.emit("device jammed", device, state);
2431
+ }
2432
+ onDeviceStrangerPersonDetected(device, state) {
2433
+ this.emit("device stranger person detected", device, state);
2434
+ }
2435
+ onDeviceDogDetected(device, state) {
2436
+ this.emit("device dog detected", device, state);
2437
+ }
2438
+ onDeviceDogLickDetected(device, state) {
2439
+ this.emit("device dog lick detected", device, state);
2440
+ }
2441
+ onDeviceDogPoopDetected(device, state) {
2442
+ this.emit("device dog poop detected", device, state);
2443
+ }
2444
+ onDeviceReady(device) {
2445
+ try {
2446
+ if (device.getPropertyValue(types_1.PropertyName.DeviceRTSPStream) !== undefined &&
2447
+ device.getPropertyValue(types_1.PropertyName.DeviceRTSPStream) === true) {
2448
+ this.getStation(device.getStationSerial())
2449
+ .then((station) => {
2450
+ station.setRTSPStream(device, true);
2451
+ })
2452
+ .catch((err) => {
2453
+ const error = (0, error_1.ensureError)(err);
2454
+ logging_1.rootMainLogger.error(`Device ready error - station enable rtsp`, {
2455
+ error: (0, utils_1.getError)(error),
2456
+ deviceSN: device.getSerial(),
2457
+ stationSN: device.getStationSerial(),
2458
+ });
2459
+ });
2460
+ }
2461
+ }
2462
+ catch (err) {
2463
+ const error = (0, error_1.ensureError)(err);
2464
+ logging_1.rootMainLogger.error(`Device ready error`, {
2465
+ error: (0, utils_1.getError)(error),
2466
+ deviceSN: device.getSerial(),
2467
+ stationSN: device.getStationSerial(),
2468
+ });
2469
+ }
2470
+ }
2471
+ onStationRuntimeState(station, channel, batteryLevel, temperature) {
2472
+ this.getStationDevice(station.getSerial(), channel)
2473
+ .then((device) => {
2474
+ if (device.hasProperty(types_1.PropertyName.DeviceBattery)) {
2475
+ const metadataBattery = device.getPropertyMetadata(types_1.PropertyName.DeviceBattery);
2476
+ device.updateRawProperty(metadataBattery.key, batteryLevel.toString(), "p2p");
2477
+ }
2478
+ if (device.hasProperty(types_1.PropertyName.DeviceBatteryTemp)) {
2479
+ const metadataBatteryTemperature = device.getPropertyMetadata(types_1.PropertyName.DeviceBatteryTemp);
2480
+ device.updateRawProperty(metadataBatteryTemperature.key, temperature.toString(), "p2p");
2481
+ }
2482
+ })
2483
+ .catch((err) => {
2484
+ const error = (0, error_1.ensureError)(err);
2485
+ logging_1.rootMainLogger.error(`Station runtime state error`, {
2486
+ error: (0, utils_1.getError)(error),
2487
+ stationSN: station.getSerial(),
2488
+ channel: channel,
2489
+ batteryLevel: batteryLevel,
2490
+ temperature: temperature,
2491
+ });
2492
+ });
2493
+ }
2494
+ onStationChargingState(station, channel, chargeType, batteryLevel) {
2495
+ this.getStationDevice(station.getSerial(), channel)
2496
+ .then((device) => {
2497
+ if (device.hasProperty(types_1.PropertyName.DeviceBattery)) {
2498
+ const metadataBattery = device.getPropertyMetadata(types_1.PropertyName.DeviceBattery);
2499
+ if ((0, utils_3.isCharging)(chargeType) && batteryLevel > 0)
2500
+ device.updateRawProperty(metadataBattery.key, batteryLevel.toString(), "p2p");
2501
+ }
2502
+ if (device.hasProperty(types_1.PropertyName.DeviceChargingStatus)) {
2503
+ const metadataChargingStatus = device.getPropertyMetadata(types_1.PropertyName.DeviceChargingStatus);
2504
+ device.updateRawProperty(metadataChargingStatus.key, chargeType.toString(), "p2p");
2505
+ }
2506
+ })
2507
+ .catch((err) => {
2508
+ const error = (0, error_1.ensureError)(err);
2509
+ logging_1.rootMainLogger.error(`Station charging state error`, {
2510
+ error: (0, utils_1.getError)(error),
2511
+ stationSN: station.getSerial(),
2512
+ channel: channel,
2513
+ chargeType: chargeType,
2514
+ charging: (0, utils_3.isCharging)(chargeType),
2515
+ batteryLevel: batteryLevel,
2516
+ });
2517
+ });
2518
+ }
2519
+ onStationWifiRssi(station, channel, rssi) {
2520
+ this.getStationDevice(station.getSerial(), channel)
2521
+ .then((device) => {
2522
+ if (device.hasProperty(types_1.PropertyName.DeviceWifiRSSI)) {
2523
+ const metadataWifiRssi = device.getPropertyMetadata(types_1.PropertyName.DeviceWifiRSSI);
2524
+ device.updateRawProperty(metadataWifiRssi.key, rssi.toString(), "p2p");
2525
+ }
2526
+ })
2527
+ .catch((err) => {
2528
+ const error = (0, error_1.ensureError)(err);
2529
+ logging_1.rootMainLogger.error(`Station wifi rssi error`, {
2530
+ error: (0, utils_1.getError)(error),
2531
+ stationSN: station.getSerial(),
2532
+ channel: channel,
2533
+ rssi: rssi,
2534
+ });
2535
+ });
2536
+ }
2537
+ onCaptchaRequest(id, captcha) {
2538
+ this.emit("captcha request", id, captcha);
2539
+ }
2540
+ onFloodlightManualSwitch(station, channel, enabled) {
2541
+ this.getStationDevice(station.getSerial(), channel)
2542
+ .then((device) => {
2543
+ if (device.hasProperty(types_1.PropertyName.DeviceLight)) {
2544
+ const metadataLight = device.getPropertyMetadata(types_1.PropertyName.DeviceLight);
2545
+ device.updateRawProperty(metadataLight.key, enabled ? "1" : "0", "p2p");
2546
+ }
2547
+ })
2548
+ .catch((err) => {
2549
+ const error = (0, error_1.ensureError)(err);
2550
+ logging_1.rootMainLogger.error(`Station floodlight manual switch error`, {
2551
+ error: (0, utils_1.getError)(error),
2552
+ stationSN: station.getSerial(),
2553
+ channel: channel,
2554
+ enabled: enabled,
2555
+ });
2556
+ });
2557
+ }
2558
+ onAuthTokenInvalidated() {
2559
+ this.persistentData.cloud_token = undefined;
2560
+ this.persistentData.cloud_token_expiration = undefined;
2561
+ this.writePersistentData();
2562
+ }
2563
+ onTfaRequest() {
2564
+ this.emit("tfa request");
2565
+ }
2566
+ onStationTalkbackStart(station, channel, talkbackStream) {
2567
+ this.getStationDevice(station.getSerial(), channel)
2568
+ .then((device) => {
2569
+ this.emit("station talkback start", station, device, talkbackStream);
2570
+ })
2571
+ .catch((err) => {
2572
+ const error = (0, error_1.ensureError)(err);
2573
+ logging_1.rootMainLogger.error(`Station talkback start error`, {
2574
+ error: (0, utils_1.getError)(error),
2575
+ stationSN: station.getSerial(),
2576
+ channel: channel,
2577
+ });
2578
+ });
2579
+ }
2580
+ onStationTalkbackStop(station, channel) {
2581
+ this.getStationDevice(station.getSerial(), channel)
2582
+ .then((device) => {
2583
+ this.emit("station talkback stop", station, device);
2584
+ })
2585
+ .catch((err) => {
2586
+ const error = (0, error_1.ensureError)(err);
2587
+ logging_1.rootMainLogger.error(`Station talkback stop error`, {
2588
+ error: (0, utils_1.getError)(error),
2589
+ stationSN: station.getSerial(),
2590
+ channel: channel,
2591
+ });
2592
+ });
2593
+ }
2594
+ onStationTalkbackError(station, channel, origError) {
2595
+ this.getStationDevice(station.getSerial(), channel)
2596
+ .then((device) => {
2597
+ station.stopTalkback(device);
2598
+ })
2599
+ .catch((err) => {
2600
+ const error = (0, error_1.ensureError)(err);
2601
+ logging_1.rootMainLogger.error(`Station talkback error`, {
2602
+ error: (0, utils_1.getError)(error),
2603
+ stationSN: station.getSerial(),
2604
+ channel: channel,
2605
+ origError: (0, utils_1.getError)(origError),
2606
+ });
2607
+ });
2608
+ }
2609
+ async startStationTalkback(deviceSN) {
2610
+ const device = await this.getDevice(deviceSN);
2611
+ const station = await this.getStation(device.getStationSerial());
2612
+ if (!device.hasCommand(types_1.CommandName.DeviceStartTalkback))
2613
+ throw new error_1.NotSupportedError("This functionality is not implemented or supported by this device", {
2614
+ context: { device: deviceSN, commandName: types_1.CommandName.DeviceStartTalkback },
2615
+ });
2616
+ if (station.isLiveStreaming(device)) {
2617
+ if (!station.isTalkbackOngoing(device)) {
2618
+ station.startTalkback(device);
2619
+ }
2620
+ else {
2621
+ logging_1.rootMainLogger.warn(`The station talkback for the device ${deviceSN} cannot be started, because it is ongoing!`);
2622
+ }
2623
+ }
2624
+ else {
2625
+ logging_1.rootMainLogger.warn(`The station talkback for the device ${deviceSN} cannot be started, because it isn't live streaming!`);
2626
+ }
2627
+ }
2628
+ async stopStationTalkback(deviceSN) {
2629
+ const device = await this.getDevice(deviceSN);
2630
+ const station = await this.getStation(device.getStationSerial());
2631
+ if (!device.hasCommand(types_1.CommandName.DeviceStopTalkback))
2632
+ throw new error_1.NotSupportedError("This functionality is not implemented or supported by this device", {
2633
+ context: { device: deviceSN, commandName: types_1.CommandName.DeviceStopTalkback },
2634
+ });
2635
+ if (station.isLiveStreaming(device)) {
2636
+ if (station.isTalkbackOngoing(device)) {
2637
+ station.stopTalkback(device);
2638
+ }
2639
+ else {
2640
+ logging_1.rootMainLogger.warn(`The station talkback for the device ${deviceSN} cannot be stopped, because it isn't ongoing!`);
2641
+ }
2642
+ }
2643
+ else {
2644
+ logging_1.rootMainLogger.warn(`The station talkback for the device ${deviceSN} cannot be stopped, because it isn't live streaming!`);
2645
+ }
2646
+ }
2647
+ onStationDeviceShakeAlarm(deviceSN, event) {
2648
+ this.getDevice(deviceSN)
2649
+ .then((device) => {
2650
+ if (device.isSmartSafe())
2651
+ device.shakeEvent(event, this.config.eventDurationSeconds);
2652
+ })
2653
+ .catch((err) => {
2654
+ const error = (0, error_1.ensureError)(err);
2655
+ logging_1.rootMainLogger.error(`onStationDeviceShakeAlarm error`, {
2656
+ error: (0, utils_1.getError)(error),
2657
+ deviceSN: deviceSN,
2658
+ event: types_2.SmartSafeShakeAlarmEvent[event],
2659
+ });
2660
+ });
2661
+ }
2662
+ onStationDevice911Alarm(deviceSN, event) {
2663
+ this.getDevice(deviceSN)
2664
+ .then((device) => {
2665
+ if (device.isSmartSafe())
2666
+ device.alarm911Event(event, this.config.eventDurationSeconds);
2667
+ })
2668
+ .catch((err) => {
2669
+ const error = (0, error_1.ensureError)(err);
2670
+ logging_1.rootMainLogger.error(`onStationDevice911Alarm error`, {
2671
+ error: (0, utils_1.getError)(error),
2672
+ deviceSN: deviceSN,
2673
+ event: types_2.SmartSafeAlarm911Event[event],
2674
+ });
2675
+ });
2676
+ }
2677
+ onStationDeviceJammed(deviceSN) {
2678
+ this.getDevice(deviceSN)
2679
+ .then((device) => {
2680
+ if (device.isSmartSafe())
2681
+ device.jammedEvent(this.config.eventDurationSeconds);
2682
+ })
2683
+ .catch((err) => {
2684
+ const error = (0, error_1.ensureError)(err);
2685
+ logging_1.rootMainLogger.error(`onStationDeviceJammed error`, { error: (0, utils_1.getError)(error), deviceSN: deviceSN });
2686
+ });
2687
+ }
2688
+ onStationDeviceLowBattery(deviceSN) {
2689
+ this.getDevice(deviceSN)
2690
+ .then((device) => {
2691
+ if (device.isSmartSafe())
2692
+ device.lowBatteryEvent(this.config.eventDurationSeconds);
2693
+ })
2694
+ .catch((err) => {
2695
+ const error = (0, error_1.ensureError)(err);
2696
+ logging_1.rootMainLogger.error(`onStationDeviceLowBattery error`, { error: (0, utils_1.getError)(error), deviceSN: deviceSN });
2697
+ });
2698
+ }
2699
+ onStationDeviceWrongTryProtectAlarm(deviceSN) {
2700
+ this.getDevice(deviceSN)
2701
+ .then((device) => {
2702
+ if (device.isSmartSafe())
2703
+ device.wrongTryProtectAlarmEvent(this.config.eventDurationSeconds);
2704
+ })
2705
+ .catch((err) => {
2706
+ const error = (0, error_1.ensureError)(err);
2707
+ logging_1.rootMainLogger.error(`onStationDeviceWrongTryProtectAlarm error`, {
2708
+ error: (0, utils_1.getError)(error),
2709
+ deviceSN: deviceSN,
2710
+ });
2711
+ });
2712
+ }
2713
+ async addUser(deviceSN, username, passcode, schedule) {
2714
+ const device = await this.getDevice(deviceSN);
2715
+ const station = await this.getStation(device.getStationSerial());
2716
+ try {
2717
+ if (!device.hasCommand(types_1.CommandName.DeviceAddUser))
2718
+ throw new error_1.NotSupportedError("This functionality is not implemented or supported by this device", {
2719
+ context: {
2720
+ device: deviceSN,
2721
+ commandName: types_1.CommandName.DeviceAddUser,
2722
+ username: username,
2723
+ passcode: "[redacted]",
2724
+ schedule: schedule,
2725
+ },
2726
+ });
2727
+ const addUserResponse = await this.api.addUser(deviceSN, username, device.getStationSerial());
2728
+ if (addUserResponse !== null) {
2729
+ station.addUser(device, username, addUserResponse.short_user_id, passcode, schedule);
2730
+ }
2731
+ else {
2732
+ this.emit("user error", device, username, new error_1.AddUserError("Error on creating user through cloud api call", {
2733
+ context: { deivce: deviceSN, username: username, passcode: "[redacted]", schedule: schedule },
2734
+ }));
2735
+ }
2736
+ }
2737
+ catch (err) {
2738
+ const error = (0, error_1.ensureError)(err);
2739
+ logging_1.rootMainLogger.error(`addUser error`, {
2740
+ error: (0, utils_1.getError)(error),
2741
+ deviceSN: deviceSN,
2742
+ username: username,
2743
+ schedule: schedule,
2744
+ });
2745
+ this.emit("user error", device, username, new error_1.AddUserError("Generic error", {
2746
+ cause: error,
2747
+ context: { device: deviceSN, username: username, passcode: "[redacted]", schedule: schedule },
2748
+ }));
2749
+ }
2750
+ }
2751
+ async deleteUser(deviceSN, username) {
2752
+ const device = await this.getDevice(deviceSN);
2753
+ const station = await this.getStation(device.getStationSerial());
2754
+ if (!device.hasCommand(types_1.CommandName.DeviceDeleteUser))
2755
+ throw new error_1.NotSupportedError("This functionality is not implemented or supported by this device", {
2756
+ context: { device: deviceSN, commandName: types_1.CommandName.DeviceDeleteUser, username: username },
2757
+ });
2758
+ try {
2759
+ const users = await this.api.getUsers(deviceSN, device.getStationSerial());
2760
+ if (users !== null) {
2761
+ let found = false;
2762
+ for (const user of users) {
2763
+ if (user.user_name === username) {
2764
+ station.deleteUser(device, user.user_name, user.short_user_id);
2765
+ found = true;
2766
+ break;
2767
+ }
2768
+ }
2769
+ if (!found) {
2770
+ this.emit("user error", device, username, new error_1.DeleteUserError("User not found", { context: { device: deviceSN, username: username } }));
2771
+ }
2772
+ }
2773
+ else {
2774
+ this.emit("user error", device, username, new error_1.DeleteUserError("Error on getting user list through cloud api call", {
2775
+ context: { device: deviceSN, username: username },
2776
+ }));
2777
+ }
2778
+ }
2779
+ catch (err) {
2780
+ const error = (0, error_1.ensureError)(err);
2781
+ logging_1.rootMainLogger.error(`deleteUser error`, { error: (0, utils_1.getError)(error), deviceSN: deviceSN, username: username });
2782
+ this.emit("user error", device, username, new error_1.DeleteUserError("Generic error", { cause: error, context: { device: deviceSN, username: username } }));
2783
+ }
2784
+ }
2785
+ async updateUser(deviceSN, username, newUsername) {
2786
+ const device = await this.getDevice(deviceSN);
2787
+ const station = await this.getStation(device.getStationSerial());
2788
+ if (!device.hasCommand(types_1.CommandName.DeviceUpdateUsername))
2789
+ throw new error_1.NotSupportedError("This functionality is not implemented or supported by this device", {
2790
+ context: {
2791
+ device: deviceSN,
2792
+ commandName: types_1.CommandName.DeviceUpdateUsername,
2793
+ usernmae: username,
2794
+ newUsername: newUsername,
2795
+ },
2796
+ });
2797
+ try {
2798
+ const users = await this.api.getUsers(deviceSN, device.getStationSerial());
2799
+ if (users !== null) {
2800
+ let found = false;
2801
+ for (const user of users) {
2802
+ if (user.user_name === username) {
2803
+ if ((device.isLockWifiT8506() ||
2804
+ device.isLockWifiT8502() ||
2805
+ device.isLockWifiT8510P() ||
2806
+ device.isLockWifiT8520P() ||
2807
+ device.isLockWifiT8531() ||
2808
+ device.isLockWifiT85L0()) &&
2809
+ user.password_list.length > 0) {
2810
+ for (const entry of user.password_list) {
2811
+ if (entry.password_type === types_1.UserPasswordType.PIN) {
2812
+ let schedule = entry.schedule;
2813
+ if (schedule !== undefined && typeof schedule == "string") {
2814
+ schedule = JSON.parse(schedule);
2815
+ }
2816
+ if (schedule !== undefined &&
2817
+ schedule.endDay !== undefined &&
2818
+ schedule.endTime !== undefined &&
2819
+ schedule.startDay !== undefined &&
2820
+ schedule.startTime !== undefined &&
2821
+ schedule.week !== undefined) {
2822
+ station.updateUserSchedule(device, newUsername, user.short_user_id, (0, utils_2.hexStringScheduleToSchedule)(schedule.startDay, schedule.startTime, schedule.endDay, schedule.endTime, schedule.week));
2823
+ }
2824
+ }
2825
+ }
2826
+ }
2827
+ else if (device.isLockWifiR10() || device.isLockWifiR20()) {
2828
+ for (const entry of user.password_list) {
2829
+ if (entry.password_type === types_1.UserPasswordType.PIN) {
2830
+ station.updateUsername(device, newUsername, entry.password_id);
2831
+ }
2832
+ }
2833
+ }
2834
+ const result = await this.api.updateUser(deviceSN, device.getStationSerial(), user.short_user_id, newUsername);
2835
+ if (result) {
2836
+ this.emit("user username updated", device, username);
2837
+ }
2838
+ else {
2839
+ this.emit("user error", device, username, new error_1.UpdateUserUsernameError("Error in changing username through cloud api call", {
2840
+ context: { device: deviceSN, username: username, newUsername: newUsername },
2841
+ }));
2842
+ }
2843
+ found = true;
2844
+ break;
2845
+ }
2846
+ }
2847
+ if (!found) {
2848
+ this.emit("user error", device, username, new error_1.UpdateUserUsernameError("User not found", {
2849
+ context: { device: deviceSN, username: username, newUsername: newUsername },
2850
+ }));
2851
+ }
2852
+ }
2853
+ else {
2854
+ this.emit("user error", device, username, new error_1.UpdateUserUsernameError("Error on getting user list through cloud api call", {
2855
+ context: { device: deviceSN, username: username, newUsername: newUsername },
2856
+ }));
2857
+ }
2858
+ }
2859
+ catch (err) {
2860
+ const error = (0, error_1.ensureError)(err);
2861
+ logging_1.rootMainLogger.error(`updateUser error`, {
2862
+ error: (0, utils_1.getError)(error),
2863
+ deviceSN: deviceSN,
2864
+ username: username,
2865
+ newUsername: newUsername,
2866
+ });
2867
+ this.emit("user error", device, username, new error_1.UpdateUserUsernameError("Generic error", {
2868
+ cause: error,
2869
+ context: { device: deviceSN, username: username, newUsername: newUsername },
2870
+ }));
2871
+ }
2872
+ }
2873
+ async updateUserPasscode(deviceSN, username, passcode) {
2874
+ const device = await this.getDevice(deviceSN);
2875
+ const station = await this.getStation(device.getStationSerial());
2876
+ if (!device.hasCommand(types_1.CommandName.DeviceUpdateUserPasscode))
2877
+ throw new error_1.NotSupportedError("This functionality is not implemented or supported by this device", {
2878
+ context: {
2879
+ device: deviceSN,
2880
+ commandName: types_1.CommandName.DeviceUpdateUserPasscode,
2881
+ username: username,
2882
+ passcode: "[redacted]",
2883
+ },
2884
+ });
2885
+ try {
2886
+ const users = await this.api.getUsers(deviceSN, device.getStationSerial());
2887
+ if (users !== null) {
2888
+ let found = false;
2889
+ for (const user of users) {
2890
+ if (user.user_name === username) {
2891
+ for (const entry of user.password_list) {
2892
+ if (entry.password_type === types_1.UserPasswordType.PIN) {
2893
+ station.updateUserPasscode(device, user.user_name, entry.password_id, passcode);
2894
+ found = true;
2895
+ }
2896
+ }
2897
+ }
2898
+ }
2899
+ if (!found) {
2900
+ this.emit("user error", device, username, new error_1.UpdateUserPasscodeError("User not found", {
2901
+ context: { device: deviceSN, username: username, passcode: "[redacted]" },
2902
+ }));
2903
+ }
2904
+ }
2905
+ else {
2906
+ this.emit("user error", device, username, new error_1.UpdateUserPasscodeError("Error on getting user list through cloud api call", {
2907
+ context: { device: deviceSN, username: username, passcode: "[redacted]" },
2908
+ }));
2909
+ }
2910
+ }
2911
+ catch (err) {
2912
+ const error = (0, error_1.ensureError)(err);
2913
+ logging_1.rootMainLogger.error(`updateUserPasscode error`, {
2914
+ error: (0, utils_1.getError)(error),
2915
+ deviceSN: deviceSN,
2916
+ username: username,
2917
+ });
2918
+ this.emit("user error", device, username, new error_1.UpdateUserPasscodeError("Generic error", {
2919
+ cause: error,
2920
+ context: { device: deviceSN, username: username, passcode: "[redacted]" },
2921
+ }));
2922
+ }
2923
+ }
2924
+ async updateUserSchedule(deviceSN, username, schedule) {
2925
+ const device = await this.getDevice(deviceSN);
2926
+ const station = await this.getStation(device.getStationSerial());
2927
+ if (!device.hasCommand(types_1.CommandName.DeviceUpdateUserSchedule))
2928
+ throw new error_1.NotSupportedError("This functionality is not implemented or supported by this device", {
2929
+ context: {
2930
+ device: deviceSN,
2931
+ commandName: types_1.CommandName.DeviceUpdateUserSchedule,
2932
+ usernmae: username,
2933
+ schedule: schedule,
2934
+ },
2935
+ });
2936
+ try {
2937
+ const users = await this.api.getUsers(deviceSN, device.getStationSerial());
2938
+ if (users !== null) {
2939
+ let found = false;
2940
+ for (const user of users) {
2941
+ if (user.user_name === username) {
2942
+ station.updateUserSchedule(device, user.user_name, user.short_user_id, schedule);
2943
+ found = true;
2944
+ }
2945
+ }
2946
+ if (!found) {
2947
+ this.emit("user error", device, username, new error_1.UpdateUserScheduleError("User not found", {
2948
+ context: { device: deviceSN, username: username, schedule: schedule },
2949
+ }));
2950
+ }
2951
+ }
2952
+ else {
2953
+ this.emit("user error", device, username, new error_1.UpdateUserScheduleError("Error on getting user list through cloud api call", {
2954
+ context: { device: deviceSN, username: username, schedule: schedule },
2955
+ }));
2956
+ }
2957
+ }
2958
+ catch (err) {
2959
+ const error = (0, error_1.ensureError)(err);
2960
+ logging_1.rootMainLogger.error(`updateUserSchedule error`, {
2961
+ error: (0, utils_1.getError)(error),
2962
+ deviceSN: deviceSN,
2963
+ username: username,
2964
+ schedule: schedule,
2965
+ });
2966
+ this.emit("user error", device, username, new error_1.UpdateUserScheduleError("Generic error", {
2967
+ cause: error,
2968
+ context: { device: deviceSN, username: username, schedule: schedule },
2969
+ }));
2970
+ }
2971
+ }
2972
+ onStationDevicePinVerified(deviceSN, successfull) {
2973
+ this.getDevice(deviceSN)
2974
+ .then((device) => {
2975
+ this.emit("device pin verified", device, successfull);
2976
+ })
2977
+ .catch((err) => {
2978
+ const error = (0, error_1.ensureError)(err);
2979
+ logging_1.rootMainLogger.error(`onStationDevicePinVerified error`, {
2980
+ error: (0, utils_1.getError)(error),
2981
+ deviceSN: deviceSN,
2982
+ successfull: successfull,
2983
+ });
2984
+ });
2985
+ }
2986
+ onStationSdInfoEx(station, sdStatus, sdCapacity, sdCapacityAvailable) {
2987
+ if (station.hasProperty(types_1.PropertyName.StationSdStatus)) {
2988
+ station.updateProperty(types_1.PropertyName.StationSdStatus, sdStatus);
2989
+ }
2990
+ if (station.hasProperty(types_1.PropertyName.StationSdCapacity)) {
2991
+ station.updateProperty(types_1.PropertyName.StationSdCapacity, sdCapacity);
2992
+ }
2993
+ if (station.hasProperty(types_1.PropertyName.StationSdCapacityAvailable)) {
2994
+ station.updateProperty(types_1.PropertyName.StationSdCapacityAvailable, sdCapacityAvailable);
2995
+ }
2996
+ }
2997
+ _emitStationImageDownload(station, file, picture) {
2998
+ this.emit("station image download", station, file, picture);
2999
+ this.getDevicesFromStation(station.getSerial())
3000
+ .then((devices) => {
3001
+ for (const device of devices) {
3002
+ if (device.getPropertyValue(types_1.PropertyName.DevicePictureUrl) === file) {
3003
+ logging_1.rootMainLogger.debug(`onStationImageDownload - Set picture for device ${device.getSerial()} file: ${file} picture_ext: ${picture.type.ext} picture_mime: ${picture.type.mime}`);
3004
+ device.updateProperty(types_1.PropertyName.DevicePicture, picture);
3005
+ break;
3006
+ }
3007
+ }
3008
+ })
3009
+ .catch((err) => {
3010
+ const error = (0, error_1.ensureError)(err);
3011
+ logging_1.rootMainLogger.error(`onStationImageDownload - Set picture error`, {
3012
+ error: (0, utils_1.getError)(error),
3013
+ stationSN: station.getSerial(),
3014
+ file: file,
3015
+ });
3016
+ });
3017
+ }
3018
+ onStationImageDownload(station, file, image) {
3019
+ import("image-type")
3020
+ .then(({ default: imageType }) => {
3021
+ imageType(image)
3022
+ .then((type) => {
3023
+ const picture = {
3024
+ data: image,
3025
+ type: type !== null && type !== undefined ? type : { ext: "unknown", mime: "application/octet-stream" },
3026
+ };
3027
+ this._emitStationImageDownload(station, file, picture);
3028
+ })
3029
+ .catch(() => {
3030
+ this._emitStationImageDownload(station, file, {
3031
+ data: image,
3032
+ type: { ext: "unknown", mime: "application/octet-stream" },
3033
+ });
3034
+ });
3035
+ })
3036
+ .catch(() => {
3037
+ this._emitStationImageDownload(station, file, {
3038
+ data: image,
3039
+ type: { ext: "unknown", mime: "application/octet-stream" },
3040
+ });
3041
+ });
3042
+ }
3043
+ onStationDatabaseQueryLatest(station, returnCode, data) {
3044
+ if (returnCode === types_2.DatabaseReturnCode.SUCCESSFUL) {
3045
+ for (const element of data) {
3046
+ if ((element.device_sn !== "" && !station.isStation()) ||
3047
+ (station.isStation() && element.device_sn !== station.getSerial())) {
3048
+ this.getDevice(element.device_sn)
3049
+ .then((device) => {
3050
+ const raw = device.getRawDevice();
3051
+ if ("crop_local_path" in element) {
3052
+ raw.cover_path = element.crop_local_path;
3053
+ }
3054
+ else if ("crop_cloud_path" in element) {
3055
+ raw.cover_path = element.crop_cloud_path;
3056
+ }
3057
+ device.update(raw);
3058
+ })
3059
+ .catch((err) => {
3060
+ const error = (0, error_1.ensureError)(err);
3061
+ if (!(error instanceof error_1.DeviceNotFoundError)) {
3062
+ logging_1.rootMainLogger.error("onStationDatabaseQueryLatest Error", {
3063
+ error: (0, utils_1.getError)(error),
3064
+ stationSN: station.getSerial(),
3065
+ returnCode: returnCode,
3066
+ });
3067
+ }
3068
+ });
3069
+ }
3070
+ }
3071
+ }
3072
+ this.emit("station database query latest", station, returnCode, data);
3073
+ }
3074
+ onStationDatabaseQueryLocal(station, returnCode, data) {
3075
+ this.emit("station database query local", station, returnCode, data);
3076
+ }
3077
+ onStationDatabaseQueryByDate(station, returnCode, data) {
3078
+ this.emit("station database query by date", station, returnCode, data);
3079
+ }
3080
+ onStationDatabaseCountByDate(station, returnCode, data) {
3081
+ this.emit("station database count by date", station, returnCode, data);
3082
+ }
3083
+ onStationDatabaseDelete(station, returnCode, failedIds) {
3084
+ this.emit("station database delete", station, returnCode, failedIds);
3085
+ }
3086
+ onStationSensorStatus(station, channel, status) {
3087
+ this.getStationDevice(station.getSerial(), channel)
3088
+ .then((device) => {
3089
+ if (device.hasProperty(types_1.PropertyName.DeviceSensorOpen)) {
3090
+ const metadataSensorOpen = device.getPropertyMetadata(types_1.PropertyName.DeviceSensorOpen);
3091
+ device.updateRawProperty(metadataSensorOpen.key, status.toString(), "p2p");
3092
+ }
3093
+ })
3094
+ .catch((err) => {
3095
+ const error = (0, error_1.ensureError)(err);
3096
+ logging_1.rootMainLogger.error(`Station sensor status error`, {
3097
+ error: (0, utils_1.getError)(error),
3098
+ stationSN: station.getSerial(),
3099
+ channel: channel,
3100
+ });
3101
+ });
3102
+ }
3103
+ onStationGarageDoorStatus(station, channel, doorId, status) {
3104
+ this.getStationDevice(station.getSerial(), channel)
3105
+ .then((device) => {
3106
+ device.updateRawProperty(types_2.CommandType.CMD_CAMERA_GARAGE_DOOR_STATUS, status.toString(), "p2p");
3107
+ })
3108
+ .catch((err) => {
3109
+ const error = (0, error_1.ensureError)(err);
3110
+ logging_1.rootMainLogger.error(`Station garage door status error`, {
3111
+ error: (0, utils_1.getError)(error),
3112
+ stationSN: station.getSerial(),
3113
+ channel: channel,
3114
+ });
3115
+ });
3116
+ }
3117
+ onStorageInfoHb3(station, channel, storageInfo) {
3118
+ if (station.hasProperty(types_1.PropertyName.StationStorageInfoEmmc)) {
3119
+ station.updateProperty(types_1.PropertyName.StationStorageInfoEmmc, storageInfo.emmc_info);
3120
+ }
3121
+ if (station.hasProperty(types_1.PropertyName.StationStorageInfoHdd)) {
3122
+ station.updateProperty(types_1.PropertyName.StationStorageInfoHdd, storageInfo.hdd_info);
3123
+ }
3124
+ if (storageInfo.sd_card_info !== undefined && station.hasProperty(types_1.PropertyName.StationStorageInfoSdCard)) {
3125
+ station.updateProperty(types_1.PropertyName.StationStorageInfoSdCard, storageInfo.sd_card_info);
3126
+ }
3127
+ }
3128
+ onDeviceTampering(device, state) {
3129
+ this.emit("device tampering", device, state);
3130
+ }
3131
+ onDeviceLowTemperature(device, state) {
3132
+ this.emit("device low temperature", device, state);
3133
+ }
3134
+ onDeviceHighTemperature(device, state) {
3135
+ this.emit("device high temperature", device, state);
3136
+ }
3137
+ onDevicePinIncorrect(device, state) {
3138
+ this.emit("device pin incorrect", device, state);
3139
+ }
3140
+ onDeviceLidStuck(device, state) {
3141
+ this.emit("device lid stuck", device, state);
3142
+ }
3143
+ onDeviceBatteryFullyCharged(device, state) {
3144
+ this.emit("device battery fully charged", device, state);
3145
+ }
3146
+ }
3147
+ exports.EufySecurity = EufySecurity;
3148
+ //# sourceMappingURL=eufysecurity.js.map