@frangoteam/fuxa-min 1.1.19 → 1.2.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/README.md +7 -4
- package/api/alarms/index.js +2 -1
- package/api/command/index.js +7 -7
- package/api/index.js +8 -5
- package/api/resources/index.js +38 -1
- package/dist/3rdpartylicenses.txt +1683 -1477
- package/dist/assets/i18n/de.json +2 -2
- package/dist/assets/i18n/en.json +79 -4
- package/dist/assets/i18n/pt.json +4 -1
- package/dist/assets/i18n/zh-cn.json +3 -1
- package/dist/assets/lib/svgeditor/fuxa-editor.min.js +2 -2
- package/dist/index.html +49 -49
- package/dist/main.4a37383bf3662c04.js +329 -0
- package/dist/polyfills.df504f67f09f2fbb.js +1 -0
- package/dist/scripts.a58f5e48421f8dfe.js +1 -0
- package/dist/styles.2d39fcd293a60646.css +1 -0
- package/main.js +16 -4
- package/package.json +4 -2
- package/runtime/alarms/index.js +22 -5
- package/runtime/devices/bacnet/index.js +86 -73
- package/runtime/devices/device-utils.js +66 -20
- package/runtime/devices/device.js +17 -11
- package/runtime/devices/ethernetip/index.js +37 -37
- package/runtime/devices/fuxaserver/index.js +15 -15
- package/runtime/devices/httprequest/index.js +40 -42
- package/runtime/devices/index.js +115 -37
- package/runtime/devices/modbus/datatypes.js +8 -8
- package/runtime/devices/modbus/index.js +169 -53
- package/runtime/devices/mqtt/index.js +28 -27
- package/runtime/devices/odbc/index.js +33 -117
- package/runtime/devices/opcua/index.js +36 -59
- package/runtime/devices/s7/index.js +29 -27
- package/runtime/events.js +1 -0
- package/runtime/index.js +24 -9
- package/runtime/jobs/helper/image-generator.js +62 -58
- package/runtime/jobs/report.js +12 -11
- package/runtime/plugins/index.js +17 -8
- package/runtime/project/index.js +44 -39
- package/runtime/scripts/index.js +18 -10
- package/runtime/scripts/msm.js +4 -3
- package/runtime/storage/tdengine/index.js +8 -6
- package/settings.default.js +86 -64
- package/dist/main.a356f552d9838b9e.js +0 -1
- package/dist/polyfills.2696a6f9dc75535e.js +0 -1
- package/dist/scripts.1c3385254ff4c93c.js +0 -1
- package/dist/styles.cf8e3cf50d039a5c.css +0 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ FUXA is a web-based Process Visualization (SCADA/HMI/Dashboard) software. With F
|
|
|
9
9
|

|
|
10
10
|
|
|
11
11
|
## Features
|
|
12
|
-
- Devices connectivity with Modbus RTU/TCP, OPC-UA, BACnet IP, MQTT, WebAPI, Ethernet/IP (Allen Bradley)
|
|
12
|
+
- Devices connectivity with Modbus RTU/TCP, Siemens S7 Protocol, OPC-UA, BACnet IP, MQTT, WebAPI, Ethernet/IP (Allen Bradley), ODBC
|
|
13
13
|
- SCADA/HMI Web-Editor - Engineering and Design completely web-based
|
|
14
14
|
- Cross-Platform Full-Stack - Backend with NodeJs and Frontend with Web technologies (HTML5, CSS, Javascript, Angular, SVG)
|
|
15
15
|
|
|
@@ -21,16 +21,19 @@ FUXA is developed with NodeJS (backend) and Angular (frontend).
|
|
|
21
21
|
|
|
22
22
|
**WARNING** You need to have installed [Node](https://nodejs.org/en/about/previous-releases) Version 14 || 16 || 18
|
|
23
23
|
|
|
24
|
-
Install from [NPM](https://www.npmjs.com/package/@frangoteam/fuxa
|
|
24
|
+
Install from [NPM](https://www.npmjs.com/package/@frangoteam/fuxa)
|
|
25
25
|
```
|
|
26
|
-
npm install -g --unsafe-perm @frangoteam/fuxa
|
|
26
|
+
npm install -g --unsafe-perm @frangoteam/fuxa
|
|
27
27
|
fuxa
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
Open up a browser (better Chrome) and navigate to http://localhost:1881
|
|
31
31
|
|
|
32
32
|
## Usage
|
|
33
|
-
Look the guide in [wiki](https://github.com/frangoteam/FUXA/wiki) pages
|
|
33
|
+
- Look the guide in [wiki](https://github.com/frangoteam/FUXA/wiki) pages
|
|
34
|
+
- Look video from [frangoteam](https://www.youtube.com/@umbertonocelli5301)
|
|
35
|
+
- Look video from [Fusion Automate - Urvish Nakum](https://youtube.com/playlist?list=PLxrSjjYyzaaK8uY3kVaFzfGnwhVXiCEAO&si=aU1OxgkUvLQ3bXHq)
|
|
36
|
+
|
|
34
37
|
|
|
35
38
|
## Let us know!
|
|
36
39
|
We’d be really happy if you send us your own shapes in order to collect a library to share it with others. Just send an email to 4frango@gmail.com and do let us know if you have any questions or suggestions regarding our work.
|
package/api/alarms/index.js
CHANGED
|
@@ -34,7 +34,8 @@ module.exports = {
|
|
|
34
34
|
runtime.logger.error("api get alarms: Tocken Expired");
|
|
35
35
|
} else {
|
|
36
36
|
try {
|
|
37
|
-
var
|
|
37
|
+
var filter = req.query.filter ? JSON.parse(req.query.filter) : null;
|
|
38
|
+
var result = runtime.alarmsMgr.getAlarmsValues(filter, groups);
|
|
38
39
|
// res.header("Access-Control-Allow-Origin", "*");
|
|
39
40
|
// res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
|
40
41
|
if (result) {
|
package/api/command/index.js
CHANGED
|
@@ -131,8 +131,8 @@ module.exports = {
|
|
|
131
131
|
} catch (error) {
|
|
132
132
|
res.status(400).json({ error: "error", message: error});
|
|
133
133
|
runtime.logger.error("api get getTagValue: " + error);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
136
|
});
|
|
137
137
|
|
|
138
138
|
/**
|
|
@@ -151,21 +151,21 @@ module.exports = {
|
|
|
151
151
|
var errors = '';
|
|
152
152
|
for (const tag of req.body.tags) {
|
|
153
153
|
try {
|
|
154
|
-
if (!runtime.devices.setTagValue(tag.id, tag.value)) {
|
|
155
|
-
errors += `${tag.id}; `
|
|
154
|
+
if (!await runtime.devices.setTagValue(tag.id, tag.value)) {
|
|
155
|
+
errors += `${tag.id} not found; `
|
|
156
156
|
}
|
|
157
157
|
} catch (err) {
|
|
158
158
|
errors += `${tag.id}: ${err}`;
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
if (errors) {
|
|
162
|
-
res.status(400).json({ error: "not_found", message: '
|
|
163
|
-
runtime.logger.error("api post setTagValue:
|
|
162
|
+
res.status(400).json({ error: "not_found", message: 'setTagValue Failed: ' + errors});
|
|
163
|
+
runtime.logger.error("api post setTagValue Failed:" + errors);
|
|
164
164
|
} else {
|
|
165
165
|
res.end();
|
|
166
166
|
}
|
|
167
167
|
} else {
|
|
168
|
-
res.status(400).json({ error: "not_found", message: '
|
|
168
|
+
res.status(400).json({ error: "not_found", message: 'no tags to set!'});
|
|
169
169
|
runtime.logger.error("api post setTagValue: " + 'id not found!');
|
|
170
170
|
}
|
|
171
171
|
} catch (error) {
|
package/api/index.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
var express = require('express');
|
|
7
|
+
var morgan = require('morgan');
|
|
7
8
|
var bodyParser = require('body-parser');
|
|
8
9
|
const authJwt = require('./jwt-helper');
|
|
9
10
|
const rateLimit = require("express-rate-limit");
|
|
@@ -30,7 +31,9 @@ function init(_server, _runtime) {
|
|
|
30
31
|
return new Promise(function (resolve, reject) {
|
|
31
32
|
if (runtime.settings.disableServer !== false) {
|
|
32
33
|
apiApp = express();
|
|
33
|
-
|
|
34
|
+
apiApp.use(morgan(['combined', 'common', 'dev', 'short', 'tiny'].
|
|
35
|
+
includes(runtime.settings.logApiLevel) ? runtime.settings.logApiLevel : 'combined'));
|
|
36
|
+
|
|
34
37
|
var maxApiRequestSize = runtime.settings.apiMaxLength || '35mb';
|
|
35
38
|
apiApp.use(bodyParser.json({limit:maxApiRequestSize}));
|
|
36
39
|
apiApp.use(bodyParser.urlencoded({limit:maxApiRequestSize,extended:true}));
|
|
@@ -60,7 +63,7 @@ function init(_server, _runtime) {
|
|
|
60
63
|
windowMs: 5 * 60 * 1000, // 5 minutes
|
|
61
64
|
max: 100 // limit each IP to 100 requests per windowMs
|
|
62
65
|
});
|
|
63
|
-
|
|
66
|
+
|
|
64
67
|
// apply to all requests
|
|
65
68
|
apiApp.use(limiter);
|
|
66
69
|
|
|
@@ -75,7 +78,7 @@ function init(_server, _runtime) {
|
|
|
75
78
|
delete tosend.smtp.password;
|
|
76
79
|
}
|
|
77
80
|
// res.header("Access-Control-Allow-Origin", "*");
|
|
78
|
-
// res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
|
81
|
+
// res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
|
79
82
|
res.json(tosend);
|
|
80
83
|
} else {
|
|
81
84
|
res.status(404).end();
|
|
@@ -121,9 +124,9 @@ function init(_server, _runtime) {
|
|
|
121
124
|
} else if (req.body.params) {
|
|
122
125
|
const token = authJwt.getNewToken(req.headers)
|
|
123
126
|
if (token) {
|
|
124
|
-
res.status(200).json({
|
|
127
|
+
res.status(200).json({
|
|
125
128
|
message: 'tokenRefresh',
|
|
126
|
-
token: token
|
|
129
|
+
token: token
|
|
127
130
|
});
|
|
128
131
|
} else {
|
|
129
132
|
res.end();
|
package/api/resources/index.js
CHANGED
|
@@ -29,7 +29,7 @@ module.exports = {
|
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* GET Server
|
|
32
|
+
* GET Server images folder content
|
|
33
33
|
*/
|
|
34
34
|
resourcesApp.get('/api/resources/images', secureFnc, function (req, res) {
|
|
35
35
|
var groups = checkGroupsFnc(req);
|
|
@@ -100,6 +100,43 @@ module.exports = {
|
|
|
100
100
|
}
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
+
/**
|
|
104
|
+
* GET Server widgets folder content
|
|
105
|
+
*/
|
|
106
|
+
resourcesApp.get('/api/resources/widgets', secureFnc, function (req, res) {
|
|
107
|
+
var groups = checkGroupsFnc(req);
|
|
108
|
+
if (res.statusCode === 403) {
|
|
109
|
+
runtime.logger.error("api get resources/widgets: Tocken Expired");
|
|
110
|
+
} else if (authJwt.adminGroups.indexOf(groups) === -1) {
|
|
111
|
+
res.status(401).json({ error: "unauthorized_error", message: "Unauthorized!" });
|
|
112
|
+
runtime.logger.error("api get resources/widgets: Unauthorized!");
|
|
113
|
+
} else {
|
|
114
|
+
try {
|
|
115
|
+
var result = {...req.query, ...{ groups: [] }};
|
|
116
|
+
var resourcesDirs = getDirectories(runtime.settings.widgetsFileDir);
|
|
117
|
+
for (var i = 0; i < resourcesDirs.length; i++) {
|
|
118
|
+
var group = { name: resourcesDirs[i], items: [] };
|
|
119
|
+
var dirPath = path.resolve(runtime.settings.widgetsFileDir, resourcesDirs[i]);
|
|
120
|
+
var wwwSubDir = path.join('_widgets', resourcesDirs[i]);
|
|
121
|
+
var files = getFiles(dirPath, ['.svg']);
|
|
122
|
+
for (var x = 0; x < files.length; x++) {
|
|
123
|
+
var filename = files[x].replace(/\.[^\/.]+$/, '');
|
|
124
|
+
group.items.push({ path: path.join(wwwSubDir, files[x]).split(path.sep).join(path.posix.sep), name: filename });
|
|
125
|
+
}
|
|
126
|
+
result.groups.push(group);
|
|
127
|
+
}
|
|
128
|
+
res.json(result);
|
|
129
|
+
} catch (err) {
|
|
130
|
+
if (err.code) {
|
|
131
|
+
res.status(400).json({ error: err.code, message: err.message });
|
|
132
|
+
} else {
|
|
133
|
+
res.status(400).json({ error: "unexpected_error", message: err.toString() });
|
|
134
|
+
}
|
|
135
|
+
runtime.logger.error("api get resources/widgets: " + err.message);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
|
|
103
140
|
return resourcesApp;
|
|
104
141
|
}
|
|
105
142
|
}
|