@ray-js/lock-sdk 1.0.0-beta-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/index.d.ts +5 -0
- package/lib/api/index.js +18 -0
- package/lib/api/linkage.d.ts +161 -0
- package/lib/api/linkage.js +74 -0
- package/lib/api/lock.d.ts +195 -0
- package/lib/api/lock.js +129 -0
- package/lib/api/log.d.ts +166 -0
- package/lib/api/log.js +44 -0
- package/lib/api/setting.d.ts +14 -0
- package/lib/api/setting.js +36 -0
- package/lib/api/temp.d.ts +211 -0
- package/lib/api/temp.js +130 -0
- package/lib/api/user.d.ts +154 -0
- package/lib/api/user.js +59 -0
- package/lib/api/video.d.ts +9 -0
- package/lib/api/video.js +17 -0
- package/lib/config/dp-code/index.d.ts +175 -0
- package/lib/config/dp-code/index.js +224 -0
- package/lib/config/dp-map/common.d.ts +102 -0
- package/lib/config/dp-map/common.js +120 -0
- package/lib/config/dp-map/normal.d.ts +6 -0
- package/lib/config/dp-map/normal.js +51 -0
- package/lib/config/dp-map/open.d.ts +21 -0
- package/lib/config/dp-map/open.js +62 -0
- package/lib/config/dp-map/unlock-method-big.d.ts +559 -0
- package/lib/config/dp-map/unlock-method-big.js +237 -0
- package/lib/config/dp-map/unlock-method.d.ts +551 -0
- package/lib/config/dp-map/unlock-method.js +231 -0
- package/lib/config/index.d.ts +46 -0
- package/lib/config/index.js +56 -0
- package/lib/constant.d.ts +101 -0
- package/lib/constant.js +136 -0
- package/lib/dp-interface.d.ts +7 -0
- package/lib/dp-interface.js +1 -0
- package/lib/event.d.ts +8 -0
- package/lib/event.js +9 -0
- package/lib/index.d.ts +25 -0
- package/lib/index.js +92 -0
- package/lib/interface.d.ts +807 -0
- package/lib/interface.js +1 -0
- package/lib/linkage.d.ts +26 -0
- package/lib/linkage.js +175 -0
- package/lib/log.d.ts +91 -0
- package/lib/log.js +314 -0
- package/lib/media.d.ts +43 -0
- package/lib/media.js +80 -0
- package/lib/open.d.ts +48 -0
- package/lib/open.js +247 -0
- package/lib/other.d.ts +36 -0
- package/lib/other.js +178 -0
- package/lib/parse/index.d.ts +6 -0
- package/lib/parse/index.js +22 -0
- package/lib/signal.d.ts +26 -0
- package/lib/signal.js +38 -0
- package/lib/sleep.d.ts +61 -0
- package/lib/sleep.js +121 -0
- package/lib/state.d.ts +54 -0
- package/lib/state.js +429 -0
- package/lib/sync/remote-serect-key.d.ts +5 -0
- package/lib/sync/remote-serect-key.js +60 -0
- package/lib/sync/t0.d.ts +5 -0
- package/lib/sync/t0.js +33 -0
- package/lib/sync/temp.d.ts +7 -0
- package/lib/sync/temp.js +88 -0
- package/lib/sync/unlock-mothod.d.ts +5 -0
- package/lib/sync/unlock-mothod.js +54 -0
- package/lib/temporary.d.ts +226 -0
- package/lib/temporary.js +637 -0
- package/lib/unlock-method.d.ts +269 -0
- package/lib/unlock-method.js +723 -0
- package/lib/user.d.ts +108 -0
- package/lib/user.js +361 -0
- package/lib/utils/base64-to-hex.d.ts +1 -0
- package/lib/utils/base64-to-hex.js +12 -0
- package/lib/utils/byte.d.ts +19 -0
- package/lib/utils/byte.js +74 -0
- package/lib/utils/constant.d.ts +11 -0
- package/lib/utils/constant.js +17 -0
- package/lib/utils/device.d.ts +207 -0
- package/lib/utils/device.js +353 -0
- package/lib/utils/errors.d.ts +2 -0
- package/lib/utils/errors.js +125 -0
- package/lib/utils/event.d.ts +23 -0
- package/lib/utils/event.js +144 -0
- package/lib/utils/hex-to-base64.d.ts +1 -0
- package/lib/utils/hex-to-base64.js +8 -0
- package/lib/utils/hex-to-bytes.d.ts +6 -0
- package/lib/utils/hex-to-bytes.js +16 -0
- package/lib/utils/index.d.ts +169 -0
- package/lib/utils/index.js +419 -0
- package/lib/utils/log.d.ts +5 -0
- package/lib/utils/log.js +78 -0
- package/lib/utils/publishDps.d.ts +11 -0
- package/lib/utils/publishDps.js +91 -0
- package/package.json +37 -0
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
2
|
+
import "core-js/modules/esnext.iterator.for-each.js";
|
|
3
|
+
import "core-js/modules/esnext.iterator.map.js";
|
|
4
|
+
import config from "../config";
|
|
5
|
+
import dpCodes from "../config/dp-code";
|
|
6
|
+
import { ProductCommunicationType } from "../constant";
|
|
7
|
+
import { LoopTypes } from "./constant";
|
|
8
|
+
import { getBackgroundFetchData, getCurrentHomeInfo, onBackgroundFetchData } from "./device";
|
|
9
|
+
import { getError } from "./errors";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 格式化为24时间格式
|
|
13
|
+
* @param time
|
|
14
|
+
* @returns
|
|
15
|
+
*/
|
|
16
|
+
export const get24Time = time => {
|
|
17
|
+
const hours = Math.floor(time / 60);
|
|
18
|
+
return [hours, time % 60];
|
|
19
|
+
};
|
|
20
|
+
export const getNowTime = () => {
|
|
21
|
+
const now = new Date();
|
|
22
|
+
return now.getHours() * 3600 + now.getMinutes() * 60 + now.getSeconds();
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 判断设备在线类型
|
|
27
|
+
* @param onlineType 设备的通道在线数据
|
|
28
|
+
* @param type 待检测的通道类型,0为wifi,1为局域网,2为蓝牙,3为Mesh, 4为 beacon
|
|
29
|
+
* @returns
|
|
30
|
+
*/
|
|
31
|
+
export const isOnlineByType = (onlineType, type) => {
|
|
32
|
+
// eslint-disable-next-line no-bitwise
|
|
33
|
+
return (onlineType & 2 ** type) >> type === 1;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// 遍历capability类型,通讯类型
|
|
37
|
+
const supportCapabilities = [{
|
|
38
|
+
id: 0,
|
|
39
|
+
name: "wifi",
|
|
40
|
+
short: "wf"
|
|
41
|
+
}, {
|
|
42
|
+
id: 1,
|
|
43
|
+
name: "cable",
|
|
44
|
+
short: "ca"
|
|
45
|
+
}, {
|
|
46
|
+
id: 2,
|
|
47
|
+
name: "gprs",
|
|
48
|
+
short: "gp"
|
|
49
|
+
}, {
|
|
50
|
+
id: 3,
|
|
51
|
+
name: "nb-iot",
|
|
52
|
+
short: "nb"
|
|
53
|
+
}, {
|
|
54
|
+
id: 10,
|
|
55
|
+
name: "bluetooth",
|
|
56
|
+
short: "ble"
|
|
57
|
+
}, {
|
|
58
|
+
id: 11,
|
|
59
|
+
name: "blemesh",
|
|
60
|
+
short: "bm"
|
|
61
|
+
}, {
|
|
62
|
+
id: 12,
|
|
63
|
+
name: "zigbee",
|
|
64
|
+
short: "zig"
|
|
65
|
+
}, {
|
|
66
|
+
id: 13,
|
|
67
|
+
name: "infrared",
|
|
68
|
+
short: "inf"
|
|
69
|
+
}, {
|
|
70
|
+
id: 14,
|
|
71
|
+
name: "subpieces",
|
|
72
|
+
short: "sub"
|
|
73
|
+
}, {
|
|
74
|
+
id: 15,
|
|
75
|
+
name: "sigmesh",
|
|
76
|
+
short: "sig"
|
|
77
|
+
}, {
|
|
78
|
+
id: 16,
|
|
79
|
+
name: "mcu",
|
|
80
|
+
short: "mcu"
|
|
81
|
+
}, {
|
|
82
|
+
id: 17,
|
|
83
|
+
name: "ty_smesh",
|
|
84
|
+
short: "TY_SMESH"
|
|
85
|
+
}, {
|
|
86
|
+
id: 18,
|
|
87
|
+
name: "Zwave",
|
|
88
|
+
short: "Zwave"
|
|
89
|
+
}, {
|
|
90
|
+
id: 19,
|
|
91
|
+
name: "pl-mesh",
|
|
92
|
+
short: "pl-mesh"
|
|
93
|
+
}, {
|
|
94
|
+
id: 20,
|
|
95
|
+
name: "cat1",
|
|
96
|
+
short: "cat1"
|
|
97
|
+
}, {
|
|
98
|
+
id: 21,
|
|
99
|
+
name: "beacon",
|
|
100
|
+
short: "beacon"
|
|
101
|
+
}, {
|
|
102
|
+
id: 22,
|
|
103
|
+
name: "cat4",
|
|
104
|
+
short: "cat4"
|
|
105
|
+
}, {
|
|
106
|
+
id: 23,
|
|
107
|
+
name: "cat10",
|
|
108
|
+
short: "cat10"
|
|
109
|
+
}, {
|
|
110
|
+
id: 24,
|
|
111
|
+
name: "lte-catm",
|
|
112
|
+
short: "catm"
|
|
113
|
+
}, {
|
|
114
|
+
id: 25,
|
|
115
|
+
name: "thread",
|
|
116
|
+
short: "thread"
|
|
117
|
+
}];
|
|
118
|
+
export function isCapability(capability, id) {
|
|
119
|
+
const redId = 1 << id;
|
|
120
|
+
return (capability & redId) === redId;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 获取产品支持的通讯能力
|
|
125
|
+
* @param capability 产品能力值
|
|
126
|
+
* @returns
|
|
127
|
+
*/
|
|
128
|
+
export function getCapabilities(capability) {
|
|
129
|
+
return supportCapabilities.filter(item => {
|
|
130
|
+
return isCapability(capability, item.id);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// 格式化周
|
|
135
|
+
export const formatWeek = value => {
|
|
136
|
+
return parseInt([...value].reverse().join(""), 2);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// 格式化周
|
|
140
|
+
export const parseWeek = value => {
|
|
141
|
+
return Number(value).toString(2).padStart(7, "0").split("").reverse().map(Number).slice(0, 7);
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* 获取一个永久生效的设置
|
|
146
|
+
* @returns
|
|
147
|
+
*/
|
|
148
|
+
export const getPermanentSetting = () => {
|
|
149
|
+
const now = Math.floor(+new Date() / 1000);
|
|
150
|
+
return {
|
|
151
|
+
startTime: now,
|
|
152
|
+
// 如果是永久生效,则设置为 100 年后失效
|
|
153
|
+
endTime: now + 3153600000,
|
|
154
|
+
loop: LoopTypes.NONE,
|
|
155
|
+
loopConfig: 0,
|
|
156
|
+
weeks: [0, 0, 0, 0, 0, 0, 0],
|
|
157
|
+
days: [],
|
|
158
|
+
startHour: 0,
|
|
159
|
+
startMinute: 0,
|
|
160
|
+
endHour: 0,
|
|
161
|
+
endMinute: 0
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
export const isAdmin = userType => userType === 10 || userType === 50 ? true : false;
|
|
165
|
+
export const validateEffectiveConfig = effective => {
|
|
166
|
+
if (!effective) {
|
|
167
|
+
// 不是永久生效时,需要传入生效时间配置
|
|
168
|
+
throw getError(1032);
|
|
169
|
+
}
|
|
170
|
+
// 生效时间段判断
|
|
171
|
+
if (!effective.effectiveDate) {
|
|
172
|
+
throw getError(1033);
|
|
173
|
+
}
|
|
174
|
+
if (!effective.expiredDate) {
|
|
175
|
+
throw getError(1034);
|
|
176
|
+
}
|
|
177
|
+
if (+effective.effectiveDate > +effective.expiredDate) {
|
|
178
|
+
throw getError(1010);
|
|
179
|
+
}
|
|
180
|
+
switch (effective.repeat) {
|
|
181
|
+
case "week":
|
|
182
|
+
if (!effective.weeks) {
|
|
183
|
+
throw getError(1035);
|
|
184
|
+
}
|
|
185
|
+
break;
|
|
186
|
+
// case "month":
|
|
187
|
+
// if (!effective.days) {
|
|
188
|
+
// throw getError(1036);
|
|
189
|
+
// }
|
|
190
|
+
// break;
|
|
191
|
+
// default:
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* 是否使用近场通道,一般为蓝牙
|
|
197
|
+
* @returns
|
|
198
|
+
*/
|
|
199
|
+
export const isUseNearChannel = () => {
|
|
200
|
+
const {
|
|
201
|
+
onlineType,
|
|
202
|
+
devInfo,
|
|
203
|
+
communication
|
|
204
|
+
} = config;
|
|
205
|
+
const isBleOnline = isOnlineByType(onlineType, 2);
|
|
206
|
+
const isSupportWifi = communication.includes(ProductCommunicationType.WIFI);
|
|
207
|
+
const isSupportBle = communication.includes(ProductCommunicationType.BLUETOOTH);
|
|
208
|
+
const isSupportThread = communication.includes(ProductCommunicationType.THREAD);
|
|
209
|
+
// wifi + ble 双模
|
|
210
|
+
if (isSupportWifi && isSupportBle) {
|
|
211
|
+
return isBleOnline;
|
|
212
|
+
}
|
|
213
|
+
// thread + ble 双模
|
|
214
|
+
if (isSupportThread && isSupportBle) {
|
|
215
|
+
return isBleOnline && !devInfo.isCloudOnline && !devInfo.isLocalOnline;
|
|
216
|
+
}
|
|
217
|
+
return isBleOnline;
|
|
218
|
+
};
|
|
219
|
+
export const parseOfflinePassword = value => {
|
|
220
|
+
if (config.passwordDigitalBase === 10) {
|
|
221
|
+
// 10进制时,直接显示
|
|
222
|
+
return value;
|
|
223
|
+
}
|
|
224
|
+
// 其他进制时,转换后显示
|
|
225
|
+
let digitalCode = Number(value).toString(config.passwordDigitalBase);
|
|
226
|
+
// 补0
|
|
227
|
+
const zeroList = value.match(/(^0+)/);
|
|
228
|
+
if (zeroList) {
|
|
229
|
+
digitalCode = zeroList[0] + digitalCode;
|
|
230
|
+
}
|
|
231
|
+
// 是否隐藏0
|
|
232
|
+
if (config.passwordSupportZero === false) {
|
|
233
|
+
digitalCode = digitalCode.split("").map(n => {
|
|
234
|
+
return Number(n) + 1;
|
|
235
|
+
}).join("");
|
|
236
|
+
}
|
|
237
|
+
return digitalCode;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* 格式化时间戳为毫秒
|
|
242
|
+
* 注意此方法只支持 2010 年之后的时间戳
|
|
243
|
+
* @param timestamp 时间戳
|
|
244
|
+
*/
|
|
245
|
+
export const formatTimestampToMilliseconds = timestamp => {
|
|
246
|
+
const isMilliseconds = timestamp.toString().length >= 13;
|
|
247
|
+
return isMilliseconds ? timestamp : timestamp * 1000;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* 开锁方式配置数据
|
|
252
|
+
*/
|
|
253
|
+
export const unlockMethodConfigs = [{
|
|
254
|
+
type: "password",
|
|
255
|
+
code: dpCodes.unlockPassword,
|
|
256
|
+
id: 1
|
|
257
|
+
}, {
|
|
258
|
+
type: "card",
|
|
259
|
+
code: dpCodes.unlockCard,
|
|
260
|
+
id: 2
|
|
261
|
+
}, {
|
|
262
|
+
type: "finger",
|
|
263
|
+
code: dpCodes.unlockFingerprint,
|
|
264
|
+
id: 3
|
|
265
|
+
}, {
|
|
266
|
+
type: "face",
|
|
267
|
+
code: dpCodes.unlockFace,
|
|
268
|
+
id: 4
|
|
269
|
+
}, {
|
|
270
|
+
type: "hand",
|
|
271
|
+
code: dpCodes.unlockHand,
|
|
272
|
+
id: 5
|
|
273
|
+
}, {
|
|
274
|
+
type: "fingerVein",
|
|
275
|
+
code: dpCodes.unlockFingerVein,
|
|
276
|
+
id: 6
|
|
277
|
+
}];
|
|
278
|
+
const getUnlockMethodType = cb => {
|
|
279
|
+
const result = unlockMethodConfigs.find(cb);
|
|
280
|
+
// 有此方式且设备是否支持此能力
|
|
281
|
+
if (result && config.dpSchema[result.code]) {
|
|
282
|
+
return result;
|
|
283
|
+
}
|
|
284
|
+
throw getError(1014);
|
|
285
|
+
};
|
|
286
|
+
export const getUnlockMethodTypeByDpCode = dpCode => {
|
|
287
|
+
return getUnlockMethodType(item => item.code === dpCode);
|
|
288
|
+
};
|
|
289
|
+
export const getUnlockMethodTypeById = id => {
|
|
290
|
+
return getUnlockMethodType(item => item.id === id);
|
|
291
|
+
};
|
|
292
|
+
export const getUnlockMethodTypeByType = type => {
|
|
293
|
+
return getUnlockMethodType(item => item.type === type);
|
|
294
|
+
};
|
|
295
|
+
let cbIndex = 0;
|
|
296
|
+
const cbMap = {};
|
|
297
|
+
/**
|
|
298
|
+
* 针对异常函数,当函数在短时间内被多次调用时,只保留最先一次调用,并统一返回结果
|
|
299
|
+
* @param cb 回调函数
|
|
300
|
+
* @returns
|
|
301
|
+
*/
|
|
302
|
+
export const parallelMerge = cb => {
|
|
303
|
+
let isRuning = false;
|
|
304
|
+
let cbId = cbIndex++;
|
|
305
|
+
// @ts-expect-error
|
|
306
|
+
return async function () {
|
|
307
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
308
|
+
args[_key] = arguments[_key];
|
|
309
|
+
}
|
|
310
|
+
const key = JSON.stringify(args);
|
|
311
|
+
// 如果正在执行,则直接抛错
|
|
312
|
+
if (isRuning) {
|
|
313
|
+
// 暂存回调
|
|
314
|
+
if (!cbMap[cbId]) {
|
|
315
|
+
cbMap[cbId] = {};
|
|
316
|
+
}
|
|
317
|
+
if (!cbMap[cbId][key]) {
|
|
318
|
+
cbMap[cbId][key] = [];
|
|
319
|
+
}
|
|
320
|
+
return new Promise((resolve, reject) => {
|
|
321
|
+
cbMap[cbId][key].push({
|
|
322
|
+
resolve,
|
|
323
|
+
reject
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
isRuning = true;
|
|
328
|
+
try {
|
|
329
|
+
const result = await cb(...args);
|
|
330
|
+
isRuning = false;
|
|
331
|
+
// 如果是 merge 模式,执行所有暂存的回调
|
|
332
|
+
if (cbMap[cbId] && cbMap[cbId][key]) {
|
|
333
|
+
let list = cbMap[cbId][key];
|
|
334
|
+
delete cbMap[cbId][key]; // 删除已处理的回调
|
|
335
|
+
setTimeout(() => {
|
|
336
|
+
list.forEach(item => item.resolve(result));
|
|
337
|
+
}, 0);
|
|
338
|
+
}
|
|
339
|
+
return result;
|
|
340
|
+
} catch (error) {
|
|
341
|
+
isRuning = false;
|
|
342
|
+
// 如果是 merge 模式,执行所有暂存的回调
|
|
343
|
+
if (cbMap[cbId] && cbMap[cbId][key]) {
|
|
344
|
+
let list = cbMap[cbId][key];
|
|
345
|
+
delete cbMap[cbId][key]; // 删除已处理的回调
|
|
346
|
+
setTimeout(() => {
|
|
347
|
+
list.forEach(item => item.reject(error));
|
|
348
|
+
}, 0);
|
|
349
|
+
}
|
|
350
|
+
throw error;
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* 针对异常函数,当函数在短时间内被多次调用时,只允许函数在短时间内执行一次
|
|
357
|
+
* @param cb 回调函数
|
|
358
|
+
* @returns
|
|
359
|
+
*/
|
|
360
|
+
export const parallelOnly = cb => {
|
|
361
|
+
let isRuning = false;
|
|
362
|
+
cbIndex++; // @ts-expect-error
|
|
363
|
+
return async function () {
|
|
364
|
+
// 如果正在执行,则直接抛错
|
|
365
|
+
if (isRuning) {
|
|
366
|
+
throw getError(1052);
|
|
367
|
+
}
|
|
368
|
+
isRuning = true;
|
|
369
|
+
try {
|
|
370
|
+
const result = await cb(...arguments);
|
|
371
|
+
isRuning = false;
|
|
372
|
+
return result;
|
|
373
|
+
} catch (error) {
|
|
374
|
+
isRuning = false;
|
|
375
|
+
throw error;
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
};
|
|
379
|
+
const preFetchKeys = ["getRotate", "getCurrentUser", "getDeviceProperties"];
|
|
380
|
+
/**
|
|
381
|
+
* 预加载数据处理
|
|
382
|
+
*/
|
|
383
|
+
const preFetchData = {};
|
|
384
|
+
// @ts-expect-error
|
|
385
|
+
onBackgroundFetchData(preFetchKeys, res => {
|
|
386
|
+
var _res$fetchedData;
|
|
387
|
+
Object.keys((_res$fetchedData = res === null || res === void 0 ? void 0 : res.fetchedData) !== null && _res$fetchedData !== void 0 ? _res$fetchedData : {}).forEach(key => {
|
|
388
|
+
preFetchData[key] = res.fetchedData[key].fetchedData;
|
|
389
|
+
});
|
|
390
|
+
});
|
|
391
|
+
export const getDataWithPreFetch = async (key, apiCb) => {
|
|
392
|
+
if (preFetchData[key]) {
|
|
393
|
+
return preFetchData[key];
|
|
394
|
+
}
|
|
395
|
+
try {
|
|
396
|
+
const result = await getBackgroundFetchData([key]);
|
|
397
|
+
if (result && result.fetchedData[key] && result.fetchedData[key].fetchedData) {
|
|
398
|
+
// 有数据时,则返回数据,无数据则执行接口调用
|
|
399
|
+
return result.fetchedData[key].fetchedData;
|
|
400
|
+
}
|
|
401
|
+
} catch {
|
|
402
|
+
//
|
|
403
|
+
}
|
|
404
|
+
return apiCb();
|
|
405
|
+
};
|
|
406
|
+
export const equels = (source, target) => {
|
|
407
|
+
return JSON.stringify(source) === JSON.stringify(target);
|
|
408
|
+
};
|
|
409
|
+
export const sleep = ms => {
|
|
410
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
411
|
+
};
|
|
412
|
+
let homeInfo = null;
|
|
413
|
+
export const getHomeInfo = async () => {
|
|
414
|
+
if (homeInfo) {
|
|
415
|
+
return homeInfo;
|
|
416
|
+
}
|
|
417
|
+
homeInfo = await getCurrentHomeInfo();
|
|
418
|
+
return homeInfo;
|
|
419
|
+
};
|
package/lib/utils/log.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 处理日志数据
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { LocalOperateCategory } from "../constant";
|
|
6
|
+
import { bytesToUint } from "./byte";
|
|
7
|
+
import hexToBytes from "./hex-to-bytes";
|
|
8
|
+
const localRecordUnlock = [LocalOperateCategory.ADD_UNLOCK_METHOD, LocalOperateCategory.DELETE_UNLOCK_METHOD, LocalOperateCategory.MODIFY_UNLOCK_METHOD];
|
|
9
|
+
const localRecordUserOperate = [LocalOperateCategory.ADD_USER, LocalOperateCategory.DELETE_USER];
|
|
10
|
+
const unlockMethodMap = ["finger", "face", "password", "card", "fingerVein", "hand", "eye", "remoteControl"];
|
|
11
|
+
export const handleLocalOperation = log => {
|
|
12
|
+
if (!log) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const {
|
|
16
|
+
operClassify,
|
|
17
|
+
userId,
|
|
18
|
+
userType,
|
|
19
|
+
operType,
|
|
20
|
+
operDetail,
|
|
21
|
+
toUserType,
|
|
22
|
+
toUserId
|
|
23
|
+
} = log;
|
|
24
|
+
const data = hexToBytes(operDetail);
|
|
25
|
+
const viewData = new DataView(data.buffer);
|
|
26
|
+
/**
|
|
27
|
+
* 开锁方式操作
|
|
28
|
+
*/
|
|
29
|
+
if (localRecordUnlock.includes(operClassify)) {
|
|
30
|
+
const unlockId = viewData.getInt16(0);
|
|
31
|
+
return {
|
|
32
|
+
category: operClassify,
|
|
33
|
+
unlockMethod: unlockMethodMap[operType],
|
|
34
|
+
unlockId,
|
|
35
|
+
isRemoveAll: unlockId === 0xffff,
|
|
36
|
+
userId,
|
|
37
|
+
userType,
|
|
38
|
+
toUserId,
|
|
39
|
+
toUserType
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 添加用户操作
|
|
44
|
+
*/
|
|
45
|
+
if (localRecordUserOperate.includes(operClassify)) {
|
|
46
|
+
return {
|
|
47
|
+
category: operClassify,
|
|
48
|
+
userId,
|
|
49
|
+
userType,
|
|
50
|
+
toUserId,
|
|
51
|
+
toUserType
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 本地设置操作
|
|
56
|
+
*/
|
|
57
|
+
if (operClassify === LocalOperateCategory.SETTING) {
|
|
58
|
+
return {
|
|
59
|
+
category: LocalOperateCategory.SETTING,
|
|
60
|
+
userId,
|
|
61
|
+
userType,
|
|
62
|
+
toUserId,
|
|
63
|
+
toUserType,
|
|
64
|
+
type: operType,
|
|
65
|
+
data: data.length <= 4 ? bytesToUint(data) : data,
|
|
66
|
+
originData: data
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
category: operClassify,
|
|
71
|
+
type: operType,
|
|
72
|
+
data: data,
|
|
73
|
+
userId,
|
|
74
|
+
userType,
|
|
75
|
+
toUserId,
|
|
76
|
+
toUserType
|
|
77
|
+
};
|
|
78
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DpValue } from "../interface";
|
|
2
|
+
/**
|
|
3
|
+
* 执行下发 dp
|
|
4
|
+
* @param dpData
|
|
5
|
+
* @returns
|
|
6
|
+
*/
|
|
7
|
+
export declare const publishDpsOnly: (dpData: Record<string, string | number | boolean>) => Promise<void>;
|
|
8
|
+
export declare const publishDps: (dpData: Record<string, DpValue>, option?: {
|
|
9
|
+
timeout?: number;
|
|
10
|
+
checkReport?: (dps: Record<string, any>) => boolean | Record<string, any>;
|
|
11
|
+
}) => Promise<Record<string, DpValue>>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
2
|
+
import "core-js/modules/esnext.iterator.constructor.js";
|
|
3
|
+
import "core-js/modules/esnext.iterator.for-each.js";
|
|
4
|
+
import "core-js/modules/esnext.iterator.reduce.js";
|
|
5
|
+
import config from "../config";
|
|
6
|
+
import { isOnlineByType } from ".";
|
|
7
|
+
import { publishDeviceDps } from "./device";
|
|
8
|
+
import emitter from "./event";
|
|
9
|
+
import { DPCHANGE } from "./constant";
|
|
10
|
+
import { getError } from "./errors";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 执行下发 dp
|
|
14
|
+
* @param dpData
|
|
15
|
+
* @returns
|
|
16
|
+
*/
|
|
17
|
+
export const publishDpsOnly = async dpData => {
|
|
18
|
+
console.log("_publishDps", dpData);
|
|
19
|
+
const {
|
|
20
|
+
devInfo,
|
|
21
|
+
idsByCode
|
|
22
|
+
} = config;
|
|
23
|
+
const option = {};
|
|
24
|
+
if (config.onlineType === 0) {
|
|
25
|
+
// 设备离线
|
|
26
|
+
throw getError(1001);
|
|
27
|
+
}
|
|
28
|
+
if (isOnlineByType(config.onlineType, 2)) {
|
|
29
|
+
// 由于设备只能支持wifi 或蓝牙在线,wifi 在线又可能为假在线,因此当蓝牙在线时,优先走蓝牙通道
|
|
30
|
+
option.pipelines = [3];
|
|
31
|
+
}
|
|
32
|
+
const dps = Object.keys(dpData).reduce((acc, key) => {
|
|
33
|
+
const id = idsByCode[key];
|
|
34
|
+
if (id) {
|
|
35
|
+
acc[id] = dpData[key];
|
|
36
|
+
}
|
|
37
|
+
return acc;
|
|
38
|
+
}, {});
|
|
39
|
+
if (Object.keys(dps).length > 0) {
|
|
40
|
+
await publishDeviceDps(_objectSpread({
|
|
41
|
+
deviceId: devInfo.devId,
|
|
42
|
+
dps
|
|
43
|
+
}, option));
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// 发送 dp 并等待上报
|
|
48
|
+
export const publishDps = async (dpData, option) => {
|
|
49
|
+
await publishDpsOnly(dpData);
|
|
50
|
+
console.log("publishDps success");
|
|
51
|
+
// 默认 15s 超时
|
|
52
|
+
const {
|
|
53
|
+
timeout = 15000,
|
|
54
|
+
checkReport
|
|
55
|
+
} = option || {};
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
const codes = Object.keys(dpData);
|
|
58
|
+
const result = {};
|
|
59
|
+
const handleChangeDp = dpCodes => {
|
|
60
|
+
// 是否自定义检查上报数据
|
|
61
|
+
if (checkReport) {
|
|
62
|
+
const pass = checkReport(dpCodes);
|
|
63
|
+
if (pass) {
|
|
64
|
+
emitter.off(DPCHANGE, handleChangeDp);
|
|
65
|
+
clearTimeout(timer);
|
|
66
|
+
resolve(typeof pass !== "boolean" ? pass : dpCodes);
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
Object.keys(dpCodes).forEach(code => {
|
|
70
|
+
const eixst = codes.indexOf(code);
|
|
71
|
+
if (eixst > -1) {
|
|
72
|
+
codes.splice(eixst, 1)[0];
|
|
73
|
+
result[code] = dpCodes[code];
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
// 所有 dp 都上报了
|
|
77
|
+
if (codes.length === 0) {
|
|
78
|
+
emitter.off(DPCHANGE, handleChangeDp);
|
|
79
|
+
clearTimeout(timer);
|
|
80
|
+
resolve(result);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
// 超时处理
|
|
85
|
+
const timer = setTimeout(() => {
|
|
86
|
+
emitter.off(DPCHANGE, handleChangeDp);
|
|
87
|
+
reject(getError(1002));
|
|
88
|
+
}, timeout);
|
|
89
|
+
emitter.on(DPCHANGE, handleChangeDp);
|
|
90
|
+
});
|
|
91
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ray-js/lock-sdk",
|
|
3
|
+
"version": "1.0.0-beta-1",
|
|
4
|
+
"files": [
|
|
5
|
+
"lib"
|
|
6
|
+
],
|
|
7
|
+
"main": "lib/index.js",
|
|
8
|
+
"types": "lib/index.d.ts",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "ray build --type=component",
|
|
11
|
+
"compile": "ray build --type=component",
|
|
12
|
+
"lint": "eslint . --max-warnings 0",
|
|
13
|
+
"generate:component": "turbo gen react-component",
|
|
14
|
+
"check-types": "tsc --noEmit"
|
|
15
|
+
},
|
|
16
|
+
"maintainers": [
|
|
17
|
+
"tuya_npm",
|
|
18
|
+
{
|
|
19
|
+
"name": "tuyafe"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@turbo/gen": "^2.4.0",
|
|
25
|
+
"@types/node": "^22.13.0",
|
|
26
|
+
"@types/react": "19.0.8",
|
|
27
|
+
"eslint": "^9.21.0",
|
|
28
|
+
"typescript": "5.7.3"
|
|
29
|
+
},
|
|
30
|
+
"peerDependencies": {
|
|
31
|
+
"react": "^19.0.0"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@ray-js/tuya-dp-transform": "^0.0.6",
|
|
35
|
+
"js-base64": "^3.7.7"
|
|
36
|
+
}
|
|
37
|
+
}
|