mqtt-devices-parser 1.0.28 → 1.0.29

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/Changelog.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.29
4
+ fix(models/sensors): allow null model_id
5
+ fix: synching mqtt topics
6
+ feat: stores mqtt messages
7
+
3
8
  ## 1.0.28
4
9
  test: Add comprehensive Jest test suite for device.js module (#2)
5
10
  feat: scope FOTA checks to device variant_id (#11)
@@ -0,0 +1,29 @@
1
+
2
+ module.exports = (sequelize,DataTypes)=>{
3
+ return sequelize.define("logs_mqtt", {
4
+ mqtt_id: {
5
+ type: DataTypes.INTEGER,
6
+ allowNull: false,
7
+ },
8
+ device_id: {
9
+ type: DataTypes.INTEGER,
10
+ allowNull: false,
11
+ },
12
+ source: {
13
+ type: DataTypes.STRING,
14
+ allowNull: false
15
+ },
16
+ action: {
17
+ type: DataTypes.STRING,
18
+ allowNull: false
19
+ },
20
+ payload: {
21
+ type: DataTypes.STRING,
22
+ allowNull: true
23
+ },
24
+ },
25
+ {
26
+ tableName: 'logs_mqtt',
27
+ freezeTableName: true
28
+ })
29
+ }
@@ -0,0 +1,29 @@
1
+
2
+ module.exports = (sequelize,DataTypes)=>{
3
+ return sequelize.define("logs_mqtt_msgs", {
4
+ device_id: {
5
+ type: DataTypes.INTEGER,
6
+ allowNull: false,
7
+ },
8
+ topic: {
9
+ type: DataTypes.STRING,
10
+ allowNull: false
11
+ },
12
+ payload: {
13
+ type: DataTypes.STRING,
14
+ allowNull: true
15
+ },
16
+ qos: {
17
+ type: DataTypes.INTEGER,
18
+ allowNull: false
19
+ },
20
+ retain: {
21
+ type: DataTypes.INTEGER,
22
+ allowNull: false
23
+ },
24
+ },
25
+ {
26
+ tableName: 'logs_mqtt_msgs',
27
+ freezeTableName: true
28
+ })
29
+ }
@@ -3,7 +3,7 @@ module.exports = (sequelize,DataTypes)=>{
3
3
  return sequelize.define("sensors", {
4
4
  model_id: { // reference a model
5
5
  type: DataTypes.INTEGER,
6
- allowNull: false,
6
+ allowNull: true,
7
7
  references: {
8
8
  model: 'models',
9
9
  key: 'id'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mqtt-devices-parser",
3
- "version": "1.0.28",
3
+ "version": "1.0.29",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/db/device.js CHANGED
@@ -216,6 +216,56 @@ var self = module.exports = {
216
216
  });
217
217
  },
218
218
 
219
+ addMqttLog : async(deviceId,dbTopicId,from,action,payload)=>{
220
+ return new Promise((resolve,reject) => {
221
+
222
+ const timestamp = moment().utc().format('YYYY-MM-DD HH:mm:ss')
223
+ let obj = {
224
+ createdAt : timestamp,
225
+ updatedAt : timestamp
226
+ };
227
+
228
+ obj['device_id'] = deviceId;
229
+ obj['mqtt_id'] = dbTopicId;
230
+ obj['source'] = from;
231
+ obj['action'] = action;
232
+ obj['payload'] = payload;
233
+
234
+ $.db.insert("logs_mqtt",obj)
235
+ .then (rows => {
236
+ return resolve(rows);
237
+ })
238
+ .catch(error => {
239
+ return reject(error);
240
+ });
241
+ });
242
+ },
243
+
244
+ addMqttMsgLog : async(deviceId,topic,payload,retain,qos)=>{
245
+ return new Promise((resolve,reject) => {
246
+
247
+ const timestamp = moment().utc().format('YYYY-MM-DD HH:mm:ss')
248
+ let obj = {
249
+ createdAt : timestamp,
250
+ updatedAt : timestamp
251
+ };
252
+
253
+ obj['device_id'] = deviceId;
254
+ obj['topic'] = topic;
255
+ obj['payload'] = payload;
256
+ obj['retain'] = retain;
257
+ obj['qos'] = qos;
258
+
259
+ $.db.insert("logs_mqtt_msgs",obj)
260
+ .then (rows => {
261
+ return resolve(rows);
262
+ })
263
+ .catch(error => {
264
+ return reject(error);
265
+ });
266
+ });
267
+ },
268
+
219
269
  addLogIfChanged : async(id,column,value)=>{
220
270
  return new Promise(async (resolve,reject) => {
221
271
 
@@ -33,7 +33,7 @@ var self = module.exports = {
33
33
  });
34
34
  },
35
35
 
36
- parseMessage : async (client,topic,payload,retain)=>{
36
+ parseMessage : async (client,topic,payload,retain,qos=0)=>{
37
37
 
38
38
  let topic_bck = topic;
39
39
  let project_name = null;
@@ -77,6 +77,7 @@ var self = module.exports = {
77
77
  if(device.protocol.toLowerCase() === "lwm2m"){
78
78
  parseLwm2mMessage(client, project_name, device, topic, payload, action);
79
79
  }else if(device.protocol.toLowerCase() === "mqtt"){
80
+ $.db_device.addMqttMsgLog(device.id,topic,payload,retain,qos);
80
81
  parseMqttMessage(client, project_name, device, topic, payload, retain);
81
82
  }
82
83
  },
@@ -266,7 +267,6 @@ var self = module.exports = {
266
267
  }
267
268
  },
268
269
 
269
-
270
270
  updateSensor : async (device,ref,payload)=>{
271
271
 
272
272
  let sensors = await $.db_device.getSensorsByRef(device.id,ref)
@@ -319,17 +319,37 @@ var self = module.exports = {
319
319
 
320
320
  handleMqttTopic : async(device, dbTopic, payload, set)=>{
321
321
  if(set){
322
+ if(payload === "" || payload == null){
323
+ // acknowledgment
324
+ $.db_device.setSynchedTopic(dbTopic.id,true);
325
+ $.db_device.updateRemoteTopic(dbTopic.id,dbTopic?.localData?.value ? dbTopic.localData.value : dbTopic?.localData);
326
+ let from = "device";
327
+ let action = "ack"
328
+ $.db_device.addMqttLog(device.id,dbTopic.id,from,action,null);
329
+ return;
330
+ }
322
331
  // update local topic
332
+ let from = "server";
333
+ let action = "write";
334
+ $.db_device.addMqttLog(device.id,dbTopic.id,from,action,JSON.stringify(payload));
335
+
323
336
  $.db_device.updateLocalTopic(dbTopic.id,payload)
324
337
  .then(()=>{
325
338
  // set as not synched
326
- $.db_device.setSynchedTopic(dbTopic.id,false);
339
+ if(isDeepStrictEqual(payload, dbTopic?.remoteData))
340
+ $.db_device.setSynchedTopic(dbTopic.id,true);
341
+ else
342
+ $.db_device.setSynchedTopic(dbTopic.id,false);
327
343
  })
328
344
  .catch((error)=>{
329
345
  console.error(error);
330
346
  })
331
347
  }else{
332
348
  // update remote topic
349
+ let from = "device";
350
+ let action = "update";
351
+ $.db_device.addMqttLog(device.id,dbTopic.id,from,action,JSON.stringify(payload));
352
+
333
353
  $.db_device.updateRemoteTopic(dbTopic.id,payload)
334
354
  .then(async (res)=>{
335
355
  // check if topics mismatch
@@ -383,8 +403,17 @@ async function parseLwm2mMessage(client, project_name, device, topic, payload, a
383
403
 
384
404
  async function parseMqttMessage(client, project_name, device, topic, payload, retain){
385
405
 
386
- if(topic.endsWith("/get"))
406
+ if(topic.endsWith("/get")){
407
+ let findTopic = $.parser.getWordBeforeLastSlash(topic);
408
+ const dbTopic = await $.db_device.getMqttTopic(device.id,findTopic)
409
+ if(dbTopic != null){
410
+ let from = "server";
411
+ let action = "request";
412
+ let data = null;
413
+ $.db_device.addMqttLog(device.id,dbTopic.id,from,action,data);
414
+ }
387
415
  return;
416
+ }
388
417
 
389
418
  const topicBck = topic;
390
419
  //console.log("[MQTT] parse topic: ",topic);
@@ -485,7 +514,8 @@ async function parseMqttMessage(client, project_name, device, topic, payload, re
485
514
  }
486
515
  }
487
516
  break;
488
- case "settings":
517
+ case "settings": // deprecated
518
+ break;
489
519
  if(topic.endsWith("/set")){
490
520
  updateLocalSettings(device,topic,payload);
491
521
  }else{
@@ -525,19 +555,25 @@ async function synchMqttTopic(device,dbTopic){
525
555
  let mqtt_prefix = `${project.name}/${device.uid}`;
526
556
  let topic = `${mqtt_prefix}/${dbTopic.topic}/set`
527
557
  let payload = "";
528
- if(dbTopic?.remoteData && typeof dbTopic?.remoteData === 'object'){
558
+ if(dbTopic?.localData && typeof dbTopic?.localData === 'object'){
529
559
  try{
530
- payload = JSON.stringify(dbTopic?.remoteData);
560
+ if(dbTopic?.localData?.value)
561
+ payload = JSON.stringify(dbTopic?.localData?.value);
562
+ else
563
+ payload = JSON.stringify(dbTopic?.localData);
531
564
  }catch(err){
532
565
  console.error(err);
533
566
  return;
534
567
  }
535
568
  }else{
536
- payload = dbTopic?.remoteData;
569
+ payload = dbTopic?.localData;
537
570
  }
538
571
  $.mqtt_client.publish(topic,payload,{qos:1,retain:false});
539
572
  }
540
573
 
574
+ // keep a struct with all settings configured on the device
575
+ // only topics <project>/<uid>/settings are stored on this struct
576
+ // easier way to return all settings at once
541
577
  async function updateLocalSettings(device,topic,payload){
542
578
 
543
579
  $.db_device.addLog(device.id,"local_settings",JSON.stringify(payload));
@@ -586,6 +622,9 @@ async function updateLocalSettings(device,topic,payload){
586
622
  }
587
623
  }
588
624
 
625
+ // keep a struct with all settings configured on the device
626
+ // only topics <project>/<uid>/settings are stored on this struct
627
+ // easier way to return all settings at once
589
628
  async function updateRemoteSettings(device,topic,payload){
590
629
 
591
630
  $.db_device.addLog(device.id,"remote_settings",JSON.stringify(payload));
@@ -629,13 +668,15 @@ async function updateRemoteSettings(device,topic,payload){
629
668
 
630
669
  try {
631
670
  await $.db_device.updateRemoteSettings(JSON.stringify(settings), device.id);
632
- if(device?.synch)
671
+ // deprecated, only defined topics with synch enabled can be synched
672
+ if(device?.synch && false)
633
673
  synchSettings(device,route[0]);
634
674
  } catch (err) {
635
675
  console.error("Failed to update local settings:", err);
636
676
  }
637
677
  }
638
678
 
679
+ // deprecated - only defined mqtt topics can be synched
639
680
  async function synchSettings(device,key){
640
681
 
641
682
  console.log(`check topic ${key} from ${device.uid}`);
@@ -646,6 +687,7 @@ async function synchSettings(device,key){
646
687
  console.log(remoteSettings)
647
688
 
648
689
  //let keys = await checkSettings(localSettings,remoteSettings);
690
+ /*
649
691
  if(localSettings?.hasOwnProperty(key) && remoteSettings?.hasOwnProperty(key)){
650
692
  if(!isDeepStrictEqual(localSettings?.[key], remoteSettings?.[key])){
651
693
  const project = await $.db_project.getById(device.project_id);
@@ -662,9 +704,9 @@ async function synchSettings(device,key){
662
704
  }
663
705
  }
664
706
  }
707
+ */
665
708
  }
666
709
 
667
-
668
710
  function handleFotaSuccess (deviceId){
669
711
  let object = {
670
712
  "nAttempts" : 0,
@@ -140,6 +140,7 @@ var self = module.exports = {
140
140
 
141
141
  try{
142
142
  payload = JSON.parse(payload);
143
+ //console.log(`[KAFKA] payload: ${payload.mqtt.payload}`);
143
144
  }catch(error){
144
145
  console.log(`[KAFKA] error: ${payload}`);
145
146
  console.log(error)