@tier0/node-red-contrib-opcda-client 1.0.4 → 1.0.5

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/patch-ntlm.js DELETED
@@ -1,46 +0,0 @@
1
- const fs = require('fs');
2
- const file = '/usr/src/node-red/node_modules/node-dcom/dcom/rpc/security/ntlmauthentication.js';
3
- let code = fs.readFileSync(file, 'utf8');
4
-
5
- // Fix 1: Replace all Encdec references with inline uint16le decode
6
- code = code.replace(
7
- /new Encdec\(\)\.dec_uint16le\(targetInformation,\s*i\)/g,
8
- '(targetInformation[i] | (targetInformation[i+1] << 8))'
9
- );
10
- code = code.replace(
11
- /new Encdec\.dec_uint16le\(targetInformation,\s*i\)/g,
12
- '(targetInformation[i] | (targetInformation[i+1] << 8))'
13
- );
14
-
15
- // Fix 2: Add debug logging for NTLM credentials
16
- code = code.replace(
17
- 'let target = null;',
18
- 'let target = null;\n console.log("[NTLM-DBG] domain=" + info.domain + " user=" + this.credentials.username);'
19
- );
20
-
21
- // Verify no syntax errors
22
- try {
23
- new Function(code);
24
- console.log('ERROR: wrapped in function - not a module');
25
- } catch(e) {
26
- // Expected since it's a class/module, not a function body
27
- }
28
-
29
- fs.writeFileSync(file, code);
30
-
31
- // Verify it loads
32
- try {
33
- delete require.cache[require.resolve(file)];
34
- require(file);
35
- console.log('Patched and verified OK');
36
- } catch(e) {
37
- console.log('WARNING: Load check result:', e.message);
38
- // May fail due to missing dependencies in standalone context, that's OK
39
- // as long as it's not a syntax error
40
- if (e.message.includes('Unexpected token')) {
41
- console.log('SYNTAX ERROR - reverting!');
42
- // Don't revert for now, let's see the error
43
- } else {
44
- console.log('Non-syntax error (expected in standalone context)');
45
- }
46
- }
package/patch-pwdcheck.js DELETED
@@ -1,17 +0,0 @@
1
- const fs = require('fs');
2
- const file = '/usr/src/node-red/node_modules/node-dcom/dcom/rpc/security/ntlmauthentication.js';
3
- let code = fs.readFileSync(file, 'utf8');
4
-
5
- // Add password length and MD4 check debug
6
- code = code.replace(
7
- 'let target = null;',
8
- `let target = null;
9
- console.log("[NTLM-DBG] domain=" + info.domain + " user=" + this.credentials.username + " pwdLen=" + (this.credentials.password ? this.credentials.password.length : "NULL"));
10
- try { const _h = Crypto.createHash('md4'); _h.update(Buffer.from(this.credentials.password || '', 'utf16le')); console.log("[NTLM-DBG] md4-ok ntHash=" + _h.digest('hex')); } catch(e) { console.log("[NTLM-DBG] md4-FAIL: " + e.message); }`
11
- );
12
-
13
- fs.writeFileSync(file, code);
14
-
15
- // Verify loads
16
- try { require('node-opc-da'); console.log('Patched OK, module loads'); }
17
- catch(e) { console.log('Load result:', e.message); }
package/test-connect.js DELETED
@@ -1,69 +0,0 @@
1
- const opcda = require('node-opc-da');
2
- const { OPCServer } = opcda;
3
- const { ComServer, Session, Clsid } = opcda.dcom;
4
-
5
- const config = {
6
- address: '192.168.31.75',
7
- domain: 'DESKTOP-BBD7VBL',
8
- username: 'Administrator',
9
- password: 'Supos@1304',
10
- clsid: '7BC0CC8E-482C-47CA-ABDC-0FE7F9C6E729',
11
- timeout: 10000
12
- };
13
-
14
- async function test() {
15
- console.log('=== OPC DA Connection Test ===');
16
- console.log('Address:', config.address);
17
- console.log('Domain:', config.domain);
18
- console.log('Username:', config.username);
19
- console.log('CLSID:', config.clsid);
20
- console.log('');
21
-
22
- try {
23
- console.log('[1] Creating session...');
24
- var session = new Session();
25
- session = session.createSession(config.domain, config.username, config.password);
26
- session.setGlobalSocketTimeout(config.timeout);
27
- console.log('[1] Session created OK');
28
-
29
- console.log('[2] Creating ComServer...');
30
- var comServer = new ComServer(new Clsid(config.clsid), config.address, session);
31
- console.log('[2] ComServer created, calling init()...');
32
-
33
- await comServer.init();
34
- console.log('[2] ComServer.init() OK!');
35
-
36
- console.log('[3] Creating COM instance...');
37
- var comObject = await comServer.createInstance();
38
- console.log('[3] COM instance created OK!');
39
-
40
- console.log('[4] Creating OPC Server...');
41
- var opcServer = new OPCServer();
42
- await opcServer.init(comObject);
43
- console.log('[4] OPC Server connected!');
44
-
45
- console.log('[5] Getting browser...');
46
- var browser = await opcServer.getBrowser();
47
- var items = await browser.browseAllFlat();
48
- console.log('[5] Found', items.length, 'items');
49
- items.slice(0, 10).forEach(i => console.log(' ', i));
50
-
51
- await browser.end();
52
- await opcServer.end();
53
- await comServer.closeStub();
54
- console.log('\n=== SUCCESS ===');
55
- } catch (e) {
56
- console.log('\n=== FAILED ===');
57
- console.log('Error type:', typeof e);
58
- console.log('Error value:', e);
59
- if (e instanceof Error) {
60
- console.log('Message:', e.message);
61
- console.log('Stack:', e.stack);
62
- }
63
- if (typeof e === 'number') {
64
- console.log('Hex:', '0x' + (e >>> 0).toString(16));
65
- }
66
- }
67
- }
68
-
69
- test();
package/test-connect2.js DELETED
@@ -1,30 +0,0 @@
1
- const opcda = require('node-opc-da');
2
- const { OPCServer } = opcda;
3
- const { ComServer, Session, Clsid } = opcda.dcom;
4
-
5
- async function test(domain) {
6
- console.log('\n--- Testing with domain="' + domain + '" ---');
7
- try {
8
- var session = new Session();
9
- session = session.createSession(domain, 'Administrator', 'Supos@1304');
10
- session.setGlobalSocketTimeout(10000);
11
-
12
- var comServer = new ComServer(
13
- new Clsid('7BC0CC8E-482C-47CA-ABDC-0FE7F9C6E729'),
14
- '192.168.31.75', session);
15
-
16
- await comServer.init();
17
- console.log('SUCCESS with domain="' + domain + '"');
18
- await comServer.closeStub();
19
- } catch (e) {
20
- var code = typeof e === 'number' ? '0x' + (e >>> 0).toString(16) : (e.message || String(e));
21
- console.log('FAILED:', code);
22
- }
23
- }
24
-
25
- (async () => {
26
- await test('DESKTOP-BBD7VBL');
27
- await test('.');
28
- await test('');
29
- await test('WORKGROUP');
30
- })();
package/test-direct.js DELETED
@@ -1,53 +0,0 @@
1
- const opcda = require('/usr/src/node-red/node_modules/node-opc-da/src/index.js');
2
- const dcom = require('node-dcom');
3
- const { ComServer, Session, Clsid } = dcom;
4
-
5
- const address = '192.168.31.75';
6
- const domain = 'DESKTOP-BBD7VBL';
7
- const username = 'Administrator';
8
- const password = 'Supos@1304';
9
- const clsidStr = '7BC0CC8E-482C-47CA-ABDC-0FE7F9C6E729';
10
-
11
- async function main() {
12
- console.log('=== OPC DA Direct Connection Test ===');
13
-
14
- let comSession, comServer;
15
- try {
16
- comSession = new Session();
17
- comSession = comSession.createSession(domain, username, password);
18
- comSession.setGlobalSocketTimeout(15000);
19
- console.log('Session: domain=' + comSession.getDomain() + ' user=' + comSession.getUserName());
20
-
21
- comServer = new ComServer(new Clsid(clsidStr), address, comSession);
22
- console.log('Connecting...');
23
- await comServer.init();
24
- console.log('Connected!');
25
-
26
- const comObject = await comServer.createInstance();
27
- console.log('Instance created');
28
-
29
- const server = new opcda.OPCServer();
30
- await server.init(comObject);
31
- console.log('OPCServer initialized');
32
-
33
- const status = await server.getStatus();
34
- console.log('Server Status:', JSON.stringify(status, null, 2));
35
-
36
- const browser = await server.getBrowser();
37
- console.log('Got browser');
38
-
39
- const items = await browser.browse();
40
- console.log('Items found:', items.length);
41
- if (items.length > 0) {
42
- console.log('First 5 items:', items.slice(0, 5));
43
- }
44
-
45
- console.log('\n=== SUCCESS ===');
46
- } catch (err) {
47
- console.error('ERROR:', err.message || err);
48
- console.error('Stack:', err.stack);
49
- }
50
- process.exit(0);
51
- }
52
-
53
- main();
@@ -1,100 +0,0 @@
1
- // MS-NLMP Appendix A test vectors for NTLMv2
2
- // Reference: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/
3
- const Crypto = require('crypto');
4
-
5
- // Force legacy provider for MD4
6
- process.env.NODE_OPTIONS = '--openssl-legacy-provider';
7
-
8
- const Responses = require('/usr/src/node-red/node_modules/node-dcom/dcom/rpc/security/responses.js');
9
-
10
- const r = new Responses();
11
-
12
- // MS-NLMP test vectors
13
- const User = 'User';
14
- const UserDom = 'Domain';
15
- const Passwd = 'Password';
16
- const ServerChallenge = [0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
17
- const ClientChallenge = [0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa];
18
- const Time = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
19
-
20
- // Expected values from MS-NLMP spec
21
- const EXPECTED_NT_HASH = 'a4f49c406510bdcab6824ee7c30fd852';
22
- const EXPECTED_NTLMv2_HASH = '0c868a403bfd7a93a3001ef22ef02e3f';
23
-
24
- // Test 1: NT Hash (MD4 of UTF-16LE password)
25
- console.log('=== Test 1: NT Hash ===');
26
- const ntHash = r.ntlmHash(Passwd);
27
- const ntHashHex = Buffer.from(ntHash).toString('hex');
28
- console.log('Computed:', ntHashHex);
29
- console.log('Expected:', EXPECTED_NT_HASH);
30
- console.log('Match:', ntHashHex === EXPECTED_NT_HASH ? 'PASS' : 'FAIL');
31
-
32
- // Test 2: NTLMv2 Hash
33
- console.log('\n=== Test 2: NTLMv2 Hash ===');
34
- const ntlmv2Hash = r.ntlmv2Hash(UserDom, User, Passwd);
35
- const ntlmv2HashHex = Buffer.from(ntlmv2Hash).toString('hex');
36
- console.log('Computed:', ntlmv2HashHex);
37
- console.log('Expected:', EXPECTED_NTLMv2_HASH);
38
- console.log('Match:', ntlmv2HashHex === EXPECTED_NTLMv2_HASH ? 'PASS' : 'FAIL');
39
-
40
- // Test 3: LMv2 Response
41
- console.log('\n=== Test 3: LMv2 Response ===');
42
- const lmv2 = r.getLMv2Response(UserDom, User, Passwd, ServerChallenge, ClientChallenge);
43
- const lmv2Hex = Buffer.from(lmv2).toString('hex');
44
- console.log('Computed:', lmv2Hex);
45
- // Expected from MS-NLMP: d6e6152ea25d03b7c6ba6629c2d6aaf0aaaaaaaaaaaaaaaa
46
- const EXPECTED_LMv2 = 'd6e6152ea25d03b7c6ba6629c2d6aaf0aaaaaaaaaaaaaaaa';
47
- console.log('Expected:', EXPECTED_LMv2);
48
- console.log('Match:', lmv2Hex === EXPECTED_LMv2 ? 'PASS' : 'FAIL');
49
-
50
- // Test 4: hmacMD5 argument order verification
51
- console.log('\n=== Test 4: HMAC-MD5 argument order ===');
52
- const testHmac = r.hmacMD5([0x01, 0x02, 0x03], [0x04, 0x05, 0x06]);
53
- console.log('hmacMD5([1,2,3], [4,5,6]) =', Buffer.from(testHmac).toString('hex'));
54
- // Verify: HMAC-MD5(key=040506, data=010203)
55
- const verifyHmac = Crypto.createHmac('md5', Buffer.from([0x04, 0x05, 0x06]));
56
- verifyHmac.update(Buffer.from([0x01, 0x02, 0x03]));
57
- console.log('Crypto.HMAC(key=040506, data=010203) =', verifyHmac.digest('hex'));
58
-
59
- // Test 5: NTLMv2 Response with known blob
60
- console.log('\n=== Test 5: NTLMv2 Response ===');
61
- // Build a minimal target info for testing
62
- const targetInfo = [
63
- 0x02, 0x00, 0x0c, 0x00, // MsvAvNbDomainName, len=12
64
- 0x44, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, // "Domain" in UTF-16LE
65
- 0x01, 0x00, 0x0c, 0x00, // MsvAvNbComputerName, len=12
66
- 0x53, 0x00, 0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, // "Server" in UTF-16LE
67
- 0x00, 0x00, 0x00, 0x00 // MsvAvEOL
68
- ];
69
-
70
- // Test blob creation
71
- const blob = r.createBlob(targetInfo, ClientChallenge);
72
- console.log('Blob length:', blob.length);
73
- console.log('Blob header (first 8):', Buffer.from(blob.slice(0, 8)).toString('hex'));
74
- console.log('Blob timestamp (next 8):', Buffer.from(blob.slice(8, 16)).toString('hex'));
75
- console.log('Blob clientNonce (next 8):', Buffer.from(blob.slice(16, 24)).toString('hex'));
76
-
77
- // Verify blob structure
78
- console.log('\nBlob structure check:');
79
- console.log('Byte 0-1 (signature):', blob[0] === 1 && blob[1] === 1 ? 'PASS (0x0101)' : 'FAIL');
80
- console.log('Byte 2-7 (zeros):', blob.slice(2, 8).every(b => b === 0) ? 'PASS' : 'FAIL');
81
- console.log('Byte 16-23 (client nonce):', Buffer.from(blob.slice(16, 24)).toString('hex') === 'aaaaaaaaaaaaaaaa' ? 'PASS' : 'FAIL');
82
- console.log('Byte 24-27 (Z4):', blob.slice(24, 28).every(b => b === 0) ? 'PASS' : 'FAIL');
83
-
84
- // Verify the full NTLMv2 response computation
85
- const retval = r.getNTLMv2Response(UserDom, User, Passwd, targetInfo, ServerChallenge, ClientChallenge);
86
- console.log('\nNTLMv2Response length:', retval[0].length);
87
- console.log('NTProofStr:', Buffer.from(retval[0].slice(0, 16)).toString('hex'));
88
-
89
- // Test session base key
90
- const ntProofStr = retval[0].slice(0, 16);
91
- const hashForSession = r.ntlmv2Hash(UserDom, User, Passwd);
92
- const sessionBaseKey = r.hmacMD5(ntProofStr, hashForSession);
93
- console.log('SessionBaseKey:', Buffer.from(sessionBaseKey).toString('hex'));
94
-
95
- // Now test with actual credentials
96
- console.log('\n\n=== Test with actual credentials ===');
97
- const actualNtHash = r.ntlmHash('Supos@1304');
98
- console.log('NT Hash (Supos@1304):', Buffer.from(actualNtHash).toString('hex'));
99
- const actualV2Hash = r.ntlmv2Hash('DESKTOP-BBD7VBL', 'Administrator', 'Supos@1304');
100
- console.log('NTLMv2 Hash:', Buffer.from(actualV2Hash).toString('hex'));
@@ -1,77 +0,0 @@
1
- const Crypto = require('crypto');
2
-
3
- // Verify DES update() vs final() behavior in this Node.js version
4
- console.log('=== Node.js version:', process.version, '===');
5
- console.log('=== OpenSSL version:', process.versions.openssl, '===\n');
6
-
7
- // Test 1: DES-ECB update() behavior
8
- console.log('--- Test 1: DES-ECB update vs final ---');
9
- const key1 = Buffer.from('0123456789ABCDEF', 'hex');
10
- const data1 = Buffer.from('4E6F772069732074', 'hex');
11
- const des1 = Crypto.createCipheriv('des-ecb', key1, '');
12
- const update1 = des1.update(data1);
13
- const final1 = des1.final();
14
- console.log('update() returned', update1.length, 'bytes:', update1.toString('hex'));
15
- console.log('final() returned', final1.length, 'bytes:', final1.toString('hex'));
16
- console.log('Expected update=3fa40e8a984d4815 (8 bytes)\n');
17
-
18
- // Test 2: Verify NT hash
19
- console.log('--- Test 2: NT Hash of Supos@1304 ---');
20
- const md4 = Crypto.createHash('md4');
21
- md4.update(Buffer.from('Supos@1304', 'utf16le'));
22
- const ntHash = md4.digest();
23
- console.log('NT Hash:', ntHash.toString('hex'));
24
- console.log('Length:', ntHash.length, '\n');
25
-
26
- // Test 3: NTLM2 Session Response with known values
27
- console.log('--- Test 3: Full NTLM2 Session Response ---');
28
- const Responses = require('node-opc-da/node_modules/node-dcom/dcom/rpc/security/responses.js');
29
- const r = new Responses();
30
-
31
- const fakeChallenge = Buffer.from('0123456789abcdef', 'hex');
32
- const fakeClientNonce = Buffer.from('ffffff0011223344', 'hex');
33
- const testResponse = r.getNTLM2SessionResponse('Password', fakeChallenge, fakeClientNonce);
34
- console.log('Response type:', typeof testResponse, testResponse.constructor.name);
35
- console.log('Response length:', testResponse.length);
36
- console.log('Response hex:', testResponse.toString('hex'));
37
-
38
- // Independent verification of the same computation
39
- const ntHash2 = Crypto.createHash('md4').update(Buffer.from('Password', 'utf16le')).digest();
40
- console.log('\nIndependent NT hash:', ntHash2.toString('hex'));
41
- const sessionNonce = Buffer.concat([fakeChallenge, fakeClientNonce]);
42
- const sessionHash = Crypto.createHash('md5').update(sessionNonce).digest().slice(0, 8);
43
- console.log('Session hash:', sessionHash.toString('hex'));
44
-
45
- // Manual DES with NT hash
46
- function createDESKey(bytes, offset) {
47
- let keyBytes = bytes.slice(offset, 7 + offset);
48
- let material = Buffer.alloc(8);
49
- material[0] = keyBytes[0];
50
- material[1] = ((keyBytes[0] << 7) & 0xff | ((keyBytes[1] & 0xff) >>> 1));
51
- material[2] = ((keyBytes[1] << 6) & 0xff | ((keyBytes[2] & 0xff) >>> 2));
52
- material[3] = ((keyBytes[2] << 5) & 0xff | ((keyBytes[3] & 0xff) >>> 3));
53
- material[4] = ((keyBytes[3] << 4) & 0xff | ((keyBytes[4] & 0xff) >>> 4));
54
- material[5] = ((keyBytes[4] << 3) & 0xff | ((keyBytes[5] & 0xff) >>> 5));
55
- material[6] = ((keyBytes[5] << 2) & 0xff | ((keyBytes[6] & 0xff) >>> 6));
56
- material[7] = ((keyBytes[6] << 1));
57
- // odd parity
58
- for (let i = 0; i < 8; i++) {
59
- let b = material[i];
60
- let needsParity = (((b >>> 7) ^ (b >>> 6) ^ (b >>> 5) ^ (b >>> 4) ^ (b >>> 3) ^ (b >>> 2) ^ (b >>> 1)) & 0x01) == 0;
61
- if (needsParity) material[i] |= 0x01;
62
- else material[i] &= 0xfe;
63
- }
64
- return material;
65
- }
66
-
67
- const padded = Buffer.concat([ntHash2, Buffer.alloc(5)]);
68
- let manualResult = Buffer.alloc(0);
69
- for (let off of [0, 7, 14]) {
70
- const k = createDESKey(padded, off);
71
- const d = Crypto.createCipheriv('des-ecb', k, '');
72
- const enc = d.update(sessionHash);
73
- d.final();
74
- manualResult = Buffer.concat([manualResult, enc]);
75
- }
76
- console.log('Manual response:', manualResult.toString('hex'));
77
- console.log('Match:', testResponse.toString('hex') === manualResult.toString('hex') ? 'YES' : 'NO');
package/uns_import.json DELETED
@@ -1,204 +0,0 @@
1
- {
2
- "UNS": [
3
- {
4
- "type": "path",
5
- "name": "opcda",
6
- "children": [
7
- {
8
- "type": "path",
9
- "name": "通道_1",
10
- "children": [
11
- {
12
- "type": "path",
13
- "name": "设备_1",
14
- "children": [
15
- {
16
- "dataType": "METRIC",
17
- "displayName": "Metric",
18
- "type": "path",
19
- "name": "Metric",
20
- "children": [
21
- {
22
- "topicType": "METRIC",
23
- "generateDashboard": "TRUE",
24
- "writeData": "FALSE",
25
- "name": "标记_1",
26
- "enableHistory": "TRUE",
27
- "dataType": "TIME_SEQUENCE_TYPE",
28
- "fields": [
29
- {
30
- "systemField": true,
31
- "unique": true,
32
- "type": "DATETIME",
33
- "name": "timeStamp"
34
- },
35
- {
36
- "tbValueName": "tag",
37
- "systemField": true,
38
- "unique": true,
39
- "type": "LONG",
40
- "name": "tag"
41
- },
42
- {
43
- "index": "double_1",
44
- "type": "FLOAT",
45
- "name": "value"
46
- },
47
- {
48
- "systemField": true,
49
- "type": "LONG",
50
- "name": "quality"
51
- }
52
- ],
53
- "type": "topic",
54
- "mockData": "FALSE"
55
- },
56
- {
57
- "topicType": "METRIC",
58
- "generateDashboard": "TRUE",
59
- "writeData": "FALSE",
60
- "name": "标记_2",
61
- "enableHistory": "TRUE",
62
- "dataType": "TIME_SEQUENCE_TYPE",
63
- "fields": [
64
- {
65
- "systemField": true,
66
- "unique": true,
67
- "type": "DATETIME",
68
- "name": "timeStamp"
69
- },
70
- {
71
- "tbValueName": "tag",
72
- "systemField": true,
73
- "unique": true,
74
- "type": "LONG",
75
- "name": "tag"
76
- },
77
- {
78
- "index": "double_1",
79
- "type": "FLOAT",
80
- "name": "value"
81
- },
82
- {
83
- "systemField": true,
84
- "type": "LONG",
85
- "name": "quality"
86
- }
87
- ],
88
- "type": "topic",
89
- "mockData": "FALSE"
90
- }
91
- ]
92
- }
93
- ]
94
- }
95
- ]
96
- },
97
- {
98
- "type": "path",
99
- "name": "模拟器示例",
100
- "children": [
101
- {
102
- "type": "path",
103
- "name": "功能",
104
- "children": [
105
- {
106
- "dataType": "METRIC",
107
- "displayName": "Metric",
108
- "type": "path",
109
- "name": "Metric",
110
- "children": [
111
- {
112
- "topicType": "METRIC",
113
- "generateDashboard": "TRUE",
114
- "writeData": "FALSE",
115
- "name": "Sine1",
116
- "enableHistory": "TRUE",
117
- "dataType": "TIME_SEQUENCE_TYPE",
118
- "fields": [
119
- {
120
- "systemField": true,
121
- "unique": true,
122
- "type": "DATETIME",
123
- "name": "timeStamp"
124
- },
125
- {
126
- "tbValueName": "tag",
127
- "systemField": true,
128
- "unique": true,
129
- "type": "LONG",
130
- "name": "tag"
131
- },
132
- {
133
- "index": "double_1",
134
- "type": "FLOAT",
135
- "name": "value"
136
- },
137
- {
138
- "systemField": true,
139
- "type": "LONG",
140
- "name": "quality"
141
- }
142
- ],
143
- "type": "topic",
144
- "mockData": "FALSE"
145
- }
146
- ]
147
- }
148
- ]
149
- }
150
- ]
151
- },
152
- {
153
- "type": "path",
154
- "name": "_System",
155
- "children": [
156
- {
157
- "dataType": "METRIC",
158
- "displayName": "Metric",
159
- "type": "path",
160
- "name": "Metric",
161
- "children": [
162
- {
163
- "topicType": "METRIC",
164
- "generateDashboard": "TRUE",
165
- "writeData": "FALSE",
166
- "name": "_Time",
167
- "enableHistory": "TRUE",
168
- "dataType": "TIME_SEQUENCE_TYPE",
169
- "fields": [
170
- {
171
- "systemField": true,
172
- "unique": true,
173
- "type": "DATETIME",
174
- "name": "timeStamp"
175
- },
176
- {
177
- "tbValueName": "tag",
178
- "systemField": true,
179
- "unique": true,
180
- "type": "LONG",
181
- "name": "tag"
182
- },
183
- {
184
- "index": "double_1",
185
- "type": "FLOAT",
186
- "name": "value"
187
- },
188
- {
189
- "systemField": true,
190
- "type": "LONG",
191
- "name": "quality"
192
- }
193
- ],
194
- "type": "topic",
195
- "mockData": "FALSE"
196
- }
197
- ]
198
- }
199
- ]
200
- }
201
- ]
202
- }
203
- ]
204
- }