mqtt-devices-parser 1.0.8 → 1.0.10

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,7 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.10
4
+ src/db/data: handles json data
5
+ - Adds updateJson call
6
+ - Adds addJsonLog
7
+ src/db/project: deals with settings
8
+ src/device/device: fixes fota fw link, stores settings on project table (twin model)
9
+
10
+ ## 1.0.9
11
+ - Adds method to delete logs older than 1 week
12
+
3
13
  ## 1.0.8
4
14
  - removes port from link to update fw devices
15
+ - fixes fw_version comparison
5
16
 
6
17
  ## 1.0.7
7
18
  - config/index: changes local IP
package/index.js CHANGED
@@ -41,6 +41,11 @@ var self = module.exports = {
41
41
  console.log("mqtt connecting..")
42
42
  mqtt_connect();
43
43
 
44
+ setInterval(async ()=>{
45
+ await $.device.deleteLogs();
46
+ },60*60*1000);
47
+
48
+
44
49
  return resolve();
45
50
  })
46
51
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mqtt-devices-parser",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/db/data.js CHANGED
@@ -5,24 +5,24 @@ var self = module.exports = {
5
5
 
6
6
  checkEntry : async (table,deviceId)=>{
7
7
 
8
- return new Promise((resolve,reject) => {
9
-
10
- let query = "SELECT * FROM ?? where device_id = ?";
11
- let args = [table,deviceId];
12
- query = mysql.format(query,args);
13
-
14
- $.db.queryRow(query)
15
- .then( rows => {
16
- if(rows.length > 0)
17
- return resolve(rows[0]);
18
- else
19
- return resolve(null);
20
- })
21
- .catch( err => {
22
- console.log(err);
23
- return resolve(null);
24
- });
25
- });
8
+ return new Promise((resolve,reject) => {
9
+
10
+ let query = "SELECT * FROM ?? where device_id = ?";
11
+ let args = [table,deviceId];
12
+ query = mysql.format(query,args);
13
+
14
+ $.db.queryRow(query)
15
+ .then( rows => {
16
+ if(rows.length > 0)
17
+ return resolve(rows[0]);
18
+ else
19
+ return resolve(null);
20
+ })
21
+ .catch( err => {
22
+ console.log(err);
23
+ return resolve(null);
24
+ });
25
+ });
26
26
  },
27
27
 
28
28
  update : async (table, deviceId, topic, payload)=>{
@@ -54,41 +54,41 @@ var self = module.exports = {
54
54
  topic = topic.substring(index+1);
55
55
 
56
56
  if(db_columns.hasOwnProperty(key)){ // check if db has a column for this key
57
- // create JSON struct with the remaining topic
58
- // table is the table
59
- // key is the column
60
-
61
- // build object with the remaining topic and respective data
62
- if(typeof data === "object")
63
- obj[key] = JSON.stringify(parser.pathIntoObject(topic,JSON.stringify(data)))
64
- else
65
- obj[key] = JSON.stringify(parser.pathIntoObject(topic,data));
66
-
67
- let exists = await self.checkEntry(table,deviceId);
68
- if(!exists){
69
- obj['device_id'] = deviceId;
70
- obj['createdAt'] = moment().utc().format('YYYY-MM-DD HH:mm:ss');
71
- $.db.insert(table,obj)
72
- .then((rows)=>{
73
- return resolve(rows);
74
- })
75
- .catch((err)=>{
76
- console.log(err);
77
- return resolve();
78
- })
79
- }else{
80
- let filter = {
81
- device_id : deviceId
82
- }
83
- $.db.update(table,obj,filter)
84
- .then((rows)=>{
85
- return resolve(rows);
86
- })
87
- .catch((err)=>{
88
- console.log(err);
89
- return resolve();
90
- })
91
- }
57
+ // create JSON struct with the remaining topic
58
+ // table is the table
59
+ // key is the column
60
+
61
+ // build object with the remaining topic and respective data
62
+ if(typeof data === "object")
63
+ obj[key] = JSON.stringify(parser.pathIntoObject(topic,JSON.stringify(data)))
64
+ else
65
+ obj[key] = JSON.stringify(parser.pathIntoObject(topic,data));
66
+
67
+ let exists = await self.checkEntry(table,deviceId);
68
+ if(!exists){
69
+ obj['device_id'] = deviceId;
70
+ obj['createdAt'] = moment().utc().format('YYYY-MM-DD HH:mm:ss');
71
+ $.db.insert(table,obj)
72
+ .then((rows)=>{
73
+ return resolve(rows);
74
+ })
75
+ .catch((err)=>{
76
+ console.log(err);
77
+ return resolve();
78
+ })
79
+ }else{
80
+ let filter = {
81
+ device_id : deviceId
82
+ }
83
+ $.db.update(table,obj,filter)
84
+ .then((rows)=>{
85
+ return resolve(rows);
86
+ })
87
+ .catch((err)=>{
88
+ console.log(err);
89
+ return resolve();
90
+ })
91
+ }
92
92
 
93
93
  }else return resolve();
94
94
  }else{
@@ -115,7 +115,7 @@ var self = module.exports = {
115
115
  })
116
116
  }else{
117
117
  let filter = {
118
- device_id : deviceId
118
+ device_id : deviceId
119
119
  }
120
120
 
121
121
  $.db.update(table,obj,filter)
@@ -132,28 +132,195 @@ var self = module.exports = {
132
132
  })
133
133
  },
134
134
 
135
+ updateJson : async (table, deviceId, payload)=>{
136
+
137
+ return new Promise( async (resolve, reject) => {
138
+
139
+ if (!payload || typeof payload !== 'object')
140
+ return resolve();
141
+
142
+ let obj = {
143
+ updatedAt: moment().utc().format('YYYY-MM-DD HH:mm:ss'),
144
+ device_id: deviceId,
145
+ };
146
+
147
+ // Get columns info
148
+ const db_columns = $.models.get(table);
149
+ if (db_columns == null)
150
+ return resolve();
151
+
152
+ // Prepare data for insertion
153
+ for (let key in payload) {
154
+ if (db_columns.hasOwnProperty(key)) {
155
+ let value = payload[key];
156
+
157
+ // Convert object to JSON string if needed
158
+ if (typeof value === 'object') {
159
+ value = JSON.stringify(value);
160
+ }
161
+
162
+ obj[key] = value;
163
+ }
164
+ }
165
+
166
+ let exists = await self.checkEntry(table,deviceId);
167
+ if(!exists){
168
+ obj['createdAt'] = moment().utc().format('YYYY-MM-DD HH:mm:ss');
169
+ $.db.insert(table,obj)
170
+ .then((rows)=>{
171
+ return resolve(rows);
172
+ })
173
+ .catch((err)=>{
174
+ console.log(err);
175
+ return resolve();
176
+ })
177
+ }else{
178
+ let filter = {
179
+ device_id : deviceId
180
+ }
181
+ $.db.update(table,obj,filter)
182
+ .then((rows)=>{
183
+ return resolve(rows);
184
+ })
185
+ .catch((err)=>{
186
+ console.log(err);
187
+ return resolve();
188
+ })
189
+ }
190
+
191
+ return resolve();
192
+ });
193
+ },
194
+
135
195
  addLog : async (table, deviceId, topic, payload)=>{
136
196
 
137
197
  return new Promise((resolve,reject) => {
138
198
 
139
199
  if(!payload) return resolve();
140
200
 
141
- let data = null;
142
- // check if data is in JSON format
143
- try{
144
- data = JSON.parse(payload);
145
- }catch(e){
146
- data = payload;
147
- }
201
+ let data = null;
202
+ // check if data is in JSON format
203
+ try{
204
+ data = JSON.parse(payload);
205
+ }catch(e){
206
+ data = payload;
207
+ }
148
208
 
149
- let obj = {
150
- updatedAt : moment().utc().format('YYYY-MM-DD HH:mm:ss')
151
- }
209
+ let obj = {
210
+ updatedAt : moment().utc().format('YYYY-MM-DD HH:mm:ss')
211
+ }
212
+
213
+ let db_columns = $.models.get(table);
214
+ if(db_columns == null)
215
+ return resolve();
216
+
217
+ let index = topic.indexOf("/");
218
+
219
+ if(index > -1){ // check if topic has subtopics
220
+ let key = topic.substring(0,index);
221
+ topic = topic.substring(index+1);
222
+
223
+ if(db_columns.hasOwnProperty(key)){ // check if db has a column for this key
224
+ // create JSON struct with the remaining topic
225
+ // key is the column
226
+
227
+ // build object with the remaining topic and respective data
228
+ if(typeof data === "object")
229
+ obj[key] = JSON.stringify(parser.pathIntoObject(topic,JSON.stringify(data)))
230
+ else
231
+ obj[key] = JSON.stringify(parser.pathIntoObject(topic,data));
232
+
233
+ obj['device_id'] = deviceId;
234
+ obj['createdAt'] = moment().utc().format('YYYY-MM-DD HH:mm:ss');
235
+ $.db.insert(table,obj)
236
+ .then((rows)=>{
237
+ return resolve(rows);
238
+ })
239
+ .catch((err)=>{
240
+ console.log(err);
241
+ return resolve();
242
+ })
243
+
244
+ }else
245
+ return resolve();
246
+ }else{
247
+
248
+ let key = topic;
249
+ if(db_columns.hasOwnProperty(key)){ // check if db has a column for this key
250
+ // build object with respective data
251
+ if(typeof data === "object")
252
+ obj[key] = JSON.stringify(data);
253
+ else
254
+ obj[key] = data;
255
+
256
+ obj['device_id'] = deviceId;
257
+ obj['createdAt'] = moment().utc().format('YYYY-MM-DD HH:mm:ss');
258
+ $.db.insert(table,obj)
259
+ .then((rows)=>{
260
+ return resolve(rows);
261
+ })
262
+ .catch((err)=>{
263
+ console.log(err);
264
+ return resolve();
265
+ })
266
+ }else
267
+ return resolve();
268
+ }
269
+
270
+ });
271
+ },
272
+
273
+ addJsonLog: async (table, deviceId, dataObject) => {
274
+ return new Promise((resolve, reject) => {
275
+ if (!dataObject || typeof dataObject !== 'object')
276
+ return resolve();
277
+
278
+ let obj = {
279
+ updatedAt: moment().utc().format('YYYY-MM-DD HH:mm:ss'),
280
+ device_id: deviceId,
281
+ createdAt: moment().utc().format('YYYY-MM-DD HH:mm:ss')
282
+ };
283
+
284
+ // Get columns info
285
+ const db_columns = $.models.get(table);
286
+ if (db_columns == null)
287
+ return resolve();
288
+
289
+ // Prepare data for insertion
290
+ for (let key in dataObject) {
291
+ if (db_columns.hasOwnProperty(key)) {
292
+ let value = dataObject[key];
293
+
294
+ // Convert object to JSON string if needed
295
+ if (typeof value === 'object') {
296
+ value = JSON.stringify(value);
297
+ }
298
+
299
+ obj[key] = value;
300
+ }
301
+ }
302
+
303
+ //console.log("updateJSONlog")
304
+ $.db.insert(table, obj)
305
+ .then((rows)=>{
306
+ return resolve(rows);
307
+ })
308
+ .catch((err)=>{
309
+ console.log(err);
310
+ return resolve();
311
+ })
312
+ });
313
+ },
314
+
315
+ deleteLogs : async (table, deviceId, topic, payload)=>{
316
+
317
+ return new Promise((resolve,reject) => {
152
318
 
153
319
  let db_columns = $.models.get(table);
154
320
  if(db_columns == null)
155
321
  return resolve();
156
322
 
323
+ $.db.delete(table,{id:0})
157
324
  let index = topic.indexOf("/");
158
325
 
159
326
  if(index > -1){ // check if topic has subtopics
@@ -173,7 +340,13 @@ var self = module.exports = {
173
340
  obj['device_id'] = deviceId;
174
341
  obj['createdAt'] = moment().utc().format('YYYY-MM-DD HH:mm:ss');
175
342
  $.db.insert(table,obj)
176
-
343
+ .then((rows)=>{
344
+ return resolve(rows);
345
+ })
346
+ .catch((err)=>{
347
+ console.log(err);
348
+ return resolve();
349
+ })
177
350
  }
178
351
  }else{
179
352
 
@@ -187,7 +360,7 @@ var self = module.exports = {
187
360
 
188
361
  obj['device_id'] = deviceId;
189
362
  obj['createdAt'] = moment().utc().format('YYYY-MM-DD HH:mm:ss');
190
- $.db.insert(table,obj);
363
+ $.db.insert(table,obj)
191
364
  }
192
365
  }
193
366
 
package/src/db/db.js CHANGED
@@ -264,6 +264,59 @@ var self = module.exports = {
264
264
  });
265
265
  },
266
266
 
267
+ getTables : async()=>{
268
+
269
+ return new Promise((resolve,reject) => {
270
+
271
+ self.getConnection((err,conn)=>{
272
+ if(err) return reject(err);
273
+
274
+ let query = "SHOW TABLES;"
275
+
276
+ conn.query(query,function(err,rows){
277
+ self.close_db_connection(conn);
278
+ if(err) return reject(err)
279
+ else return resolve(rows);
280
+ });
281
+ });
282
+ });
283
+ },
284
+
285
+ deleteOldEntries : async(table,filter)=>{
286
+
287
+ return new Promise((resolve,reject) => {
288
+
289
+ self.getConnection((err,conn)=>{
290
+ if(err) return reject(err);
291
+
292
+ let query = "";
293
+ if(typeof filter === "object"){
294
+ let values = [];
295
+ query = `DELETE FROM ?? WHERE `;
296
+ values.push(table);
297
+ for (let key in filter){
298
+ if(key == "createdAt"){
299
+ query += "createdAt < ?";
300
+ }else if(key = "id")
301
+ query += "id < ?"
302
+ else
303
+ return reject("key not supported");
304
+ values.push(filter[key]);
305
+ }
306
+ query = mysql.format(query,values);
307
+ }else{
308
+ return reject("filter passed is not an object");
309
+ }
310
+
311
+ conn.query(query,function(err,rows){
312
+ self.close_db_connection(conn);
313
+ if(err) return reject(err)
314
+ else return resolve(rows);
315
+ });
316
+ });
317
+ });
318
+ },
319
+
267
320
  getFieldFromDeviceId : async (table,deviceId,field)=>{
268
321
 
269
322
  return new Promise((resolve,reject) => {
package/src/db/project.js CHANGED
@@ -20,8 +20,7 @@ var self = module.exports = {
20
20
  return resolve(null);
21
21
  })
22
22
  .catch( err => {
23
- console.log(err);
24
- return resolve(null);
23
+ return reject(err);
25
24
  });
26
25
  });
27
26
  },
@@ -42,8 +41,7 @@ var self = module.exports = {
42
41
  return resolve(null);
43
42
  })
44
43
  .catch( err => {
45
- console.log(err);
46
- return resolve(null);
44
+ return reject(err);
47
45
  });
48
46
  });
49
47
  },
@@ -61,8 +59,7 @@ var self = module.exports = {
61
59
  return resolve(rows);
62
60
  })
63
61
  .catch( err => {
64
- console.log(err);
65
- return resolve(null);
62
+ return reject(null);
66
63
  });
67
64
  });
68
65
  },
@@ -88,4 +85,49 @@ var self = module.exports = {
88
85
  });
89
86
  },
90
87
 
88
+ getSettings : async(project,deviceId)=>{
89
+
90
+ return new Promise((resolve,reject) => {
91
+
92
+ let query = "SELECT settings FROM ?? where device_id = ?";
93
+ let table = [project, deviceId];
94
+ query = mysql.format(query,table);
95
+
96
+ $.db.queryRow(query)
97
+ .then( rows => {
98
+ if(rows?.length > 0)
99
+ return resolve(rows[0].settings);
100
+ else
101
+ return resolve(null);
102
+ })
103
+ .catch( err => {
104
+ return reject(err);
105
+ });
106
+ });
107
+ },
108
+
109
+ updateSettings : async(project, settings, deviceId)=>{
110
+
111
+ return new Promise((resolve,reject) => {
112
+ let obj = {
113
+ settings : settings,
114
+ updatedAt : moment().utc().format('YYYY-MM-DD HH:mm:ss')
115
+ }
116
+
117
+ let filter = {
118
+ device_id : deviceId
119
+ };
120
+
121
+ resolve(null)
122
+
123
+ $.db.update(project,obj,filter)
124
+ .then (rows => {
125
+ return resolve(rows[0]);
126
+ })
127
+ .catch(error => {
128
+ return reject(error);
129
+ });
130
+
131
+ });
132
+ },
91
133
  }
@@ -1,3 +1,4 @@
1
+ const moment = require('moment');
1
2
 
2
3
  var project = [];
3
4
  const logs_table = "sensor_logs";
@@ -31,6 +32,25 @@ var self = module.exports = {
31
32
 
32
33
  },
33
34
 
35
+ deleteLogs : async()=>{
36
+
37
+ let tables = await $.db.getTables();
38
+ // Define one week in milliseconds
39
+ // Loop through each table
40
+ for (const tableObj of tables) {
41
+ const tableName = tableObj['Tables_in_mqtt-aedes']
42
+ const oneWeekAgo = moment().utc().subtract(7, 'days').format('YYYY-MM-DD HH:mm:ss');
43
+ if(tableName.startsWith("logs_")){
44
+ const uptimeSeconds = Math.floor(process.uptime());
45
+ console.log(`deleting logs of table ${tableName} older than ${oneWeekAgo}"`);
46
+ await $.db.deleteOldEntries(tableName, { createdAt: oneWeekAgo });
47
+ time = Math.floor(process.uptime()) - uptimeSeconds;
48
+ console.log(`Logs of table ${tableName} deleted in ${time}s`);
49
+ }
50
+ }
51
+
52
+ },
53
+
34
54
  parseMessage : async (client,topic,payload,retain)=>{
35
55
 
36
56
  let topic_bck = topic;
@@ -110,15 +130,17 @@ var self = module.exports = {
110
130
  return;
111
131
 
112
132
  let mqtt_prefix = `${project_name}/${uid}`;
113
- let link = `${$.config.web.protocol}${$.config.web.domain}${$.config.web.fw_path}${new_firmware.filename}/download?token=${new_firmware.token}`;
114
133
 
115
- if(new_firmware != null && semver.lt(fw_version, new_firmware.fw_version)) {
116
- console.log(`updating firmware of ${uid} to ${new_firmware.fw_version}`);
134
+ if(new_app != null && semver.lt(app_version, new_app.app_version)) {
135
+ console.log(new_app)
136
+ console.log(`updating firmware of ${uid} to minor version ${new_app.app_version}`);
137
+ let link = `${$.config.web.protocol}${$.config.web.domain}${$.config.web.fw_path}${new_app.filename}/download?token=${new_app.token}`;
117
138
  client.publish(mqtt_prefix+"/fw/fota/update/set",`{"url":"${link}"}`,{qos:2,retain:false});
118
139
  await $.db_data.update(project_name,device.id,"fota_tries",++fota_tries);
119
140
  }else{
120
- if(new_app != null && semver.lt(app_version, new_app.app_version)) {
121
- console.log(`updating firmware of ${uid} to ${new_app.app_version}`);
141
+ if(new_firmware != null && semver.lt(fw_version, new_firmware.fw_version)) {
142
+ console.log(`updating firmware of ${uid} to major version ${new_firmware.fw_version}`);
143
+ let link = `${$.config.web.protocol}${$.config.web.domain}${$.config.web.fw_path}${new_firmware.filename}/download?token=${new_firmware.token}`;
122
144
  client.publish(mqtt_prefix+"/fw/fota/update/set",`{"url":"${link}"}`,{qos:2,retain:false});
123
145
  await $.db_data.update(project_name,device.id,"fota_tries",++fota_tries);
124
146
  }
@@ -133,6 +155,55 @@ var self = module.exports = {
133
155
  }
134
156
  }
135
157
 
158
+ // store remote device settings on project table - twin model
159
+ if(topic.endsWith("/set") && payload != "" ){
160
+
161
+ let route = topic.split("/");
162
+
163
+ if(route == null){
164
+ console.log("topic invalid:",topic);
165
+ return;
166
+ }
167
+ // get settings
168
+ let settings = await $.db_project.getSettings(project_name,device.id);
169
+ let obj = settings;
170
+
171
+ if(obj == null){
172
+ console.log("no settings available for deviceId:",device.id)
173
+ obj = {};
174
+ }
175
+ // Traverse through all route parts except the last one
176
+ route.slice(0, -1).forEach(property => {
177
+ if (!obj.hasOwnProperty(property) ||
178
+ ( obj.hasOwnProperty(property) && typeof obj[property] !== 'object'))
179
+ {
180
+ obj[property] = {}; // create nested object if missing or not an object
181
+ }
182
+ obj = obj[property]; // go deeper
183
+ })
184
+
185
+ let data = {};
186
+ try{
187
+ data = JSON.parse(payload)
188
+ }catch(error){}
189
+
190
+ if (true || (data && typeof payload === 'object' && !Array.isArray(payload) ) ) {
191
+ // Assuming payload is an object with properties to process
192
+ for (const [key, value] of Object.entries(data)) {
193
+ obj[key] = value; // go deeper
194
+ };
195
+ }else{
196
+ obj = payload
197
+ }
198
+
199
+ // update on device fw settings
200
+ try{
201
+ await $.db_project.updateSettings(project_name,JSON.stringify(settings),device.id);
202
+ }catch(error){
203
+ console.log(error);
204
+ }
205
+ }
206
+
136
207
  if(project[project_name]){
137
208
  project[project_name].module.parseMessage(client,project_name,device,topic,payload,retain,()=>{});
138
209
  }
@@ -141,3 +212,6 @@ var self = module.exports = {
141
212
  },
142
213
 
143
214
  }
215
+
216
+
217
+