@jotiotech/node-red-sia-premise-device 0.1.0 → 0.2.2

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 CHANGED
@@ -2,3 +2,5 @@
2
2
 
3
3
  TODO
4
4
 
5
+ Warning: ONLY ASCII characters are supported, if you ever try to use UTF8 it will not be converted to Windows-1252 and on the receiving end you will end up with gibberish.
6
+
package/package.json CHANGED
@@ -1,19 +1,23 @@
1
1
  {
2
2
  "name": "@jotiotech/node-red-sia-premise-device",
3
- "version": "0.1.0",
4
- "engines": {
5
- "node" : ">=12.0.0"
6
- },
7
- "license": "MIT",
3
+ "version": "0.2.2",
4
+ "engines": {
5
+ "node": ">=12.0.0"
6
+ },
7
+ "license": "MIT",
8
8
  "description": "",
9
- "dependencies": {},
9
+ "dependencies": {
10
+ "retry": "^0.13.1"
11
+ },
10
12
  "keywords": [
11
- "node-red", "parsing"
13
+ "node-red",
14
+ "parsing"
12
15
  ],
13
16
  "node-red": {
14
- "version" : ">=1.0.0",
17
+ "version": ">=1.0.0",
15
18
  "nodes": {
16
- "SIA_device": "SIA_device.js"
19
+ "SIA_device": "src/SIA_device.js",
20
+ "SIA_server": "src/SIA_server.js"
17
21
  }
18
22
  }
19
23
  }
@@ -0,0 +1,44 @@
1
+ <script type="text/javascript">
2
+ RED.nodes.registerType('SIA-device', {
3
+ category: 'common',
4
+ color: '#0B99D8',
5
+ defaults: {
6
+ name: { value: "" },
7
+ server: { value: "", type: "SIA-server", required: true }, // This will
8
+ },
9
+ align: 'left',
10
+ icon: "icon.png",
11
+ inputs: 1,
12
+ outputs: 0,
13
+ label: function () {
14
+ return this.name || "SIA Device";
15
+ },
16
+
17
+ });
18
+
19
+ </script>
20
+
21
+ <style>
22
+
23
+ .input-button-wrap>input {
24
+ width: 100% !important;
25
+ }
26
+ select {
27
+ width: 100% !important;
28
+ }
29
+ .editor-button {
30
+ height: 30px;
31
+ padding: 0 10px;
32
+ }
33
+ </style>
34
+
35
+ <script type="text/x-red" data-template-name="SIA-device">
36
+ <div class="form-row">
37
+ <label for="node-input-name"><i class="icon-tag"></i> Name</label>
38
+ <input type="text" id="node-input-name" placeholder="Name">
39
+ </div>
40
+ <div class="form-row">
41
+ <label for="node-input-server"><i class="icon-globe"></i> <span data-i18n="modbus-contrib.label.server"></span></label>
42
+ <input type="text" id="node-input-server">
43
+ </div>
44
+ </script>
package/src/SIA_device.js CHANGED
@@ -1,22 +1,240 @@
1
- 'use strict';
2
- const __importDefault = (this && this.__importDefault) || function (module_) {
3
- return (module_ && module_.__esModule) ? module_ : {default: module_};
4
- };
1
+ // const { Iconv } = require('iconv');
5
2
 
6
- const Net = require('node:net');
7
3
 
8
- Object.defineProperty(exports, '__esModule', {value: true});
4
+ module.exports = function (RED) {
5
+ const tableCRC = [
6
+ 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
7
+ 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
8
+ 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
9
+ 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
10
+ 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
11
+ 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
12
+ 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
13
+ 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
14
+ 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
15
+ 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
16
+ 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
17
+ 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
18
+ 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
19
+ 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
20
+ 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
21
+ 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
22
+ 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
23
+ 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
24
+ 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
25
+ 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
26
+ 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
27
+ 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
28
+ 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
29
+ 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
30
+ 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
31
+ 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
32
+ 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
33
+ 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
34
+ 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
35
+ 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
36
+ 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
37
+ 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
38
+ ];
9
39
 
10
- class SIADevice {
11
- constructor(serverConfig) {
12
- console.log(serverConfig);
13
- }
40
+ const deviceMap = new Map();
41
+ const crypto = require('crypto');
14
42
 
15
- connect() {
16
43
 
17
- }
18
44
 
45
+ function SIADeviceNode(config) {
46
+ RED.nodes.createNode(this, config);
47
+
48
+ // TODO: eventually we should disconnect from the server after each message as there shouldn't be a high volume of messages
49
+ const server = RED.nodes.getNode(config.server);
50
+
51
+ const siaConfig = server.getSIAConfig();
52
+ console.log('SIA Config:', siaConfig);
53
+
54
+
55
+ server.connect();
56
+
57
+
58
+
59
+ function utf8toWin1252(str) {
60
+ tmpBuf = Buffer.from(str, 'utf8');
61
+ return tmpBuf.toString('latin1');
62
+ }
63
+
64
+ function calculateCRCIBM16(str){
65
+ data = new Buffer.from(str);
66
+ let len = data.length;
67
+ let buffer = 0;
68
+ let crc;
69
+ while (len--) {
70
+ crc = ((crc >>> 8) ^ (tableCRC[(crc ^ (data[buffer++])) & 0xff]));
71
+ }
72
+ return crc.toString(16).padStart(4, '0').toUpperCase();
73
+ }
74
+
75
+ function encrypt(encryptionType, encryptionKey, str) {
76
+ try {
77
+ const encryptionKeyBuf = new Buffer.from(encryptionKey, 'hex');
78
+ let iv = new Buffer.alloc(16);
79
+ iv.fill(0);
80
+ let cipher = crypto.createCipheriv(encryptionType, encryptionKeyBuf, iv);
81
+ cipher.setAutoPadding(false);
82
+ let encoded = cipher.update(str, 'utf8', 'hex');
83
+ encoded += cipher.final('hex');
84
+ return (encoded ? encoded : undefined);
85
+ } catch (e) {
86
+ return undefined;
87
+ }
88
+ }
89
+
90
+
91
+ function generateTimestamp(){
92
+ const now = new Date();
93
+
94
+ // Pad single-digit numbers with a leading zero
95
+ const pad = (num) => num.toString().padStart(2, '0');
96
+
97
+ const hours = pad(now.getHours());
98
+ const minutes = pad(now.getMinutes());
99
+ const seconds = pad(now.getSeconds());
100
+ const month = pad(now.getMonth() + 1); // Months are 0-indexed
101
+ const day = pad(now.getDate());
102
+ const year = now.getFullYear();
103
+
104
+ return `_${hours}:${minutes}:${seconds},${month}-${day}-${year}`;
105
+
106
+ }
107
+
108
+ function generatePadding(data){
109
+ buffer = new Buffer.from(data); // we need to get byte length of the message body, not string length
110
+ let msgLength = buffer.length;
111
+
112
+ let padding = '';
113
+ if(msgLength % 16 !== 0){
114
+ const paddingNeeded = 15 - (msgLength % 16);
115
+ // generate random uppercase letters (only letters) for paddingNeeded
116
+ for(let i=0; i<paddingNeeded; i++){
117
+ const randomChar = String.fromCharCode(65 + Math.floor(Math.random() * 26));
118
+ padding += randomChar;
119
+ }
120
+ // generate byte array
121
+ console.log('Padding needed:', paddingNeeded, 'Generated padding:', padding);
122
+ return padding+'|';
123
+ }else
124
+ return '';
125
+ }
126
+
127
+
128
+ function validateHexString(str, strName, minLength, maxLength){ // NOTE LGTM
129
+ if(str.length < minLength || str.length > maxLength){
130
+ console.error(`${strName} must be between ${minLength} and ${maxLength} characters long`);
131
+ return false;
132
+
133
+ }
134
+
135
+ if(str.length !=0 && !/^[0-9A-Fa-f]+$/.test(str)){
136
+ console.error(`${strName} must be hexadecimal characters only (0-9, A-F)`);
137
+ return false;
138
+ }
139
+ return true;
140
+ }
141
+
142
+ function iterateMsgCount(id){ // NOTE LGTM
143
+ if(!deviceMap.has(id)){
144
+ deviceMap.set(id, 1);
145
+ }else{
146
+ let count = deviceMap.get(id);
147
+ count = (count % 9999) + 1; // wrap around at 999
148
+ deviceMap.set(id, count);
149
+ }
150
+ }
19
151
 
20
- }
21
- exports.default = SIADevice;
22
- // # sourceMappingURL=BJ_parser.js.map
152
+ // utf8toWin1252("a test ñ");
153
+
154
+
155
+ this.on('input', message => {
156
+ // const payload = message.payload;
157
+
158
+ let payload = {
159
+ "account" : "AABBCC",
160
+ "accountPrefix" : "5678"
161
+ }
162
+ siaConfig.receiverNumber = "1234";
163
+
164
+ const deviceAccount = payload.account;
165
+ const deviceAccountPrefix = payload.accountPrefix || '0';
166
+
167
+ // INPUT VALIDATION
168
+
169
+ if(!validateHexString(deviceAccount, 'Device account', 3, 16)) return;
170
+ if(!validateHexString(deviceAccountPrefix, 'Device account prefix', 1, 6)) return;
171
+ if(!validateHexString(siaConfig.receiverNumber, 'Receiver number', 0, 6)) return;
172
+
173
+ const deviceIdentifier = 'L'+ deviceAccountPrefix + '#' + deviceAccount;
174
+
175
+ iterateMsgCount(deviceIdentifier);
176
+
177
+
178
+ // PART: <"id"><seq><Rrcvr><Lpref><#acct>[
179
+ let messageBodyStart = '"'; // <"id"><seq><Rrcvr><Lpref><#acct>[
180
+ if(siaConfig.encryptionEnabled)
181
+ messageBodyStart += '*';
182
+
183
+ messageBodyStart += 'SIA-DCS"' // ID placeholder
184
+ messageBodyStart += deviceMap.get(deviceIdentifier).toString().padStart(4, '0'); // message sequence number
185
+ if(siaConfig.receiverNumber.length >0)
186
+ messageBodyStart += 'R'+siaConfig.receiverNumber;
187
+ messageBodyStart += deviceIdentifier;
188
+ messageBodyStart += '[';
189
+
190
+
191
+ // PART: #<acct>|<data>][<extende data>]
192
+ let messageBodyData = '#'+deviceAccount + '|'; // <pad>|...data...][x…data…]
193
+
194
+ // data format
195
+ // (N)(id-number)(DCS)(zone)
196
+ // there's also a format of group-zone
197
+
198
+ // messageBodyData += "NFA"; //
199
+ messageBodyData += "Nri129/FA1234"; //
200
+ // optional extended data can be added here, for example
201
+
202
+ // PART: ]<timestamp>, finalization of body
203
+ let messageBody = ''; // <"id"><seq><Rrcvr><Lpref><#acct>[<pad>|...data...][x…data…]<timestamp>
204
+ let timestamp = generateTimestamp(); // TODO: this should be optional
205
+
206
+ if(siaConfig.encryptionEnabled){ // everything past [ till <CR> is to be encrypted
207
+ let toEncrypt = messageBodyData+']'+timestamp;
208
+ toEncrypt = generatePadding(toEncrypt) + toEncrypt;
209
+ messageBody = messageBodyStart + encrypt(siaConfig.encryptionType, siaConfig.encryptionKey, toEncrypt);
210
+ }else{
211
+ messageBody += messageBodyStart;
212
+ messageBody += messageBodyData;
213
+ messageBody += ']'; // end of data fields
214
+ // optional extended data
215
+ messageBody += timestamp;
216
+ }
217
+
218
+ // Append <LF><crc><>
219
+ msgCount = (new Buffer.from(messageBody)).length;
220
+
221
+ let msg = '\n'; // <LF><crc><0LLL><"id"><seq><Rrcvr><Lpref><#acct>[<pad>|...data...][x…data…]<timestamp><CR>
222
+ msg += calculateCRCIBM16(messageBody); // CRC is 4 ASCII characters
223
+ msg += '0'+msgCount.toString(16).toUpperCase().padStart(3, '0'); // Carriage return
224
+ msg += messageBody;
225
+ msg += '\r';
226
+
227
+ // let hexMsg = '';
228
+ // for(let i=0; i<msg.length; i++){
229
+ // hexMsg += msg.charCodeAt(i).toString(16).padStart(2, '0').toUpperCase() + ' ';
230
+ // }
231
+ // console.log('Final message in hex: ', hexMsg);
232
+
233
+ server.connect();
234
+ server.write(msg);
235
+ server.close();
236
+ });
237
+ }
238
+
239
+ RED.nodes.registerType('SIA-device', SIADeviceNode);
240
+ };
@@ -0,0 +1,75 @@
1
+ <!--
2
+ Copyright (c) since the year 2016 Klaus Landsdorf (http://plus4nodered.com/)
3
+ Copyright 2016 - Jason D. Harper, Argonne National Laboratory
4
+ Copyright 2015,2016 - Mika Karaila, Valmet Automation Inc.
5
+ All rights reserved.
6
+ node-red-contrib-modbus
7
+
8
+ @author <a href="mailto:klaus.landsdorf@bianco-royal.de">Klaus Landsdorf</a> (Bianco Royal)
9
+ -->
10
+ <script type="text/javascript">
11
+ RED.nodes.registerType('SIA-server', {
12
+ category: 'config',
13
+ defaults: {
14
+
15
+ name: { value: "" },
16
+ receiverHost: { value: "", required: true },
17
+ receiverPort: { value: "", required: true },
18
+ receiverNumber : { value: ""},
19
+ encryptionKey: { value: ""},
20
+ },
21
+ label: function () {
22
+ return this.name || 'sia-server@' + this.receiverHost;
23
+ },
24
+
25
+ oneditprepare: function () {
26
+ let previous = null;
27
+
28
+
29
+ if(this.encryptionKey == null){
30
+ this.encryptionKey = "";
31
+ }
32
+
33
+ let allowedLengths = [0, 32, 48, 64];
34
+ if(!allowedLengths.includes(this.encryptionKey.length)){
35
+ Node.error('Encryption key must be empty or 128, 192, 256 bits long in HEX');
36
+ }
37
+
38
+ if(!/^[0-9A-Fa-f]+$/.test(this.encryptionKey)){ // hexadecimal characters only
39
+ Node.error('Encryption key must be in hexadecimal characters only (0-9, A-F)');
40
+ }
41
+
42
+
43
+
44
+ // check if encryptionKey is 128 bit 192 or 256 bit long
45
+ // encryptionKey needs to be a hex string
46
+
47
+
48
+
49
+ }
50
+ })
51
+ </script>
52
+
53
+ <script type="text/x-red" data-template-name="SIA-server">
54
+ <div class="form-row">
55
+ <label for="node-config-input-name"><i class="icon-tag"></i> Name</label>
56
+ <input type="text" id="node-config-input-name" placeholder="Name">
57
+ </div>
58
+ <div class="form-row">
59
+ <label for="node-config-input-receiverHost">Receiver IP</label>
60
+ <input type="text" id="node-config-input-receiverHost" placeholder="Receiver Host">
61
+ </div>
62
+ <div class="form-row">
63
+ <label for="node-config-input-receiverPort">Receiver Port</label>
64
+ <input type="number" id="node-config-input-receiverPort" placeholder="Receiver Port">
65
+ </div>
66
+ <div class="form-row">
67
+ <label for="node-config-input-receiverNumber">Receiver Number</label>
68
+ <input type="number" id="node-config-input-receiverNumber" placeholder="Receiver Number">
69
+ </div>
70
+ <div class="form-row">
71
+ <label for="node-config-input-encryptionKey">Encryption Key</label>
72
+ <input type="password" id="node-config-input-encryptionKey" placeholder="SIA Password">
73
+ </div>
74
+ </script>
75
+
@@ -0,0 +1,127 @@
1
+ module.exports = function (RED) {
2
+ 'use strict';
3
+ // SOURCE-MAP-REQUIRED
4
+
5
+ const Net = require('node:net');
6
+ const Retry = require('retry');
7
+
8
+ function SIAServer(config) {
9
+ RED.nodes.createNode(this, config);
10
+
11
+ this.receiverHost = config.receiverHost;
12
+ this.receiverPort = Number.parseInt(config.receiverPort);
13
+ this.receiverNumber = config.receiverNumber || '';
14
+ // This.siaAccount = config.siaAccount;
15
+ // this.siaAccountPrefix = config.siaAccountPrefix || 'L0';
16
+ this.encryptionKey = config.encryptionKey || '';
17
+ this.encryptionEnabled = this.encryptionKey.length > 0;
18
+
19
+ switch (this.encryptionKey.length) {
20
+ case 32:
21
+ this.encryptionType = 'aes-128-cbc';
22
+ break;
23
+ case 48:
24
+ this.encryptionType = 'aes-192-cbc';
25
+ break;
26
+ case 64:
27
+ this.encryptionType = 'aes-256-cbc';
28
+ break;
29
+ default:
30
+ return undefined;
31
+ }
32
+
33
+
34
+
35
+ const client = new Net.Socket();
36
+
37
+ process.on('uncaughtException', error => {
38
+ console.error('Uncaught Exception:', error);
39
+ client.destroy();
40
+ });
41
+
42
+ this.connect = function () {
43
+ // If(!client.destroyed && client.readyState == 'open') {
44
+ // console.log('Already connected to SIA server at ' + this.receiverHost + ':' + this.receiverPort);
45
+ // return;
46
+ // }
47
+
48
+ if (!this.receiverHost || !this.receiverPort) {
49
+ console.error('Receiver host or port not set');
50
+ return;
51
+ }
52
+
53
+ console.log('Connecting to SIA server at', this.receiverHost, this.receiverPort);
54
+
55
+ const operation = Retry.operation({
56
+ retries: 5,
57
+ factor: 2,
58
+ minTimeout: 1000,
59
+ maxTimeout: 20_000,
60
+ randomize: true,
61
+ });
62
+
63
+ const tmpRef = this;
64
+
65
+ let errorListener = null;
66
+
67
+
68
+ const connectCallback = () => {
69
+ console.log('Connected to SIA server at', tmpRef.receiverHost, tmpRef.receiverPort);
70
+ };
71
+
72
+ operation.attempt(currentAttempt => {
73
+
74
+ if (errorListener) { // will not be active on first attempt
75
+ client.off('error', errorListener);
76
+ client.off('connect', connectCallback);
77
+ }
78
+
79
+ errorListener = error => {
80
+ console.log(`Connection error: ${error.message}`);
81
+ if (operation.retry(error)) {
82
+ console.log(`Retrying connection to SIA server, attempt number: ${currentAttempt}`);
83
+ return;
84
+ }
85
+
86
+ console.error('Failed to connect to SIA server:', error);
87
+ };
88
+
89
+ client.once('error', errorListener);
90
+
91
+ client.connect(tmpRef.receiverPort, tmpRef.receiverHost, connectCallback);
92
+ });
93
+ };
94
+
95
+ this.getSIAConfig = function () {
96
+ return {
97
+ receiverNumber: this.receiverNumber,
98
+ encryptionKey: this.encryptionKey,
99
+ encryptionEnabled: this.encryptionEnabled,
100
+ encryptionType: this.encryptionType,
101
+ };
102
+ };
103
+
104
+ this.write = function (data) {
105
+ if (!client.destroyed && client.readyState == 'open') {
106
+ console.log('Sending data to SIA server:', data);
107
+ client.write(data);
108
+ }
109
+ };
110
+
111
+ this.close = function () {
112
+ if (!client.destroyed) {
113
+ client.end();
114
+ }
115
+ };
116
+
117
+ // Handle sending of data
118
+ // handle failure to connect
119
+ // payload won't be prepared here but in SIA device
120
+
121
+ // client.write('Hello, server.');
122
+ }
123
+
124
+ RED.nodes.registerType('SIA-server', SIAServer);
125
+
126
+ /* istanbul ignore next */
127
+ };
package/SIA_device.html DELETED
@@ -1,37 +0,0 @@
1
- <script type="text/javascript">
2
- RED.nodes.registerType('SIA-device', {
3
- category: 'common',
4
- color: '#0B99D8',
5
- defaults: {
6
- name: { value: "" },
7
- server: { value: "", type: "SIA-server", required: true }, // This will
8
- },
9
- align: 'left',
10
- icon: "icon.png",
11
- inputs: 1,
12
- outputs: 0,
13
- label: function () {
14
- return this.name || "SIA Device";
15
- },
16
-
17
- });
18
-
19
- </script>
20
-
21
- <style>
22
-
23
- .input-button-wrap>input {
24
- width: 100% !important;
25
- }
26
- </style>
27
-
28
- <script type="text/x-red" data-template-name="BJ-parser">
29
- <div class="form-row">
30
- <label for="node-input-name"><i class="icon-tag"></i> Name</label>
31
- <input type="text" id="node-input-name" placeholder="Name">
32
- </div>
33
- <div class="form-row">
34
- <label for="node-input-server">SIA Server</label>
35
- <input type="text" id="node-input-server" placeholder="Select SIA Server">
36
- </div>
37
- </script>
package/SIA_device.js DELETED
@@ -1,43 +0,0 @@
1
- const clientModule = __importDefault(require('./src/SIA_device.js'));
2
-
3
-
4
- module.exports = function (RED) {
5
-
6
-
7
- function ParserNode(config) {
8
- RED.nodes.createNode(this, config);
9
-
10
- this.serverConfig = RED.nodes.getNode(config.server);
11
- const siaModule = new clientModule.default(serverConfig);
12
- siaModule.connect();
13
-
14
- this.on('input', message => {
15
- parsedPayload = message.payload;
16
-
17
-
18
- // const parser = new parserModule.default(message.statusSchema, parserConfig);
19
- // message.payload.outJson = parser.processPayload(parsedPayload);
20
-
21
-
22
- if(parsedPayload === undefined){
23
- this.send(message);
24
- return;
25
- }
26
- if(message.payload.parsingError == true){
27
- this.send(message);
28
- return;
29
- }
30
-
31
- this.send(message);
32
- });
33
- }
34
-
35
- RED.nodes.registerType('SIA-device', ParserNode);
36
- RED.nodes.registerType('SIA-server', require('./sia-server.js'));
37
-
38
-
39
- };
40
-
41
-
42
-
43
-
package/SIA_server.html DELETED
@@ -1,47 +0,0 @@
1
- <script type="text/javascript">
2
- RED.nodes.registerType('SIA-server', {
3
- category: 'config',
4
- defaults: {
5
- name: { value: "" },
6
- receiverIP: { value: "", required: true },
7
- receiverPort: { value: "", required: true },
8
- siaAccount: { value: "", required: true },
9
- siaPassword: { value: "", required: true },
10
- encryptionEnabled: { value: false },
11
- passwordInHex: { value: false },
12
- },
13
- label: function () {
14
- return this.name || "SIA Server";
15
- },
16
- });
17
- </script>
18
- <script type="text/x-red" data-template-name="SIA-server">
19
- <div class="form-row">
20
- <label for="node-config-input-name"><i class="icon-tag"></i> Name</label>
21
- <input type="text" id="node-config-input-name" placeholder="Name">
22
- </div>
23
- <div class="form-row">
24
- <label for="node-config-input-receiverIP">Receiver IP</label>
25
- <input type="text" id="node-config-input-receiverIP" placeholder="Receiver IP">
26
- </div>
27
- <div class="form-row">
28
- <label for="node-config-input-receiverPort">Receiver Port</label>
29
- <input type="text" id="node-config-input-receiverPort" placeholder="Receiver Port">
30
- </div>
31
- <div class="form-row">
32
- <label for="node-config-input-siaAccount">SIA Account</label>
33
- <input type="text" id="node-config-input-siaAccount" placeholder="SIA Account">
34
- </div>
35
- <div class="form-row">
36
- <label for="node-config-input-siaPassword">SIA Password</label>
37
- <input type="password" id="node-config-input-siaPassword" placeholder="SIA Password">
38
- </div>
39
- <div class="form-row">
40
- <label for="node-config-input-encryptionEnabled">Encryption Enabled</label>
41
- <input type="checkbox" id="node-config-input-encryptionEnabled" style="display: inline-block; width: auto; vertical-align: middle;">
42
- </div>
43
- <div class="form-row">
44
- <label for="node-config-input-passwordInHex">Password in Hex</label>
45
- <input type="checkbox" id="node-config-input-passwordInHex" style="display: inline-block; width: auto; vertical-align: middle;">
46
- </div>
47
- </script>
package/SIA_server.js DELETED
@@ -1,14 +0,0 @@
1
- module.exports = function(RED) {
2
- function SIAServerNode(config) {
3
- RED.nodes.createNode(this, config);
4
- // Store the configuration values
5
- this.name = config.name;
6
- this.receiverIP = config.receiverIP;
7
- this.receiverPort = config.receiverPort;
8
- this.siaAccount = config.siaAccount;
9
- this.siaPassword = config.siaPassword;
10
- this.encryptionEnabled = config.encryptionEnabled;
11
- this.passwordInHex = config.passwordInHex;
12
- }
13
- RED.nodes.registerType("SIA-server", SIAServerNode);
14
- };