mqtt-devices-parser 1.0.17 → 1.0.19

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,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.19
4
+ Removes adding project on launching process
5
+ models/models:
6
+ - seedCommonLwM2MObjects: avoids error on description property not defined on object
7
+ - changes lwm2m seed functions name
8
+
9
+ ## 1.0.18
10
+ Fix and improve Sensors, checks uid length
11
+ Adds seedCommonLwM2MObjects and seedCommonLwM2MResources functions
12
+ fixes sync project tables. Makes load .models more robust
13
+ Adds templates table
14
+ add template_id to devices table
15
+
3
16
  ## 1.0.17
4
17
  Fix and improve Sensors, checks uid length
5
18
  config/index: When defining a project from here uidPrefix and uidLength must be defined
package/config/index.js CHANGED
@@ -27,7 +27,7 @@ module.exports = {
27
27
  projects: {
28
28
  demo : process.env.demo || false,
29
29
  },
30
- demo : {
30
+ demo : { // not need anymore. Can be created on dashboard
31
31
  uidPrefix: 'uid:',
32
32
  uidLength: 16 // max len for uid
33
33
  }
package/index.js CHANGED
@@ -94,7 +94,7 @@ var self = module.exports = {
94
94
 
95
95
  //main tables
96
96
  if($.config.sync_main_tables){
97
-
97
+
98
98
  await $.models.load(__dirname+"/models");
99
99
  await $.models.dropTableIndexes();
100
100
  await $.models.sync();
@@ -106,7 +106,8 @@ var self = module.exports = {
106
106
  await $.models.insertUser("client","client_pwd",3);
107
107
  // adds client with credentials admin@admin
108
108
  await $.models.insertClient("admin","admin",user_id); // dashboard login
109
-
109
+
110
+ /* Add projects using dashboard !!
110
111
  for(name of projects){
111
112
  project = $.config[name];
112
113
  if (project) {
@@ -115,13 +116,11 @@ var self = module.exports = {
115
116
  await $.models.insertProject(projectData);
116
117
  }
117
118
  }
119
+ */
118
120
  }
119
121
 
120
122
  // project tables
121
123
  await self.readModelsInsideProjects(projectsPath);
122
- await $.models.dropTableIndexes();
123
- await $.models.sync();
124
-
125
124
  }
126
125
  }
127
126
 
@@ -20,6 +20,10 @@ module.exports = (sequelize,DataTypes)=>{
20
20
  key: 'id'
21
21
  }
22
22
  },
23
+ template_id: {
24
+ type: DataTypes.INTEGER,
25
+ allowNull: true
26
+ },
23
27
  model_id: {
24
28
  type: DataTypes.INTEGER,
25
29
  references: {
package/models/models.js CHANGED
@@ -39,22 +39,28 @@ var self = module.exports = {
39
39
 
40
40
  load: async (modelsPath) => {
41
41
  return new Promise(async (resolve, reject) => {
42
- var files = await fs.readdir(modelsPath);
43
- files = files.filter((file) => {
44
- // Exclude models.js and non-js files
45
- return (
46
- file.indexOf('.') !== 0 &&
47
- file !== 'models.js' &&
48
- file.slice(-9) === 'models.js'
49
- );
50
- });
51
- files.forEach((file, counter) => {
52
- const model = require(path.join(modelsPath, file));
53
- model(sequelize, DataTypes);
54
- if (counter === files.length - 1) {
55
- return resolve();
42
+ try {
43
+ let files = await fs.readdir(modelsPath);
44
+ files = files.filter((file) => {
45
+ // Exclude models.js and non-js files
46
+ return (
47
+ file.indexOf('.') !== 0 &&
48
+ file !== 'models.js' &&
49
+ file.slice(-9) === 'models.js'
50
+ );
51
+ });
52
+
53
+ // Use a for...of loop to load models sequentially
54
+ for (const file of files) {
55
+ console.log(`Sync file ${file}`);
56
+ const model = require(path.join(modelsPath, file));
57
+ await model(sequelize, DataTypes); // Ensure each model is loaded before moving to the next
56
58
  }
57
- });
59
+
60
+ resolve(); // Resolve the Promise after all files are processed
61
+ } catch (error) {
62
+ reject(error); // Reject the Promise on any error
63
+ }
58
64
  });
59
65
  },
60
66
 
@@ -246,5 +252,153 @@ var self = module.exports = {
246
252
  });
247
253
  });
248
254
  },
249
-
255
+
256
+ seedLwM2MObjects: async(objects) => {
257
+ try {
258
+ const results = await Promise.all(
259
+ objects.map(async (object) => {
260
+ const [record, created] = await sequelize.models['lwm2mObjects'].upsert(
261
+ {
262
+ objectId: object.objectId,
263
+ name: object.name,
264
+ description: object?.description,
265
+ },
266
+ {
267
+ where: { objectId: object.objectId }, // Ensure the record exists based on objectId
268
+ }
269
+ );
270
+ return { record, created };
271
+ })
272
+ );
273
+ console.log("Insert/Update completed for LwM2M Objects.");
274
+ return results;
275
+ } catch (error) {
276
+ console.error("Error inserting/updating LwM2M Objects:", error.message);
277
+ throw error;
278
+ }
279
+ },
280
+ /*
281
+ seedCommonLwM2MResources: async(resources) => {
282
+ try {
283
+ const results = await Promise.all(
284
+ resources.map(async (resource) => {
285
+ const [record, created] = await sequelize.models['lwm2mResources'].upsert(
286
+ {
287
+ objectId: resource.objectId,
288
+ resourceId: resource.resourceId,
289
+ name: resource.name,
290
+ description: resource.description,
291
+ },
292
+ {
293
+ where: { objectId: object.objectId, resourceId: object.resourceId }, // Ensure the record exists based on objectId and resourceId
294
+ }
295
+ );
296
+ return { record, created };
297
+ })
298
+ );
299
+ console.log("Insert/Update completed for LwM2M Resources.");
300
+ return results;
301
+ } catch (error) {
302
+ console.error("Error inserting/updating LwM2M Resources:", error.message);
303
+ throw error;
304
+ }
305
+ },
306
+ */
307
+
308
+ /**
309
+ * Seed LwM2M resources into the database.
310
+ *
311
+ * Expected DB model: sequelize.models['lwm2mResources']
312
+ * with a composite unique key on (objectId, resourceId) recommended.
313
+ *
314
+ * @param {Array} resources - Either:
315
+ * - Flat: [{ objectId, resourceId, name, description }, ...]
316
+ * - Nested: [{ objectId, name, resources: [{ resourceId, name, description }, ...] }, ...]
317
+ * @param {import('sequelize').Sequelize} sequelize - An initialized Sequelize instance.
318
+ * @returns {Promise<Array<{ objectId:number, resourceId:number, created:boolean, updated:boolean }>>}
319
+ */
320
+ seedLwM2MResources: async (resources) => {
321
+ if (!sequelize || !sequelize.models || !sequelize.models['lwm2mResources']) {
322
+ throw new Error("sequelize instance with model 'lwm2mResources' is required");
323
+ }
324
+ if (!Array.isArray(resources)) {
325
+ throw new Error('resources must be an array');
326
+ }
327
+
328
+ // Normalize input: flatten nested object.resources into a flat {objectId,resourceId,...} list
329
+ const flatResources = [];
330
+ for (const entry of resources) {
331
+ if (entry && Array.isArray(entry.resources)) {
332
+ // Nested structure: object -> resources[]
333
+ for (const res of entry.resources) {
334
+ flatResources.push({
335
+ objectId: entry.objectId,
336
+ resourceId: res.resourceId,
337
+ name: res.name,
338
+ description: res.description
339
+ });
340
+ }
341
+ } else if (
342
+ entry &&
343
+ typeof entry.objectId !== 'undefined' &&
344
+ typeof entry.resourceId !== 'undefined'
345
+ ) {
346
+ // Already flat
347
+ flatResources.push({
348
+ objectId: entry.objectId,
349
+ resourceId: entry.resourceId,
350
+ name: entry.name,
351
+ description: entry.description
352
+ });
353
+ } else {
354
+ // Skip invalid entries but warn
355
+ // eslint-disable-next-line no-console
356
+ console.warn('Skipping invalid resource entry:', entry);
357
+ }
358
+ }
359
+
360
+ const { lwm2mResources } = sequelize.models;
361
+
362
+ const results = [];
363
+ try {
364
+ await sequelize.transaction(async (t) => {
365
+ for (const res of flatResources) {
366
+ const where = { objectId: res.objectId, resourceId: res.resourceId };
367
+
368
+ // Try to find existing record
369
+ const [record, created] = await lwm2mResources.findOrCreate({
370
+ where,
371
+ defaults: {
372
+ name: res.name,
373
+ description: res.description
374
+ },
375
+ transaction: t
376
+ });
377
+
378
+ if (!created) {
379
+ // Update existing with latest values
380
+ await record.update(
381
+ { name: res.name, description: res.description },
382
+ { transaction: t }
383
+ );
384
+ }
385
+
386
+ results.push({
387
+ objectId: res.objectId,
388
+ resourceId: res.resourceId,
389
+ created,
390
+ updated: !created
391
+ });
392
+ }
393
+ });
394
+
395
+ // eslint-disable-next-line no-console
396
+ console.log('Insert/Update completed for LwM2M Resources.');
397
+ return results;
398
+ } catch (error) {
399
+ // eslint-disable-next-line no-console
400
+ console.error('Error inserting/updating LwM2M Resources:', error.message);
401
+ throw error;
402
+ }
403
+ }
250
404
  };
@@ -0,0 +1,25 @@
1
+
2
+ module.exports = (sequelize,DataTypes)=>{
3
+ return sequelize.define("templates", {
4
+ tag: {
5
+ type: DataTypes.STRING,
6
+ allowNull: false
7
+ },
8
+ name: {
9
+ type: DataTypes.STRING,
10
+ allowNull: false
11
+ },
12
+ client_id: {
13
+ type: DataTypes.INTEGER,
14
+ allowNull: false
15
+ },
16
+ project_id: {
17
+ type: DataTypes.INTEGER,
18
+ allowNull: false
19
+ },
20
+ },
21
+ {
22
+ tableName: 'templates',
23
+ freezeTableName: true
24
+ })
25
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mqtt-devices-parser",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {