@frangoteam/fuxa-min 1.2.0 → 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 +4 -3
- 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/assets/i18n/de.json +2 -2
- package/dist/assets/i18n/en.json +25 -0
- 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 +1 -1
- package/dist/{main.5077e611f1edda9a.js → main.4a37383bf3662c04.js} +18 -18
- package/main.js +10 -4
- package/package.json +4 -2
- package/runtime/alarms/index.js +16 -2
- package/runtime/devices/bacnet/index.js +33 -33
- package/runtime/devices/device-utils.js +9 -4
- package/runtime/devices/ethernetip/index.js +14 -14
- package/runtime/devices/fuxaserver/index.js +13 -13
- package/runtime/devices/httprequest/index.js +18 -18
- package/runtime/devices/index.js +36 -38
- package/runtime/devices/modbus/datatypes.js +8 -8
- package/runtime/devices/modbus/index.js +132 -54
- package/runtime/devices/mqtt/index.js +15 -15
- package/runtime/devices/opcua/index.js +27 -51
- package/runtime/devices/s7/index.js +22 -21
- package/runtime/index.js +20 -9
- package/runtime/project/index.js +44 -39
- package/runtime/scripts/index.js +7 -7
- package/runtime/storage/tdengine/index.js +8 -6
- package/settings.default.js +86 -64
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,9 +21,9 @@ 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
|
|
|
@@ -34,6 +34,7 @@ Open up a browser (better Chrome) and navigate to http://localhost:1881
|
|
|
34
34
|
- Look video from [frangoteam](https://www.youtube.com/@umbertonocelli5301)
|
|
35
35
|
- Look video from [Fusion Automate - Urvish Nakum](https://youtube.com/playlist?list=PLxrSjjYyzaaK8uY3kVaFzfGnwhVXiCEAO&si=aU1OxgkUvLQ3bXHq)
|
|
36
36
|
|
|
37
|
+
|
|
37
38
|
## Let us know!
|
|
38
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.
|
|
39
40
|
|
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
|
}
|
package/dist/assets/i18n/de.json
CHANGED
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
"dlg.linkproperty-title": "Hyperlink erstellen",
|
|
106
106
|
"dlg.linkproperty-url": "Hyperlink-URL",
|
|
107
107
|
|
|
108
|
-
"dlg.login-title": "
|
|
108
|
+
"dlg.login-title": "Anmelden...",
|
|
109
109
|
"dlg.logout-btn": "Abmelden",
|
|
110
110
|
|
|
111
111
|
"dlg.ok": "OK",
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"general.search": "Suchen...",
|
|
127
127
|
"general.search-notfound": "Keine Optionen gefunden",
|
|
128
128
|
"general.username": "Benutzername",
|
|
129
|
-
"general.fullname": "
|
|
129
|
+
"general.fullname": "Vollständiger Name",
|
|
130
130
|
"general.password": "Kennwort",
|
|
131
131
|
"general.clientId": "Kunden-ID",
|
|
132
132
|
"general.authority": "Berechtigung",
|
package/dist/assets/i18n/en.json
CHANGED
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"dlg.layout-lbl-margin-left": "Margin left",
|
|
66
66
|
"dlg.layout-lbl-margin-right": "Margin right",
|
|
67
67
|
"dlg.layout-lbl-login-info": "Login info",
|
|
68
|
+
"dlg.layout-lbl-custom-styles": "Custom styles",
|
|
68
69
|
|
|
69
70
|
"dlg.menuitem-title": "Menu Item",
|
|
70
71
|
"dlg.menuitem-image": "[My Image...]",
|
|
@@ -379,6 +380,7 @@
|
|
|
379
380
|
"graph.rangetype-last1d": "Last day",
|
|
380
381
|
"graph.rangetype-last3d": "Last 3 days",
|
|
381
382
|
"graph.rangetype-last1w": "Last week",
|
|
383
|
+
"graph.rangetype-last1m": "Last month",
|
|
382
384
|
|
|
383
385
|
"graph.grouptype-hours": "Hours",
|
|
384
386
|
"graph.grouptype-days": "Days",
|
|
@@ -423,6 +425,8 @@
|
|
|
423
425
|
"table.property-gridline": "Show grid",
|
|
424
426
|
"table.property-type-data": "Data table",
|
|
425
427
|
"table.property-type-history": "History table",
|
|
428
|
+
"table.property-type-alarms": "Alarms table",
|
|
429
|
+
"table.property-type-alarms-history": "Alarms History table",
|
|
426
430
|
"table.property-grid-color": "Grid color",
|
|
427
431
|
"table.property-cols": "Columns",
|
|
428
432
|
"table.property-rows": "Rows",
|
|
@@ -461,6 +465,13 @@
|
|
|
461
465
|
"table.rangetype-last1d": "Last day",
|
|
462
466
|
"table.rangetype-last3d": "Last 3 days",
|
|
463
467
|
|
|
468
|
+
"table.alarms-title": "Table Alarms",
|
|
469
|
+
"table.alarms-history-title": "Table Alarms History",
|
|
470
|
+
"table.alarm-column": "Alarms Column",
|
|
471
|
+
"table.alarm-filter": "Alarms Filter",
|
|
472
|
+
"table.alarm-priority": "Priority",
|
|
473
|
+
"table.alarm-tags": "Tags",
|
|
474
|
+
|
|
464
475
|
"editor.view-svg": "Canvas/SVG",
|
|
465
476
|
"editor.view-cards": "Multi views container",
|
|
466
477
|
"editor.views": "Views",
|
|
@@ -539,6 +550,8 @@
|
|
|
539
550
|
"editor.cmenu-layer-delete": "Delete Layer",
|
|
540
551
|
"editor.cmenu-layer-marge-down": "Merge Down",
|
|
541
552
|
"editor.cmenu-layer-marge-all": "Merge All",
|
|
553
|
+
"editor.cmenu-unlock": "Unlock",
|
|
554
|
+
"editor.cmenu-lock": "Lock",
|
|
542
555
|
|
|
543
556
|
"editor.transform": "Transform",
|
|
544
557
|
"editor.transform-x": "x",
|
|
@@ -681,6 +694,8 @@
|
|
|
681
694
|
"shapes.event-click": "Click",
|
|
682
695
|
"shapes.event-mouseup": "MouseUp",
|
|
683
696
|
"shapes.event-mousedown": "MouseDown",
|
|
697
|
+
"shapes.event-mouseover": "MouseOver",
|
|
698
|
+
"shapes.event-mouseout": "MouseOut",
|
|
684
699
|
"shapes.event-enter": "Enter",
|
|
685
700
|
"shapes.event-select": "Select",
|
|
686
701
|
"shapes.event-onpage": "Open Page",
|
|
@@ -699,6 +714,8 @@
|
|
|
699
714
|
"shapes.event-onmonitor": "Monitor",
|
|
700
715
|
"shapes.event-onViewToPanel": "Set View to Panel",
|
|
701
716
|
"shapes.event-onLoad": "OnLoad",
|
|
717
|
+
"shapes.event-relativefrom-window": "Window",
|
|
718
|
+
"shapes.event-relativefrom-mouse": "Mouse",
|
|
702
719
|
|
|
703
720
|
"pipe.property-props": "Property",
|
|
704
721
|
"pipe.property-border-width": "Border width",
|
|
@@ -851,6 +868,7 @@
|
|
|
851
868
|
"device.property-dsn": "Data Source Name (DSN=Database name)",
|
|
852
869
|
"device.property-odbc-result": "Result of tables found",
|
|
853
870
|
"device.not-odbc-result": "Database tables result",
|
|
871
|
+
"device.property-socket-reuse": "Socket Reuse",
|
|
854
872
|
|
|
855
873
|
"device.browsetopics-property-title": "Broker Topics to subscribe and publish",
|
|
856
874
|
"device.browsetopics-property-sub": "Subscribe",
|
|
@@ -912,6 +930,7 @@
|
|
|
912
930
|
"device.tag-daq-restored": "To restore",
|
|
913
931
|
|
|
914
932
|
"device.tag-format": "Format digits (2 = #.##)",
|
|
933
|
+
"device.tag-deadband": "Deadband",
|
|
915
934
|
"device.tag-scale": "Scale Mode / Convertion",
|
|
916
935
|
"device.tag-scale-mode-undefined": "No Scaling",
|
|
917
936
|
"device.tag-scale-mode-undefined-tooltip": "Tag Value",
|
|
@@ -969,6 +988,7 @@
|
|
|
969
988
|
"gauges.property-event-type": "Type",
|
|
970
989
|
"gauges.property-event-action": "Action",
|
|
971
990
|
"gauges.property-event-destination": "Destination",
|
|
991
|
+
"gauges.property-event-destination-relative-from": "Relative from",
|
|
972
992
|
"gauges.property-event-destination-panel": "Panel",
|
|
973
993
|
"gauges.property-event-destination-hide-close": "Hide Close",
|
|
974
994
|
"gauges.property-event-single-card": "Single Card",
|
|
@@ -1016,6 +1036,7 @@
|
|
|
1016
1036
|
|
|
1017
1037
|
"gauges.property-update-enabled": "Enable update",
|
|
1018
1038
|
"gauges.property-update-esc": "ESC update",
|
|
1039
|
+
"gauges.property-select-content-on-click": "Select content on click",
|
|
1019
1040
|
"gauges.property-numeric-enabled": "Only number",
|
|
1020
1041
|
"gauges.property-format-digits": "Format digits",
|
|
1021
1042
|
"gauges.property-actions": "Actions",
|
|
@@ -1105,6 +1126,7 @@
|
|
|
1105
1126
|
"alarms.view-offtime": "OFF Date/Time",
|
|
1106
1127
|
"alarms.view-acktime": "ACK Date/Time",
|
|
1107
1128
|
"alarms.view-userack": "ACK User",
|
|
1129
|
+
"alarms.view-ack": "ACK",
|
|
1108
1130
|
"alarms.view-ack-all-alarms": "ACK All Alarms",
|
|
1109
1131
|
"alarm.status-active": "Active",
|
|
1110
1132
|
"alarm.status-passive": "Passive",
|
|
@@ -1197,6 +1219,8 @@
|
|
|
1197
1219
|
"script.delay": "Delay (seconds)",
|
|
1198
1220
|
"script.sys-fnc-setview-text": "$setView (View name)",
|
|
1199
1221
|
"script.sys-fnc-setview-tooltip": "System function to set View on client: $setView (View name as string)",
|
|
1222
|
+
"script.sys-fnc-opencard-text": "$openCard (View name)",
|
|
1223
|
+
"script.sys-fnc-opencard-tooltip": "System function to open Card on client: $openCard (View name as string, Options as dict {left, top})",
|
|
1200
1224
|
"script.sys-fnc-enableDevice-text": "$enableDevice (Device name, enable True/False)",
|
|
1201
1225
|
"script.sys-fnc-enableDevice-tooltip": "System function to enable Device connection: $enableDevice (Device name as string, enable as boolean)",
|
|
1202
1226
|
"script.sys-fnc-enableDevice-params": "'Device name', true",
|
|
@@ -1322,6 +1346,7 @@
|
|
|
1322
1346
|
"card.style-zoom": "Zoom",
|
|
1323
1347
|
|
|
1324
1348
|
"resources.lib-images": "Images",
|
|
1349
|
+
"resources.lib-widgets": "Widgets",
|
|
1325
1350
|
|
|
1326
1351
|
"texts.list-title": "Texts settings",
|
|
1327
1352
|
"texts.list-filter": "Filter",
|
package/dist/assets/i18n/pt.json
CHANGED
|
@@ -340,7 +340,9 @@
|
|
|
340
340
|
"shapes.action-clockwise": "Mudar sentido do Relógio",
|
|
341
341
|
"shapes.action-anticlockwise": "Mudar Contra-relógio",
|
|
342
342
|
"shapes.action-downup": "Cima e abaixo",
|
|
343
|
-
|
|
343
|
+
"shapes.event-relativefrom-window": "Janela",
|
|
344
|
+
"shapes.event-relativefrom-mouse": "Cursor",
|
|
345
|
+
|
|
344
346
|
"pipe.property-props": "Propriedade",
|
|
345
347
|
"pipe.property-border-width": "Largura da fronteira",
|
|
346
348
|
"pipe.property-border-color": "Cor da fronteira",
|
|
@@ -509,6 +511,7 @@
|
|
|
509
511
|
"gauges.property-tooltip-add-event": "Adicionar evento",
|
|
510
512
|
"gauges.property-interval-msec": "Intervalo (msec.)",
|
|
511
513
|
|
|
514
|
+
|
|
512
515
|
"bag.property-ticks": "Ticks",
|
|
513
516
|
"bag.property-divisions": "Divisões",
|
|
514
517
|
"bag.property-subdivisions": "Subdivisões",
|
|
@@ -467,7 +467,7 @@
|
|
|
467
467
|
"editor.transform-y2-title": "改变线条的起始Y坐标",
|
|
468
468
|
"editor.transform-rect-width-title": "改变矩形宽度",
|
|
469
469
|
"editor.transform-width": "宽度",
|
|
470
|
-
"editor.transform-rect-height-title": "改变矩形高度",
|
|
470
|
+
"editor.transform-rect-height-title": "改变矩形高度",
|
|
471
471
|
"editor.transform-height": "高度",
|
|
472
472
|
"editor.transform-rect-radius-title": "改变矩形角半径",
|
|
473
473
|
"editor.transform-radiuscorner": "半径角",
|
|
@@ -736,6 +736,8 @@
|
|
|
736
736
|
"device.webapi-property-gettags": "URL GET标签",
|
|
737
737
|
"device.webapi-property-posttags": "URL POST标签",
|
|
738
738
|
"device.webapi-property-loadtags": "加载标签",
|
|
739
|
+
"device.property-socket-reuse": "Socket复用",
|
|
740
|
+
"device.property-socket-serial": "Socket串行",
|
|
739
741
|
|
|
740
742
|
"device.browsetopics-property-title": "要订阅和发布的经纪人主题",
|
|
741
743
|
"device.browsetopics-property-sub": "订阅",
|