mqtt-devices-parser 1.0.0 → 1.0.1
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 +3 -1
- package/Readme.md +10 -52
- package/example/deploy.js +14 -0
- package/example/index.js +25 -0
- package/index.js +64 -0
- package/package.json +1 -1
- 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
|
|
|
@@ -41,6 +43,68 @@ var self = module.exports = {
|
|
|
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
|
|
package/package.json
CHANGED
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
|
-
|