mm_os 2.3.9 → 2.4.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.
@@ -58,7 +58,10 @@ exports.unlock = async function(clientid, uuid = '0', pass = false, tip = '没
58
58
  // 0不开门,1开门
59
59
  "ctrl_type": pass ? "on" : "off"
60
60
  });
61
- return res
61
+ if (res.message !== "ACK") {
62
+ return res.code;
63
+ }
64
+ return
62
65
  }
63
66
 
64
67
  /**
@@ -67,13 +70,15 @@ exports.unlock = async function(clientid, uuid = '0', pass = false, tip = '没
67
70
  * @param {String} uuid 用户唯一标识
68
71
  * @param {Number} longtime 超时回馈
69
72
  */
70
- exports.del_member = function(clientid, uuid) {
71
- var res = this.push("delete_face", clientid, {
73
+ exports.delete_member = async function(clientid, uuid) {
74
+ var res = await this.push("delete_face", clientid, {
72
75
  "per_id": uuid,
73
76
  "type": 0
74
77
  });
75
- var bl = res.code == 0;
76
- return $.ret.bl(bl, res.reply || "删除成功");
78
+ if (res.message !== "ACK") {
79
+ return res.code;
80
+ }
81
+ return
77
82
  }
78
83
 
79
84
  /**
@@ -82,33 +87,73 @@ exports.del_member = function(clientid, uuid) {
82
87
  * @param {Object} arr 成员列表
83
88
  * @param {Number} longtime 超时回馈
84
89
  */
85
- exports.del_member_batch = async function(clientid, arr, longtime) {
86
- var list = [];
90
+ exports.delete_member_batch = async function(clientid, arr, longtime) {
91
+ if (!this.drives[clientid]) {
92
+ this.drives[clientid] = {};
93
+ }
94
+ if (this.drives[clientid].pushing == 1) {
95
+ return {
96
+ detail: "busy"
97
+ }
98
+ }
99
+ this.drives[clientid].pushing = 1;
100
+ this.drives[clientid].mode = "update";
101
+
102
+ var result;
103
+ var error = 0;
104
+ var success = 0;
105
+ var error_info = [];
106
+ var success_info = [];
107
+
108
+ var now = new Date().toStr("yyyy-MM-dd hh:mm:ss");
87
109
  for (var i = 0; i < arr.length; i++) {
88
- var uuid = arr[i];
110
+ var customId = arr[i];
89
111
  var res = await this.push("delete_face", clientid, {
90
- "per_id": uuid,
112
+ "per_id": customId,
91
113
  "type": 0
92
114
  });
93
- var bl = false;
94
- if (res.code == 0) {
95
- bl = true;
115
+ if (res.message == "ACK") {
116
+ success++;
117
+ success_info.push({
118
+ customId,
119
+ time_create: now
120
+ });
121
+ } else {
122
+ error++;
123
+ // 407 人脸像素太大(大于 1072)
124
+ // 408 图片格式错误
125
+ // 410 获取到的特征数据为空
126
+ // 412 相似人脸禁止录入
127
+ // 419 缓存初始化中
128
+ // 420 图片长度小于 112
129
+ error_info.push({
130
+ customId,
131
+ errcode: res.code.toString(),
132
+ time_create: now
133
+ });
96
134
  }
97
- list.push({
98
- uuid,
99
- bl,
100
- tip: res.reply || "删除成功"
101
- });
102
135
  }
103
- return list;
136
+ this.drives[clientid].pushing = 0;
137
+ this.drives[clientid].mode = "";
138
+
139
+ return {
140
+ error,
141
+ success,
142
+ error_info,
143
+ success_info,
144
+ result: 'ok'
145
+ };
104
146
  }
105
147
 
106
148
  /**
107
149
  * 重启设备
108
150
  * @param {String} clientid 设备sn
109
151
  */
110
- exports.reboot_device = function(clientid) {
111
- return this.push("reboot_cam", clientid, {});
152
+ exports.reboot_device = async function(clientid) {
153
+ var res = await this.push("reboot_cam", clientid, {});
154
+ if (res.message !== "ACK") {
155
+ return res.code;
156
+ }
112
157
  }
113
158
 
114
159
  /**
@@ -122,7 +167,10 @@ exports.set_device_time = async function(clientid, datetime) {
122
167
  "datetime": datetime
123
168
  }
124
169
  });
125
- return
170
+
171
+ if (res.message !== "ACK") {
172
+ return res.code;
173
+ }
126
174
  }
127
175
 
128
176
  /**
@@ -151,7 +199,10 @@ exports.reset_device = function(clientid, record = true, member = false, log = t
151
199
  * @param {String} clientid 设备sn
152
200
  */
153
201
  exports.get_progress = function(clientid) {
154
- // return this.push("QueryProgress", clientid, {});
202
+ if (!this.drives[clientid]) {
203
+ this.drives[clientid] = {};
204
+ }
205
+ return this.drives[clientid].pushing || 0;
155
206
  }
156
207
 
157
208
  /**
@@ -163,6 +214,11 @@ exports.get_progress = function(clientid) {
163
214
  exports.convert_in = function(push_topic, msg, topic) {
164
215
  var cg = this.config;
165
216
  var method = msg[cg.method];
217
+ if (push_topic.indexOf("heartbeat") !== -1) {
218
+ method = "mqtt_heartbeat";
219
+ } else if (push_topic.indexOf("face/response") !== -1) {
220
+ method = "push_face";
221
+ }
166
222
  var json = {
167
223
  clientid: "",
168
224
  id: msg[cg.msgid] || this.get_msgid(method, 'client'),
@@ -172,13 +228,15 @@ exports.convert_in = function(push_topic, msg, topic) {
172
228
  json.params = msg[cg.params];
173
229
  }
174
230
  if (msg[cg.result]) {
175
- json.result = msg[cg.result];
231
+ json.result = {
232
+ code: msg.code,
233
+ message: msg[cg.result]
234
+ };
176
235
  }
177
- json.clientid = this.get_clientid(push_topic, json.params || json.result || {}, msg, topic);
178
-
179
- if (push_topic.indexOf("heartbeat") !== -1) {
180
- json.method = "mqtt_heartbeat";
236
+ if (!json.params && !json.result) {
237
+ json.result = msg;
181
238
  }
239
+ json.clientid = this.get_clientid(push_topic, json.params || json.result || {}, msg, topic).toLocaleUpperCase();
182
240
  return json;
183
241
  }
184
242
 
@@ -251,25 +309,24 @@ exports.member_model_out = function(m) {
251
309
  "per_id": m.customId,
252
310
  "per_name": m.name,
253
311
  "idcardNum": m.nfc || '',
254
- "img_url": m.avatar,
312
+ "img_url": this.fullUrl(m.avatar),
255
313
  "idcardper": m.idcard,
256
- // 1 待审核 | 2 已拒绝 | 3 已通过 | 4 黑名单
257
- "per_type": m.type == 4 ? 2 : 0,
314
+ "auth_type": 0,
315
+ // 1 待审核 | 2 已拒绝 | 3 已通过 | 4 黑名单 , 设备0为白名单,2为黑名单
316
+ "per_type": m.state == 4 ? 2 : 0,
258
317
  "usr_type": m.gm,
259
318
  "gender": m.sex == 1 ? '男' : '女'
260
319
  }
261
320
 
262
- if (m.time_valid_end && m.time_valid_end > date && m.time_valid_end <= endDate) {
263
- if (typeof(m.time_valid_start) == "object") {
264
- obj.s_time = m.time_valid_start.toStr("yyyy-MM-dd hh:mm:ss");
265
- } else {
266
- obj.s_time = m.time_valid_start.toTime().toStr("yyyy-MM-dd hh:mm:ss");
267
- }
268
- if (typeof(m.time_valid_end) == "object") {
269
- obj.e_time = m.time_valid_end.toStr("yyyy-MM-dd hh:mm:ss");
270
- } else {
271
- obj.e_time = m.time_valid_end.toTime().toStr("yyyy-MM-dd hh:mm:ss");
272
- }
321
+ if (typeof(m.time_valid_start) == "object") {
322
+ obj.s_time = m.time_valid_start.stamp();
323
+ } else {
324
+ obj.s_time = m.time_valid_start.toTime().stamp();
325
+ }
326
+ if (typeof(m.time_valid_end) == "object") {
327
+ obj.e_time = m.time_valid_end.stamp();
328
+ } else {
329
+ obj.e_time = m.time_valid_end.toTime().stamp();
273
330
  }
274
331
  return obj
275
332
  }
@@ -279,37 +336,80 @@ exports.member_model_out = function(m) {
279
336
  * @param {String} clientid 设备ID
280
337
  * @param {Object} user 人员信息
281
338
  */
282
- exports.update_member = function(clientid, user) {
339
+ exports.update_member = async function(clientid, user) {
283
340
  var member = this.member_model_out(user);
284
- return this.push(clientid, member);
341
+ var res = await this.push("update_face_ex", clientid, member);
342
+ if (res.message !== "ACK") {
343
+ return res.code;
344
+ }
345
+ return
285
346
  }
286
347
 
287
348
  /**
288
- * 批量下发人员名单
349
+ * 批量下发人员名单(模拟) 设备本身没有批量下发,因此需要自己设计一个来模拟
289
350
  * @param {String} clientid 客户端ID
290
351
  * @param {Array} list 人员名单
291
352
  * @param {Number} longtime 超时回馈
292
353
  */
293
354
  exports.update_member_batch = async function(clientid, list, longtime = 0) {
294
- var list = [];
295
- for (var i = 0; i < arr.length; i++) {
355
+ if (!this.drives[clientid]) {
356
+ this.drives[clientid] = {};
357
+ }
358
+ if (this.drives[clientid].pushing == 1) {
359
+ return {
360
+ detail: "busy"
361
+ }
362
+ }
363
+ this.drives[clientid].pushing = 1;
364
+ this.drives[clientid].mode = "delete";
365
+
366
+ var result;
367
+ var error = 0;
368
+ var success = 0;
369
+ var error_info = [];
370
+ var success_info = [];
371
+
372
+ var now = new Date().toStr("yyyy-MM-dd hh:mm:ss");
373
+ for (var i = 0; i < list.length; i++) {
296
374
  var user = list[i];
297
- var res = await this.push(clientid, this.member_model_out(user));
298
- var bl = false;
299
- if (res.code == 0) {
300
- bl = true;
375
+ var res = await this.push("update_face_ex", clientid, this.member_model_out(user));
376
+ if (res.message == "ACK") {
377
+ success++;
378
+ success_info.push({
379
+ customId: user.customId,
380
+ time_create: now
381
+ });
382
+ } else {
383
+ error++;
384
+ // 407 人脸像素太大(大于 1072)
385
+ // 408 图片格式错误
386
+ // 410 获取到的特征数据为空
387
+ // 412 相似人脸禁止录入
388
+ // 419 缓存初始化中
389
+ // 420 图片长度小于 112
390
+ error_info.push({
391
+ customId: user.customId,
392
+ errcode: res.code.toString(),
393
+ time_create: now
394
+ });
301
395
  }
302
- list.push({
303
- uuid: user.customId,
304
- bl,
305
- tip: res.reply || "删除成功"
306
- });
307
396
  }
308
- return list;
397
+ this.drives[clientid].pushing = 0;
398
+ this.drives[clientid].mode = "";
399
+
400
+ return {
401
+ error,
402
+ success,
403
+ error_info,
404
+ success_info,
405
+ result: 'ok'
406
+ };
309
407
  }
310
408
 
311
409
  /**
312
410
  * 播放语音
411
+ * @param {String} clientid 客户端ID
412
+ * @param {Number} type 语音类型 1为没有权限,2为鉴权失败,3为鉴权成功
313
413
  */
314
414
  exports.play_audio = async function(clientid, type = 3) {
315
415
  var body = {};
@@ -333,11 +433,48 @@ exports.play_audio = async function(clientid, type = 3) {
333
433
  var res = await this.push("trylisten_wav", clientid, {
334
434
  body
335
435
  });
436
+
437
+ if (res.message !== "ACK") {
438
+ return res.code;
439
+ }
440
+ return
441
+ }
442
+
443
+ /**
444
+ * 设置扫描二维码模式
445
+ * @param {String} clientid 客户端ID
446
+ * @param {Number} mode 模式
447
+ */
448
+ exports.set_qrcode_mode = async function(clientid, mode = 1) {
449
+ var res = await this.push("set_qrcode_mode", clientid, {
450
+ body: {
451
+ "enable": 0,
452
+ mode
453
+ }
454
+ });
455
+ if (res.message !== "ACK") {
456
+ return res.code;
457
+ }
458
+ return
459
+ }
460
+
461
+ /**
462
+ * 发送灯光
463
+ * @param {String} clientid 客户端ID
464
+ * @param {Number} color 颜色选项
465
+ */
466
+ exports.send_led = async function(clientid, color = 1) {
467
+ var res = await this.push("set_led_color_test", clientid, {
468
+ "body": {
469
+ color
470
+ }
471
+ });
472
+ if (res.message !== "ACK") {
473
+ return res.code;
474
+ }
475
+ return
336
476
  }
337
477
 
338
- // exports.convert_in = function(push_topic, msg, topic, index) {
339
- // console.log("收到", push_topic, msg, topic, index);
340
- // }
341
478
 
342
479
  /**
343
480
  * 初始化函数, 用于定义开放给前端的函数
@@ -352,7 +489,7 @@ exports.init = function() {
352
489
  }
353
490
  _this.drives[clientid].online = 1;
354
491
  _this.drives[clientid].time_last = new Date().getTime();
355
- console.log("心跳", clientid, _this.drives[clientid]);
492
+ // console.log("心跳", clientid, _this.drives[clientid]);
356
493
  }
357
494
 
358
495
  /**
@@ -362,100 +499,41 @@ exports.init = function() {
362
499
  */
363
500
  m["mqtt_online"] = async function(clientid, params) {
364
501
  _this.update_online(clientid, 1);
502
+ _this.set_qrcode_mode(clientid);
365
503
  console.log("上线", clientid, _this.drives[clientid]);
366
504
  };
367
505
 
368
- m["RecPush"] = async function(clientid, params, msg, id) {
369
- var info = msg.body;
370
- // "body": {
371
- // "e_imgsize": 13485,
372
- // "ext_sec": 1709089205,
373
- // "hat": -1,
374
- // "hcode_status": 0,
375
- // "idcard": "",
376
- // "img_data": "/9j/4AAQSkZJRgABAQIAdgB2AAD/7wAPAAAAAAAAAAAAAAAAAP",
377
- // "isRealtimeData": 601,
378
- // "isurl": false,
379
- // "mask": -1,
380
- // "matched": 93,
381
- // "name": "schmidt",
382
- // "name_base64": "c2NobWlkdA==",
383
- // "per_id": "1706099386778",
384
- // "per_id_base64": "MTcwNjA5OTM4Njc3OA==",
385
- // "role": 0,
386
- // "sequence": 27307,
387
- // "sn": "7560d2db-fd20feb7",
388
- // "tep": 0,
389
- // "usec": 1709118005
390
- // }
391
-
506
+ m["push_face"] = async function(clientid, params, msg, id) {
392
507
  var type = 1;
393
- switch (params.otype) {
394
- // (1人脸验证|2远程开门|3智码开门|4刷卡验证)
395
- case "7":
396
- case "27":
397
- type = 2;
508
+ var action;
509
+ switch (msg.type) {
510
+ case "face_result":
511
+ type = 1;
398
512
  break;
399
- case "47":
400
- case "48":
401
- case "55":
402
- case "56":
403
- case "57":
404
- type = 3;
405
- break;
406
- case "21":
407
- case "22":
408
- case "24":
409
- case "25":
513
+ case "wgin_read":
410
514
  type = 4;
411
515
  break;
412
516
  default:
413
517
  break;
414
518
  }
415
- if (type == 2) {
416
- return;
417
- }
418
- // 1白名单|2黑名单
419
- var person_type = params.PersonType == "1" ? 2 : 1;
420
- var record_type = params.RecordType ? Number(params.RecordType) + 1 : 1;
421
-
422
- // 拿到打卡人的姓名
423
- var name = params.persionName || params.name;
424
- if (!name) {
425
- return;
426
- }
427
- var customId = params.customId.trim();
428
- var phone = (params.telnum || "").trim();
429
- var idcard = (params.idCard || "").trim();
430
- var nfc = (params.cardNum2 || params.RFIDCard || "").trim();
431
- var time = params.time;
432
- var avatar = "";
433
- if (params.pic) {
434
- avatar = params.pic;
435
- }
436
519
  var log = {
437
- customId,
438
- name,
439
- phone,
440
- idcard,
441
- nfc,
520
+ customId: params.per_id,
521
+ name: params.name,
522
+ idcard: params.idcard,
442
523
  clientid,
524
+ // (1刷脸验证|2远程开门|3智码开门|4刷卡验证)
443
525
  type,
444
- person_type,
445
- record_type,
446
- time,
447
- avatar
526
+ // 1白名单|2黑名单
527
+ person_type: params.matchRole || params.role || 0,
528
+ record_type: 1,
529
+ action,
530
+ nfc: params.wg_num,
531
+ // usec / ext_sec
532
+ time: params.ext_sec.toTime().toStr("yyyy-MM-dd hh:mm:ss"),
533
+ avatar: params.img_data,
534
+ sex: params.gender == '男' ? 1 : 2
448
535
  }
449
536
  $.server.exec_log(clientid, log);
450
-
451
- _this.send(`mqtt/face/${clientid}`, {
452
- "messageId": _this.get_msgid('PushAck'),
453
- "operator": "PushAck",
454
- "info": {
455
- "PushAckType": "2",
456
- "SnapOrRecordID": params.RecordID
457
- }
458
- });
459
537
  }
460
538
 
461
539
  m["send_qr_msg"] = async function(clientid, params, msg, id) {
@@ -466,21 +544,18 @@ exports.init = function() {
466
544
  tip,
467
545
  device
468
546
  } = await $.server.exec_qrcode(clientid, qrcode);
469
- console.log('扫码', qrcode, uuid,
470
- pass,
471
- tip,
472
- device)
473
547
  if (device && device.online) {
474
- console.log("看门", clientid.toLocaleUpperCase(), uuid, pass, tip);
475
- await _this.unlock(clientid.toLocaleUpperCase(), uuid, pass, tip);
548
+ await _this.unlock(clientid, uuid, pass, tip);
476
549
  }
477
550
  if (tip) {
478
- if (tip.indexOf("过期") !== -1) {
551
+ if (tip.indexOf("过期") !== -1 || tip.indexOf("超限") !== -1) {
479
552
  _this.play_audio(clientid, 1);
553
+ _this.send_led(clientid);
480
554
  } else if (tip.indexOf("通行") !== -1) {
481
555
  // _this.play_audio(clientid, 3);
482
556
  } else {
483
557
  _this.play_audio(clientid, 2);
558
+ _this.send_led(clientid);
484
559
  }
485
560
  }
486
561
  }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * 定时任务函数
3
+ */
4
+ exports.main = async function main() {
5
+ $.log.debug('定时任务, 执行中...');
6
+ };
7
+
8
+ /**
9
+ * 执行结果通知
10
+ * @param {String} name 任务名称
11
+ * @param {String} state 状态
12
+ */
13
+ exports.notify = async function(name, state) {
14
+ switch (state) {
15
+ case "init":
16
+ $.log.debug('初始化');
17
+ break;
18
+ case "start":
19
+ $.log.debug('开始执行');
20
+ break;
21
+ case "stop":
22
+ $.log.debug('已暂停');
23
+ break;
24
+ case "suspend":
25
+ // 主动中断
26
+ $.log.debug('已中断');
27
+ break;
28
+ case "time_end":
29
+ $.log.debug('已到期');
30
+ break;
31
+ case "completed":
32
+ $.log.debug('已完成');
33
+ break;
34
+ default:
35
+ break;
36
+ }
37
+ };
@@ -0,0 +1,26 @@
1
+ {
2
+ // 任务标题
3
+ "title": "示例任务",
4
+ // 任务描述
5
+ "description": "描述任务使用方法",
6
+ // 任务名称,用于动态增删改查
7
+ "name": "demo",
8
+ // 状态 0未启用,1启用
9
+ "state": 1,
10
+ // 任务驱动的脚本文件
11
+ "func_file": "./index.js",
12
+ // 任务执行次数,执行次数达标后不再执行。0为不限次数,一直执行
13
+ "num": 10,
14
+ // 任务间隔时长,单位:毫秒
15
+ "interval": 1000,
16
+ // 任务启动等待时长,单位:毫秒
17
+ "wait": 0,
18
+ // 任务触发的时间,可设置的格式分别为: yyyy-MM-dd hh:mm:ss, MM-dd hh:mm:ss, dd hh:mm:ss, hh:mm:ss, hh:mm, mm 例如: 08:00, 则为每天8点触发
19
+ "time": "",
20
+ // 任务开始日期,例如:2020-10-01开始执行,为空则不限制
21
+ "date_start": "",
22
+ // 任务结束日期,例如:2020-10-07不再执行,为空则不限制
23
+ "date_end": "",
24
+ // 任务排序,决定多个任务的执行优先顺序
25
+ "sort": 100
26
+ }