mqtt-devices-parser 1.0.0

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.
@@ -0,0 +1,111 @@
1
+ const moment = require('moment');
2
+ var mysql = require('mysql2')
3
+
4
+ var self = module.exports = {
5
+
6
+ get : async (uid)=>{
7
+ return new Promise((resolve,reject) => {
8
+
9
+ let query = "SELECT id,uid,project_id,model_id,status FROM ?? where uid = ?";
10
+ let table = ["devices",uid];
11
+ query = mysql.format(query,table);
12
+
13
+ $.db.queryRow(query)
14
+ .then( rows => {
15
+ if(rows.length > 0)
16
+ return resolve(rows[0]);
17
+ else
18
+ return resolve(null);
19
+ })
20
+ .catch( err => {
21
+ console.log(err);
22
+ return resolve(null);
23
+ });
24
+ });
25
+ },
26
+
27
+ insert : async(uid)=>{
28
+
29
+ return new Promise((resolve,reject) => {
30
+ let obj = {
31
+ uid : uid,
32
+ createdAt : moment().utc().format('YYYY-MM-DD HH:mm:ss'),
33
+ updatedAt : moment().utc().format('YYYY-MM-DD HH:mm:ss')
34
+ }
35
+
36
+ $.db.insert("devices",obj)
37
+ .then (rows => {
38
+ return resolve(rows[0]);
39
+ })
40
+ .catch(error => {
41
+ return reject(error);
42
+ });
43
+ });
44
+ },
45
+
46
+ updateStatus : async(uid,status)=>{
47
+ return new Promise((resolve,reject) => {
48
+
49
+ let obj = {
50
+ status : status,
51
+ updatedAt : moment().utc().format('YYYY-MM-DD HH:mm:ss')
52
+ };
53
+
54
+ let filter = {
55
+ uid : uid,
56
+ };
57
+
58
+ $.db.update("devices",obj,filter)
59
+ .then (rows => {
60
+ return resolve(rows);
61
+ })
62
+ .catch(error => {
63
+ return reject(error);
64
+ });
65
+ });
66
+ },
67
+
68
+ updateProject : async(uid,project_id)=>{
69
+ return new Promise((resolve,reject) => {
70
+
71
+ let obj = {
72
+ project_id : project_id,
73
+ updatedAt : moment().utc().format('YYYY-MM-DD HH:mm:ss')
74
+ };
75
+
76
+ let filter = {
77
+ uid : uid,
78
+ };
79
+
80
+ $.db.update("devices",obj,filter)
81
+ .then (rows => {
82
+ return resolve(rows);
83
+ })
84
+ .catch(error => {
85
+ return reject(error);
86
+ });
87
+ });
88
+ },
89
+
90
+ updateModel : async(uid,model_id)=>{
91
+ return new Promise((resolve,reject) => {
92
+
93
+ let obj = {
94
+ model_id : model_id,
95
+ updatedAt : moment().utc().format('YYYY-MM-DD HH:mm:ss')
96
+ };
97
+
98
+ let filter = {
99
+ uid : uid,
100
+ };
101
+
102
+ $.db.update("devices",obj,filter)
103
+ .then (rows => {
104
+ return resolve(rows);
105
+ })
106
+ .catch(error => {
107
+ return reject(error);
108
+ });
109
+ });
110
+ },
111
+ }
@@ -0,0 +1,79 @@
1
+ const moment = require('moment');
2
+ var mysql = require('mysql2')
3
+
4
+ var self = module.exports = {
5
+
6
+ getLatestFWVersion : async (modelId,release)=>{
7
+
8
+ return new Promise((resolve,reject) => {
9
+
10
+ let query = "";
11
+ let table = [];
12
+
13
+ if(release == "stable"){
14
+ query = `SELECT fw_version,filename,token FROM firmwares where model_id = ? and fw_release = ? ORDER BY CAST(SUBSTRING_INDEX(fw_version, '.', 1) AS UNSIGNED) DESC,
15
+ CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(fw_version, '.', 2), '.', -1) AS UNSIGNED) DESC,
16
+ CAST(SUBSTRING_INDEX(fw_version, '.', -1) AS UNSIGNED) DESC
17
+ LIMIT 1`;
18
+ table = [modelId,release];
19
+ }else{
20
+ query = `SELECT fw_version,filename,token FROM firmwares where model_id = ? ORDER BY CAST(SUBSTRING_INDEX(fw_version, '.', 1) AS UNSIGNED) DESC,
21
+ CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(fw_version, '.', 2), '.', -1) AS UNSIGNED) DESC,
22
+ CAST(SUBSTRING_INDEX(fw_version, '.', -1) AS UNSIGNED) DESC
23
+ LIMIT 1`;
24
+ table = [modelId];
25
+ }
26
+
27
+ query = mysql.format(query,table);
28
+
29
+ $.db.queryRow(query)
30
+ .then( rows => {
31
+ if(rows.length > 0)
32
+ return resolve(rows[0]);
33
+ else
34
+ return resolve(null);
35
+ })
36
+ .catch( err => {
37
+ console.log(err);
38
+ return resolve(null);
39
+ });
40
+ });
41
+ },
42
+
43
+ getLatestAppVersion : async (modelId,release)=>{
44
+
45
+ return new Promise((resolve,reject) => {
46
+
47
+ let query = "";
48
+ let table = [];
49
+
50
+ if(release == "stable"){
51
+ query = `SELECT app_version,filename,token FROM firmwares where model_id = ? and fw_release = ? ORDER BY CAST(SUBSTRING_INDEX(app_version, '.', 1) AS UNSIGNED) DESC,
52
+ CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(app_version, '.', 2), '.', -1) AS UNSIGNED) DESC,
53
+ CAST(SUBSTRING_INDEX(app_version, '.', -1) AS UNSIGNED) DESC
54
+ LIMIT 1`;
55
+ table = [modelId,release];
56
+ }else{
57
+ query = `SELECT app_version,filename,token FROM firmwares where model_id = ? ORDER BY CAST(SUBSTRING_INDEX(app_version, '.', 1) AS UNSIGNED) DESC,
58
+ CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(app_version, '.', 2), '.', -1) AS UNSIGNED) DESC,
59
+ CAST(SUBSTRING_INDEX(app_version, '.', -1) AS UNSIGNED) DESC
60
+ LIMIT 1`;
61
+ table = [modelId];
62
+ }
63
+
64
+ query = mysql.format(query,table);
65
+
66
+ $.db.queryRow(query)
67
+ .then( rows => {
68
+ if(rows.length > 0)
69
+ return resolve(rows[0]);
70
+ else
71
+ return resolve(null);
72
+ })
73
+ .catch( err => {
74
+ console.log(err);
75
+ return resolve(null);
76
+ });
77
+ });
78
+ },
79
+ }
@@ -0,0 +1,115 @@
1
+ const moment = require('moment');
2
+ var mysql = require('mysql2')
3
+
4
+ var self = module.exports = {
5
+
6
+ getById : async (projectId)=>{
7
+
8
+ return new Promise((resolve,reject) => {
9
+
10
+ let query = "SELECT * FROM ?? where id = ?";
11
+ let table = ["models",projectId];
12
+ query = mysql.format(query,table);
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
+ },
27
+
28
+ getByName : async (model)=>{
29
+
30
+ return new Promise((resolve,reject) => {
31
+
32
+ let query = "SELECT * FROM ?? where name = ?";
33
+ let table = ["models",model];
34
+ query = mysql.format(query,table);
35
+
36
+ $.db.queryRow(query)
37
+ .then( rows => {
38
+ if(rows.length > 0)
39
+ return resolve(rows[0]);
40
+ else
41
+ return resolve(null);
42
+ })
43
+ .catch( err => {
44
+ console.log(err);
45
+ return resolve(null);
46
+ });
47
+ });
48
+ },
49
+
50
+ getAll : async ()=>{
51
+
52
+ return new Promise((resolve,reject) => {
53
+
54
+ let query = "SELECT id,name FROM ??";
55
+ let table = ["models"];
56
+ query = mysql.format(query,table);
57
+
58
+ $.db.queryRow(query)
59
+ .then( rows => {
60
+ return resolve(rows);
61
+ })
62
+ .catch( err => {
63
+ console.log(err);
64
+ return resolve(null);
65
+ });
66
+ });
67
+ },
68
+
69
+ insert : async(model, model_table, logs_table)=>{
70
+
71
+ return new Promise((resolve,reject) => {
72
+ let obj = {
73
+ name : model,
74
+ model_table : model_table,
75
+ logs_table : logs_table,
76
+ createdAt : moment().utc().format('YYYY-MM-DD HH:mm:ss'),
77
+ updatedAt : moment().utc().format('YYYY-MM-DD HH:mm:ss')
78
+ }
79
+
80
+ $.db.insert("models",obj)
81
+ .then (rows => {
82
+ return resolve(rows[0]);
83
+ })
84
+ .catch(error => {
85
+ return reject(error);
86
+ });
87
+ });
88
+ },
89
+
90
+ update : async(model, model_table, logs_table)=>{
91
+
92
+ return new Promise((resolve,reject) => {
93
+ let obj = {
94
+ name : model,
95
+ model_table : model_table,
96
+ logs_table : logs_table,
97
+ createdAt : moment().utc().format('YYYY-MM-DD HH:mm:ss'),
98
+ updatedAt : moment().utc().format('YYYY-MM-DD HH:mm:ss')
99
+ };
100
+
101
+ let filter = {
102
+ name : model
103
+ };
104
+
105
+ $.db.update("models",obj,filter)
106
+ .then (rows => {
107
+ return resolve(rows[0]);
108
+ })
109
+ .catch(error => {
110
+ return reject(error);
111
+ });
112
+ });
113
+ },
114
+
115
+ }
@@ -0,0 +1,91 @@
1
+ const moment = require('moment');
2
+ var mysql = require('mysql2')
3
+
4
+
5
+ var self = module.exports = {
6
+
7
+ getById : async (projectId)=>{
8
+
9
+ return new Promise((resolve,reject) => {
10
+
11
+ let query = "SELECT * FROM ?? where id = ?";
12
+ let table = ["projects",projectId];
13
+ query = mysql.format(query,table);
14
+
15
+ $.db.queryRow(query)
16
+ .then( rows => {
17
+ if(rows.length > 0)
18
+ return resolve(rows[0]);
19
+ else
20
+ return resolve(null);
21
+ })
22
+ .catch( err => {
23
+ console.log(err);
24
+ return resolve(null);
25
+ });
26
+ });
27
+ },
28
+
29
+ getByName : async (project)=>{
30
+
31
+ return new Promise((resolve,reject) => {
32
+
33
+ let query = "SELECT * FROM ?? where name = ?";
34
+ let table = ["projects",project];
35
+ query = mysql.format(query,table);
36
+
37
+ $.db.queryRow(query)
38
+ .then( rows => {
39
+ if(rows.length > 0)
40
+ return resolve(rows[0]);
41
+ else
42
+ return resolve(null);
43
+ })
44
+ .catch( err => {
45
+ console.log(err);
46
+ return resolve(null);
47
+ });
48
+ });
49
+ },
50
+
51
+ getAll : async ()=>{
52
+
53
+ return new Promise((resolve,reject) => {
54
+
55
+ let query = "SELECT id,name FROM ??";
56
+ let table = ["projects"];
57
+ query = mysql.format(query,table);
58
+
59
+ $.db.queryRow(query)
60
+ .then( rows => {
61
+ return resolve(rows);
62
+ })
63
+ .catch( err => {
64
+ console.log(err);
65
+ return resolve(null);
66
+ });
67
+ });
68
+ },
69
+
70
+ insert : async(project, project_table, logs_table)=>{
71
+
72
+ return new Promise((resolve,reject) => {
73
+ let obj = {
74
+ name : project,
75
+ project_table : project_table,
76
+ logs_table : logs_table,
77
+ createdAt : moment().utc().format('YYYY-MM-DD HH:mm:ss'),
78
+ updatedAt : moment().utc().format('YYYY-MM-DD HH:mm:ss')
79
+ }
80
+
81
+ $.db.insert("projects",obj)
82
+ .then (rows => {
83
+ return resolve(rows[0]);
84
+ })
85
+ .catch(error => {
86
+ return reject(error);
87
+ });
88
+ });
89
+ },
90
+
91
+ }
@@ -0,0 +1,113 @@
1
+ const moment = require('moment');
2
+ var mysql = require('mysql2')
3
+ const table = "sensors"
4
+
5
+ var self = module.exports = {
6
+
7
+ getById : async (id)=>{
8
+
9
+ return new Promise((resolve,reject) => {
10
+
11
+ let query = "SELECT * FROM ?? where id = ?";
12
+ let args = [table,id];
13
+ query = mysql.format(query,args);
14
+
15
+ $.db.queryRow(query)
16
+ .then( rows => {
17
+ if(rows.length > 0)
18
+ return resolve(rows[0]);
19
+ else
20
+ return resolve(null);
21
+ })
22
+ .catch( err => {
23
+ console.log(err);
24
+ return resolve(null);
25
+ });
26
+ });
27
+ },
28
+
29
+ getByRef : async (ref)=>{
30
+
31
+ return new Promise((resolve,reject) => {
32
+
33
+ let query = "SELECT * FROM ?? where ref = ?";
34
+ let args = [table,ref];
35
+ query = mysql.format(query,args);
36
+
37
+ $.db.queryRow(query)
38
+ .then( rows => {
39
+ if(rows.length > 0)
40
+ return resolve(rows[0]);
41
+ else
42
+ return resolve(null);
43
+ })
44
+ .catch( err => {
45
+ console.log(err);
46
+ return resolve(null);
47
+ });
48
+ });
49
+ },
50
+
51
+ getByName : async (name)=>{
52
+
53
+ return new Promise((resolve,reject) => {
54
+
55
+ let query = "SELECT * FROM ?? where name = ?";
56
+ let args = [table,name];
57
+ query = mysql.format(query,args);
58
+
59
+ $.db.queryRow(query)
60
+ .then( rows => {
61
+ if(rows.length > 0)
62
+ return resolve(rows[0]);
63
+ else
64
+ return resolve(null);
65
+ })
66
+ .catch( err => {
67
+ console.log(err);
68
+ return resolve(null);
69
+ });
70
+ });
71
+ },
72
+
73
+ getAll : async ()=>{
74
+
75
+ return new Promise((resolve,reject) => {
76
+
77
+ let query = "SELECT id,name FROM ??";
78
+ let args = [table];
79
+ query = mysql.format(query,args);
80
+
81
+ $.db.queryRow(query)
82
+ .then( rows => {
83
+ return resolve(rows);
84
+ })
85
+ .catch( err => {
86
+ console.log(err);
87
+ return resolve(null);
88
+ });
89
+ });
90
+ },
91
+
92
+ insert : async(table,deviceId,sensorId,payload)=>{
93
+
94
+ return new Promise((resolve,reject) => {
95
+ let obj = {
96
+ device_id : deviceId,
97
+ sensor_id : sensorId,
98
+ value : payload,
99
+ createdAt : moment().utc().format('YYYY-MM-DD HH:mm:ss'),
100
+ updatedAt : moment().utc().format('YYYY-MM-DD HH:mm:ss')
101
+ }
102
+
103
+ $.db.insert(table,obj)
104
+ .then (rows => {
105
+ return resolve(rows[0]);
106
+ })
107
+ .catch(error => {
108
+ return reject(error);
109
+ });
110
+ });
111
+ },
112
+
113
+ }
@@ -0,0 +1,59 @@
1
+
2
+ # Devices
3
+
4
+ ## State Machine
5
+ This modules parses mqtt messages with the following format
6
+
7
+ :project/:device/
8
+
9
+ Only messages with MACRO_UID_PREFIX in topic will be parsed.
10
+ MACRO_UID_PREFIX allows the module to discover the device uid.
11
+ If uid doesn't exist in db it will add it.
12
+ After that, it will associate the project if the project exists in db.
13
+ If the device already exists it will verify the project and update it in case of need
14
+
15
+ :project/:device/status
16
+ Updates the device status
17
+
18
+ :project/:device/model
19
+ Updates the model if the model already exists in db
20
+
21
+
22
+ ## New Project
23
+
24
+ In order to support a new type of device, you need to create a js file with the same name of topic before MACRO_UID_PREFIX
25
+
26
+ Example:
27
+
28
+ topic: demo/uid:001122aabbcc
29
+ MACRO_UID_PREFIX = "uid:"
30
+
31
+ demo is the project
32
+ uid:001122aabbcc is the UID
33
+
34
+ Then, inside projects folder, you can create a demo folder with apps and models as subfolders
35
+ Ex:
36
+
37
+ ../projects/demo/demo.js
38
+ ../projects/demo/apps/myapp/myapp.js
39
+ ../projects/demo/models/myapp.models.js
40
+
41
+ All messages published on the topic demo will be processed by demo.js file
42
+ You can also create models inside models folder and use it to store data
43
+
44
+ Furthermore, all published topics started with:
45
+ :project/:uid/app/:app
46
+ will call the respective modules inside apps folder.
47
+
48
+ Ex:
49
+ demo/uid:001122aabbcc/app/myapp/hello
50
+ will result in a call to myapp.parseMessage
51
+
52
+ To activate the project you just need to add the project in config/index.js file and set to true
53
+ projects: {
54
+ demo : process.env.demo || true
55
+ }
56
+
57
+
58
+
59
+
@@ -0,0 +1,97 @@
1
+
2
+ var project = [];
3
+ const logs_table = "sensor_logs";
4
+
5
+ var self = module.exports = {
6
+
7
+ init : async (projects)=>{
8
+
9
+ return new Promise(async (resolve,reject) => {
10
+ $.db.connect(()=>{
11
+ console.log("MYSQL is connected");
12
+
13
+ projects.map( async (name,counter)=>{
14
+ console.log("project:",name)
15
+ project[name] = {
16
+ module : null
17
+ };
18
+ project[name].module = require(`${BASE_DIR}/projects/${name}/${name}.js`)
19
+ project[name].module?.init();
20
+ let row = await $.db_project.getByName(name);
21
+ if(row == null)
22
+ $.db_project.insert(name,name,"logs_"+name);
23
+
24
+ if(counter == projects.length-1)
25
+ return resolve();
26
+ })
27
+ })
28
+ });
29
+
30
+
31
+ },
32
+
33
+ parseMessage : async (client,topic,payload,retain)=>{
34
+
35
+ let topic_bck = topic;
36
+
37
+ //let index = topic.indexOf(MACRO_UID_PREFIX);
38
+ // --- project ---
39
+ let index = topic.indexOf("/");
40
+ if(index == -1)
41
+ return;
42
+ let project_name = topic.substring(0,index);
43
+
44
+ // --- uid ---
45
+ topic = topic.substring(index+1);
46
+ index = topic.indexOf("/");
47
+ if(index == -1)
48
+ return;
49
+ let uid = topic.substring(0,index);
50
+
51
+ topic = topic.substring(index+1);
52
+
53
+ // check if topic corresponds to a device
54
+ if(uid.startsWith(MACRO_UID_PREFIX)){
55
+ let device = await $.db_device.get(uid);
56
+
57
+ if(device == null){
58
+ $.db_device.insert(uid)
59
+ .then(async()=>{
60
+ device = await $.db_device.get(uid);
61
+ })
62
+ .catch( (err) => {});
63
+ }
64
+
65
+ if(device?.project_id == null){
66
+ let res = await $.db_project.getByName(project_name);
67
+ let project_id = res?.id;
68
+ if(project_id != null) $.db_device.updateProject(uid,project_id);
69
+ }
70
+
71
+ if(topic.endsWith("status")){
72
+ if(payload == "online" || payload == "offline")
73
+ await $.db_device.updateStatus(uid,payload);
74
+ console.log(project_name,uid,payload)
75
+ }else if(topic.endsWith("model")){
76
+ let res = await $.db_model.getByName(payload);
77
+ let model_id = res?.id;
78
+
79
+ if(model_id != null) $.db_device.updateModel(uid,model_id);
80
+ }
81
+
82
+ if(device.project_id != null && device.model_id != null){
83
+ let res = await $.db_sensor.getByRef(topic)
84
+ if(res != null){
85
+ $.db_sensor.insert(logs_table,device.id,res.id,payload);
86
+ }
87
+ }
88
+
89
+ if(project[project_name]){
90
+ project[project_name].module.parseMessage(client,project_name,device,topic,payload,retain,()=>{});
91
+ }
92
+ }
93
+
94
+ },
95
+
96
+ }
97
+
@@ -0,0 +1,25 @@
1
+ var models_name = ["myapp"];
2
+ var model_table = "myapp";
3
+ var model_logs_table = "logs_myapp";
4
+
5
+ module.exports = {
6
+
7
+ init : async()=>{
8
+ console.log("App myapp from project freeRTOS2 started");
9
+
10
+ models_name.forEach(async(model_name)=>{
11
+ let res = await $.db_model.getByName(model_name);
12
+ let model_id = res?.id;
13
+
14
+ if(model_id == null) $.db_model.insert(model_name,model_table,model_logs_table);
15
+ })
16
+
17
+ },
18
+
19
+ parseMessage : async (client,app,device,topic,payload,retain,cb)=>{
20
+
21
+ $.db_data.update(model_table,device.id,topic,payload);
22
+ $.db_data.addLog(model_logs_table,device.id,topic,payload);
23
+
24
+ }
25
+ }