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.
- package/Changelog.md +3 -0
- package/Readme.md +77 -0
- package/config/index.js +29 -0
- package/deploy.js +70 -0
- package/index.js +113 -0
- package/models/clients.models.js +41 -0
- package/models/devices.models.js +39 -0
- package/models/firmwares.models.js +41 -0
- package/models/modelPermissions.js +23 -0
- package/models/models.js +226 -0
- package/models/models.models.js +40 -0
- package/models/permissions.models.js +26 -0
- package/models/projects.models.js +24 -0
- package/models/sensor_logs.models.js +41 -0
- package/models/sensors.models.js +40 -0
- package/models/users.models.js +19 -0
- package/package.json +25 -0
- package/src/aux/parser.js +20 -0
- package/src/db/data.js +197 -0
- package/src/db/db.js +315 -0
- package/src/db/device.js +111 -0
- package/src/db/firmware.js +79 -0
- package/src/db/model.js +115 -0
- package/src/db/project.js +91 -0
- package/src/db/sensor.js +113 -0
- package/src/device/Readme.md +59 -0
- package/src/device/device.js +97 -0
- package/src/projects/demo/apps/myapp.js +25 -0
- package/src/projects/demo/demo.js +77 -0
- package/src/projects/demo/models/logs_myapp.js +17 -0
- package/src/projects/demo/models/myapp.models.js +18 -0
- package/src/unitTest/device.test.js +90 -0
package/Changelog.md
ADDED
package/Readme.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
|
|
2
|
+
# mqtt-devices-parser
|
|
3
|
+
|
|
4
|
+
MQTT parser
|
|
5
|
+
Parses topics received from devices and updates data on dB
|
|
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
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
module.exports = {
|
|
43
|
+
sync_db : async()=>{
|
|
44
|
+
},
|
|
45
|
+
init : async ()=>{
|
|
46
|
+
},
|
|
47
|
+
parseMessage : async (client, project, device, topic, payload, retain, cb)=>{
|
|
48
|
+
},
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Ex: If project name is freeRTOS2, so must exist a file in projects/freeRTOS2/freeRTOS2.js.
|
|
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
|
+
|
|
58
|
+
```
|
|
59
|
+
$.db_data.update(project,device?.id,topic,payload);
|
|
60
|
+
$.db_data.addLog("logs_"+project,device.id,topic,payload);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## UnitTest
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Dependencies
|
|
67
|
+
|
|
68
|
+
- mysql8.0
|
|
69
|
+
- MQTT
|
|
70
|
+
|
|
71
|
+
## Front end
|
|
72
|
+
- Node service running the following [project](https://github.com/zimbora/mgmt-iot-web)
|
|
73
|
+
|
|
74
|
+
## Configuration
|
|
75
|
+
|
|
76
|
+
The default configuration uses ./config/index.js file\
|
|
77
|
+
In your program set the same struct and pass it as argument on the module init call.
|
package/config/index.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
version : "0.0.0",
|
|
3
|
+
dev : process.env.dev || "true",
|
|
4
|
+
web:{
|
|
5
|
+
protocol : process.env.HTTP_PROTOCOL || "http://",
|
|
6
|
+
domain: process.env.DOMAIN || '192.168.1.1',
|
|
7
|
+
},
|
|
8
|
+
mqtt: {
|
|
9
|
+
protocol:process.env.MQTT_PROTOCOL || 'MQTT',
|
|
10
|
+
host:process.env.MQTT_HOST || 'localhost',
|
|
11
|
+
port:process.env.MQTT_PORT || '1883',
|
|
12
|
+
user:process.env.MQTT_USER || 'admin',
|
|
13
|
+
pwd:process.env.MQTT_PWD || 'admin',
|
|
14
|
+
client:process.env.MQTT_CLIENT || 'mqtt-devices-parser',
|
|
15
|
+
logs_path: process.env.MQTT_LOGS || 'uServices'
|
|
16
|
+
},
|
|
17
|
+
mysqldb: {
|
|
18
|
+
conn_limit: process.env.DB_CONN_LIMIT || 15,
|
|
19
|
+
host: process.env.DB_HOST || 'localhost',
|
|
20
|
+
port: process.env.DB_PORT || 3306,
|
|
21
|
+
user: process.env.DB_USER || 'user',
|
|
22
|
+
pwd: process.env.DB_PWD || 'user_pwd',
|
|
23
|
+
name: process.env.DB_NAME || 'mqtt-aedes',
|
|
24
|
+
},
|
|
25
|
+
sync_main_tables : process.env.sync_main_tables || true,
|
|
26
|
+
projects: {
|
|
27
|
+
demo : process.env.demo || false,
|
|
28
|
+
}
|
|
29
|
+
}
|
package/deploy.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
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();
|
package/index.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const mqtt = require("mqtt");
|
|
2
|
+
|
|
3
|
+
$ = {};
|
|
4
|
+
$.md5 = require('md5');
|
|
5
|
+
|
|
6
|
+
$.config = require('./config');
|
|
7
|
+
$.models = require('./models/models.js');
|
|
8
|
+
$.device = require('./src/device/device.js');
|
|
9
|
+
$.db = require('./src/db/db');
|
|
10
|
+
$.db_data = require('./src/db/data');
|
|
11
|
+
$.db_project = require('./src/db/project');
|
|
12
|
+
$.db_device = require('./src/db/device');
|
|
13
|
+
$.db_model = require('./src/db/model');
|
|
14
|
+
$.db_firmware = require('./src/db/firmware');
|
|
15
|
+
$.db_sensor = require('./src/db/sensor');
|
|
16
|
+
|
|
17
|
+
const packageJson = require(__dirname+'/package.json');
|
|
18
|
+
const packageVersion = packageJson.version;
|
|
19
|
+
|
|
20
|
+
var projects = [];
|
|
21
|
+
|
|
22
|
+
var self = module.exports = {
|
|
23
|
+
|
|
24
|
+
init : async(_config, _projects)=>{
|
|
25
|
+
|
|
26
|
+
return new Promise(async (resolve,reject) => {
|
|
27
|
+
|
|
28
|
+
if(_config != null)
|
|
29
|
+
$.config = _config;
|
|
30
|
+
if(_projects != null)
|
|
31
|
+
projects = _projects;
|
|
32
|
+
|
|
33
|
+
await $.models.init();
|
|
34
|
+
await $.models.connect();
|
|
35
|
+
|
|
36
|
+
//auth.init();
|
|
37
|
+
await $.device.init(projects);
|
|
38
|
+
|
|
39
|
+
console.log("mqtt connecting..")
|
|
40
|
+
mqtt_connect();
|
|
41
|
+
|
|
42
|
+
return resolve();
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function mqtt_connect(){
|
|
48
|
+
|
|
49
|
+
const mqtt_prefix = $.config.mqtt.logs_path+"/"+$.config.mqtt.client;
|
|
50
|
+
const client = mqtt.connect({
|
|
51
|
+
host : $.config.mqtt.host,
|
|
52
|
+
port : $.config.mqtt.port,
|
|
53
|
+
username : $.config.mqtt.user,
|
|
54
|
+
password : $.config.mqtt.pwd,
|
|
55
|
+
clientId : $.config.mqtt.client,
|
|
56
|
+
protocolId : $.config.mqtt.protocol,
|
|
57
|
+
will : {
|
|
58
|
+
topic: mqtt_prefix+"/status",
|
|
59
|
+
payload: "offline",
|
|
60
|
+
qos: 2,
|
|
61
|
+
retain: true
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
client.on("connect", () => {
|
|
66
|
+
|
|
67
|
+
client.publish(mqtt_prefix+"/status","online",{qos:2,retain:true});
|
|
68
|
+
client.publish(mqtt_prefix+"/version",packageVersion,{qos:2,retain:true});
|
|
69
|
+
|
|
70
|
+
projects.map( (project)=>{
|
|
71
|
+
client.subscribe(project+"/#", (err) => {});
|
|
72
|
+
|
|
73
|
+
for(let project in $.config.projects){
|
|
74
|
+
if($.config.projects[project])
|
|
75
|
+
client.publish(mqtt_prefix+"/"+project,"active");
|
|
76
|
+
else
|
|
77
|
+
client.publish(mqtt_prefix+"/"+project,"deactive");
|
|
78
|
+
};
|
|
79
|
+
})
|
|
80
|
+
console.log(`MQTT connected to: ${$.config.mqtt.host}:${$.config.mqtt.port}`);
|
|
81
|
+
projects.map( project=>{
|
|
82
|
+
console.log("subscribing project:",project);
|
|
83
|
+
client.subscribe(project+"/#")
|
|
84
|
+
})
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
client.on("message", (topic, payload, packet) => {
|
|
88
|
+
// payload is Buffer
|
|
89
|
+
$.device.parseMessage(client,topic.toString(),payload.toString(),packet.retain);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
client.on("reconnect",()=>{
|
|
93
|
+
console.log("reconnect")
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
client.on("close",()=>{
|
|
97
|
+
console.log("close")
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
client.on("offline",()=>{
|
|
101
|
+
console.log("offline")
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
client.on("disconnect",(packet)=>{
|
|
105
|
+
console.log(packet)
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
client.on("error",(error)=>{
|
|
109
|
+
console.log(error)
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = (sequelize,DataTypes)=>{
|
|
3
|
+
return sequelize.define("clients", {
|
|
4
|
+
user_id: {
|
|
5
|
+
type: DataTypes.INTEGER,
|
|
6
|
+
references : {
|
|
7
|
+
model: 'users',
|
|
8
|
+
key: 'id'
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
nick: {
|
|
12
|
+
type: DataTypes.STRING(64),
|
|
13
|
+
unique: true
|
|
14
|
+
},
|
|
15
|
+
token: {
|
|
16
|
+
type: DataTypes.STRING,
|
|
17
|
+
allowNull: true
|
|
18
|
+
},
|
|
19
|
+
api_token: {
|
|
20
|
+
type: DataTypes.STRING,
|
|
21
|
+
allowNull: true
|
|
22
|
+
},
|
|
23
|
+
gmail: {
|
|
24
|
+
type: DataTypes.STRING(64),
|
|
25
|
+
//unique: true,
|
|
26
|
+
allowNull: true
|
|
27
|
+
},
|
|
28
|
+
name: {
|
|
29
|
+
type: DataTypes.STRING,
|
|
30
|
+
allowNull: true
|
|
31
|
+
},
|
|
32
|
+
avatar: {
|
|
33
|
+
type: DataTypes.STRING,
|
|
34
|
+
allowNull: true
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
tableName: 'clients',
|
|
39
|
+
freezeTableName: true
|
|
40
|
+
})
|
|
41
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = (sequelize,DataTypes)=>{
|
|
3
|
+
return sequelize.define("devices", {
|
|
4
|
+
uid: {
|
|
5
|
+
type: DataTypes.STRING,
|
|
6
|
+
unique: true
|
|
7
|
+
},
|
|
8
|
+
name: {
|
|
9
|
+
type: DataTypes.STRING,
|
|
10
|
+
allowNull: true
|
|
11
|
+
},
|
|
12
|
+
project: { // deprecated
|
|
13
|
+
type: DataTypes.STRING,
|
|
14
|
+
allowNull: true
|
|
15
|
+
},
|
|
16
|
+
status: {
|
|
17
|
+
type: DataTypes.STRING,
|
|
18
|
+
allowNull: true
|
|
19
|
+
},
|
|
20
|
+
project_id: {
|
|
21
|
+
type: DataTypes.INTEGER,
|
|
22
|
+
references: {
|
|
23
|
+
model: 'projects',
|
|
24
|
+
key: 'id'
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
model_id: {
|
|
28
|
+
type: DataTypes.INTEGER,
|
|
29
|
+
references: {
|
|
30
|
+
model: 'models',
|
|
31
|
+
key: 'id'
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
tableName: 'devices',
|
|
37
|
+
freezeTableName: true
|
|
38
|
+
})
|
|
39
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = (sequelize,DataTypes)=>{
|
|
3
|
+
return sequelize.define("firmwares", {
|
|
4
|
+
filename: {
|
|
5
|
+
type: DataTypes.STRING,
|
|
6
|
+
allowNull: true
|
|
7
|
+
},
|
|
8
|
+
originalname: {
|
|
9
|
+
type: DataTypes.STRING,
|
|
10
|
+
allowNull: true,
|
|
11
|
+
unique: true
|
|
12
|
+
},
|
|
13
|
+
fw_version: {
|
|
14
|
+
type: DataTypes.STRING,
|
|
15
|
+
allowNull: true
|
|
16
|
+
},
|
|
17
|
+
app_version: {
|
|
18
|
+
type: DataTypes.STRING,
|
|
19
|
+
allowNull: true
|
|
20
|
+
},
|
|
21
|
+
fw_release: {
|
|
22
|
+
type: DataTypes.STRING,
|
|
23
|
+
allowNull: true
|
|
24
|
+
},
|
|
25
|
+
model_id: { // deprecated
|
|
26
|
+
type: DataTypes.INTEGER,
|
|
27
|
+
references: {
|
|
28
|
+
model: 'models',
|
|
29
|
+
key: 'id'
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
token: {
|
|
33
|
+
type: DataTypes.STRING,
|
|
34
|
+
allowNull: true
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
tableName: 'firmwares',
|
|
39
|
+
freezeTableName: true
|
|
40
|
+
})
|
|
41
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = (sequelize,DataTypes)=>{
|
|
3
|
+
return sequelize.define("modelPermissions", {
|
|
4
|
+
client_id: {
|
|
5
|
+
type: DataTypes.INTEGER,
|
|
6
|
+
references: {
|
|
7
|
+
model: 'clients',
|
|
8
|
+
key: 'id'
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
model_id: {
|
|
12
|
+
type: DataTypes.INTEGER,
|
|
13
|
+
references: {
|
|
14
|
+
model: 'models',
|
|
15
|
+
key: 'id'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
tableName: 'modelPermissions',
|
|
21
|
+
freezeTableName: true
|
|
22
|
+
})
|
|
23
|
+
}
|
package/models/models.js
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
const fs = require('fs').promises;
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const {Sequelize, DataTypes} = require("sequelize");
|
|
4
|
+
var SqlString = require('sequelize/lib/sql-string')
|
|
5
|
+
var mysql = require('mysql2');
|
|
6
|
+
var sequelize;
|
|
7
|
+
|
|
8
|
+
//var modelsPath = './models/';
|
|
9
|
+
var config = require('../config');
|
|
10
|
+
|
|
11
|
+
var self = module.exports = {
|
|
12
|
+
|
|
13
|
+
init : async ()=>{
|
|
14
|
+
|
|
15
|
+
return new Promise((resolve,reject) => {
|
|
16
|
+
sequelize = new Sequelize(
|
|
17
|
+
config.mysqldb.name,
|
|
18
|
+
config.mysqldb.user,
|
|
19
|
+
config.mysqldb.pwd,
|
|
20
|
+
{
|
|
21
|
+
host: config.mysqldb.host,
|
|
22
|
+
dialect: 'mysql'
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
return resolve(sequelize);
|
|
26
|
+
})
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
connect : async ()=>{
|
|
30
|
+
|
|
31
|
+
return new Promise((resolve,reject) => {
|
|
32
|
+
sequelize.authenticate().then(() => {
|
|
33
|
+
console.log('Connection has been established successfully.');
|
|
34
|
+
return resolve();
|
|
35
|
+
}).catch((error) => {
|
|
36
|
+
console.error('Unable to connect to the database: ', error);
|
|
37
|
+
return reject();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
load : async (modelsPath)=>{
|
|
43
|
+
|
|
44
|
+
return new Promise(async(resolve,reject) => {
|
|
45
|
+
var files = await fs.readdir(modelsPath)
|
|
46
|
+
files = files.filter((file) => {
|
|
47
|
+
// Exclude models.js and any non-js files
|
|
48
|
+
return (file.indexOf('.') !== 0) && (file !== 'models.js') && (file.slice(-9) === 'models.js');
|
|
49
|
+
})
|
|
50
|
+
files.forEach((file,counter) => {
|
|
51
|
+
const model = require(path.join(modelsPath, file));
|
|
52
|
+
model(sequelize, DataTypes);
|
|
53
|
+
if(counter == files.length-1){
|
|
54
|
+
return resolve();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
sync : async ()=>{
|
|
61
|
+
|
|
62
|
+
return new Promise((resolve,reject) => {
|
|
63
|
+
//sequelize.sync({alter:true,force:true}).then(() => {
|
|
64
|
+
sequelize.sync({alter:true}).then( async () => {
|
|
65
|
+
console.log('All tables were synced!');
|
|
66
|
+
return resolve();
|
|
67
|
+
}).catch((error) => {
|
|
68
|
+
console.error('Unable to create table : ', error);
|
|
69
|
+
return reject();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
dropTableIndexes : async()=>{
|
|
75
|
+
|
|
76
|
+
return new Promise((resolve,reject) => {
|
|
77
|
+
let tables = Object.keys(sequelize.models);
|
|
78
|
+
|
|
79
|
+
console.log(tables);
|
|
80
|
+
if(!tables?.length)
|
|
81
|
+
return resolve();
|
|
82
|
+
|
|
83
|
+
tables.forEach(async(tableName,counter)=>{
|
|
84
|
+
self.dropAllIndexes(tableName)
|
|
85
|
+
.then(res =>{
|
|
86
|
+
if(counter == tables.length-1)
|
|
87
|
+
return resolve();
|
|
88
|
+
})
|
|
89
|
+
.catch(error => {
|
|
90
|
+
if(counter == tables.length-1)
|
|
91
|
+
return resolve();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
dropAllIndexes : async (tableName)=>{
|
|
99
|
+
|
|
100
|
+
return new Promise( async(resolve,reject) => {
|
|
101
|
+
// Fetch all indexes from the table
|
|
102
|
+
let query = `SHOW INDEXES FROM ??`
|
|
103
|
+
query = mysql.format(query,[tableName]);
|
|
104
|
+
|
|
105
|
+
var indexes;
|
|
106
|
+
sequelize.query(query)
|
|
107
|
+
.then(res=>{
|
|
108
|
+
indexes = res;
|
|
109
|
+
|
|
110
|
+
// Filter out primary key index and unique indexes if you don't want to drop them
|
|
111
|
+
const filteredIndexes = indexes[0].filter(index => index.Key_name !== 'PRIMARY' && !index.Non_unique);
|
|
112
|
+
|
|
113
|
+
if(!filteredIndexes?.length)
|
|
114
|
+
return resolve();
|
|
115
|
+
|
|
116
|
+
// Drop each index
|
|
117
|
+
filteredIndexes.forEach( async(index,counter)=>{
|
|
118
|
+
let query = `DROP INDEX ?? ON ??`
|
|
119
|
+
query = mysql.format(query,[index.Key_name,tableName]);
|
|
120
|
+
sequelize.query(query)
|
|
121
|
+
.then(res=>{
|
|
122
|
+
console.log(`Dropped index ${index.Key_name}`);
|
|
123
|
+
if(counter == filteredIndexes.length-1)
|
|
124
|
+
return resolve();
|
|
125
|
+
})
|
|
126
|
+
.catch(error=>{
|
|
127
|
+
if(counter == filteredIndexes.length-1)
|
|
128
|
+
return resolve();
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
.catch(error=>{
|
|
133
|
+
return resolve();
|
|
134
|
+
})
|
|
135
|
+
});
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
get: (modelName)=>{
|
|
139
|
+
|
|
140
|
+
if(modelName != ""){
|
|
141
|
+
if(sequelize.models[modelName]){
|
|
142
|
+
const model = sequelize.models[modelName];
|
|
143
|
+
const keys = Object.keys(model.rawAttributes);
|
|
144
|
+
let obj = {}
|
|
145
|
+
keys.map((key)=>{
|
|
146
|
+
obj[key] = null;
|
|
147
|
+
})
|
|
148
|
+
return obj;
|
|
149
|
+
}else return;
|
|
150
|
+
}else{
|
|
151
|
+
return models = Object.keys(sequelize.models).map(modelName => {
|
|
152
|
+
const model = sequelize.models[modelName];
|
|
153
|
+
const keys = Object.keys(model.rawAttributes);
|
|
154
|
+
return {
|
|
155
|
+
modelName,
|
|
156
|
+
keys
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
getUser : async (type)=>{
|
|
163
|
+
|
|
164
|
+
return new Promise( async (resolve,reject) => {
|
|
165
|
+
const user = await sequelize.models['users'].findOne({
|
|
166
|
+
where: {
|
|
167
|
+
type: type
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
return resolve(user);
|
|
171
|
+
});
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
insertUser: async (type, password,level)=>{
|
|
175
|
+
|
|
176
|
+
return new Promise( async (resolve,reject) => {
|
|
177
|
+
// Insert a record if it doesn't exist
|
|
178
|
+
const res = await sequelize.models['users'].findOrCreate({
|
|
179
|
+
where: { type: type },
|
|
180
|
+
defaults: {
|
|
181
|
+
password: password,
|
|
182
|
+
level: level
|
|
183
|
+
}
|
|
184
|
+
})
|
|
185
|
+
.then(([user, created]) => {
|
|
186
|
+
if (created) {
|
|
187
|
+
console.log('New user created:', type);
|
|
188
|
+
} else {
|
|
189
|
+
console.log('User already exists:', type);
|
|
190
|
+
}
|
|
191
|
+
return resolve(user);
|
|
192
|
+
})
|
|
193
|
+
.catch(error => {
|
|
194
|
+
console.error('Error:', error);
|
|
195
|
+
return reject(error);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
insertClient: async (nick, token, user_id)=>{
|
|
201
|
+
|
|
202
|
+
return new Promise( async (resolve,reject) => {
|
|
203
|
+
// Insert a record if it doesn't exist
|
|
204
|
+
const res = await sequelize.models['clients'].findOrCreate({
|
|
205
|
+
where: { nick: nick },
|
|
206
|
+
defaults: {
|
|
207
|
+
user_id: user_id,
|
|
208
|
+
token: token
|
|
209
|
+
}
|
|
210
|
+
})
|
|
211
|
+
.then(([client, created]) => {
|
|
212
|
+
if (created) {
|
|
213
|
+
console.log('New client created:', nick);
|
|
214
|
+
} else {
|
|
215
|
+
console.log('Client already exists:', nick);
|
|
216
|
+
}
|
|
217
|
+
return resolve(client);
|
|
218
|
+
})
|
|
219
|
+
.catch(error => {
|
|
220
|
+
console.error('Error:', error);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
}
|
|
226
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
module.exports = (sequelize,DataTypes)=>{
|
|
3
|
+
return sequelize.define("models", {
|
|
4
|
+
name: {
|
|
5
|
+
type: DataTypes.STRING,
|
|
6
|
+
unique: true
|
|
7
|
+
},
|
|
8
|
+
description: {
|
|
9
|
+
type: DataTypes.STRING
|
|
10
|
+
},
|
|
11
|
+
model_table: { // deprecated
|
|
12
|
+
type: DataTypes.STRING,
|
|
13
|
+
allowNull: true
|
|
14
|
+
},
|
|
15
|
+
logs_table: { // deprecated
|
|
16
|
+
type: DataTypes.STRING,
|
|
17
|
+
allowNull: true
|
|
18
|
+
},
|
|
19
|
+
fw_enabled: {
|
|
20
|
+
type: DataTypes.BOOLEAN,
|
|
21
|
+
defaultValue: false
|
|
22
|
+
},
|
|
23
|
+
ar_enabled: {
|
|
24
|
+
type: DataTypes.BOOLEAN,
|
|
25
|
+
defaultValue: false
|
|
26
|
+
},
|
|
27
|
+
alarms_enabled: {
|
|
28
|
+
type: DataTypes.BOOLEAN,
|
|
29
|
+
defaultValue: false
|
|
30
|
+
},
|
|
31
|
+
js_code_enabled: {
|
|
32
|
+
type: DataTypes.BOOLEAN,
|
|
33
|
+
defaultValue: false
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
tableName: 'models',
|
|
38
|
+
freezeTableName: true
|
|
39
|
+
})
|
|
40
|
+
}
|