@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.
Files changed (46) hide show
  1. package/README.md +7 -4
  2. package/api/alarms/index.js +2 -1
  3. package/api/command/index.js +7 -7
  4. package/api/index.js +8 -5
  5. package/api/resources/index.js +38 -1
  6. package/dist/3rdpartylicenses.txt +1683 -1477
  7. package/dist/assets/i18n/de.json +2 -2
  8. package/dist/assets/i18n/en.json +79 -4
  9. package/dist/assets/i18n/pt.json +4 -1
  10. package/dist/assets/i18n/zh-cn.json +3 -1
  11. package/dist/assets/lib/svgeditor/fuxa-editor.min.js +2 -2
  12. package/dist/index.html +49 -49
  13. package/dist/main.4a37383bf3662c04.js +329 -0
  14. package/dist/polyfills.df504f67f09f2fbb.js +1 -0
  15. package/dist/scripts.a58f5e48421f8dfe.js +1 -0
  16. package/dist/styles.2d39fcd293a60646.css +1 -0
  17. package/main.js +16 -4
  18. package/package.json +4 -2
  19. package/runtime/alarms/index.js +22 -5
  20. package/runtime/devices/bacnet/index.js +86 -73
  21. package/runtime/devices/device-utils.js +66 -20
  22. package/runtime/devices/device.js +17 -11
  23. package/runtime/devices/ethernetip/index.js +37 -37
  24. package/runtime/devices/fuxaserver/index.js +15 -15
  25. package/runtime/devices/httprequest/index.js +40 -42
  26. package/runtime/devices/index.js +115 -37
  27. package/runtime/devices/modbus/datatypes.js +8 -8
  28. package/runtime/devices/modbus/index.js +169 -53
  29. package/runtime/devices/mqtt/index.js +28 -27
  30. package/runtime/devices/odbc/index.js +33 -117
  31. package/runtime/devices/opcua/index.js +36 -59
  32. package/runtime/devices/s7/index.js +29 -27
  33. package/runtime/events.js +1 -0
  34. package/runtime/index.js +24 -9
  35. package/runtime/jobs/helper/image-generator.js +62 -58
  36. package/runtime/jobs/report.js +12 -11
  37. package/runtime/plugins/index.js +17 -8
  38. package/runtime/project/index.js +44 -39
  39. package/runtime/scripts/index.js +18 -10
  40. package/runtime/scripts/msm.js +4 -3
  41. package/runtime/storage/tdengine/index.js +8 -6
  42. package/settings.default.js +86 -64
  43. package/dist/main.a356f552d9838b9e.js +0 -1
  44. package/dist/polyfills.2696a6f9dc75535e.js +0 -1
  45. package/dist/scripts.1c3385254ff4c93c.js +0 -1
  46. 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
  ![fuxa action](/screenshot/feature-action-move.gif)
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-sim)
24
+ Install from [NPM](https://www.npmjs.com/package/@frangoteam/fuxa)
25
25
  ```
26
- npm install -g --unsafe-perm @frangoteam/fuxa-sim
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.
@@ -34,7 +34,8 @@ module.exports = {
34
34
  runtime.logger.error("api get alarms: Tocken Expired");
35
35
  } else {
36
36
  try {
37
- var result = runtime.alarmsMgr.getAlarmsValues(req.query, groups);
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) {
@@ -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: 'tag id not found: ' + errors});
163
- runtime.logger.error("api post setTagValue: " + 'id not found!' + errors);
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: 'tag id not found!'});
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();
@@ -29,7 +29,7 @@ module.exports = {
29
29
  });
30
30
 
31
31
  /**
32
- * GET Server logs folder content
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
  }