@robdobsn/raftjs 1.1.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 (149) hide show
  1. package/.editorconfig +14 -0
  2. package/.gitattributes +11 -0
  3. package/.nvmrc +1 -0
  4. package/LICENSE +22 -0
  5. package/README.md +11 -0
  6. package/TODO.md +1 -0
  7. package/dist/RaftAttributeHandler.d.ts +12 -0
  8. package/dist/RaftAttributeHandler.js +241 -0
  9. package/dist/RaftAttributeHandler.js.map +1 -0
  10. package/dist/RaftChannel.d.ts +18 -0
  11. package/dist/RaftChannel.js +12 -0
  12. package/dist/RaftChannel.js.map +1 -0
  13. package/dist/RaftChannelWebBLE.d.ts +38 -0
  14. package/dist/RaftChannelWebBLE.js +274 -0
  15. package/dist/RaftChannelWebBLE.js.map +1 -0
  16. package/dist/RaftChannelWebSerial.d.ts +37 -0
  17. package/dist/RaftChannelWebSerial.js +319 -0
  18. package/dist/RaftChannelWebSerial.js.map +1 -0
  19. package/dist/RaftChannelWebSocket.d.ts +28 -0
  20. package/dist/RaftChannelWebSocket.js +197 -0
  21. package/dist/RaftChannelWebSocket.js.map +1 -0
  22. package/dist/RaftCommsStats.d.ts +39 -0
  23. package/dist/RaftCommsStats.js +128 -0
  24. package/dist/RaftCommsStats.js.map +1 -0
  25. package/dist/RaftConnEvents.d.ts +31 -0
  26. package/dist/RaftConnEvents.js +44 -0
  27. package/dist/RaftConnEvents.js.map +1 -0
  28. package/dist/RaftConnector.d.ts +242 -0
  29. package/dist/RaftConnector.js +613 -0
  30. package/dist/RaftConnector.js.map +1 -0
  31. package/dist/RaftCustomAttrHandler.d.ts +4 -0
  32. package/dist/RaftCustomAttrHandler.js +50 -0
  33. package/dist/RaftCustomAttrHandler.js.map +1 -0
  34. package/dist/RaftDeviceInfo.d.ts +64 -0
  35. package/dist/RaftDeviceInfo.js +36 -0
  36. package/dist/RaftDeviceInfo.js.map +1 -0
  37. package/dist/RaftDeviceManager.d.ts +37 -0
  38. package/dist/RaftDeviceManager.js +450 -0
  39. package/dist/RaftDeviceManager.js.map +1 -0
  40. package/dist/RaftDeviceMsg.d.ts +9 -0
  41. package/dist/RaftDeviceMsg.js +11 -0
  42. package/dist/RaftDeviceMsg.js.map +1 -0
  43. package/dist/RaftDeviceStates.d.ts +33 -0
  44. package/dist/RaftDeviceStates.js +60 -0
  45. package/dist/RaftDeviceStates.js.map +1 -0
  46. package/dist/RaftFileHandler.d.ts +52 -0
  47. package/dist/RaftFileHandler.js +502 -0
  48. package/dist/RaftFileHandler.js.map +1 -0
  49. package/dist/RaftLog.d.ts +22 -0
  50. package/dist/RaftLog.js +63 -0
  51. package/dist/RaftLog.js.map +1 -0
  52. package/dist/RaftMiniHDLC.d.ts +18 -0
  53. package/dist/RaftMiniHDLC.js +383 -0
  54. package/dist/RaftMiniHDLC.js.map +1 -0
  55. package/dist/RaftMsgHandler.d.ts +57 -0
  56. package/dist/RaftMsgHandler.js +480 -0
  57. package/dist/RaftMsgHandler.js.map +1 -0
  58. package/dist/RaftMsgTrackInfo.d.ts +17 -0
  59. package/dist/RaftMsgTrackInfo.js +42 -0
  60. package/dist/RaftMsgTrackInfo.js.map +1 -0
  61. package/dist/RaftProtocolDefs.d.ts +30 -0
  62. package/dist/RaftProtocolDefs.js +48 -0
  63. package/dist/RaftProtocolDefs.js.map +1 -0
  64. package/dist/RaftStreamHandler.d.ts +38 -0
  65. package/dist/RaftStreamHandler.js +257 -0
  66. package/dist/RaftStreamHandler.js.map +1 -0
  67. package/dist/RaftSystemType.d.ts +21 -0
  68. package/dist/RaftSystemType.js +3 -0
  69. package/dist/RaftSystemType.js.map +1 -0
  70. package/dist/RaftSystemUtils.d.ts +136 -0
  71. package/dist/RaftSystemUtils.js +410 -0
  72. package/dist/RaftSystemUtils.js.map +1 -0
  73. package/dist/RaftTypes.d.ts +184 -0
  74. package/dist/RaftTypes.js +157 -0
  75. package/dist/RaftTypes.js.map +1 -0
  76. package/dist/RaftUpdateEvents.d.ts +33 -0
  77. package/dist/RaftUpdateEvents.js +46 -0
  78. package/dist/RaftUpdateEvents.js.map +1 -0
  79. package/dist/RaftUpdateManager.d.ts +61 -0
  80. package/dist/RaftUpdateManager.js +618 -0
  81. package/dist/RaftUpdateManager.js.map +1 -0
  82. package/dist/RaftUtils.d.ts +125 -0
  83. package/dist/RaftUtils.js +454 -0
  84. package/dist/RaftUtils.js.map +1 -0
  85. package/dist/RaftWifiTypes.d.ts +23 -0
  86. package/dist/RaftWifiTypes.js +43 -0
  87. package/dist/RaftWifiTypes.js.map +1 -0
  88. package/dist/TestDataGen.d.ts +7 -0
  89. package/dist/TestDataGen.js +133 -0
  90. package/dist/TestDataGen.js.map +1 -0
  91. package/dist/main.d.ts +18 -0
  92. package/dist/main.js +42 -0
  93. package/dist/main.js.map +1 -0
  94. package/eslint.config.mjs +33 -0
  95. package/examples/dashboard/package.json +39 -0
  96. package/examples/dashboard/src/ConnManager.ts +86 -0
  97. package/examples/dashboard/src/Main.tsx +100 -0
  98. package/examples/dashboard/src/StatusScreen.tsx +72 -0
  99. package/examples/dashboard/src/SystemTypeCog/CogStateInfo.ts +144 -0
  100. package/examples/dashboard/src/SystemTypeCog/SystemTypeCog.ts +77 -0
  101. package/examples/dashboard/src/SystemTypeMarty/RICAddOn.ts +70 -0
  102. package/examples/dashboard/src/SystemTypeMarty/RICAddOnBase.ts +33 -0
  103. package/examples/dashboard/src/SystemTypeMarty/RICAddOnManager.ts +342 -0
  104. package/examples/dashboard/src/SystemTypeMarty/RICCommsStats.ts +170 -0
  105. package/examples/dashboard/src/SystemTypeMarty/RICHWElem.ts +123 -0
  106. package/examples/dashboard/src/SystemTypeMarty/RICLEDPatternChecker.ts +207 -0
  107. package/examples/dashboard/src/SystemTypeMarty/RICROSSerial.ts +464 -0
  108. package/examples/dashboard/src/SystemTypeMarty/RICServoFaultDetector.ts +146 -0
  109. package/examples/dashboard/src/SystemTypeMarty/RICStateInfo.ts +32 -0
  110. package/examples/dashboard/src/SystemTypeMarty/RICSystemUtils.ts +371 -0
  111. package/examples/dashboard/src/SystemTypeMarty/RICTypes.ts +20 -0
  112. package/examples/dashboard/src/SystemTypeMarty/SystemTypeMarty.ts +113 -0
  113. package/examples/dashboard/src/index.html +15 -0
  114. package/examples/dashboard/src/index.tsx +15 -0
  115. package/examples/dashboard/src/styles.css +122 -0
  116. package/examples/dashboard/tsconfig.json +18 -0
  117. package/jest.config.js +11 -0
  118. package/package.json +50 -0
  119. package/src/RaftAttributeHandler.ts +289 -0
  120. package/src/RaftChannel.ts +30 -0
  121. package/src/RaftChannelWebBLE.ts +342 -0
  122. package/src/RaftChannelWebSerial.ts +408 -0
  123. package/src/RaftChannelWebSocket.ts +245 -0
  124. package/src/RaftCommsStats.ts +142 -0
  125. package/src/RaftConnEvents.ts +46 -0
  126. package/src/RaftConnector.ts +745 -0
  127. package/src/RaftCustomAttrHandler.ts +54 -0
  128. package/src/RaftDeviceInfo.ts +104 -0
  129. package/src/RaftDeviceManager.ts +542 -0
  130. package/src/RaftDeviceMsg.ts +20 -0
  131. package/src/RaftDeviceStates.ts +89 -0
  132. package/src/RaftFileHandler.ts +668 -0
  133. package/src/RaftLog.ts +70 -0
  134. package/src/RaftMiniHDLC.ts +396 -0
  135. package/src/RaftMsgHandler.ts +778 -0
  136. package/src/RaftMsgTrackInfo.ts +51 -0
  137. package/src/RaftProtocolDefs.ts +46 -0
  138. package/src/RaftStreamHandler.ts +328 -0
  139. package/src/RaftSystemType.ts +25 -0
  140. package/src/RaftSystemUtils.ts +487 -0
  141. package/src/RaftTypes.ts +250 -0
  142. package/src/RaftUpdateEvents.ts +48 -0
  143. package/src/RaftUpdateManager.ts +778 -0
  144. package/src/RaftUtils.ts +484 -0
  145. package/src/RaftWifiTypes.ts +36 -0
  146. package/src/TestDataGen.ts +157 -0
  147. package/src/main.ts +28 -0
  148. package/testdata/TestDeviceTypeRecs.json +492 -0
  149. package/tsconfig.json +27 -0
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3
+ //
4
+ // TestDataGen
5
+ // Test data generation for Raft device manager
6
+ //
7
+ // Rob Dobson (C) 2024
8
+ //
9
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ class TestDataGen {
12
+ // Start generating test data and use the callback provided to handle the data JSON string
13
+ start(handleDeviceMsgJson) {
14
+ // Start timer for testing which sends randomized data
15
+ let psVals = [50, 150];
16
+ let iterCount = 0;
17
+ let psValAltCount = 0;
18
+ let alsVal = 1000;
19
+ let alsValInc = 1;
20
+ let whiteVal = 1000;
21
+ let whiteValInc = 10;
22
+ let x = 0;
23
+ let y = 0;
24
+ let z = 0;
25
+ setInterval(() => {
26
+ // Performance testing
27
+ // const debugPerfTimerStart = performance.now();
28
+ // Vars for VSNL4040
29
+ const psVar = psVals[psValAltCount] + Math.floor(Math.random() * 10) - 5;
30
+ const alsVar = alsVal;
31
+ const whiteVar = whiteVal;
32
+ iterCount++;
33
+ if (iterCount % 10 === 0) {
34
+ psValAltCount = (psValAltCount + 1) % 2;
35
+ }
36
+ alsVal += alsValInc + Math.floor(Math.random() * 10) - 5;
37
+ if (iterCount % 1000 === 0) {
38
+ alsValInc = -alsValInc;
39
+ }
40
+ whiteVal += whiteValInc + Math.floor(Math.random() * 10) - 5;
41
+ if (iterCount % 100 === 0) {
42
+ whiteValInc = -whiteValInc;
43
+ }
44
+ const tsHexHighLow = ((Date.now()) & 0xffff).toString(16).padStart(4, '0');
45
+ const tsHexNextHighLow = ((Date.now() + 1) & 0xffff).toString(16).padStart(4, '0');
46
+ const psHexLowHigh = ((psVar & 0xff) << 8 | (psVar >> 8)).toString(16).padStart(4, '0');
47
+ const alsHexLowHigh = ((alsVar & 0xff) << 8 | (alsVar >> 8)).toString(16).padStart(4, '0');
48
+ const whiteHexLowHigh = ((whiteVar & 0xff) << 8 | (whiteVar >> 8)).toString(16).padStart(4, '0');
49
+ // Vars for ADXL313
50
+ x += Math.floor(Math.random() * 10) - 5;
51
+ y += Math.floor(Math.random() * 10) - 5;
52
+ z += Math.floor(Math.random() * 10) - 5;
53
+ // Ensure x,y,z in range -512 to 511
54
+ x = Math.floor(Math.min(511, Math.max(-512, x)));
55
+ y = Math.floor(Math.min(511, Math.max(-512, y)));
56
+ z = Math.floor(Math.min(511, Math.max(-512, z)));
57
+ // Convert x,y,z to 10-bit signed values
58
+ x = x & 0x3ff;
59
+ y = y & 0x3ff;
60
+ z = z & 0x3ff;
61
+ const xHexLowHigh = ((x & 0xff) << 8 | (x >> 8)).toString(16).padStart(4, '0');
62
+ const yHexLowHigh = ((y & 0xff) << 8 | (y >> 8)).toString(16).padStart(4, '0');
63
+ const zHexLowHigh = ((z & 0xff) << 8 | (z >> 8)).toString(16).padStart(4, '0');
64
+ // Dev messages
65
+ let devMsgs = {
66
+ "0x60@1": {
67
+ x: `${tsHexHighLow}${psHexLowHigh}${alsHexLowHigh}${whiteHexLowHigh}`,
68
+ _t: "VCNL4040",
69
+ _o: this.onlineFrom(iterCount, 0, 100)
70
+ },
71
+ "0x38@1": {
72
+ x: `${tsHexHighLow}${xHexLowHigh}${yHexLowHigh}${zHexLowHigh}`,
73
+ _t: "ADXL313",
74
+ _o: this.onlineFrom(iterCount, 0, 150)
75
+ },
76
+ "0x6f@41": {
77
+ x: `${tsHexHighLow}${this.toHex(this.randInt(0, 1) * 4, 1)}`,
78
+ _t: "QwiicButton",
79
+ _o: this.onlineFrom(iterCount, 0, 120)
80
+ },
81
+ "0x6f@42": {
82
+ x: `${tsHexHighLow}${this.toHex(this.randInt(0, 1) * 4, 1)}`,
83
+ _t: "QwiicButton",
84
+ _o: this.onlineFrom(iterCount, 0, 90)
85
+ },
86
+ "0x23@0": {
87
+ x: "",
88
+ _t: "QwiicLEDStick",
89
+ _o: this.onlineFrom(iterCount, 100, 180)
90
+ },
91
+ "0x28@0": {
92
+ x: `${tsHexHighLow}${this.toHex(this.randInt(0, 7), 2)}${tsHexNextHighLow}${this.toHex(this.randInt(0, 7), 2)}`,
93
+ _t: "CAP1203",
94
+ _o: true
95
+ },
96
+ "0x57@0": {
97
+ x: `${tsHexHighLow}${this.toHex(5, 1)}${this.toHex(0x00, 1)}${this.toHex(0x04, 1)}${this.toHex(Math.floor(10000 * Math.sin(iterCount / 10.0)) + 100000, 3)}${this.toHex(Math.floor(10000 * Math.cos(iterCount / 10.0)) + 100000, 3)}${this.toHex(0, 42)}`,
98
+ _t: "MAX30101",
99
+ _o: true
100
+ }
101
+ };
102
+ // const devMsgsEnabled:DevMsgsEnabled = { "0x6f@42":true };
103
+ const devMsgsEnabled = {};
104
+ const I2CA = Object.keys(devMsgsEnabled).length === 0 ? devMsgs : {};
105
+ for (const key in devMsgs) {
106
+ if (devMsgsEnabled[key]) {
107
+ I2CA[key] = devMsgs[key];
108
+ }
109
+ }
110
+ const msg = JSON.stringify({ I2CA: I2CA });
111
+ // Performance testing
112
+ // const debugPerfTimerEnd = performance.now();
113
+ // Call the callback to handle the data JSON string
114
+ // const debugHandleMsgStart = performance.now();
115
+ handleDeviceMsgJson(msg);
116
+ // const debugHandleMsgEnd = performance.now();
117
+ // console.log(`iterCount ${iterCount} genTestDataTime ${debugPerfTimerEnd - debugPerfTimerStart} handleTestDataTime ${debugHandleMsgEnd - debugHandleMsgStart}`);
118
+ // console.log(`iterCount ${iterCount} x ${x} Test message sent: ${JSON.stringify(JSON.parse(msg))}`);
119
+ }, 200);
120
+ }
121
+ toHex(val, numBytes) {
122
+ return val.toString(16).padStart(numBytes * 2, '0');
123
+ }
124
+ randInt(min, max) {
125
+ return Math.floor(Math.random() * (max - min + 1) + min);
126
+ }
127
+ onlineFrom(iterCount, start, end) {
128
+ const ic = iterCount % 200;
129
+ return ic >= start && ic <= end;
130
+ }
131
+ }
132
+ exports.default = TestDataGen;
133
+ //# sourceMappingURL=TestDataGen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestDataGen.js","sourceRoot":"","sources":["../src/TestDataGen.ts"],"names":[],"mappings":"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"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ export { default as RaftCommsStats } from './RaftCommsStats';
2
+ export { default as RaftConnector } from './RaftConnector';
3
+ export { default as RaftChannel } from './RaftChannel';
4
+ export { default as RaftChannelWebBLE } from './RaftChannelWebBLE';
5
+ export { default as RaftChannelWebSocket } from './RaftChannelWebSocket';
6
+ export { default as RaftFileHandler } from './RaftFileHandler';
7
+ export { default as RaftLog } from './RaftLog';
8
+ export { default as RaftMiniHDLC } from './RaftMiniHDLC';
9
+ export { default as RaftMsgHandler } from './RaftMsgHandler';
10
+ export { default as RaftStreamHandler } from './RaftStreamHandler';
11
+ export { default as RaftSystemUtils } from './RaftSystemUtils';
12
+ export { default as RaftUtils } from './RaftUtils';
13
+ export * from './RaftTypes';
14
+ export * from './RaftSystemType';
15
+ export * from './RaftWifiTypes';
16
+ export * from './RaftConnEvents';
17
+ export * from './RaftUpdateEvents';
18
+ export * from "./RaftProtocolDefs";
package/dist/main.js ADDED
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3
+ //
4
+ // RaftJS
5
+ // Commms library for the Raft ESP32 application framework supporting BLE, WebSockets and Serial
6
+ //
7
+ // Rob Dobson & Chris Greening 2020-2024
8
+ // (C) 2020-2024 All rights reserved
9
+ //
10
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RaftUtils = exports.RaftSystemUtils = exports.RaftStreamHandler = exports.RaftMsgHandler = exports.RaftMiniHDLC = exports.RaftLog = exports.RaftFileHandler = exports.RaftChannelWebSocket = exports.RaftChannelWebBLE = exports.RaftConnector = exports.RaftCommsStats = void 0;
13
+ const tslib_1 = require("tslib");
14
+ var RaftCommsStats_1 = require("./RaftCommsStats");
15
+ Object.defineProperty(exports, "RaftCommsStats", { enumerable: true, get: function () { return tslib_1.__importDefault(RaftCommsStats_1).default; } });
16
+ var RaftConnector_1 = require("./RaftConnector");
17
+ Object.defineProperty(exports, "RaftConnector", { enumerable: true, get: function () { return tslib_1.__importDefault(RaftConnector_1).default; } });
18
+ var RaftChannelWebBLE_1 = require("./RaftChannelWebBLE");
19
+ Object.defineProperty(exports, "RaftChannelWebBLE", { enumerable: true, get: function () { return tslib_1.__importDefault(RaftChannelWebBLE_1).default; } });
20
+ var RaftChannelWebSocket_1 = require("./RaftChannelWebSocket");
21
+ Object.defineProperty(exports, "RaftChannelWebSocket", { enumerable: true, get: function () { return tslib_1.__importDefault(RaftChannelWebSocket_1).default; } });
22
+ var RaftFileHandler_1 = require("./RaftFileHandler");
23
+ Object.defineProperty(exports, "RaftFileHandler", { enumerable: true, get: function () { return tslib_1.__importDefault(RaftFileHandler_1).default; } });
24
+ var RaftLog_1 = require("./RaftLog");
25
+ Object.defineProperty(exports, "RaftLog", { enumerable: true, get: function () { return tslib_1.__importDefault(RaftLog_1).default; } });
26
+ var RaftMiniHDLC_1 = require("./RaftMiniHDLC");
27
+ Object.defineProperty(exports, "RaftMiniHDLC", { enumerable: true, get: function () { return tslib_1.__importDefault(RaftMiniHDLC_1).default; } });
28
+ var RaftMsgHandler_1 = require("./RaftMsgHandler");
29
+ Object.defineProperty(exports, "RaftMsgHandler", { enumerable: true, get: function () { return tslib_1.__importDefault(RaftMsgHandler_1).default; } });
30
+ var RaftStreamHandler_1 = require("./RaftStreamHandler");
31
+ Object.defineProperty(exports, "RaftStreamHandler", { enumerable: true, get: function () { return tslib_1.__importDefault(RaftStreamHandler_1).default; } });
32
+ var RaftSystemUtils_1 = require("./RaftSystemUtils");
33
+ Object.defineProperty(exports, "RaftSystemUtils", { enumerable: true, get: function () { return tslib_1.__importDefault(RaftSystemUtils_1).default; } });
34
+ var RaftUtils_1 = require("./RaftUtils");
35
+ Object.defineProperty(exports, "RaftUtils", { enumerable: true, get: function () { return tslib_1.__importDefault(RaftUtils_1).default; } });
36
+ tslib_1.__exportStar(require("./RaftTypes"), exports);
37
+ tslib_1.__exportStar(require("./RaftSystemType"), exports);
38
+ tslib_1.__exportStar(require("./RaftWifiTypes"), exports);
39
+ tslib_1.__exportStar(require("./RaftConnEvents"), exports);
40
+ tslib_1.__exportStar(require("./RaftUpdateEvents"), exports);
41
+ tslib_1.__exportStar(require("./RaftProtocolDefs"), exports);
42
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAAA,iHAAiH;AACjH,EAAE;AACF,SAAS;AACT,gGAAgG;AAChG,EAAE;AACF,wCAAwC;AACxC,oCAAoC;AACpC,EAAE;AACF,iHAAiH;;;;AAEjH,mDAA6D;AAApD,yIAAA,OAAO,OAAkB;AAClC,iDAA2D;AAAlD,uIAAA,OAAO,OAAiB;AAEjC,yDAAmE;AAA1D,+IAAA,OAAO,OAAqB;AACrC,+DAAyE;AAAhE,qJAAA,OAAO,OAAwB;AACxC,qDAA+D;AAAtD,2IAAA,OAAO,OAAmB;AACnC,qCAA+C;AAAtC,2HAAA,OAAO,OAAW;AAC3B,+CAAyD;AAAhD,qIAAA,OAAO,OAAgB;AAChC,mDAA4D;AAAnD,yIAAA,OAAO,OAAkB;AAClC,yDAAmE;AAA1D,+IAAA,OAAO,OAAqB;AACrC,qDAA+D;AAAtD,2IAAA,OAAO,OAAmB;AACnC,yCAAmD;AAA1C,+HAAA,OAAO,OAAa;AAC7B,sDAA4B;AAC5B,2DAAiC;AACjC,0DAAgC;AAChC,2DAAiC;AACjC,6DAAmC;AACnC,6DAAmC"}
@@ -0,0 +1,33 @@
1
+ import typescriptEslint from "@typescript-eslint/eslint-plugin";
2
+ import tsParser from "@typescript-eslint/parser";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import js from "@eslint/js";
6
+ import { FlatCompat } from "@eslint/eslintrc";
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+ const compat = new FlatCompat({
11
+ baseDirectory: __dirname,
12
+ recommendedConfig: js.configs.recommended,
13
+ allConfig: js.configs.all
14
+ });
15
+
16
+ export default [
17
+ ...compat.extends("eslint:recommended", "plugin:@typescript-eslint/recommended"),
18
+ {
19
+ plugins: {
20
+ "@typescript-eslint": typescriptEslint,
21
+ },
22
+
23
+ languageOptions: {
24
+ parser: tsParser,
25
+ },
26
+
27
+ rules: {
28
+ "no-loss-of-precision": "off",
29
+ "@typescript-eslint/no-loss-of-precision": ["off"],
30
+ "@typescript-eslint/no-explicit-any": ["off"],
31
+ },
32
+ },
33
+ ];
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "raftjs-example-dashboard",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "scripts": {
6
+ "start": "parcel src/index.html",
7
+ "clean": "rm -rf dist",
8
+ "build": "npm run clean && parcel build src/index.html",
9
+ "test": "jest"
10
+ },
11
+ "keywords": [],
12
+ "author": "Rob Dobson",
13
+ "license": "ISC",
14
+ "devDependencies": {
15
+ "@types/jest": "^29.5.12",
16
+ "@types/node": "^20.12.7",
17
+ "@types/python-struct": "^1.0.4",
18
+ "@types/react": "^18.2.48",
19
+ "@types/react-dom": "^18.2.18",
20
+ "assert": "^2.1.0",
21
+ "buffer": "^6.0.3",
22
+ "console-browserify": "^1.2.0",
23
+ "jest": "^29.7.0",
24
+ "parcel": "^2.11.0",
25
+ "process": "^0.11.10",
26
+ "ts-jest": "^29.1.2",
27
+ "typescript": "^5.3.3",
28
+ "util": "^0.12.5"
29
+ },
30
+ "dependencies": {
31
+ "react": "^18.2.0",
32
+ "react-color": "^2.19.3",
33
+ "react-dom": "^18.2.0"
34
+ },
35
+ "jest": {
36
+ "preset": "ts-jest",
37
+ "testEnvironment": "node"
38
+ }
39
+ }
@@ -0,0 +1,86 @@
1
+ import { RaftChannelWebBLE, RaftConnector, RaftEventFn, RaftLog, RaftSystemUtils } from "../../../src/main";
2
+ import SystemTypeCog from "./SystemTypeCog/SystemTypeCog";
3
+ import SystemTypeMarty from "./SystemTypeMarty/SystemTypeMarty";
4
+
5
+ export default class ConnManager {
6
+
7
+ // Singleton
8
+ private static _instance: ConnManager;
9
+
10
+ // Connector
11
+ private _connector = new RaftConnector(async (systemUtils: RaftSystemUtils) => {
12
+ const systemInfo = await systemUtils.getSystemInfo();
13
+ if (systemInfo.SystemName === "RIC") {
14
+ RaftLog.info("ConnManager - Marty detected");
15
+ return new SystemTypeMarty();
16
+ } else if (systemInfo.SystemName === "Cog") {
17
+ RaftLog.info("ConnManager - Cog detected");
18
+ return new SystemTypeCog();
19
+ }
20
+ RaftLog.error(`ConnManager - unknown system ${systemInfo.SystemName} ${JSON.stringify(systemInfo)}`);
21
+ return null;
22
+ });
23
+
24
+ // Callback on connection event
25
+ private _onConnectionEvent: RaftEventFn | null = null;
26
+
27
+ // Get instance
28
+ public static getInstance(): ConnManager {
29
+ if (!ConnManager._instance) {
30
+ ConnManager._instance = new ConnManager();
31
+ }
32
+ return ConnManager._instance;
33
+ }
34
+
35
+ // Set connection event listener
36
+ public setConnectionEventListener(listener: RaftEventFn) {
37
+ this._onConnectionEvent = listener;
38
+ }
39
+
40
+ // Check if connected
41
+ public isConnected(): boolean {
42
+ return this._connector.isConnected();
43
+ }
44
+
45
+ public getConnector(): RaftConnector {
46
+ return this._connector;
47
+ }
48
+
49
+ private async getBleDevice(): Promise<BluetoothDevice | null> {
50
+ try {
51
+ const dev = await navigator.bluetooth.requestDevice({
52
+ filters: [
53
+ { services: [RaftChannelWebBLE.ServiceUUID] }
54
+ ],
55
+ optionalServices: []
56
+ });
57
+ return dev;
58
+ } catch (e) {
59
+ RaftLog.error(`getBleDevice - failed to get device ${e}`);
60
+ return null;
61
+ }
62
+ }
63
+
64
+ // Connect
65
+ public async connect(method: string, locator: string | object): Promise<boolean> {
66
+
67
+ // Hook up the connector
68
+ this._connector.setEventListener((evtType, eventEnum, eventName, eventData) => {
69
+ RaftLog.info(`ConnManager - event ${eventName}`);
70
+ if (this._onConnectionEvent) {
71
+ this._onConnectionEvent(evtType, eventEnum, eventName, eventData);
72
+ }
73
+ });
74
+ // Set the connector websocket suffix
75
+ if (method === "WebBLE") {
76
+ const dev = await this.getBleDevice();
77
+ return this._connector.connect(method, dev as object);
78
+ }
79
+ return this._connector.connect(method, locator);
80
+ }
81
+
82
+ // Disconnect
83
+ public disconnect(): Promise<void> {
84
+ return this._connector.disconnect();
85
+ }
86
+ }
@@ -0,0 +1,100 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import './styles.css';
3
+ import ConnManager from './ConnManager';
4
+ import { RaftConnEvent, RaftUpdateEvent, RaftPublishEvent } from "../../../src/main";
5
+ import StatusScreen from './StatusScreen';
6
+
7
+ const connManager = ConnManager.getInstance();
8
+
9
+ export default function Main() {
10
+ const [connectionStatus, setConnectionStatus] = useState<RaftConnEvent>(RaftConnEvent.CONN_DISCONNECTED);
11
+
12
+ useEffect(() => {
13
+ // Define the listener for raft events
14
+ const listener = (eventType: string,
15
+ eventEnum: RaftConnEvent | RaftUpdateEvent | RaftPublishEvent,
16
+ eventName: string,
17
+ data?: object | string | null) => {
18
+ console.log(`Connection event: ${eventName}`);
19
+ if (eventType === "conn") {
20
+ if ((eventEnum === RaftConnEvent.CONN_CONNECTED) || (eventEnum === RaftConnEvent.CONN_DISCONNECTED)) {
21
+ setConnectionStatus(eventEnum);
22
+ }
23
+ }
24
+ };
25
+
26
+ // Set the listener function
27
+ connManager.setConnectionEventListener(listener);
28
+
29
+ // Clean up the listener when the component unmounts
30
+ return () => {
31
+ connManager.setConnectionEventListener(() => {});
32
+ };
33
+ }, []);
34
+
35
+ return (
36
+ <div className="content-outer">
37
+ <div className="header">
38
+ <h1>RaftJS Dashboard</h1>
39
+ </div>
40
+ <div className="content-body">
41
+ {/* Div optionally shown if connected */}
42
+ {connectionStatus === RaftConnEvent.CONN_CONNECTED ?
43
+ <>
44
+ <div className="info-boxes">
45
+ <div className="info-box">
46
+ <div className="conn-indication">
47
+ Connected
48
+ </div>
49
+ <div className="action-button">
50
+ <button onClick={() => connManager.disconnect()}>Disconnect</button>
51
+ </div>
52
+ </div>
53
+ </div>
54
+ <StatusScreen />
55
+ </>
56
+ :
57
+ <>
58
+ <div className="info-boxes">
59
+ <div className="info-box">
60
+ <h3>WebSocket</h3>
61
+ <input className="ip-addr-input" id="ip-addr" type="text" placeholder="IP Address" />
62
+ <button className="action-button" onClick={() => {
63
+ // Get IP address
64
+ const ipAddrElem = document.getElementById("ip-addr") as HTMLInputElement;
65
+ if (ipAddrElem) {
66
+ const ipAddr = ipAddrElem.value;
67
+ connManager.connect("WebSocket", ipAddr);
68
+ } else {
69
+ console.error("No IP address entered");
70
+ }
71
+ }
72
+ }>
73
+ Connect
74
+ </button>
75
+ </div>
76
+ <div className="info-box">
77
+ <h3>WebBLE</h3>
78
+ <button className="action-button" onClick={() => {
79
+ connManager.connect("WebBLE", "");
80
+ }
81
+ }>
82
+ Connect
83
+ </button>
84
+ </div>
85
+ <div className="info-box">
86
+ <h3>WebSerial</h3>
87
+ <button className="action-button" onClick={() => {
88
+ connManager.connect("WebSerial", "");
89
+ }
90
+ }>
91
+ Connect
92
+ </button>
93
+ </div>
94
+ </div>
95
+ </>
96
+ }
97
+ </div>
98
+ </div>
99
+ );
100
+ }
@@ -0,0 +1,72 @@
1
+ import ConnManager from "./ConnManager";
2
+ import React, { useState } from 'react';
3
+ import './styles.css';
4
+ import { RaftSystemInfo } from "../../../src/main";
5
+
6
+ const connManager = ConnManager.getInstance();
7
+
8
+ export default function StatusScreen() {
9
+ const [systemInfo, setSystemInfo] = useState<RaftSystemInfo>(new RaftSystemInfo());
10
+
11
+ return (
12
+ <div className="info-boxes">
13
+
14
+ <div className="info-box">
15
+ <h3>SysInfo</h3>
16
+ <button className="action-button" onClick={() => {
17
+ if (connManager.isConnected()) {
18
+ connManager.getConnector().getRaftSystemUtils().getSystemInfo().then((sysInfo:RaftSystemInfo) => {
19
+ console.log(`System Info: ${JSON.stringify(sysInfo)}`);
20
+ setSystemInfo(sysInfo);
21
+ });
22
+ }
23
+ }
24
+ }>
25
+ Get
26
+ </button>
27
+ {
28
+ (systemInfo !== undefined) && (systemInfo.validMs) && (systemInfo.validMs > 0) ?
29
+ <div className="info">
30
+ <div className="info-line">
31
+ <div className="info-label">System Name:</div>
32
+ <div className="info-value">{systemInfo.SystemName}</div>
33
+ </div>
34
+
35
+ <div className="info-line">
36
+ <div className="info-label">System Version:</div>
37
+ <div className="info-value">{systemInfo.SystemVersion}</div>
38
+ </div>
39
+
40
+ <div className="info-line">
41
+ <div className="info-label">HwRev:</div>
42
+ <div className="info-value">{systemInfo.HwRev}</div>
43
+ </div>
44
+
45
+ <div className="info-line">
46
+ <div className="info-label">MAC:</div>
47
+ <div className="info-value">{systemInfo.MAC}</div>
48
+ </div>
49
+
50
+ <div className="info-line">
51
+ <div className="info-label">SerialNo:</div>
52
+ <div className="info-value">{systemInfo.SerialNo}</div>
53
+ </div>
54
+
55
+ <div className="info-line">
56
+ <div className="info-label">Friendly:</div>
57
+ <div className="info-value">{systemInfo.Friendly}</div>
58
+ </div>
59
+ </div>
60
+ :
61
+ <div className="info">
62
+ <div className="info-line">
63
+ <div className="info-label">System Info:</div>
64
+ <div className="info-value">Not available</div>
65
+ </div>
66
+ </div>
67
+ }
68
+ </div>
69
+ </div>
70
+ );
71
+
72
+ }