mqtt-devices-parser 1.0.0 → 1.0.2
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 +5 -0
- package/Readme.md +10 -52
- package/example/deploy.js +14 -0
- package/example/index.js +25 -0
- package/index.js +66 -4
- package/models/models.js +13 -16
- package/package.json +1 -1
- package/src/db/db.js +1 -3
- package/src/device/device.js +2 -3
- package/src/unitTest/device.test.js +2 -3
- package/deploy.js +0 -70
- package/src/projects/demo/apps/myapp.js +0 -25
- package/src/projects/demo/demo.js +0 -77
- package/src/projects/demo/models/logs_myapp.js +0 -17
- package/src/projects/demo/models/myapp.models.js +0 -18
package/Changelog.md
CHANGED
package/Readme.md
CHANGED
|
@@ -1,65 +1,23 @@
|
|
|
1
1
|
|
|
2
2
|
# mqtt-devices-parser
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Setup
|
|
8
|
-
|
|
9
|
-
### Command
|
|
10
|
-
>> node deploy
|
|
11
|
-
|
|
12
|
-
1. build/sync all tables inside models folder
|
|
13
|
-
2. registers users and clients if not registered already
|
|
14
|
-
|
|
15
|
-
3. build/sync all tables inside projects folder
|
|
16
|
-
4. registers projects and models/apps if not registered already
|
|
17
|
-
|
|
18
|
-
## Working mode
|
|
19
|
-
|
|
20
|
-
### Command
|
|
21
|
-
>> node index
|
|
22
|
-
|
|
23
|
-
1. Checks all projects inside src/projects folder and enable it if is activated in config/index.js
|
|
24
|
-
|
|
25
|
-
2. Connects to defined MQTT broker
|
|
26
|
-
|
|
27
|
-
3. Parse MQTT messages starting with :project/MACRO_UID_PREFIX+uid/
|
|
28
|
-
|
|
29
|
-
3.1 register device if not exists
|
|
30
|
-
3.2 Associate to a project if project is registered
|
|
31
|
-
3.3 Associate to a model/app if model is registered
|
|
32
|
-
|
|
33
|
-
4. Call project parseMessage function
|
|
34
|
-
|
|
35
|
-
## Instructions
|
|
36
|
-
|
|
37
|
-
Projects folders must be kept
|
|
38
|
-
|
|
39
|
-
The following functions must exist inside a file with the same name of the project
|
|
4
|
+
## NPM Module
|
|
5
|
+
- MQTT parser
|
|
6
|
+
- Parses topics coming from devices and updates data on dB
|
|
40
7
|
|
|
8
|
+
## Deploy
|
|
41
9
|
```
|
|
42
|
-
|
|
43
|
-
sync_db : async()=>{
|
|
44
|
-
},
|
|
45
|
-
init : async ()=>{
|
|
46
|
-
},
|
|
47
|
-
parseMessage : async (client, project, device, topic, payload, retain, cb)=>{
|
|
48
|
-
},
|
|
49
|
-
}
|
|
10
|
+
parser.deploy(config,projectsPath);
|
|
50
11
|
```
|
|
51
12
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
Calling the following methods will write data in a ${table} with the name of the project, and also
|
|
55
|
-
in other table called "logs_"+${table}. Data will be written if there is a field in the respective table
|
|
56
|
-
with the same name as the name in topic.
|
|
57
|
-
|
|
13
|
+
## Run
|
|
58
14
|
```
|
|
59
|
-
|
|
60
|
-
$.db_data.addLog("logs_"+project,device.id,topic,payload);
|
|
15
|
+
parser.init(config,projects);
|
|
61
16
|
```
|
|
62
17
|
|
|
18
|
+
## Examples
|
|
19
|
+
check example path to see how to use this module
|
|
20
|
+
|
|
63
21
|
## UnitTest
|
|
64
22
|
|
|
65
23
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const config = require('../config');
|
|
2
|
+
const parser = require('mqtt-devices-parser');
|
|
3
|
+
|
|
4
|
+
global.BASE_DIR = process.cwd();
|
|
5
|
+
var projectsPath = global.BASE_DIR+'../projects/';
|
|
6
|
+
|
|
7
|
+
parser.deploy(config,projectsPath);
|
|
8
|
+
|
|
9
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
10
|
+
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
11
|
+
// exit with failure code
|
|
12
|
+
if($.config.dev)
|
|
13
|
+
process.exit(1);
|
|
14
|
+
});
|
package/example/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
config = require('./config');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const parser = require('mqtt-devices-parser');
|
|
4
|
+
|
|
5
|
+
global.BASE_DIR = process.cwd();
|
|
6
|
+
var projectsPath = '../projects/';
|
|
7
|
+
var projects = [];
|
|
8
|
+
|
|
9
|
+
fs.readdirSync(projectsPath)
|
|
10
|
+
.filter((file) => {
|
|
11
|
+
return (file.indexOf('.') == -1);
|
|
12
|
+
})
|
|
13
|
+
.forEach((project) => {
|
|
14
|
+
if(config.projects[project])
|
|
15
|
+
projects.push(project);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
parser.init(config,projects);
|
|
19
|
+
|
|
20
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
21
|
+
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
22
|
+
// exit with failure code
|
|
23
|
+
if($.config.dev)
|
|
24
|
+
process.exit(1);
|
|
25
|
+
});
|
package/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const mqtt = require("mqtt");
|
|
2
|
+
const fs = require('fs').promises;
|
|
2
3
|
|
|
3
4
|
$ = {};
|
|
4
5
|
$.md5 = require('md5');
|
|
@@ -18,6 +19,7 @@ const packageJson = require(__dirname+'/package.json');
|
|
|
18
19
|
const packageVersion = packageJson.version;
|
|
19
20
|
|
|
20
21
|
var projects = [];
|
|
22
|
+
var project = {};
|
|
21
23
|
|
|
22
24
|
var self = module.exports = {
|
|
23
25
|
|
|
@@ -30,17 +32,79 @@ var self = module.exports = {
|
|
|
30
32
|
if(_projects != null)
|
|
31
33
|
projects = _projects;
|
|
32
34
|
|
|
33
|
-
await $.models.init();
|
|
35
|
+
await $.models.init(_config);
|
|
34
36
|
await $.models.connect();
|
|
35
37
|
|
|
36
38
|
//auth.init();
|
|
37
|
-
await $.device.init(projects);
|
|
39
|
+
await $.device.init(_config,projects);
|
|
38
40
|
|
|
39
41
|
console.log("mqtt connecting..")
|
|
40
42
|
mqtt_connect();
|
|
41
43
|
|
|
42
44
|
return resolve();
|
|
43
45
|
})
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
readModelsInsideProjects: async(projectsPath)=>{
|
|
49
|
+
|
|
50
|
+
return new Promise( async (resolve,reject) => {
|
|
51
|
+
|
|
52
|
+
// load projects dbs
|
|
53
|
+
var files = await fs.readdir(projectsPath)
|
|
54
|
+
|
|
55
|
+
files = files.filter((file) => {
|
|
56
|
+
// Exclude any extension file
|
|
57
|
+
return (file.indexOf('.') == -1);
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
let counter_help = 0;
|
|
61
|
+
files.forEach( async(name,counter) => {
|
|
62
|
+
if($.config.projects[name]){
|
|
63
|
+
project[name] = {};
|
|
64
|
+
project[name]['module'] = null;
|
|
65
|
+
project[name].module = require(`${projectsPath}${name}/${name}.js`)
|
|
66
|
+
await project[name].module.sync_db();
|
|
67
|
+
counter_help++;
|
|
68
|
+
if(files.length == counter_help) return resolve();
|
|
69
|
+
}else{
|
|
70
|
+
counter_help++;
|
|
71
|
+
if(files.length == counter_help) return resolve();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
deploy: async(_config,projectsPath)=>{
|
|
81
|
+
|
|
82
|
+
if(_config != null)
|
|
83
|
+
$.config = _config;
|
|
84
|
+
|
|
85
|
+
await $.models.init();
|
|
86
|
+
await $.models.connect();
|
|
87
|
+
|
|
88
|
+
//main tables
|
|
89
|
+
if($.config.sync_main_tables){
|
|
90
|
+
|
|
91
|
+
await $.models.load(__dirname+"/models");
|
|
92
|
+
await $.models.dropTableIndexes();
|
|
93
|
+
await $.models.sync();
|
|
94
|
+
|
|
95
|
+
let user = await $.models.insertUser("admin","admin",5); // ads user
|
|
96
|
+
//console.log(user);
|
|
97
|
+
let user_id = user.dataValues.id;
|
|
98
|
+
await $.models.insertUser("device","device",3);
|
|
99
|
+
await $.models.insertUser("client","client_pwd",3);
|
|
100
|
+
await $.models.insertClient("admin","admin",user_id); // ads client with credentials admin@admin
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// project tables
|
|
104
|
+
await self.readModelsInsideProjects(projectsPath);
|
|
105
|
+
await $.models.dropTableIndexes();
|
|
106
|
+
await $.models.sync();
|
|
107
|
+
|
|
44
108
|
}
|
|
45
109
|
}
|
|
46
110
|
|
|
@@ -109,5 +173,3 @@ function mqtt_connect(){
|
|
|
109
173
|
console.log(error)
|
|
110
174
|
})
|
|
111
175
|
}
|
|
112
|
-
|
|
113
|
-
|
package/models/models.js
CHANGED
|
@@ -6,24 +6,22 @@ var mysql = require('mysql2');
|
|
|
6
6
|
var sequelize;
|
|
7
7
|
|
|
8
8
|
//var modelsPath = './models/';
|
|
9
|
-
var config = require('../config');
|
|
10
9
|
|
|
11
10
|
var self = module.exports = {
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
})
|
|
12
|
+
init : async (config)=>{
|
|
13
|
+
|
|
14
|
+
return new Promise((resolve,reject) => {
|
|
15
|
+
sequelize = new Sequelize({
|
|
16
|
+
database: config.mysqldb.name,
|
|
17
|
+
username: config.mysqldb.user,
|
|
18
|
+
password: config.mysqldb.pwd,
|
|
19
|
+
host: config.mysqldb.host,
|
|
20
|
+
port: config.mysqldb.port,
|
|
21
|
+
dialect: 'mysql',
|
|
22
|
+
});
|
|
23
|
+
return resolve(sequelize);
|
|
24
|
+
})
|
|
27
25
|
},
|
|
28
26
|
|
|
29
27
|
connect : async ()=>{
|
|
@@ -223,4 +221,3 @@ var self = module.exports = {
|
|
|
223
221
|
}
|
|
224
222
|
|
|
225
223
|
}
|
|
226
|
-
|
package/package.json
CHANGED
package/src/db/db.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
var config = require('../../config');
|
|
2
1
|
var mysql = require('mysql2');
|
|
3
2
|
|
|
4
3
|
var pool;
|
|
5
4
|
|
|
6
5
|
var self = module.exports = {
|
|
7
|
-
connect : (cb)=>{
|
|
6
|
+
connect : (config,cb)=>{
|
|
8
7
|
pool = mysql.createPool({
|
|
9
8
|
connectionLimit : config.mysqldb.conn_limit,
|
|
10
9
|
host : config.mysqldb.host,
|
|
@@ -312,4 +311,3 @@ var self = module.exports = {
|
|
|
312
311
|
});
|
|
313
312
|
}
|
|
314
313
|
}
|
|
315
|
-
|
package/src/device/device.js
CHANGED
|
@@ -4,10 +4,10 @@ const logs_table = "sensor_logs";
|
|
|
4
4
|
|
|
5
5
|
var self = module.exports = {
|
|
6
6
|
|
|
7
|
-
init : async (projects)=>{
|
|
7
|
+
init : async (config,projects)=>{
|
|
8
8
|
|
|
9
9
|
return new Promise(async (resolve,reject) => {
|
|
10
|
-
$.db.connect(()=>{
|
|
10
|
+
$.db.connect(config,()=>{
|
|
11
11
|
console.log("MYSQL is connected");
|
|
12
12
|
|
|
13
13
|
projects.map( async (name,counter)=>{
|
|
@@ -94,4 +94,3 @@ var self = module.exports = {
|
|
|
94
94
|
},
|
|
95
95
|
|
|
96
96
|
}
|
|
97
|
-
|
|
@@ -55,7 +55,7 @@ let client = {
|
|
|
55
55
|
};
|
|
56
56
|
|
|
57
57
|
async function setup(){
|
|
58
|
-
await $.models.init();
|
|
58
|
+
await $.models.init($.config);
|
|
59
59
|
await $.models.connect();
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -70,7 +70,7 @@ async function test1(){
|
|
|
70
70
|
projects.push(project);
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
await $.device.init(projects);
|
|
73
|
+
await $.device.init($.config,projects);
|
|
74
74
|
|
|
75
75
|
topics.forEach((topic,counter)=>{
|
|
76
76
|
|
|
@@ -87,4 +87,3 @@ async function test1(){
|
|
|
87
87
|
|
|
88
88
|
setup();
|
|
89
89
|
test1();
|
|
90
|
-
|
package/deploy.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
const fs = require('fs').promises;
|
|
2
|
-
|
|
3
|
-
$ = {};
|
|
4
|
-
$.config = require('./config');
|
|
5
|
-
$.models = require('./models/models.js');
|
|
6
|
-
var projectsPath = './src/projects/';
|
|
7
|
-
var project = [];
|
|
8
|
-
|
|
9
|
-
async function readModelsInsideProjects(){
|
|
10
|
-
|
|
11
|
-
return new Promise( async (resolve,reject) => {
|
|
12
|
-
|
|
13
|
-
// load projects dbs
|
|
14
|
-
var files = await fs.readdir(projectsPath)
|
|
15
|
-
|
|
16
|
-
files = files.filter((file) => {
|
|
17
|
-
// Exclude any extension file
|
|
18
|
-
return (file.indexOf('.') == -1);
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
let counter_help = 0;
|
|
22
|
-
files.forEach( async(name,counter) => {
|
|
23
|
-
if($.config.projects[name]){
|
|
24
|
-
project[name] = {
|
|
25
|
-
module : null
|
|
26
|
-
};
|
|
27
|
-
project[name].module = require('./src/projects/'+name+'/'+name+".js")
|
|
28
|
-
await project[name].module.sync_db();
|
|
29
|
-
counter_help++;
|
|
30
|
-
if(files.length == counter_help) return resolve();
|
|
31
|
-
}else{
|
|
32
|
-
counter_help++;
|
|
33
|
-
if(files.length == counter_help) return resolve();
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
async function init(){
|
|
44
|
-
|
|
45
|
-
await $.models.init();
|
|
46
|
-
await $.models.connect();
|
|
47
|
-
|
|
48
|
-
//main tables
|
|
49
|
-
if($.config.sync_main_tables){
|
|
50
|
-
await $.models.load(__dirname+"/models");
|
|
51
|
-
await $.models.dropTableIndexes();
|
|
52
|
-
await $.models.sync();
|
|
53
|
-
|
|
54
|
-
let user = await $.models.insertUser("admin","admin",5); // ads user
|
|
55
|
-
//console.log(user);
|
|
56
|
-
let user_id = user.dataValues.id;
|
|
57
|
-
await $.models.insertUser("device","device",3);
|
|
58
|
-
await $.models.insertUser("client","client_pwd",3);
|
|
59
|
-
await $.models.insertClient("admin","admin",user_id); // ads client with credentials admin@admin
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// project tables
|
|
63
|
-
await readModelsInsideProjects();
|
|
64
|
-
await $.models.dropTableIndexes();
|
|
65
|
-
await $.models.sync();
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
init();
|
|
@@ -1,25 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
const moment = require('moment');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
var app = [];
|
|
6
|
-
|
|
7
|
-
MACRO_UID_PREFIX = "uid:"
|
|
8
|
-
|
|
9
|
-
module.exports = {
|
|
10
|
-
|
|
11
|
-
sync_db : async()=>{
|
|
12
|
-
|
|
13
|
-
return new Promise( async (resolve,reject) => {
|
|
14
|
-
|
|
15
|
-
console.log("Sync dbs for rtls-linux module");
|
|
16
|
-
await $.models.init();
|
|
17
|
-
await $.models.connect();
|
|
18
|
-
await $.models.load(__dirname+"/models");
|
|
19
|
-
|
|
20
|
-
return resolve();
|
|
21
|
-
});
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
init : async ()=>{
|
|
25
|
-
|
|
26
|
-
console.log("Project rtls-linux started");
|
|
27
|
-
await $.models.load(__dirname+"/models");
|
|
28
|
-
|
|
29
|
-
// load apps
|
|
30
|
-
if(fs.existsSync(__dirname+"/apps")){
|
|
31
|
-
fs.readdirSync(__dirname+"/apps")
|
|
32
|
-
.filter((file) => {
|
|
33
|
-
// Exclude any extension file
|
|
34
|
-
return (file.indexOf('.') == -1);
|
|
35
|
-
})
|
|
36
|
-
.forEach((name) => {
|
|
37
|
-
app[name] = {
|
|
38
|
-
module : null
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
app[name].module = require(__dirname + '/apps/'+name+'/'+name+".js")
|
|
42
|
-
app[name].module.init();
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
parseMessage : async (client, project, device, topic, payload, retain, cb)=>{
|
|
48
|
-
|
|
49
|
-
// The next two lines updates dB with received data
|
|
50
|
-
$.db_data.update(project,device.id,topic,payload);
|
|
51
|
-
$.db_data.addLog("logs_"+project,device.id,topic,payload);
|
|
52
|
-
|
|
53
|
-
let index = topic.indexOf("/")
|
|
54
|
-
if(index == -1)
|
|
55
|
-
return cb();
|
|
56
|
-
|
|
57
|
-
if(topic.substring(0,3) == "app") {
|
|
58
|
-
topic = topic.substring(4);
|
|
59
|
-
index = topic.indexOf("/")
|
|
60
|
-
if(index == -1)
|
|
61
|
-
return cb();
|
|
62
|
-
|
|
63
|
-
let app_name = topic.substring(0,index);
|
|
64
|
-
topic = topic.substring(index+1);
|
|
65
|
-
if(app[app_name]){ // call app
|
|
66
|
-
let res = await $.db_model.getByName(app_name);
|
|
67
|
-
let model_id = res?.id;
|
|
68
|
-
if(model_id != null && device.model_id != model_id) $.db_device.updateModel(device.uid,model_id);
|
|
69
|
-
app[app_name].module.parseMessage(client,app_name,device,topic,payload,retain,()=>{})
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
module.exports = (sequelize,DataTypes)=>{
|
|
3
|
-
return sequelize.define("logs_myapp", {
|
|
4
|
-
device_id: {
|
|
5
|
-
type: DataTypes.INTEGER,
|
|
6
|
-
references: {
|
|
7
|
-
model: 'devices',
|
|
8
|
-
key: 'id'
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
tableName: 'logs_myapp',
|
|
14
|
-
freezeTableName: true
|
|
15
|
-
})
|
|
16
|
-
}
|
|
17
|
-
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
module.exports = (sequelize,DataTypes)=>{
|
|
3
|
-
return sequelize.define("myapp", {
|
|
4
|
-
device_id: {
|
|
5
|
-
type: DataTypes.INTEGER,
|
|
6
|
-
unique: true,
|
|
7
|
-
references: {
|
|
8
|
-
model: 'devices',
|
|
9
|
-
key: 'id'
|
|
10
|
-
}
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
tableName: 'myapp',
|
|
15
|
-
freezeTableName: true
|
|
16
|
-
})
|
|
17
|
-
}
|
|
18
|
-
|