mqtt-devices-parser 1.0.11 → 1.0.13
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 +10 -0
- package/index.js +24 -3
- package/models/devices.models.js +20 -3
- package/models/firmwares.models.js +2 -10
- package/models/fota.models.js +32 -0
- package/models/logs_actions.models.js +17 -0
- package/models/logs_device.models.js +62 -0
- package/models/logs_fota.models.js +41 -0
- package/models/{sensor_logs.models.js → logs_sensor.models.js} +2 -2
- package/models/modelPermissions.models.js +23 -0
- package/models/models.js +238 -211
- package/models/projects.models.js +8 -0
- package/package.json +1 -1
- package/src/db/data.js +91 -87
- package/src/db/db.js +24 -0
- package/src/db/device.js +288 -7
- package/src/db/firmware.js +30 -5
- package/src/db/fota.js +219 -0
- package/src/device/Readme.md +39 -4
- package/src/device/device.js +374 -152
package/src/db/firmware.js
CHANGED
|
@@ -3,16 +3,41 @@ var mysql = require('mysql2')
|
|
|
3
3
|
|
|
4
4
|
var self = module.exports = {
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
getById : async (firmwareId)=>{
|
|
7
|
+
return new Promise((resolve,reject) => {
|
|
8
|
+
|
|
9
|
+
let query = "";
|
|
10
|
+
let table = [];
|
|
11
|
+
|
|
12
|
+
query = `SELECT * FROM firmwares where id = ?`;
|
|
13
|
+
table = [firmwareId];
|
|
14
|
+
|
|
15
|
+
query = mysql.format(query,table);
|
|
16
|
+
|
|
17
|
+
$.db.queryRow(query)
|
|
18
|
+
.then( rows => {
|
|
19
|
+
if(rows.length > 0){
|
|
20
|
+
return resolve(rows[0]);
|
|
21
|
+
}else
|
|
22
|
+
return resolve(null);
|
|
23
|
+
})
|
|
24
|
+
.catch( err => {
|
|
25
|
+
console.log(err);
|
|
26
|
+
return resolve(null);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
getLatestVersion : async (modelId,release)=>{
|
|
7
32
|
|
|
8
33
|
return new Promise((resolve,reject) => {
|
|
9
34
|
|
|
10
35
|
let query = "";
|
|
11
36
|
let table = [];
|
|
12
37
|
|
|
13
|
-
query = `SELECT
|
|
14
|
-
CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(
|
|
15
|
-
CAST(SUBSTRING_INDEX(
|
|
38
|
+
query = `SELECT version,filename,token,id FROM firmwares where model_id = ? and build_release = ? ORDER BY CAST(SUBSTRING_INDEX(version, '.', 1) AS UNSIGNED) DESC,
|
|
39
|
+
CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(version, '.', 2), '.', -1) AS UNSIGNED) DESC,
|
|
40
|
+
CAST(SUBSTRING_INDEX(version, '.', -1) AS UNSIGNED) DESC
|
|
16
41
|
LIMIT 1`;
|
|
17
42
|
table = [modelId,release];
|
|
18
43
|
|
|
@@ -39,7 +64,7 @@ var self = module.exports = {
|
|
|
39
64
|
let query = "";
|
|
40
65
|
let table = [];
|
|
41
66
|
|
|
42
|
-
query = `SELECT app_version,filename,token FROM firmwares where model_id = ? and
|
|
67
|
+
query = `SELECT app_version,filename,token,id FROM firmwares where model_id = ? and build_release = ? ORDER BY CAST(SUBSTRING_INDEX(app_version, '.', 1) AS UNSIGNED) DESC,
|
|
43
68
|
CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(app_version, '.', 2), '.', -1) AS UNSIGNED) DESC,
|
|
44
69
|
CAST(SUBSTRING_INDEX(app_version, '.', -1) AS UNSIGNED) DESC
|
|
45
70
|
LIMIT 1`;
|
package/src/db/fota.js
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
const moment = require('moment');
|
|
2
|
+
var mysql = require('mysql2')
|
|
3
|
+
|
|
4
|
+
var self = module.exports = {
|
|
5
|
+
|
|
6
|
+
getEntry : async (deviceId,filter)=>{
|
|
7
|
+
|
|
8
|
+
return new Promise((resolve,reject) => {
|
|
9
|
+
|
|
10
|
+
let query = `SELECT COUNT(*) FROM ?? where
|
|
11
|
+
device_id = ? and
|
|
12
|
+
target_version = ? and
|
|
13
|
+
target_app_version = ? and
|
|
14
|
+
target_release = ? and
|
|
15
|
+
firmware_id = ?`;
|
|
16
|
+
|
|
17
|
+
let table = [
|
|
18
|
+
"fota",
|
|
19
|
+
deviceId,
|
|
20
|
+
filter.target_version,
|
|
21
|
+
filter.target_app_version,
|
|
22
|
+
filter.target_release,
|
|
23
|
+
filter.firmware_id
|
|
24
|
+
];
|
|
25
|
+
query = mysql.format(query,table);
|
|
26
|
+
|
|
27
|
+
$.db.queryRow(query)
|
|
28
|
+
.then( rows => {
|
|
29
|
+
if(rows.length > 0)
|
|
30
|
+
return resolve(rows[0]);
|
|
31
|
+
else
|
|
32
|
+
return resolve(null);
|
|
33
|
+
})
|
|
34
|
+
.catch( err => {
|
|
35
|
+
return reject(err);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
getFirmwareId : async (deviceId)=>{
|
|
41
|
+
|
|
42
|
+
return new Promise((resolve,reject) => {
|
|
43
|
+
|
|
44
|
+
let query = "SELECT firmware_id FROM ?? where device_id = ?";
|
|
45
|
+
let table = ["fota",deviceId];
|
|
46
|
+
query = mysql.format(query,table);
|
|
47
|
+
|
|
48
|
+
$.db.queryRow(query)
|
|
49
|
+
.then( rows => {
|
|
50
|
+
if(rows.length > 0)
|
|
51
|
+
return resolve(rows[0].firmware_id);
|
|
52
|
+
else
|
|
53
|
+
return resolve(null);
|
|
54
|
+
})
|
|
55
|
+
.catch( err => {
|
|
56
|
+
return reject(err);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
getUpdatable : async (release)=>{
|
|
62
|
+
|
|
63
|
+
return new Promise((resolve,reject) => {
|
|
64
|
+
|
|
65
|
+
let query = `SELECT d.*,f.firmware_id, f.nAttempts
|
|
66
|
+
FROM fota as f
|
|
67
|
+
inner join devices as d on d.id = f.device_id
|
|
68
|
+
where d.status = ? and f.fUpdate = ? and f.nAttempts < ? and f.target_release = ?`;
|
|
69
|
+
let table = ['online',1,3,release];
|
|
70
|
+
query = mysql.format(query,table);
|
|
71
|
+
|
|
72
|
+
$.db.queryRow(query)
|
|
73
|
+
.then( rows => {
|
|
74
|
+
return resolve(rows);
|
|
75
|
+
})
|
|
76
|
+
.catch( err => {
|
|
77
|
+
console.log(err);
|
|
78
|
+
return resolve(null);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
update : async(deviceId, obj)=>{
|
|
84
|
+
|
|
85
|
+
return new Promise(async (resolve,reject) => {
|
|
86
|
+
|
|
87
|
+
obj['updatedAt'] = moment().utc().format('YYYY-MM-DD HH:mm:ss');
|
|
88
|
+
|
|
89
|
+
let firmwareId = await self.getFirmwareId(deviceId);
|
|
90
|
+
if(firmwareId == null){
|
|
91
|
+
obj['createdAt'] = moment().utc().format('YYYY-MM-DD HH:mm:ss');
|
|
92
|
+
obj['device_id'] = deviceId;
|
|
93
|
+
|
|
94
|
+
$.db.insert("fota",obj)
|
|
95
|
+
.then (rows => {
|
|
96
|
+
return resolve(rows[0]);
|
|
97
|
+
})
|
|
98
|
+
.catch(error => {
|
|
99
|
+
return reject(error);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
}else{
|
|
103
|
+
|
|
104
|
+
let filter = {
|
|
105
|
+
device_id : deviceId
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
$.db.update("fota",obj,filter)
|
|
109
|
+
.then (rows => {
|
|
110
|
+
return resolve(rows[0]);
|
|
111
|
+
})
|
|
112
|
+
.catch(error => {
|
|
113
|
+
return reject(error);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
getDeviceLastLog : async(deviceId)=>{
|
|
121
|
+
|
|
122
|
+
return new Promise((resolve,reject) => {
|
|
123
|
+
|
|
124
|
+
let query = `SELECT * FROM ??
|
|
125
|
+
where device_id = ?
|
|
126
|
+
ORDER BY updatedAt DESC
|
|
127
|
+
LIMIT 1`;
|
|
128
|
+
|
|
129
|
+
let table = [
|
|
130
|
+
"fota",
|
|
131
|
+
deviceId,
|
|
132
|
+
];
|
|
133
|
+
query = mysql.format(query,table);
|
|
134
|
+
|
|
135
|
+
$.db.queryRow(query)
|
|
136
|
+
.then( rows => {
|
|
137
|
+
if(rows.length > 0)
|
|
138
|
+
return resolve(rows[0]);
|
|
139
|
+
else
|
|
140
|
+
return resolve(null);
|
|
141
|
+
})
|
|
142
|
+
.catch( err => {
|
|
143
|
+
return reject(err);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
getDeviceLogs : async()=>{
|
|
149
|
+
|
|
150
|
+
return new Promise((resolve,reject) => {
|
|
151
|
+
|
|
152
|
+
let query = `SELECT * FROM ??
|
|
153
|
+
ORDER BY updatedAt DESC
|
|
154
|
+
LIMIT 20`;
|
|
155
|
+
|
|
156
|
+
let table = [
|
|
157
|
+
"fota",
|
|
158
|
+
];
|
|
159
|
+
query = mysql.format(query,table);
|
|
160
|
+
|
|
161
|
+
$.db.queryRow(query)
|
|
162
|
+
.then( rows => {
|
|
163
|
+
if(rows.length > 0)
|
|
164
|
+
return resolve(rows);
|
|
165
|
+
else
|
|
166
|
+
return resolve(null);
|
|
167
|
+
})
|
|
168
|
+
.catch( err => {
|
|
169
|
+
return reject(err);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
newLog : async(deviceId, obj)=>{
|
|
175
|
+
|
|
176
|
+
return new Promise(async (resolve,reject) => {
|
|
177
|
+
|
|
178
|
+
const timestamp = moment().utc().format('YYYY-MM-DD HH:mm:ss');
|
|
179
|
+
obj['updatedAt'] = timestamp;
|
|
180
|
+
obj['createdAt'] = timestamp;
|
|
181
|
+
obj['device_id'] = deviceId;
|
|
182
|
+
|
|
183
|
+
$.db.insert("logs_fota",obj)
|
|
184
|
+
.then (rows => {
|
|
185
|
+
return resolve(rows[0]);
|
|
186
|
+
})
|
|
187
|
+
.catch(error => {
|
|
188
|
+
return reject(error);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
});
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
updateLog : async(deviceId, obj)=>{
|
|
195
|
+
|
|
196
|
+
return new Promise(async (resolve,reject) => {
|
|
197
|
+
|
|
198
|
+
const log = await getDeviceLastLog(deviceId);
|
|
199
|
+
|
|
200
|
+
if(log?.createdAt != log?.updatedAt)
|
|
201
|
+
|
|
202
|
+
obj['updatedAt'] = moment().utc().format('YYYY-MM-DD HH:mm:ss');
|
|
203
|
+
|
|
204
|
+
const filter = {
|
|
205
|
+
id : log.id
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
$.db.update("logs_fota",obj,filter)
|
|
209
|
+
.then (rows => {
|
|
210
|
+
return resolve(rows[0]);
|
|
211
|
+
})
|
|
212
|
+
.catch(error => {
|
|
213
|
+
return reject(error);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
});
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
}
|
package/src/device/Readme.md
CHANGED
|
@@ -10,14 +10,49 @@ Only messages with MACRO_UID_PREFIX in topic will be parsed.
|
|
|
10
10
|
MACRO_UID_PREFIX allows the module to discover the device uid.
|
|
11
11
|
If uid doesn't exist in db it will add it.
|
|
12
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
|
|
13
|
+
If the device already exists it will verify the project and update it in case of needed
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
## Fota
|
|
16
|
+
Add a new firmware to model
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Every 5min for release = "dev" and every hour for release = "prod"
|
|
19
|
+
devices will be updated if needed
|
|
20
|
+
|
|
21
|
+
### Available topics
|
|
22
|
+
|
|
23
|
+
:project/:device/status - send it on boot with retain
|
|
24
|
+
Updates the device status (online/offline)
|
|
25
|
+
|
|
26
|
+
:project/:device/model - send it on boot with retain
|
|
19
27
|
Updates the model if the model already exists in db
|
|
20
28
|
|
|
29
|
+
:project/:device/version - send it on boot with retain
|
|
30
|
+
// If version mismatch, updates fota table with success
|
|
31
|
+
|
|
32
|
+
:project/:device/app_version - send it on boot with retain
|
|
33
|
+
// If version mismatch, updates fota table with success
|
|
34
|
+
|
|
35
|
+
:project/:device/tech - send it on boot with retain
|
|
36
|
+
// Radio technology
|
|
37
|
+
|
|
38
|
+
:project/:device/fw/fota/update/status - send if fota fails
|
|
39
|
+
// Receives fota error and updates fota table
|
|
40
|
+
|
|
41
|
+
// can be changed - Likely will be deprecated
|
|
42
|
+
:project/:device/fw - send it periodically
|
|
43
|
+
// JSON struct, stores value of keys:
|
|
44
|
+
- heapFree
|
|
45
|
+
- uptime
|
|
46
|
+
- rssi
|
|
47
|
+
|
|
48
|
+
// Under development
|
|
49
|
+
// If sensor is created stores info
|
|
50
|
+
:project/:device/sensor/:sensor
|
|
51
|
+
// JSON struct, stores value of keys:
|
|
52
|
+
- value
|
|
53
|
+
|
|
54
|
+
### Set instruction
|
|
55
|
+
Any instruction ended with /set will be added to a json file on settings table
|
|
21
56
|
|
|
22
57
|
## New Project
|
|
23
58
|
|