@robotical/raftjs 1.3.3 → 1.4.0

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 (128) hide show
  1. package/dist/react-native/RaftAttributeHandler.d.ts +1 -1
  2. package/dist/react-native/RaftAttributeHandler.js +18 -10
  3. package/dist/react-native/RaftAttributeHandler.js.map +1 -1
  4. package/dist/react-native/RaftChannelBLE.native.d.ts +11 -11
  5. package/dist/react-native/RaftChannelBLE.native.js +61 -41
  6. package/dist/react-native/RaftChannelBLE.native.js.map +1 -1
  7. package/dist/react-native/RaftChannelBLE.web.d.ts +3 -4
  8. package/dist/react-native/RaftChannelBLE.web.js +7 -8
  9. package/dist/react-native/RaftChannelBLE.web.js.map +1 -1
  10. package/dist/react-native/RaftChannelBLEScanner.native.d.ts +6 -6
  11. package/dist/react-native/RaftChannelBLEScanner.native.js +38 -46
  12. package/dist/react-native/RaftChannelBLEScanner.native.js.map +1 -1
  13. package/dist/react-native/RaftConnector.d.ts +3 -3
  14. package/dist/react-native/RaftConnector.js +4 -4
  15. package/dist/react-native/RaftConnector.js.map +1 -1
  16. package/dist/react-native/RaftCustomAttrHandler.d.ts +1 -1
  17. package/dist/react-native/RaftCustomAttrHandler.js +4 -4
  18. package/dist/react-native/RaftCustomAttrHandler.js.map +1 -1
  19. package/dist/react-native/RaftDeviceInfo.d.ts +3 -0
  20. package/dist/react-native/RaftDeviceManager.d.ts +16 -11
  21. package/dist/react-native/RaftDeviceManager.js +196 -50
  22. package/dist/react-native/RaftDeviceManager.js.map +1 -1
  23. package/dist/react-native/RaftDeviceMgrIF.d.ts +9 -6
  24. package/dist/react-native/RaftDeviceStates.d.ts +5 -1
  25. package/dist/react-native/RaftDeviceStates.js +3 -3
  26. package/dist/react-native/RaftDeviceStates.js.map +1 -1
  27. package/dist/react-native/RaftMsgHandler.d.ts +1 -1
  28. package/dist/react-native/RaftMsgHandler.js +1 -2
  29. package/dist/react-native/RaftMsgHandler.js.map +1 -1
  30. package/dist/react-native/RaftStruct.d.ts +3 -0
  31. package/dist/react-native/RaftStruct.js +208 -0
  32. package/dist/react-native/RaftStruct.js.map +1 -0
  33. package/dist/react-native/RaftSysTypeManager.d.ts +14 -0
  34. package/dist/react-native/RaftSysTypeManager.js +53 -0
  35. package/dist/react-native/RaftSysTypeManager.js.map +1 -0
  36. package/dist/react-native/RaftSystemType.d.ts +3 -0
  37. package/dist/react-native/RaftTypes.d.ts +14 -15
  38. package/dist/react-native/RaftTypes.js +13 -50
  39. package/dist/react-native/RaftTypes.js.map +1 -1
  40. package/dist/react-native/RaftUpdateManager.js +6 -3
  41. package/dist/react-native/RaftUpdateManager.js.map +1 -1
  42. package/dist/react-native/RaftUtils.d.ts +1 -0
  43. package/dist/react-native/RaftUtils.js +17 -4
  44. package/dist/react-native/RaftUtils.js.map +1 -1
  45. package/dist/react-native/main.d.ts +2 -1
  46. package/dist/react-native/main.js +4 -4
  47. package/dist/react-native/main.js.map +1 -1
  48. package/dist/web/RaftAttributeHandler.d.ts +1 -1
  49. package/dist/web/RaftAttributeHandler.js +18 -10
  50. package/dist/web/RaftAttributeHandler.js.map +1 -1
  51. package/dist/web/RaftChannelBLE.web.d.ts +3 -4
  52. package/dist/web/RaftChannelBLE.web.js +7 -8
  53. package/dist/web/RaftChannelBLE.web.js.map +1 -1
  54. package/dist/web/RaftConnector.d.ts +3 -3
  55. package/dist/web/RaftConnector.js +4 -4
  56. package/dist/web/RaftConnector.js.map +1 -1
  57. package/dist/web/RaftCustomAttrHandler.d.ts +1 -1
  58. package/dist/web/RaftCustomAttrHandler.js +4 -4
  59. package/dist/web/RaftCustomAttrHandler.js.map +1 -1
  60. package/dist/web/RaftDeviceInfo.d.ts +3 -0
  61. package/dist/web/RaftDeviceManager.d.ts +16 -11
  62. package/dist/web/RaftDeviceManager.js +196 -50
  63. package/dist/web/RaftDeviceManager.js.map +1 -1
  64. package/dist/web/RaftDeviceMgrIF.d.ts +9 -6
  65. package/dist/web/RaftDeviceStates.d.ts +5 -1
  66. package/dist/web/RaftDeviceStates.js +3 -3
  67. package/dist/web/RaftDeviceStates.js.map +1 -1
  68. package/dist/web/RaftMsgHandler.d.ts +1 -1
  69. package/dist/web/RaftMsgHandler.js +1 -2
  70. package/dist/web/RaftMsgHandler.js.map +1 -1
  71. package/dist/web/RaftStruct.d.ts +3 -0
  72. package/dist/web/RaftStruct.js +208 -0
  73. package/dist/web/RaftStruct.js.map +1 -0
  74. package/dist/web/RaftSysTypeManager.d.ts +14 -0
  75. package/dist/web/RaftSysTypeManager.js +53 -0
  76. package/dist/web/RaftSysTypeManager.js.map +1 -0
  77. package/dist/web/RaftSystemType.d.ts +3 -0
  78. package/dist/web/RaftTypes.d.ts +14 -15
  79. package/dist/web/RaftTypes.js +13 -50
  80. package/dist/web/RaftTypes.js.map +1 -1
  81. package/dist/web/RaftUpdateManager.js +6 -3
  82. package/dist/web/RaftUpdateManager.js.map +1 -1
  83. package/dist/web/RaftUtils.d.ts +1 -0
  84. package/dist/web/RaftUtils.js +17 -4
  85. package/dist/web/RaftUtils.js.map +1 -1
  86. package/dist/web/main.d.ts +2 -1
  87. package/dist/web/main.js +4 -4
  88. package/dist/web/main.js.map +1 -1
  89. package/examples/dashboard/package.json +8 -15
  90. package/examples/dashboard/src/ConnManager.ts +18 -14
  91. package/examples/dashboard/src/DeviceActionsForm.tsx +49 -49
  92. package/examples/dashboard/src/DeviceLineChart.tsx +44 -20
  93. package/examples/dashboard/src/DevicePanel.tsx +33 -2
  94. package/examples/dashboard/src/DevicesPanel.tsx +5 -4
  95. package/examples/dashboard/src/LatencyTest.ts +130 -0
  96. package/examples/dashboard/src/LatencyTestPanel.tsx +92 -0
  97. package/examples/dashboard/src/Main.tsx +191 -73
  98. package/examples/dashboard/src/SettingsManager.ts +67 -0
  99. package/examples/dashboard/src/SettingsScreen.tsx +174 -0
  100. package/examples/dashboard/src/SystemTypeCog/CogStateInfo.ts +14 -8
  101. package/examples/dashboard/src/SystemTypeCog/SystemTypeCog.ts +12 -5
  102. package/examples/dashboard/src/SystemTypeGeneric/StateInfoGeneric.ts +30 -0
  103. package/examples/dashboard/src/SystemTypeGeneric/SystemTypeGeneric.ts +91 -0
  104. package/examples/dashboard/src/SystemTypeMarty/RICStateInfo.ts +23 -4
  105. package/examples/dashboard/src/SystemTypeMarty/RICSystemUtils.ts +1 -1
  106. package/examples/dashboard/src/SystemTypeMarty/SystemTypeMarty.ts +5 -2
  107. package/examples/dashboard/src/index.html +2 -2
  108. package/examples/dashboard/src/index.tsx +0 -2
  109. package/examples/dashboard/src/styles.css +14 -0
  110. package/package.json +6 -14
  111. package/src/RaftAttributeHandler.ts +23 -14
  112. package/src/RaftChannelBLE.native.ts +77 -53
  113. package/src/RaftChannelBLE.web.ts +8 -8
  114. package/src/RaftChannelBLEScanner.native.ts +38 -44
  115. package/src/RaftConnector.ts +5 -5
  116. package/src/RaftCustomAttrHandler.ts +5 -5
  117. package/src/RaftDeviceInfo.ts +3 -0
  118. package/src/RaftDeviceManager.ts +236 -65
  119. package/src/RaftDeviceMgrIF.ts +11 -6
  120. package/src/RaftDeviceStates.ts +7 -3
  121. package/src/RaftMsgHandler.ts +1 -2
  122. package/src/RaftStruct.ts +209 -0
  123. package/src/RaftSysTypeManager.ts +60 -0
  124. package/src/RaftSystemType.ts +3 -0
  125. package/src/RaftTypes.ts +30 -33
  126. package/src/RaftUpdateManager.ts +6 -3
  127. package/src/RaftUtils.ts +14 -4
  128. package/src/main.ts +2 -2
@@ -0,0 +1,174 @@
1
+ // src/SettingsScreen.tsx
2
+ import React, { useState, useEffect } from 'react';
3
+ import SettingsManager from './SettingsManager';
4
+ import ConnManager from './ConnManager';
5
+
6
+ const connManager = ConnManager.getInstance();
7
+
8
+ const SettingsScreen = ({ onBack }: { onBack: () => void }) => {
9
+ const settingsManager = SettingsManager.getInstance();
10
+
11
+ const [latencyTest, setLatencyTest] = useState<boolean>(
12
+ settingsManager.getSetting('latencyTest')
13
+ );
14
+ const [showCharts, setShowCharts] = useState<boolean>(
15
+ settingsManager.getSetting('showCharts')
16
+ );
17
+ const [maxChartDataPoints, setMaxChartDataPoints] = useState<number>(
18
+ settingsManager.getSetting('maxChartDataPoints')
19
+ );
20
+ const [maxDatapointsToStore, setMaxDatapointsToStore] = useState<number>(
21
+ settingsManager.getSetting('maxDatapointsToStore')
22
+ );
23
+ const [latencyAttributeName, setLatencyAttributeName] = useState<string>(
24
+ settingsManager.getSetting('latencyAttributeName') || 'amb0'
25
+ );
26
+ const [latencyChangeThreshold, setLatencyChangeThreshold] = useState<number>(
27
+ settingsManager.getSetting('latencyChangeThreshold') || 100
28
+ );
29
+
30
+ const handleSaveAndReturn = () => {
31
+ // Save settings to SettingsManager
32
+ settingsManager.setSetting('latencyTest', latencyTest);
33
+ settingsManager.setSetting('showCharts', showCharts);
34
+ settingsManager.setSetting('maxChartDataPoints', maxChartDataPoints);
35
+ settingsManager.setSetting('maxDatapointsToStore', maxDatapointsToStore);
36
+
37
+ // Log and update maxDatapointsToStore in DeviceManager
38
+ console.log(
39
+ `Set maxDatapointsToStore to ${maxDatapointsToStore} ` +
40
+ `${connManager.getConnector().getSystemType()} ` +
41
+ `${connManager.getConnector().getSystemType()?.deviceMgrIF}` +
42
+ `${connManager.getConnector().getSystemType()?.deviceMgrIF?.setMaxDataPointsToStore}`
43
+ );
44
+
45
+ connManager.getConnector().getSystemType()?.deviceMgrIF?.setMaxDataPointsToStore(maxDatapointsToStore);
46
+
47
+
48
+ if (latencyTest) {
49
+ settingsManager.setSetting('latencyAttributeName', latencyAttributeName);
50
+ settingsManager.setSetting('latencyChangeThreshold', latencyChangeThreshold);
51
+ }
52
+
53
+ onBack();
54
+ };
55
+
56
+ return (
57
+ <div className="content-outer">
58
+ <div className="header">
59
+ <h1>RaftJS Dashboard Settings</h1>
60
+ </div>
61
+ <div className="content-body">
62
+ <div className="info-boxes">
63
+ <div className="info-box">
64
+
65
+ <div className="settings-item">
66
+ <label>
67
+ <input
68
+ type="checkbox"
69
+ checked={showCharts}
70
+ onChange={(e) => setShowCharts(e.target.checked)}
71
+ />
72
+ Show Charts
73
+ </label>
74
+ </div>
75
+
76
+ <div className="settings-item">
77
+ <label>
78
+ Max Chart Points
79
+ <input
80
+ type="number"
81
+ min="1"
82
+ max="500"
83
+ value={maxChartDataPoints}
84
+ onChange={(e) =>
85
+ setMaxChartDataPoints(
86
+ Math.min(parseInt(e.target.value, 10) || 1, 500)
87
+ )
88
+ }
89
+ style={{ width: '50px', marginLeft: '10px' }}
90
+ />
91
+ </label>
92
+ </div>
93
+
94
+ <div className="settings-item">
95
+ <label>
96
+ Max Stored Points
97
+ <input
98
+ type="number"
99
+ min="1"
100
+ max="100000"
101
+ value={maxDatapointsToStore}
102
+ onChange={(e) =>
103
+ setMaxDatapointsToStore(
104
+ Math.min(parseInt(e.target.value, 10) || 1, 100000)
105
+ )
106
+ }
107
+ style={{ width: '50px', marginLeft: '10px' }}
108
+ />
109
+ </label>
110
+ </div>
111
+
112
+ <div className="settings-item">
113
+ <label>
114
+ <input
115
+ type="checkbox"
116
+ checked={latencyTest}
117
+ onChange={(e) => setLatencyTest(e.target.checked)}
118
+ />
119
+ Latency Test
120
+ </label>
121
+ </div>
122
+
123
+ {latencyTest && (
124
+ <>
125
+ <div className="settings-item">
126
+ <label>
127
+ Attribute Name
128
+ <input
129
+ type="text"
130
+ value={latencyAttributeName}
131
+ onChange={(e) => setLatencyAttributeName(e.target.value)}
132
+ style={{ marginLeft: '10px' }}
133
+ />
134
+ </label>
135
+ </div>
136
+ <div className="settings-item">
137
+ <label>
138
+ Change Threshold
139
+ <input
140
+ type="number"
141
+ min="1"
142
+ value={latencyChangeThreshold}
143
+ onChange={(e) =>
144
+ setLatencyChangeThreshold(parseInt(e.target.value, 10) || 1)
145
+ }
146
+ style={{ width: '60px', marginLeft: '10px' }}
147
+ />
148
+ </label>
149
+ </div>
150
+ </>
151
+ )}
152
+
153
+ <button className="action-button" onClick={handleSaveAndReturn}>
154
+ Save and Return
155
+ </button>
156
+
157
+ <button
158
+ className="action-button"
159
+ style={{ marginTop: '10px' }}
160
+ onClick={() => {
161
+ settingsManager.resetSettings();
162
+ window.location.reload();
163
+ }}
164
+ >
165
+ Reset to Defaults
166
+ </button>
167
+ </div>
168
+ </div>
169
+ </div>
170
+ </div>
171
+ );
172
+ };
173
+
174
+ export default SettingsScreen;
@@ -1,6 +1,8 @@
1
1
  import { time } from "console";
2
2
  import RaftLog from "../../../../src/RaftLog";
3
3
  import { DeviceManager } from "../../../../src/RaftDeviceManager";
4
+ import RaftUtils from "../../../../src/RaftUtils";
5
+ import { TextDecoder } from 'text-encoding';
4
6
 
5
7
  // export interface IMUStateInfo {
6
8
  // gx: number;
@@ -45,18 +47,22 @@ export class CogStateInfo {
45
47
  return this._deviceManager;
46
48
  }
47
49
 
48
- updateFromMsg(rxMsg: Uint8Array, frameTimeMs: number): Array<string> {
50
+ updateFromMsg(rxMsg: Uint8Array, frameTimeMs: number, isBinary: boolean): Array<string> {
49
51
 
50
52
  // Debug
51
53
  // RaftLog.info(`CogStateInfo: updateFromMsg: rxMsg: ${rxMsg} frameTimeMs: ${frameTimeMs}`);
52
54
 
53
- // Convert Uint8Array to string
54
- const decoder = new TextDecoder('utf-8');
55
- const jsonString = decoder.decode(rxMsg.slice(2));
56
-
57
- // Handle using device manager
58
- this._deviceManager.handleClientMsgJson(jsonString);
59
-
55
+ if (isBinary) {
56
+ // console.log(`CogStateInfo: updateFromMsg: ${RaftUtils.bufferToHex(rxMsg)}`);
57
+ this._deviceManager.handleClientMsgBinary(rxMsg);
58
+ } else {
59
+ // Convert Uint8Array to string
60
+ const decoder = new TextDecoder('utf-8');
61
+ const jsonString = decoder.decode(rxMsg.slice(2));
62
+
63
+ // Handle using device manager
64
+ this._deviceManager.handleClientMsgJson(jsonString);
65
+ }
60
66
 
61
67
  // // Debug
62
68
  // // RaftLog.info(`CogStateInfo: updateFromMsg: jsonString: ${jsonString}`);
@@ -3,12 +3,17 @@ import { RaftEventFn, RaftLog, RaftOKFail, RaftPublishEvent, RaftPublishEventNam
3
3
  import { CogStateInfo } from "./CogStateInfo";
4
4
  import { DeviceManager } from "../../../../src/RaftDeviceManager";
5
5
 
6
+ const SUBSCRIBE_BINARY_MSGS = true;
7
+
6
8
  export default class SystemTypeCog implements RaftSystemType {
7
9
  nameForDialogs = "Robotical Cog";
8
10
  defaultWiFiHostname = "Cog";
9
11
  firmwareDestName = "ricfw";
10
12
  normalFileDestName = "fs";
11
13
  connectorOptions = {wsSuffix: "wsjson", bleConnItvlMs: 50};
14
+ BLEServiceUUIDs = ["da903f65-d5c2-4f4d-a065-d1aade7af874"];
15
+ BLECmdUUID = "aa76677e-9cfd-4626-a510-0d305be57c8e";
16
+ BLERespUUID = "aa76677e-9cfd-4626-a510-0d305be57c8f";
12
17
 
13
18
  // Event handler
14
19
  private _onEvent: RaftEventFn | null = null;
@@ -35,15 +40,16 @@ export default class SystemTypeCog implements RaftSystemType {
35
40
  // Subscribe for updates
36
41
  subscribeForUpdates: RaftSubscribeForUpdatesCBType | null = async (systemUtils: RaftSystemUtils, enable: boolean) => {
37
42
  // Subscription rate
43
+ const topic = SUBSCRIBE_BINARY_MSGS ? "devbin" : "devjson";
38
44
  const subscribeRateHz = 0.1;
39
45
  try {
40
46
  const subscribeDisable = '{"cmdName":"subscription","action":"update",' +
41
47
  '"pubRecs":[' +
42
- `{"name":"devjson","rateHz":0,}` +
48
+ `{"name":"${topic}","rateHz":0,}` +
43
49
  ']}';
44
50
  const subscribeEnable = '{"cmdName":"subscription","action":"update",' +
45
51
  '"pubRecs":[' +
46
- `{"name":"devjson","trigger":"timeorchange","rateHz":${subscribeRateHz.toString()}}` +
52
+ `{"name":"${topic}","trigger":"timeorchange","rateHz":${subscribeRateHz.toString()}}` +
47
53
  ']}';
48
54
 
49
55
  const msgHandler = systemUtils.getMsgHandler();
@@ -64,9 +70,9 @@ export default class SystemTypeCog implements RaftSystemType {
64
70
  // Other message type
65
71
  rxOtherMsgType(payload: Uint8Array, frameTimeMs: number) {
66
72
 
67
- // RICLog.debug(`rxOtherMsgType payload ${RICUtils.bufferToHex(payload)}`);
73
+ // RICLog.debug(`rxOtherMsgType payload ${RaftUtils.bufferToHex(payload)}`);
68
74
  RaftLog.verbose(`rxOtherMsgType payloadLen ${payload.length}`);
69
- const topicIDs = this._stateInfo.updateFromMsg(payload, frameTimeMs);
75
+ const topicIDs = this._stateInfo.updateFromMsg(payload, frameTimeMs, SUBSCRIBE_BINARY_MSGS);
70
76
 
71
77
  // Call event handler if registered
72
78
  if (this._onEvent) {
@@ -74,7 +80,8 @@ export default class SystemTypeCog implements RaftSystemType {
74
80
  {
75
81
  topicIDs: topicIDs,
76
82
  payload: payload,
77
- frameTimeMs: frameTimeMs
83
+ frameTimeMs: frameTimeMs,
84
+ isBinary: SUBSCRIBE_BINARY_MSGS
78
85
  });
79
86
  }
80
87
  };
@@ -0,0 +1,30 @@
1
+ import { time } from "console";
2
+ import RaftLog from "../../../../src/RaftLog";
3
+ import { DeviceManager } from "../../../../src/RaftDeviceManager";
4
+
5
+ export class StateInfoGeneric {
6
+
7
+ public constructor(private _deviceManager: DeviceManager) {
8
+ }
9
+
10
+ updateFromMsg(rxMsg: Uint8Array, frameTimeMs: number, isBinary: boolean): Array<string> {
11
+
12
+ // Debug
13
+ // RaftLog.info(`StateInfoGeneric: updateFromMsg: rxMsg: ${rxMsg} frameTimeMs: ${frameTimeMs}`);
14
+
15
+ // Handle binary or JSON
16
+ if (isBinary) {
17
+ // Handle using device manager
18
+ this._deviceManager.handleClientMsgBinary(rxMsg);
19
+ } else {
20
+ // Convert Uint8Array to string
21
+ const decoder = new TextDecoder('utf-8');
22
+ const jsonString = decoder.decode(rxMsg.slice(2));
23
+
24
+ // Handle using device manager
25
+ this._deviceManager.handleClientMsgJson(jsonString);
26
+ }
27
+ return [];
28
+
29
+ }
30
+ }
@@ -0,0 +1,91 @@
1
+ import { RaftSubscribeForUpdatesCBType, RaftSystemType } from "../../../../src/RaftSystemType";
2
+ import { RaftEventFn, RaftLog, RaftOKFail, RaftPublishEvent, RaftPublishEventNames, RaftSystemUtils } from "../../../../src/main";
3
+ import { StateInfoGeneric } from "./StateInfoGeneric";
4
+ import { DeviceManager } from "../../../../src/RaftDeviceManager";
5
+
6
+ const SUBSCRIBE_BINARY_MSGS = false;
7
+
8
+ export default class SystemTypeGeneric implements RaftSystemType {
9
+ nameForDialogs = "Generic System";
10
+ defaultWiFiHostname = "Generic";
11
+ firmwareDestName = "ricfw";
12
+ normalFileDestName = "fs";
13
+ connectorOptions = {wsSuffix: "wsjson", bleConnItvlMs: 50};
14
+ BLEServiceUUIDs = ["aa76677e-9cfd-4626-a510-0d305be57c8d", "da903f65-d5c2-4f4d-a065-d1aade7af874"];
15
+ BLECmdUUID = "aa76677e-9cfd-4626-a510-0d305be57c8e";
16
+ BLERespUUID = "aa76677e-9cfd-4626-a510-0d305be57c8f";
17
+
18
+ // Event handler
19
+ private _onEvent: RaftEventFn | null = null;
20
+
21
+ // Raft system utils
22
+ private _systemUtils: RaftSystemUtils | null = null;
23
+
24
+ // Device manager
25
+ private _deviceManager: DeviceManager = new DeviceManager();
26
+
27
+ // Setup
28
+ setup(systemUtils: RaftSystemUtils, onEvent: RaftEventFn | null): void {
29
+ this._systemUtils = systemUtils;
30
+ this._onEvent = onEvent;
31
+ this._deviceManager.setup(systemUtils);
32
+ }
33
+
34
+ // Latest data from servos, IMU, etc
35
+ private _stateInfo: StateInfoGeneric = new StateInfoGeneric(this._deviceManager);
36
+ getStateInfo(): StateInfoGeneric {
37
+ return this._stateInfo;
38
+ }
39
+
40
+ // Subscribe for updates
41
+ subscribeForUpdates: RaftSubscribeForUpdatesCBType | null = async (systemUtils: RaftSystemUtils, enable: boolean) => {
42
+ // Subscription rate
43
+ const subscribeRateHz = 0.1;
44
+ try {
45
+ const topic = SUBSCRIBE_BINARY_MSGS ? "devbin" : "devjson";
46
+ const subscribeDisable = '{"cmdName":"subscription","action":"update",' +
47
+ '"pubRecs":[' +
48
+ `{"name":"${topic}","rateHz":0,}` +
49
+ ']}';
50
+ const subscribeEnable = '{"cmdName":"subscription","action":"update",' +
51
+ '"pubRecs":[' +
52
+ `{"name":"${topic}","trigger":"timeorchange","rateHz":${subscribeRateHz.toString()}}` +
53
+ ']}';
54
+
55
+ const msgHandler = systemUtils.getMsgHandler();
56
+ const ricResp = await msgHandler.sendRICRESTCmdFrame<RaftOKFail>(
57
+ enable ? subscribeEnable : subscribeDisable
58
+ );
59
+
60
+ // Debug
61
+ RaftLog.debug(`subscribe enable/disable returned ${JSON.stringify(ricResp)}`);
62
+ } catch (error: unknown) {
63
+ RaftLog.warn(`getRICCalibInfo Failed subscribe for updates ${error}`);
64
+ }
65
+ };
66
+
67
+ // Invalidate state
68
+ stateIsInvalid(): void {};
69
+
70
+ // Other message type
71
+ rxOtherMsgType(payload: Uint8Array, frameTimeMs: number) {
72
+
73
+ // RICLog.debug(`rxOtherMsgType payload ${RaftUtils.bufferToHex(payload)}`);
74
+ RaftLog.verbose(`rxOtherMsgType payloadLen ${payload.length}`);
75
+ const topicIDs = this._stateInfo.updateFromMsg(payload, frameTimeMs, SUBSCRIBE_BINARY_MSGS);
76
+
77
+ // Call event handler if registered
78
+ if (this._onEvent) {
79
+ this._onEvent("pub", RaftPublishEvent.PUBLISH_EVENT_DATA, RaftPublishEventNames[RaftPublishEvent.PUBLISH_EVENT_DATA],
80
+ {
81
+ topicIDs: topicIDs,
82
+ payload: payload,
83
+ frameTimeMs: frameTimeMs,
84
+ isBinary: SUBSCRIBE_BINARY_MSGS
85
+ });
86
+ }
87
+ };
88
+
89
+ // Get device manager
90
+ deviceMgrIF = this._deviceManager;
91
+ }
@@ -50,19 +50,38 @@ export class RICStateInfo implements RaftDeviceMgrIF {
50
50
  deviceAttributes: {},
51
51
  deviceIsNew: false,
52
52
  stateChanged: false,
53
- isOnline: false
53
+ isOnline: false,
54
+ deviceAddress: "",
55
+ deviceType: "",
56
+ busName: ""
54
57
  };
55
58
  }
56
59
 
57
- onNewDevice(callback: (deviceKey: string, state: DeviceState) => void): void {
60
+ setMaxDataPointsToStore(maxDataPointsToStore: number): void {
58
61
  // TODO - implement if RICStateInfo is to be used as a DeviceMgr
59
62
  }
60
63
 
61
- onNewDeviceAttribute(callback: (deviceKey: string, attrState: DeviceAttributeState) => void): void {
64
+ addNewDeviceCallback(callback: (deviceKey: string, state: DeviceState) => void): void {
62
65
  // TODO - implement if RICStateInfo is to be used as a DeviceMgr
63
66
  }
64
67
 
65
- onNewAttributeData(callback: (deviceKey: string, attrState: DeviceAttributeState) => void): void {
68
+ removeNewDeviceCallback(callback: (deviceKey: string, state: DeviceState) => void): void {
69
+ // TODO - implement if RICStateInfo is to be used as a DeviceMgr
70
+ }
71
+
72
+ addNewAttributeCallback(callback: (deviceKey: string, attrState: DeviceAttributeState) => void): void {
73
+ // TODO - implement if RICStateInfo is to be used as a DeviceMgr
74
+ }
75
+
76
+ removeNewAttributeCallback(callback: (deviceKey: string, attrState: DeviceAttributeState) => void): void {
77
+ // TODO - implement if RICStateInfo is to be used as a DeviceMgr
78
+ }
79
+
80
+ addAttributeDataCallback(callback: (deviceKey: string, attrState: DeviceAttributeState) => void): void {
81
+ // TODO - implement if RICStateInfo is to be used as a DeviceMgr
82
+ }
83
+
84
+ removeAttributeDataCallback(callback: (deviceKey: string, attrState: DeviceAttributeState) => void): void {
66
85
  // TODO - implement if RICStateInfo is to be used as a DeviceMgr
67
86
  }
68
87
 
@@ -152,7 +152,7 @@ export default class RICSystemUtils {
152
152
  // Result
153
153
  console.log("Set calibration flag to true");
154
154
  const rslt = new RaftOKFail();
155
- rslt.set(overallResult);
155
+ rslt.rslt = overallResult ? "ok" : "fail";
156
156
  return rslt;
157
157
  }
158
158
  return false;
@@ -12,6 +12,9 @@ export default class SystemTypeMarty implements RaftSystemType {
12
12
  firmwareDestName = "ricfw";
13
13
  normalFileDestName = "fs";
14
14
  connectorOptions = {wsSuffix: "ws", bleConnItvlMs: 7.5};
15
+ BLEServiceUUIDs = ["aa76677e-9cfd-4626-a510-0d305be57c8d"];
16
+ BLECmdUUID = "aa76677e-9cfd-4626-a510-0d305be57c8e";
17
+ BLERespUUID = "aa76677e-9cfd-4626-a510-0d305be57c8f";
15
18
 
16
19
  // LED Pattern checker
17
20
  private _ledPatternChecker: RICLEDPatternChecker = new RICLEDPatternChecker();
@@ -21,7 +24,7 @@ export default class SystemTypeMarty implements RaftSystemType {
21
24
 
22
25
  // Latest data from servos, IMU, etc
23
26
  private _ricStateInfo: RICStateInfo = new RICStateInfo();
24
- getRICStateInfo(): RICStateInfo {
27
+ getStateInfo(): RICStateInfo {
25
28
  return this._ricStateInfo;
26
29
  }
27
30
 
@@ -95,7 +98,7 @@ export default class SystemTypeMarty implements RaftSystemType {
95
98
 
96
99
  // Other message type
97
100
  rxOtherMsgType(payload: Uint8Array, frameTimeMs: number) {
98
- // RICLog.debug(`onRxROSSerialMsg payload ${RICUtils.bufferToHex(payload)}`);
101
+ // RICLog.debug(`onRxROSSerialMsg payload ${RaftUtils.bufferToHex(payload)}`);
99
102
  RaftLog.verbose(`onRxROSSerialMsg payloadLen ${payload.length}`);
100
103
  const topicIDs = this._ricStateInfo.updateFromROSSerialMsg(payload, this._commsStats, this._addOnManager, frameTimeMs);
101
104
 
@@ -4,8 +4,8 @@
4
4
  <head>
5
5
  <meta charset="UTF-8">
6
6
  <meta name="viewport" content="width=device-width,initial-scale=1">
7
- <meta name="description" content="BusI2CWebTest">
8
- <title>BusI2CWebTest</title>
7
+ <meta name="description" content="RaftJS Dashboard">
8
+ <title>RaftJS Dashboard</title>
9
9
  <link rel="icon" href="data:image/svg+xml;base64, PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB3aWR0aD0iNTExIgogICBoZWlnaHQ9IjUxMSIKICAgdmlld0JveD0iMCAwIDEzNS4yMDIwOSAxMzUuMjAyMDkiCiAgIHZlcnNpb249IjEuMSIKICAgaWQ9InN2ZzE3OCIKICAgaW5rc2NhcGU6dmVyc2lvbj0iMS4zLjIgKDA5MWUyMGUsIDIwMjMtMTEtMjUsIGN1c3RvbSkiCiAgIHNvZGlwb2RpOmRvY25hbWU9IlNjYWRlclVpTG9nby5zdmciCiAgIGlua3NjYXBlOmV4cG9ydC1maWxlbmFtZT0ibG9nbzUxMi5wbmciCiAgIGlua3NjYXBlOmV4cG9ydC14ZHBpPSI5Ni4xODc4NjYiCiAgIGlua3NjYXBlOmV4cG9ydC15ZHBpPSI5Ni4xODc4NjYiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIgogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxzb2RpcG9kaTpuYW1lZHZpZXcKICAgICBpZD0ibmFtZWR2aWV3MTgwIgogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxLjAiCiAgICAgaW5rc2NhcGU6c2hvd3BhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAiCiAgICAgaW5rc2NhcGU6cGFnZWNoZWNrZXJib2FyZD0iMCIKICAgICBpbmtzY2FwZTpkZXNrY29sb3I9IiNkMWQxZDEiCiAgICAgaW5rc2NhcGU6ZG9jdW1lbnQtdW5pdHM9Im1tIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBzaG93Z3VpZGVzPSJ0cnVlIgogICAgIGlua3NjYXBlOnpvb209IjEiCiAgICAgaW5rc2NhcGU6Y3g9IjU3OCIKICAgICBpbmtzY2FwZTpjeT0iNTM2LjUiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIzODQwIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjE1MjkiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjI1NTIiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9Ii04IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ibGF5ZXIxIj4KICAgIDxzb2RpcG9kaTpndWlkZQogICAgICAgcG9zaXRpb249IjM4Ljc1MTcwNSw1NS4yMDIwODIiCiAgICAgICBvcmllbnRhdGlvbj0iMCwxIgogICAgICAgaWQ9Imd1aWRlMzg4IgogICAgICAgaW5rc2NhcGU6bG9ja2VkPSJmYWxzZSIKICAgICAgIGlua3NjYXBlOmxhYmVsPSIiCiAgICAgICBpbmtzY2FwZTpjb2xvcj0icmdiKDAsMTM0LDIyOSkiIC8+CiAgICA8c29kaXBvZGk6Z3VpZGUKICAgICAgIHBvc2l0aW9uPSI2Ny43NTAwMDMsMTQzLjQwNDE3IgogICAgICAgb3JpZW50YXRpb249Ii0xLDAiCiAgICAgICBpZD0iZ3VpZGUzOTAiCiAgICAgICBpbmtzY2FwZTpsb2NrZWQ9ImZhbHNlIgogICAgICAgaW5rc2NhcGU6bGFiZWw9IiIKICAgICAgIGlua3NjYXBlOmNvbG9yPSJyZ2IoMCwxMzQsMjI5KSIgLz4KICAgIDxzb2RpcG9kaTpndWlkZQogICAgICAgcG9zaXRpb249IjEzNSw2Ni4wODUyNDUiCiAgICAgICBvcmllbnRhdGlvbj0iLTEsMCIKICAgICAgIGlkPSJndWlkZTM5MiIKICAgICAgIGlua3NjYXBlOmxvY2tlZD0iZmFsc2UiCiAgICAgICBpbmtzY2FwZTpsYWJlbD0iIgogICAgICAgaW5rc2NhcGU6Y29sb3I9InJnYigwLDEzNCwyMjkpIiAvPgogICAgPHNvZGlwb2RpOmd1aWRlCiAgICAgICBwb3NpdGlvbj0iMzUuMDAwMDAyLDkyLjY5MDg5MyIKICAgICAgIG9yaWVudGF0aW9uPSItMSwwIgogICAgICAgaWQ9Imd1aWRlMzk0IgogICAgICAgaW5rc2NhcGU6bG9ja2VkPSJmYWxzZSIKICAgICAgIGlua3NjYXBlOmxhYmVsPSIiCiAgICAgICBpbmtzY2FwZTpjb2xvcj0icmdiKDAsMTM0LDIyOSkiIC8+CiAgICA8c29kaXBvZGk6Z3VpZGUKICAgICAgIHBvc2l0aW9uPSIxNDkuMjc3MzQsLTE0Ljc5NzkyIgogICAgICAgb3JpZW50YXRpb249IjAsMSIKICAgICAgIGlkPSJndWlkZTM5NiIKICAgICAgIGlua3NjYXBlOmxvY2tlZD0iZmFsc2UiCiAgICAgICBpbmtzY2FwZTpsYWJlbD0iIgogICAgICAgaW5rc2NhcGU6Y29sb3I9InJnYigwLDEzNCwyMjkpIiAvPgogICAgPHNvZGlwb2RpOmd1aWRlCiAgICAgICBwb3NpdGlvbj0iNDUuMDAwMDAzLDk4LjQxMzY5MyIKICAgICAgIG9yaWVudGF0aW9uPSItMSwwIgogICAgICAgaWQ9Imd1aWRlNDMxIgogICAgICAgaW5rc2NhcGU6bG9ja2VkPSJmYWxzZSIKICAgICAgIGlua3NjYXBlOmxhYmVsPSIiCiAgICAgICBpbmtzY2FwZTpjb2xvcj0icmdiKDAsMTM0LDIyOSkiIC8+CiAgICA8c29kaXBvZGk6Z3VpZGUKICAgICAgIHBvc2l0aW9uPSItNDEuMTAyMzkyLC00Ljc5NzkyMTEiCiAgICAgICBvcmllbnRhdGlvbj0iMCwxIgogICAgICAgaWQ9Imd1aWRlNDMzIgogICAgICAgaW5rc2NhcGU6bG9ja2VkPSJmYWxzZSIKICAgICAgIGlua3NjYXBlOmxhYmVsPSIiCiAgICAgICBpbmtzY2FwZTpjb2xvcj0icmdiKDAsMTM0LDIyOSkiIC8+CiAgICA8c29kaXBvZGk6Z3VpZGUKICAgICAgIHBvc2l0aW9uPSIxMjUsODQuMDc5NzE3IgogICAgICAgb3JpZW50YXRpb249Ii0xLDAiCiAgICAgICBpZD0iZ3VpZGU0MzUiCiAgICAgICBpbmtzY2FwZTpsb2NrZWQ9ImZhbHNlIgogICAgICAgaW5rc2NhcGU6bGFiZWw9IiIKICAgICAgIGlua3NjYXBlOmNvbG9yPSJyZ2IoMCwxMzQsMjI5KSIgLz4KICAgIDxzb2RpcG9kaTpndWlkZQogICAgICAgcG9zaXRpb249IjE0LjMxNDI2Niw1MS4yMDIwODUiCiAgICAgICBvcmllbnRhdGlvbj0iMCwxIgogICAgICAgaWQ9Imd1aWRlNDM3IgogICAgICAgaW5rc2NhcGU6bG9ja2VkPSJmYWxzZSIKICAgICAgIGlua3NjYXBlOmxhYmVsPSIiCiAgICAgICBpbmtzY2FwZTpjb2xvcj0icmdiKDAsMTM0LDIyOSkiIC8+CiAgICA8c29kaXBvZGk6Z3VpZGUKICAgICAgIHBvc2l0aW9uPSI1NS4wMDAwMDMsNzMuODg3ODUzIgogICAgICAgb3JpZW50YXRpb249Ii0xLDAiCiAgICAgICBpZD0iZ3VpZGU0MzkiCiAgICAgICBpbmtzY2FwZTpsb2NrZWQ9ImZhbHNlIgogICAgICAgaW5rc2NhcGU6bGFiZWw9IiIKICAgICAgIGlua3NjYXBlOmNvbG9yPSJyZ2IoMCwxMzQsMjI5KSIgLz4KICAgIDxzb2RpcG9kaTpndWlkZQogICAgICAgcG9zaXRpb249Ijk3Ljc1MDAwNSwxNTUuODM5NTkiCiAgICAgICBvcmllbnRhdGlvbj0iLTEsMCIKICAgICAgIGlkPSJndWlkZTQ0MSIKICAgICAgIGlua3NjYXBlOmxvY2tlZD0iZmFsc2UiCiAgICAgICBpbmtzY2FwZTpsYWJlbD0iIgogICAgICAgaW5rc2NhcGU6Y29sb3I9InJnYigwLDEzNCwyMjkpIiAvPgogICAgPHNvZGlwb2RpOmd1aWRlCiAgICAgICBwb3NpdGlvbj0iLTM2LjYwMzYyMSw1LjIwMjA3OTQiCiAgICAgICBvcmllbnRhdGlvbj0iMCwxIgogICAgICAgaWQ9Imd1aWRlNDQzIgogICAgICAgaW5rc2NhcGU6bG9ja2VkPSJmYWxzZSIKICAgICAgIGlua3NjYXBlOmxhYmVsPSIiCiAgICAgICBpbmtzY2FwZTpjb2xvcj0icmdiKDAsMTM0LDIyOSkiIC8+CiAgICA8c29kaXBvZGk6Z3VpZGUKICAgICAgIHBvc2l0aW9uPSItMjAuNjUzNDQsNDcuMjAyMDg1IgogICAgICAgb3JpZW50YXRpb249IjAsMSIKICAgICAgIGlkPSJndWlkZTQ0NSIKICAgICAgIGlua3NjYXBlOmxvY2tlZD0iZmFsc2UiCiAgICAgICBpbmtzY2FwZTpsYWJlbD0iIgogICAgICAgaW5rc2NhcGU6Y29sb3I9InJnYigwLDEzNCwyMjkpIiAvPgogIDwvc29kaXBvZGk6bmFtZWR2aWV3PgogIDxkZWZzCiAgICAgaWQ9ImRlZnMxNzUiPgogICAgPGxpbmVhckdyYWRpZW50CiAgICAgICBpZD0ibGluZWFyR3JhZGllbnQ0ODEzIgogICAgICAgaW5rc2NhcGU6c3dhdGNoPSJzb2xpZCI+CiAgICAgIDxzdG9wCiAgICAgICAgIHN0eWxlPSJzdG9wLWNvbG9yOiMwMDAwMDA7c3RvcC1vcGFjaXR5OjE7IgogICAgICAgICBvZmZzZXQ9IjAiCiAgICAgICAgIGlkPSJzdG9wNDgxMSIgLz4KICAgIDwvbGluZWFyR3JhZGllbnQ+CiAgICA8bGluZWFyR3JhZGllbnQKICAgICAgIGlua3NjYXBlOmNvbGxlY3Q9ImFsd2F5cyIKICAgICAgIHhsaW5rOmhyZWY9IiNsaW5lYXJHcmFkaWVudDQ4MTMiCiAgICAgICBpZD0ibGluZWFyR3JhZGllbnQ0ODE1IgogICAgICAgeDE9IjY0LjY0NDQzNyIKICAgICAgIHkxPSI2NS44Njc1ODUiCiAgICAgICB4Mj0iOTcuNDU5NTYxIgogICAgICAgeTI9IjY1Ljg2NzU4NSIKICAgICAgIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiAvPgogICAgPGZpbHRlcgogICAgICAgaW5rc2NhcGU6Y29sbGVjdD0iYWx3YXlzIgogICAgICAgc3R5bGU9ImNvbG9yLWludGVycG9sYXRpb24tZmlsdGVyczpzUkdCIgogICAgICAgaWQ9ImZpbHRlcjEwIgogICAgICAgeD0iLTAuMDMyNzgxOTciCiAgICAgICB5PSItMC4wMjQ3MTkxNSIKICAgICAgIHdpZHRoPSIxLjA2NTU2MzkiCiAgICAgICBoZWlnaHQ9IjEuMDUzNzIxMyI+CiAgICAgIDxmZUdhdXNzaWFuQmx1cgogICAgICAgICBpbmtzY2FwZTpjb2xsZWN0PSJhbHdheXMiCiAgICAgICAgIHN0ZERldmlhdGlvbj0iMC41MzI1ODIwNCIKICAgICAgICAgaWQ9ImZlR2F1c3NpYW5CbHVyMTAiIC8+CiAgICA8L2ZpbHRlcj4KICAgIDxmaWx0ZXIKICAgICAgIGlua3NjYXBlOmNvbGxlY3Q9ImFsd2F5cyIKICAgICAgIHN0eWxlPSJjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM6c1JHQiIKICAgICAgIGlkPSJmaWx0ZXIxMSIKICAgICAgIHg9Ii0wLjAzNzc2MjYyMiIKICAgICAgIHk9Ii0wLjAyODE4ODY5OCIKICAgICAgIHdpZHRoPSIxLjA3NTUyNTIiCiAgICAgICBoZWlnaHQ9IjEuMDYxNjkyOCI+CiAgICAgIDxmZUdhdXNzaWFuQmx1cgogICAgICAgICBpbmtzY2FwZTpjb2xsZWN0PSJhbHdheXMiCiAgICAgICAgIHN0ZERldmlhdGlvbj0iMC40MjU0MjA3MSIKICAgICAgICAgaWQ9ImZlR2F1c3NpYW5CbHVyMTEiIC8+CiAgICA8L2ZpbHRlcj4KICAgIDxmaWx0ZXIKICAgICAgIGlua3NjYXBlOmNvbGxlY3Q9ImFsd2F5cyIKICAgICAgIHN0eWxlPSJjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM6c1JHQiIKICAgICAgIGlkPSJmaWx0ZXIxMiIKICAgICAgIHg9Ii0wLjAyOTI5NjUwOSIKICAgICAgIHk9Ii0wLjAxNzUwNzUyNCIKICAgICAgIHdpZHRoPSIxLjA1ODU5MyIKICAgICAgIGhlaWdodD0iMS4wMzUwMTUiPgogICAgICA8ZmVHYXVzc2lhbkJsdXIKICAgICAgICAgaW5rc2NhcGU6Y29sbGVjdD0iYWx3YXlzIgogICAgICAgICBzdGREZXZpYXRpb249IjAuMzU1NDU5NiIKICAgICAgICAgaWQ9ImZlR2F1c3NpYW5CbHVyMTIiIC8+CiAgICA8L2ZpbHRlcj4KICA8L2RlZnM+CiAgPGcKICAgICBpbmtzY2FwZTpsYWJlbD0iTGF5ZXIgMSIKICAgICBpbmtzY2FwZTpncm91cG1vZGU9ImxheWVyIgogICAgIGlkPSJsYXllcjEiPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJtaXgtYmxlbmQtbW9kZTpub3JtYWw7ZmlsbDojZTY3MTFlO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTojZmZmZmZmO3N0cm9rZS13aWR0aDo0O3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOmJldmVsO3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxO2ZpbHRlcjp1cmwoI2ZpbHRlcjEwKSIKICAgICAgIGQ9Ik0gMTcuODAyMDgzLDEyMy4wMTI1IFYgNTMuMDEyNTAxIGwgNTAsLTQzLjAzMjgyMSA0OS45OTk5OTcsNDMuMDMyODIxIFYgMTIzLjAxMjUgWiIKICAgICAgIGlkPSJwYXRoNDA3IgogICAgICAgc29kaXBvZGk6bm9kZXR5cGVzPSJjY2NjY2MiCiAgICAgICB0cmFuc2Zvcm09Im1hdHJpeCgxLjE2NzE5ODQsMCwwLDEuMTE0OTM2MiwtMTAuOTM5NTI4LC04LjE5OTc5MjkpIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNlNjcxMWU7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjQ7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46YmV2ZWw7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjE7ZmlsdGVyOnVybCgjZmlsdGVyMTEpIgogICAgICAgZD0iTSAyNy44MDIwODMsMTEzLjAxMjUgViA1Ny4wMTI1MDEgbCA0MCwtMzQuMTY4Mjg3IDM5Ljk5OTk5NywzNC4xNjgyODcgViAxMTMuMDEyNSBaIgogICAgICAgaWQ9InBhdGg0MDctOSIKICAgICAgIHNvZGlwb2RpOm5vZGV0eXBlcz0iY2NjY2NjIgogICAgICAgdHJhbnNmb3JtPSJtYXRyaXgoMS4xMDQ3NjAzLDAsMCwxLjA5MzkzODYsLTUuNTE1NDYxNywtNS44NzQ0NDU0KSIgLz4KICAgIDxyZWN0CiAgICAgICBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDowLjI2NDU4MztzdHJva2UtbGluZWpvaW46YmV2ZWw7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjA7ZmlsbC1vcGFjaXR5OjEiCiAgICAgICBpZD0icmVjdDI3NzciCiAgICAgICB3aWR0aD0iMTM1LjIwMjA5IgogICAgICAgaGVpZ2h0PSIxMzUuMjAyMDkiCiAgICAgICB4PSIwIgogICAgICAgeT0iMCIgLz4KICAgIDx0ZXh0CiAgICAgICB4bWw6c3BhY2U9InByZXNlcnZlIgogICAgICAgc3R5bGU9ImZvbnQtc3R5bGU6bm9ybWFsO2ZvbnQtdmFyaWFudDpub3JtYWw7Zm9udC13ZWlnaHQ6bm9ybWFsO2ZvbnQtc3RyZXRjaDpub3JtYWw7Zm9udC1zaXplOjk3LjEwNDhweDtsaW5lLWhlaWdodDoxLjI1O2ZvbnQtZmFtaWx5OkNhbGlicmk7LWlua3NjYXBlLWZvbnQtc3BlY2lmaWNhdGlvbjonQ2FsaWJyaSwgTm9ybWFsJztmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsO2ZvbnQtdmFyaWFudC1lYXN0LWFzaWFuOm5vcm1hbDttaXgtYmxlbmQtbW9kZTpub3JtYWw7ZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTojZmZmZmZmO3N0cm9rZS13aWR0aDowLjUwNTIwNjtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MTtmaWx0ZXI6dXJsKCNmaWx0ZXIxMikiCiAgICAgICB4PSIzOS4zOTM2NjEiCiAgICAgICB5PSIxMTYuMTE2OCIKICAgICAgIGlkPSJ0ZXh0Mjg1NCIKICAgICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMjIwMTU3OCwwLDAsMC45NDYxNTE3NSwtNS43NTQ3Mzk5LC0yLjU0ODUyODQpIj48dHNwYW4KICAgICAgICAgc29kaXBvZGk6cm9sZT0ibGluZSIKICAgICAgICAgaWQ9InRzcGFuMjg1MiIKICAgICAgICAgeD0iMzkuMzkzNjYxIgogICAgICAgICB5PSIxMTYuMTE2OCIKICAgICAgICAgc3R5bGU9ImZvbnQtc3R5bGU6bm9ybWFsO2ZvbnQtdmFyaWFudDpub3JtYWw7Zm9udC13ZWlnaHQ6bm9ybWFsO2ZvbnQtc3RyZXRjaDpub3JtYWw7Zm9udC1zaXplOjk3LjEwNDhweDtmb250LWZhbWlseTpDYWxpYnJpOy1pbmtzY2FwZS1mb250LXNwZWNpZmljYXRpb246J0NhbGlicmksIE5vcm1hbCc7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbDtmb250LXZhcmlhbnQtZWFzdC1hc2lhbjpub3JtYWw7ZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTojZmZmZmZmO3N0cm9rZS13aWR0aDowLjUwNTIwNjtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSI+UzwvdHNwYW4+PC90ZXh0PgogIDwvZz4KPC9zdmc+Cg==" type="image/svg+xml" />
10
10
  </head>
11
11
  <body>
@@ -2,8 +2,6 @@ import React from 'react';
2
2
  import { createRoot } from 'react-dom/client';
3
3
  import Main from './Main';
4
4
  import './styles.css';
5
- import 'process';
6
- import 'buffer';
7
5
 
8
6
  // Find the root element
9
7
  const rootElement = document.getElementById('root');
@@ -77,6 +77,16 @@ h1 {
77
77
  font-size: 1rem;
78
78
  }
79
79
 
80
+ .settings-item {
81
+ display: flex;
82
+ justify-content: space-between;
83
+ align-items: center;
84
+ padding: 10px;
85
+ border: 1px solid #666;
86
+ border-radius: 4px;
87
+ margin-bottom: 10px;
88
+ }
89
+
80
90
  .info-boxes {
81
91
  display: flex;
82
92
  justify-content: flex-start;
@@ -349,6 +359,10 @@ h1 {
349
359
  z-index: 10;
350
360
  }
351
361
 
362
+ .header .dropdown-menu {
363
+ margin-top: 30px;
364
+ }
365
+
352
366
  .menu-item {
353
367
  padding: 10px;
354
368
  cursor: pointer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robotical/raftjs",
3
- "version": "1.3.3",
3
+ "version": "1.4.0",
4
4
  "description": "Javascript/TS library for Raft library",
5
5
  "main": "dist/web/main.js",
6
6
  "types": "dist/web/main.d.ts",
@@ -25,32 +25,24 @@
25
25
  "build": "tsc -p tsconfig.json",
26
26
  "build:phone": "tsc -p tsconfig.react-native.json",
27
27
  "build-all": "npm run clean && npm run build && npm run build:phone",
28
- "test": "jest",
29
28
  "lint": "eslint ./src",
30
- "clean": "rm -rf dist build package",
29
+ "clean": "rimraf dist build package",
31
30
  "docs": "typedoc --entryPoints src/main.ts",
32
31
  "watch-all": "tsc -p tsconfig.json --watch & tsc -p tsconfig.react-native.json --watch"
33
32
  },
34
33
  "devDependencies": {
35
- "@types/jest": "^29.5.12",
36
34
  "@types/node": "^20.14.0",
37
- "@types/python-struct": "^1.0.4",
38
- "@types/semver": "^7.5.8",
39
35
  "@types/web-bluetooth": "^0.0.20",
40
36
  "@typescript-eslint/eslint-plugin": "^8.6.0",
41
37
  "eslint": "^9.4.0",
42
- "jest": "^29.7.0",
43
- "react-native-ble-plx": "^3.2.1",
44
- "ts-jest": "^29.1.4",
45
- "typescript": "^5.4.5"
38
+ "react-native-ble-plx": "^3.2.0",
39
+ "typescript": "^5.4.5",
40
+ "text-encoding": "^0.7.0",
41
+ "rimraf": "^6.0.1"
46
42
  },
47
43
  "dependencies": {
48
44
  "@types/text-encoding": "^0.0.39",
49
- "axios": "^1.7.2",
50
45
  "isomorphic-ws": "^5.0.0",
51
- "python-struct": "^1.1.3",
52
- "semver": "^7.6.2",
53
- "text-encoding": "^0.7.0",
54
46
  "tslib": "^2.6.2"
55
47
  },
56
48
  "peerDependencies": {