@robdobsn/raftjs 1.5.0 → 1.5.9
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/dist/react-native/RaftAttributeHandler.js +6 -1
- package/dist/react-native/RaftAttributeHandler.js.map +1 -1
- package/dist/react-native/RaftChannelBLE.native.js +1 -1
- package/dist/react-native/RaftChannelBLE.native.js.map +1 -1
- package/dist/react-native/RaftConnector.js +1 -1
- package/dist/react-native/RaftConnector.js.map +1 -1
- package/dist/react-native/RaftDeviceInfo.d.ts +3 -0
- package/dist/react-native/RaftDeviceManager.d.ts +12 -7
- package/dist/react-native/RaftDeviceManager.js +185 -41
- package/dist/react-native/RaftDeviceManager.js.map +1 -1
- package/dist/react-native/RaftDeviceMgrIF.d.ts +7 -3
- package/dist/react-native/RaftDeviceStates.d.ts +5 -1
- package/dist/react-native/RaftDeviceStates.js +2 -2
- package/dist/react-native/RaftDeviceStates.js.map +1 -1
- package/dist/react-native/RaftMsgHandler.d.ts +1 -1
- package/dist/react-native/RaftStruct.js +2 -1
- package/dist/react-native/RaftStruct.js.map +1 -1
- package/dist/react-native/RaftTypes.d.ts +9 -12
- package/dist/react-native/RaftTypes.js +5 -47
- package/dist/react-native/RaftTypes.js.map +1 -1
- package/dist/web/RaftAttributeHandler.js +6 -1
- package/dist/web/RaftAttributeHandler.js.map +1 -1
- package/dist/web/RaftConnector.js +1 -1
- package/dist/web/RaftConnector.js.map +1 -1
- package/dist/web/RaftDeviceInfo.d.ts +3 -0
- package/dist/web/RaftDeviceManager.d.ts +12 -7
- package/dist/web/RaftDeviceManager.js +185 -41
- package/dist/web/RaftDeviceManager.js.map +1 -1
- package/dist/web/RaftDeviceMgrIF.d.ts +7 -3
- package/dist/web/RaftDeviceStates.d.ts +5 -1
- package/dist/web/RaftDeviceStates.js +2 -2
- package/dist/web/RaftDeviceStates.js.map +1 -1
- package/dist/web/RaftMsgHandler.d.ts +1 -1
- package/dist/web/RaftStruct.js +2 -1
- package/dist/web/RaftStruct.js.map +1 -1
- package/dist/web/RaftTypes.d.ts +9 -12
- package/dist/web/RaftTypes.js +5 -47
- package/dist/web/RaftTypes.js.map +1 -1
- package/examples/dashboard/package.json +6 -3
- package/examples/dashboard/src/ConnManager.ts +5 -1
- package/examples/dashboard/src/DeviceActionsForm.tsx +49 -49
- package/examples/dashboard/src/DeviceLineChart.tsx +44 -20
- package/examples/dashboard/src/DevicePanel.tsx +33 -2
- package/examples/dashboard/src/DevicesPanel.tsx +5 -4
- package/examples/dashboard/src/LatencyTest.ts +130 -0
- package/examples/dashboard/src/LatencyTestPanel.tsx +92 -0
- package/examples/dashboard/src/Main.tsx +192 -76
- package/examples/dashboard/src/SettingsManager.ts +67 -0
- package/examples/dashboard/src/SettingsScreen.tsx +174 -0
- package/examples/dashboard/src/SystemTypeCog/CogStateInfo.ts +13 -8
- package/examples/dashboard/src/SystemTypeCog/SystemTypeCog.ts +9 -5
- package/examples/dashboard/src/SystemTypeGeneric/StateInfoGeneric.ts +12 -6
- package/examples/dashboard/src/SystemTypeGeneric/SystemTypeGeneric.ts +9 -5
- package/examples/dashboard/src/SystemTypeMarty/RICStateInfo.ts +23 -4
- package/examples/dashboard/src/SystemTypeMarty/RICSystemUtils.ts +1 -1
- package/examples/dashboard/src/SystemTypeMarty/SystemTypeMarty.ts +1 -1
- package/examples/dashboard/src/index.html +2 -2
- package/examples/dashboard/src/styles.css +14 -0
- package/package.json +5 -4
- package/src/RaftAttributeHandler.ts +7 -1
- package/src/RaftChannelBLE.native.ts +1 -1
- package/src/RaftConnector.ts +1 -1
- package/src/RaftDeviceInfo.ts +3 -0
- package/src/RaftDeviceManager.ts +220 -50
- package/src/RaftDeviceMgrIF.ts +9 -3
- package/src/RaftDeviceStates.ts +6 -2
- package/src/RaftStruct.ts +2 -1
- package/src/RaftTypes.ts +22 -30
|
@@ -1,114 +1,230 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
|
1
|
+
import React, { useEffect, useState, useRef } from 'react';
|
|
2
2
|
import './styles.css';
|
|
3
|
+
import SettingsScreen from './SettingsScreen';
|
|
3
4
|
import ConnManager from './ConnManager';
|
|
4
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
RaftConnEvent,
|
|
7
|
+
RaftUpdateEvent,
|
|
8
|
+
RaftPublishEvent,
|
|
9
|
+
RaftSysTypeManager,
|
|
10
|
+
} from '../../../src/main';
|
|
5
11
|
import StatusPanel from './StatusPanel';
|
|
6
12
|
import DevicesPanel from './DevicesPanel';
|
|
7
13
|
import CommandPanel from './CommandPanel';
|
|
14
|
+
import LatencyTestPanel from './LatencyTestPanel';
|
|
8
15
|
import SystemTypeCog from './SystemTypeCog/SystemTypeCog';
|
|
9
16
|
import SystemTypeMarty from './SystemTypeMarty/SystemTypeMarty';
|
|
10
17
|
import SystemTypeGeneric from './SystemTypeGeneric/SystemTypeGeneric';
|
|
18
|
+
import SettingsManager from './SettingsManager';
|
|
11
19
|
|
|
12
20
|
const sysTypeManager = RaftSysTypeManager.getInstance();
|
|
13
21
|
const connManager = ConnManager.getInstance();
|
|
14
|
-
sysTypeManager.addSystemType(
|
|
15
|
-
sysTypeManager.addSystemType(
|
|
22
|
+
sysTypeManager.addSystemType('Cog', () => new SystemTypeCog());
|
|
23
|
+
sysTypeManager.addSystemType('Marty', () => new SystemTypeMarty());
|
|
16
24
|
sysTypeManager.addDefaultSystemType(() => new SystemTypeGeneric());
|
|
17
25
|
|
|
18
|
-
|
|
19
26
|
export default function Main() {
|
|
20
|
-
const [connectionStatus, setConnectionStatus] = useState<RaftConnEvent>(
|
|
27
|
+
const [connectionStatus, setConnectionStatus] = useState<RaftConnEvent>(
|
|
28
|
+
RaftConnEvent.CONN_DISCONNECTED
|
|
29
|
+
);
|
|
30
|
+
const [connectionTime, setConnectionTime] = useState<Date | null>(null);
|
|
31
|
+
const [elapsedTime, setElapsedTime] = useState<string | null>(null);
|
|
32
|
+
const [menuOpen, setMenuOpen] = useState(false);
|
|
33
|
+
const [showSettings, setShowSettings] = useState(false);
|
|
34
|
+
const menuRef = useRef<HTMLDivElement>(null);
|
|
35
|
+
const settingsManager = SettingsManager.getInstance();
|
|
36
|
+
const [latencyTestEnabled, setLatencyTestEnabled] = useState(
|
|
37
|
+
settingsManager.getSetting('latencyTest')
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const [ipAddress, setIpAddress] = useState<string>(
|
|
41
|
+
localStorage.getItem('lastIpAddress') || ''
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
const handleConnect = () => {
|
|
45
|
+
if (ipAddress.trim() === '') {
|
|
46
|
+
console.error('No IP address entered');
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
connManager.connect('WebSocket', ipAddress, []);
|
|
50
|
+
localStorage.setItem('lastIpAddress', ipAddress);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
54
|
+
if (event.key === 'Enter') {
|
|
55
|
+
handleConnect();
|
|
56
|
+
}
|
|
57
|
+
};
|
|
21
58
|
|
|
22
59
|
useEffect(() => {
|
|
23
|
-
|
|
24
|
-
|
|
60
|
+
const listener = (
|
|
61
|
+
eventType: string,
|
|
25
62
|
eventEnum: RaftConnEvent | RaftUpdateEvent | RaftPublishEvent,
|
|
26
63
|
eventName: string,
|
|
27
|
-
data?: object | string | null
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
64
|
+
data?: object | string | null
|
|
65
|
+
) => {
|
|
66
|
+
if (eventType === 'conn') {
|
|
67
|
+
if (
|
|
68
|
+
eventEnum === RaftConnEvent.CONN_CONNECTED ||
|
|
69
|
+
eventEnum === RaftConnEvent.CONN_DISCONNECTED
|
|
70
|
+
) {
|
|
31
71
|
setConnectionStatus(eventEnum);
|
|
72
|
+
setConnectionTime(new Date());
|
|
32
73
|
}
|
|
33
74
|
}
|
|
34
75
|
};
|
|
35
76
|
|
|
36
|
-
// Set the listener function
|
|
37
77
|
connManager.setConnectionEventListener(listener);
|
|
38
78
|
|
|
39
|
-
// Clean up the listener when the component unmounts
|
|
40
79
|
return () => {
|
|
41
80
|
connManager.setConnectionEventListener(() => { });
|
|
42
81
|
};
|
|
43
82
|
}, []);
|
|
44
83
|
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
const handleClickOutside = (event: MouseEvent) => {
|
|
86
|
+
if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
|
|
87
|
+
setMenuOpen(false);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
91
|
+
return () => {
|
|
92
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
93
|
+
};
|
|
94
|
+
}, []);
|
|
95
|
+
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
const interval = setInterval(() => {
|
|
98
|
+
setLatencyTestEnabled(settingsManager.getSetting('latencyTest'));
|
|
99
|
+
}, 100);
|
|
100
|
+
return () => clearInterval(interval);
|
|
101
|
+
}, []);
|
|
102
|
+
|
|
103
|
+
useEffect(() => {
|
|
104
|
+
if (connectionStatus === RaftConnEvent.CONN_CONNECTED && connectionTime) {
|
|
105
|
+
const interval = setInterval(() => {
|
|
106
|
+
const now = new Date();
|
|
107
|
+
const elapsed = now.getTime() - connectionTime.getTime();
|
|
108
|
+
|
|
109
|
+
const hours = Math.floor(elapsed / 3600000).toString().padStart(2, '0');
|
|
110
|
+
const minutes = Math.floor((elapsed % 3600000) / 60000).toString().padStart(2, '0');
|
|
111
|
+
const seconds = Math.floor((elapsed % 60000) / 1000).toString().padStart(2, '0');
|
|
112
|
+
const milliseconds = (elapsed % 1000).toString().padStart(3, '0');
|
|
113
|
+
|
|
114
|
+
setElapsedTime(`${hours}:${minutes}:${seconds}:${milliseconds}`);
|
|
115
|
+
}, 50);
|
|
116
|
+
|
|
117
|
+
return () => clearInterval(interval);
|
|
118
|
+
} else {
|
|
119
|
+
setElapsedTime(null);
|
|
120
|
+
}
|
|
121
|
+
}, [connectionStatus, connectionTime]);
|
|
122
|
+
|
|
45
123
|
return (
|
|
46
124
|
<div className="content-outer">
|
|
47
|
-
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
125
|
+
{showSettings ? (
|
|
126
|
+
<SettingsScreen onBack={() => setShowSettings(false)} />
|
|
127
|
+
) : (
|
|
128
|
+
<>
|
|
129
|
+
<div className="header">
|
|
130
|
+
<h1>RaftJS Dashboard</h1>
|
|
131
|
+
<div
|
|
132
|
+
className="menu-icon header-menu-icon"
|
|
133
|
+
onClick={() => setMenuOpen(!menuOpen)}
|
|
134
|
+
>
|
|
135
|
+
☰
|
|
136
|
+
</div>
|
|
137
|
+
{menuOpen && (
|
|
138
|
+
<div className="dropdown-menu" ref={menuRef}>
|
|
139
|
+
<div
|
|
140
|
+
className="menu-item"
|
|
141
|
+
onClick={() => {
|
|
142
|
+
setMenuOpen(false);
|
|
143
|
+
setShowSettings(true);
|
|
144
|
+
}}
|
|
145
|
+
>
|
|
146
|
+
Settings
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
)}
|
|
150
|
+
</div>
|
|
151
|
+
<div className="content-body">
|
|
152
|
+
{connectionStatus === RaftConnEvent.CONN_CONNECTED ? (
|
|
153
|
+
<>
|
|
154
|
+
<div className="connected-panel">
|
|
155
|
+
<div className="info-boxes">
|
|
156
|
+
<div className="info-box">
|
|
157
|
+
<div className="conn-indication">
|
|
158
|
+
<h3>Connected</h3>
|
|
159
|
+
</div>
|
|
160
|
+
<div>
|
|
161
|
+
<button
|
|
162
|
+
className="action-button"
|
|
163
|
+
onClick={() => connManager.disconnect()}
|
|
164
|
+
>
|
|
165
|
+
Disconnect
|
|
166
|
+
</button>
|
|
167
|
+
</div>
|
|
168
|
+
<div>
|
|
169
|
+
{elapsedTime && <p>{elapsedTime}</p>}
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
<StatusPanel />
|
|
174
|
+
{latencyTestEnabled && <LatencyTestPanel />}
|
|
175
|
+
<CommandPanel />
|
|
176
|
+
</div>
|
|
177
|
+
<DevicesPanel />
|
|
178
|
+
</>
|
|
179
|
+
) : (
|
|
180
|
+
<>
|
|
181
|
+
<div className="info-boxes">
|
|
182
|
+
<div className="info-box">
|
|
183
|
+
<h3>WebSocket</h3>
|
|
184
|
+
<input
|
|
185
|
+
className="ip-addr-input"
|
|
186
|
+
id="ip-addr"
|
|
187
|
+
type="text"
|
|
188
|
+
placeholder="IP Address"
|
|
189
|
+
value={ipAddress}
|
|
190
|
+
onChange={(e) => setIpAddress(e.target.value)}
|
|
191
|
+
onKeyDown={handleKeyDown}
|
|
192
|
+
/>
|
|
193
|
+
<button
|
|
194
|
+
className="action-button"
|
|
195
|
+
onClick={handleConnect}
|
|
196
|
+
>
|
|
197
|
+
Connect
|
|
198
|
+
</button>
|
|
59
199
|
</div>
|
|
60
|
-
<div>
|
|
61
|
-
<
|
|
200
|
+
<div className="info-box">
|
|
201
|
+
<h3>WebBLE</h3>
|
|
202
|
+
<button
|
|
203
|
+
className="action-button"
|
|
204
|
+
onClick={() => {
|
|
205
|
+
connManager.connect('WebBLE', '', sysTypeManager.getAllServiceUUIDs());
|
|
206
|
+
}}
|
|
207
|
+
>
|
|
208
|
+
Connect
|
|
209
|
+
</button>
|
|
210
|
+
</div>
|
|
211
|
+
<div className="info-box">
|
|
212
|
+
<h3>WebSerial</h3>
|
|
213
|
+
<button
|
|
214
|
+
className="action-button"
|
|
215
|
+
onClick={() => {
|
|
216
|
+
connManager.connect('WebSerial', '', []);
|
|
217
|
+
}}
|
|
218
|
+
>
|
|
219
|
+
Connect
|
|
220
|
+
</button>
|
|
62
221
|
</div>
|
|
63
222
|
</div>
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
</>
|
|
70
|
-
:
|
|
71
|
-
<>
|
|
72
|
-
<div className="info-boxes">
|
|
73
|
-
<div className="info-box">
|
|
74
|
-
<h3>WebSocket</h3>
|
|
75
|
-
<input className="ip-addr-input" id="ip-addr" type="text" placeholder="IP Address" />
|
|
76
|
-
<button className="action-button" onClick={() => {
|
|
77
|
-
// Get IP address
|
|
78
|
-
const ipAddrElem = document.getElementById("ip-addr") as HTMLInputElement;
|
|
79
|
-
if (ipAddrElem) {
|
|
80
|
-
const ipAddr = ipAddrElem.value;
|
|
81
|
-
connManager.connect("WebSocket", ipAddr, []);
|
|
82
|
-
} else {
|
|
83
|
-
console.error("No IP address entered");
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}>
|
|
87
|
-
Connect
|
|
88
|
-
</button>
|
|
89
|
-
</div>
|
|
90
|
-
<div className="info-box">
|
|
91
|
-
<h3>WebBLE</h3>
|
|
92
|
-
<button className="action-button" onClick={() => {
|
|
93
|
-
connManager.connect("WebBLE", "", sysTypeManager.getAllServiceUUIDs());
|
|
94
|
-
}
|
|
95
|
-
}>
|
|
96
|
-
Connect
|
|
97
|
-
</button>
|
|
98
|
-
</div>
|
|
99
|
-
<div className="info-box">
|
|
100
|
-
<h3>WebSerial</h3>
|
|
101
|
-
<button className="action-button" onClick={() => {
|
|
102
|
-
connManager.connect("WebSerial", "", []);
|
|
103
|
-
}
|
|
104
|
-
}>
|
|
105
|
-
Connect
|
|
106
|
-
</button>
|
|
107
|
-
</div>
|
|
108
|
-
</div>
|
|
109
|
-
</>
|
|
110
|
-
}
|
|
111
|
-
</div>
|
|
223
|
+
</>
|
|
224
|
+
)}
|
|
225
|
+
</div>
|
|
226
|
+
</>
|
|
227
|
+
)}
|
|
112
228
|
</div>
|
|
113
229
|
);
|
|
114
230
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export type Settings = {
|
|
2
|
+
showCharts: boolean;
|
|
3
|
+
maxChartDataPoints: number;
|
|
4
|
+
maxDatapointsToStore: number;
|
|
5
|
+
latencyTest: boolean;
|
|
6
|
+
latencyAttributeName: string;
|
|
7
|
+
latencyChangeThreshold: number;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
class SettingsManager {
|
|
11
|
+
private static instance: SettingsManager;
|
|
12
|
+
private settings: Settings;
|
|
13
|
+
private storageKey = "RaftJS_Settings";
|
|
14
|
+
private maxChartDataPoints_default = 50;
|
|
15
|
+
private maxDatapointsToStore_default = 1000;
|
|
16
|
+
|
|
17
|
+
private constructor() {
|
|
18
|
+
// Load settings from localStorage or use default values
|
|
19
|
+
const savedSettings = localStorage.getItem(this.storageKey);
|
|
20
|
+
this.settings = savedSettings
|
|
21
|
+
? JSON.parse(savedSettings)
|
|
22
|
+
: {
|
|
23
|
+
latencyTest: false,
|
|
24
|
+
showCharts: true,
|
|
25
|
+
maxChartDataPoints: this.maxChartDataPoints_default,
|
|
26
|
+
maxDatapointsToStore: this.maxDatapointsToStore_default,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static getInstance(): SettingsManager {
|
|
31
|
+
if (!SettingsManager.instance) {
|
|
32
|
+
SettingsManager.instance = new SettingsManager();
|
|
33
|
+
}
|
|
34
|
+
return SettingsManager.instance;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
getSetting<K extends keyof Settings>(key: K): Settings[K] {
|
|
38
|
+
return this.settings[key];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setSetting<K extends keyof Settings>(key: K, value: Settings[K]): void {
|
|
42
|
+
this.settings[key] = value;
|
|
43
|
+
this.saveSettings();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
getAllSettings(): Settings {
|
|
47
|
+
return this.settings;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Save settings to localStorage
|
|
51
|
+
private saveSettings(): void {
|
|
52
|
+
localStorage.setItem(this.storageKey, JSON.stringify(this.settings));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Reset to default settings
|
|
56
|
+
resetSettings(): void {
|
|
57
|
+
this.settings = {
|
|
58
|
+
latencyTest: false,
|
|
59
|
+
showCharts: true,
|
|
60
|
+
maxChartDataPoints: this.maxChartDataPoints_default,
|
|
61
|
+
maxDatapointsToStore: this.maxDatapointsToStore_default,
|
|
62
|
+
};
|
|
63
|
+
this.saveSettings();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default SettingsManager;
|
|
@@ -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,7 @@
|
|
|
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";
|
|
4
5
|
|
|
5
6
|
// export interface IMUStateInfo {
|
|
6
7
|
// gx: number;
|
|
@@ -45,18 +46,22 @@ export class CogStateInfo {
|
|
|
45
46
|
return this._deviceManager;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
updateFromMsg(rxMsg: Uint8Array, frameTimeMs: number): Array<string> {
|
|
49
|
+
updateFromMsg(rxMsg: Uint8Array, frameTimeMs: number, isBinary: boolean): Array<string> {
|
|
49
50
|
|
|
50
51
|
// Debug
|
|
51
52
|
// RaftLog.info(`CogStateInfo: updateFromMsg: rxMsg: ${rxMsg} frameTimeMs: ${frameTimeMs}`);
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
if (isBinary) {
|
|
55
|
+
// console.log(`CogStateInfo: updateFromMsg: ${RaftUtils.bufferToHex(rxMsg)}`);
|
|
56
|
+
this._deviceManager.handleClientMsgBinary(rxMsg);
|
|
57
|
+
} else {
|
|
58
|
+
// Convert Uint8Array to string
|
|
59
|
+
const decoder = new TextDecoder('utf-8');
|
|
60
|
+
const jsonString = decoder.decode(rxMsg.slice(2));
|
|
61
|
+
|
|
62
|
+
// Handle using device manager
|
|
63
|
+
this._deviceManager.handleClientMsgJson(jsonString);
|
|
64
|
+
}
|
|
60
65
|
|
|
61
66
|
// // Debug
|
|
62
67
|
// // RaftLog.info(`CogStateInfo: updateFromMsg: jsonString: ${jsonString}`);
|
|
@@ -3,6 +3,8 @@ 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";
|
|
@@ -38,15 +40,16 @@ export default class SystemTypeCog implements RaftSystemType {
|
|
|
38
40
|
// Subscribe for updates
|
|
39
41
|
subscribeForUpdates: RaftSubscribeForUpdatesCBType | null = async (systemUtils: RaftSystemUtils, enable: boolean) => {
|
|
40
42
|
// Subscription rate
|
|
43
|
+
const topic = SUBSCRIBE_BINARY_MSGS ? "devbin" : "devjson";
|
|
41
44
|
const subscribeRateHz = 0.1;
|
|
42
45
|
try {
|
|
43
46
|
const subscribeDisable = '{"cmdName":"subscription","action":"update",' +
|
|
44
47
|
'"pubRecs":[' +
|
|
45
|
-
`{"name":"
|
|
48
|
+
`{"name":"${topic}","rateHz":0,}` +
|
|
46
49
|
']}';
|
|
47
50
|
const subscribeEnable = '{"cmdName":"subscription","action":"update",' +
|
|
48
51
|
'"pubRecs":[' +
|
|
49
|
-
`{"name":"
|
|
52
|
+
`{"name":"${topic}","trigger":"timeorchange","rateHz":${subscribeRateHz.toString()}}` +
|
|
50
53
|
']}';
|
|
51
54
|
|
|
52
55
|
const msgHandler = systemUtils.getMsgHandler();
|
|
@@ -67,9 +70,9 @@ export default class SystemTypeCog implements RaftSystemType {
|
|
|
67
70
|
// Other message type
|
|
68
71
|
rxOtherMsgType(payload: Uint8Array, frameTimeMs: number) {
|
|
69
72
|
|
|
70
|
-
// RICLog.debug(`rxOtherMsgType payload ${
|
|
73
|
+
// RICLog.debug(`rxOtherMsgType payload ${RaftUtils.bufferToHex(payload)}`);
|
|
71
74
|
RaftLog.verbose(`rxOtherMsgType payloadLen ${payload.length}`);
|
|
72
|
-
const topicIDs = this._stateInfo.updateFromMsg(payload, frameTimeMs);
|
|
75
|
+
const topicIDs = this._stateInfo.updateFromMsg(payload, frameTimeMs, SUBSCRIBE_BINARY_MSGS);
|
|
73
76
|
|
|
74
77
|
// Call event handler if registered
|
|
75
78
|
if (this._onEvent) {
|
|
@@ -77,7 +80,8 @@ export default class SystemTypeCog implements RaftSystemType {
|
|
|
77
80
|
{
|
|
78
81
|
topicIDs: topicIDs,
|
|
79
82
|
payload: payload,
|
|
80
|
-
frameTimeMs: frameTimeMs
|
|
83
|
+
frameTimeMs: frameTimeMs,
|
|
84
|
+
isBinary: SUBSCRIBE_BINARY_MSGS
|
|
81
85
|
});
|
|
82
86
|
}
|
|
83
87
|
};
|
|
@@ -7,17 +7,23 @@ export class StateInfoGeneric {
|
|
|
7
7
|
public constructor(private _deviceManager: DeviceManager) {
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
updateFromMsg(rxMsg: Uint8Array, frameTimeMs: number): Array<string> {
|
|
10
|
+
updateFromMsg(rxMsg: Uint8Array, frameTimeMs: number, isBinary: boolean): Array<string> {
|
|
11
11
|
|
|
12
12
|
// Debug
|
|
13
13
|
// RaftLog.info(`StateInfoGeneric: updateFromMsg: rxMsg: ${rxMsg} frameTimeMs: ${frameTimeMs}`);
|
|
14
14
|
|
|
15
|
-
//
|
|
16
|
-
|
|
17
|
-
|
|
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));
|
|
18
23
|
|
|
19
|
-
|
|
20
|
-
|
|
24
|
+
// Handle using device manager
|
|
25
|
+
this._deviceManager.handleClientMsgJson(jsonString);
|
|
26
|
+
}
|
|
21
27
|
return [];
|
|
22
28
|
|
|
23
29
|
}
|