@robdobsn/raftjs 1.5.0 → 1.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/react-native/RaftAttributeHandler.js +6 -1
  2. package/dist/react-native/RaftAttributeHandler.js.map +1 -1
  3. package/dist/react-native/RaftChannelBLE.native.js +1 -1
  4. package/dist/react-native/RaftChannelBLE.native.js.map +1 -1
  5. package/dist/react-native/RaftDeviceManager.d.ts +12 -7
  6. package/dist/react-native/RaftDeviceManager.js +152 -35
  7. package/dist/react-native/RaftDeviceManager.js.map +1 -1
  8. package/dist/react-native/RaftDeviceMgrIF.d.ts +7 -3
  9. package/dist/react-native/RaftDeviceStates.d.ts +5 -1
  10. package/dist/react-native/RaftDeviceStates.js +2 -2
  11. package/dist/react-native/RaftDeviceStates.js.map +1 -1
  12. package/dist/web/RaftAttributeHandler.js +6 -1
  13. package/dist/web/RaftAttributeHandler.js.map +1 -1
  14. package/dist/web/RaftDeviceManager.d.ts +12 -7
  15. package/dist/web/RaftDeviceManager.js +152 -35
  16. package/dist/web/RaftDeviceManager.js.map +1 -1
  17. package/dist/web/RaftDeviceMgrIF.d.ts +7 -3
  18. package/dist/web/RaftDeviceStates.d.ts +5 -1
  19. package/dist/web/RaftDeviceStates.js +2 -2
  20. package/dist/web/RaftDeviceStates.js.map +1 -1
  21. package/examples/dashboard/package.json +3 -2
  22. package/examples/dashboard/src/ConnManager.ts +5 -1
  23. package/examples/dashboard/src/DeviceLineChart.tsx +40 -20
  24. package/examples/dashboard/src/DevicePanel.tsx +33 -2
  25. package/examples/dashboard/src/DevicesPanel.tsx +5 -4
  26. package/examples/dashboard/src/LatencyTest.ts +119 -0
  27. package/examples/dashboard/src/LatencyTestPanel.tsx +81 -0
  28. package/examples/dashboard/src/Main.tsx +180 -76
  29. package/examples/dashboard/src/SettingsManager.ts +65 -0
  30. package/examples/dashboard/src/SettingsScreen.tsx +125 -0
  31. package/examples/dashboard/src/SystemTypeCog/CogStateInfo.ts +13 -8
  32. package/examples/dashboard/src/SystemTypeCog/SystemTypeCog.ts +9 -5
  33. package/examples/dashboard/src/SystemTypeGeneric/StateInfoGeneric.ts +12 -6
  34. package/examples/dashboard/src/SystemTypeGeneric/SystemTypeGeneric.ts +9 -5
  35. package/examples/dashboard/src/SystemTypeMarty/RICStateInfo.ts +23 -4
  36. package/examples/dashboard/src/SystemTypeMarty/SystemTypeMarty.ts +1 -1
  37. package/examples/dashboard/src/styles.css +14 -0
  38. package/package.json +3 -3
  39. package/src/RaftAttributeHandler.ts +7 -1
  40. package/src/RaftChannelBLE.native.ts +1 -1
  41. package/src/RaftDeviceManager.ts +179 -44
  42. package/src/RaftDeviceMgrIF.ts +9 -3
  43. package/src/RaftDeviceStates.ts +6 -2
  44. package/src/RaftTypes.ts +1 -1
@@ -0,0 +1,125 @@
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
+
24
+ const handleSaveAndReturn = () => {
25
+ // Save settings to SettingsManager
26
+ settingsManager.setSetting('latencyTest', latencyTest);
27
+ settingsManager.setSetting('showCharts', showCharts);
28
+ settingsManager.setSetting('maxChartDataPoints', maxChartDataPoints);
29
+ settingsManager.setSetting('maxDatapointsToStore', maxDatapointsToStore);
30
+
31
+ // Log and update maxDatapointsToStore in DeviceManager
32
+ console.log(
33
+ `Set maxDatapointsToStore to ${maxDatapointsToStore} ` +
34
+ `${connManager.getConnector().getSystemType()} ` +
35
+ `${connManager.getConnector().getSystemType()?.deviceMgrIF}` +
36
+ `${connManager.getConnector().getSystemType()?.deviceMgrIF?.setMaxDataPointsToStore}`
37
+ );
38
+
39
+ connManager.getConnector().getSystemType()?.deviceMgrIF?.setMaxDataPointsToStore(maxDatapointsToStore);
40
+
41
+ // Call the onBack function
42
+ onBack();
43
+ };
44
+
45
+ return (
46
+ <div className="content-outer">
47
+ <div className="header">
48
+ <h1>RaftJS Dashboard Settings</h1>
49
+ </div>
50
+ <div className="content-body">
51
+ <div className="info-boxes">
52
+ <div className="info-box">
53
+
54
+ <div className="settings-item">
55
+ <label>
56
+ <input
57
+ type="checkbox"
58
+ checked={latencyTest}
59
+ onChange={(e) => setLatencyTest(e.target.checked)}
60
+ />
61
+ Latency Test
62
+ </label>
63
+ </div>
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) => setMaxChartDataPoints(Math.min(parseInt(e.target.value, 10) || 1, 500))}
85
+ style={{ width: '50px', marginLeft: '10px' }}
86
+ />
87
+ </label>
88
+ </div>
89
+
90
+ <div className="settings-item">
91
+ <label>
92
+ Max Stored Points
93
+ <input
94
+ type="number"
95
+ min="1"
96
+ max="100000"
97
+ value={maxDatapointsToStore}
98
+ onChange={(e) => setMaxDatapointsToStore(Math.min(parseInt(e.target.value, 10) || 1, 100000))}
99
+ style={{ width: '50px', marginLeft: '10px' }}
100
+ />
101
+ </label>
102
+ </div>
103
+
104
+ <button className="action-button" onClick={handleSaveAndReturn}>
105
+ Save and Return
106
+ </button>
107
+
108
+ <button
109
+ className="action-button"
110
+ style={{ marginTop: '10px' }}
111
+ onClick={() => {
112
+ settingsManager.resetSettings();
113
+ window.location.reload();
114
+ }}
115
+ >
116
+ Reset to Defaults
117
+ </button>
118
+ </div>
119
+ </div>
120
+ </div>
121
+ </div>
122
+ );
123
+ };
124
+
125
+ 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
- // 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
-
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":"devjson","rateHz":0,}` +
48
+ `{"name":"${topic}","rateHz":0,}` +
46
49
  ']}';
47
50
  const subscribeEnable = '{"cmdName":"subscription","action":"update",' +
48
51
  '"pubRecs":[' +
49
- `{"name":"devjson","trigger":"timeorchange","rateHz":${subscribeRateHz.toString()}}` +
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 ${RICUtils.bufferToHex(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
- // Convert Uint8Array to string
16
- const decoder = new TextDecoder('utf-8');
17
- const jsonString = decoder.decode(rxMsg.slice(2));
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
- // Handle using device manager
20
- this._deviceManager.handleClientMsgJson(jsonString);
24
+ // Handle using device manager
25
+ this._deviceManager.handleClientMsgJson(jsonString);
26
+ }
21
27
  return [];
22
28
 
23
29
  }
@@ -3,6 +3,8 @@ import { RaftEventFn, RaftLog, RaftOKFail, RaftPublishEvent, RaftPublishEventNam
3
3
  import { StateInfoGeneric } from "./StateInfoGeneric";
4
4
  import { DeviceManager } from "../../../../src/RaftDeviceManager";
5
5
 
6
+ const SUBSCRIBE_BINARY_MSGS = false;
7
+
6
8
  export default class SystemTypeGeneric implements RaftSystemType {
7
9
  nameForDialogs = "Generic System";
8
10
  defaultWiFiHostname = "Generic";
@@ -40,13 +42,14 @@ export default class SystemTypeGeneric implements RaftSystemType {
40
42
  // Subscription rate
41
43
  const subscribeRateHz = 0.1;
42
44
  try {
45
+ const topic = SUBSCRIBE_BINARY_MSGS ? "devbin" : "devjson";
43
46
  const subscribeDisable = '{"cmdName":"subscription","action":"update",' +
44
47
  '"pubRecs":[' +
45
- `{"name":"devjson","rateHz":0,}` +
48
+ `{"name":"${topic}","rateHz":0,}` +
46
49
  ']}';
47
50
  const subscribeEnable = '{"cmdName":"subscription","action":"update",' +
48
51
  '"pubRecs":[' +
49
- `{"name":"devjson","trigger":"timeorchange","rateHz":${subscribeRateHz.toString()}}` +
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 SystemTypeGeneric implements RaftSystemType {
67
70
  // Other message type
68
71
  rxOtherMsgType(payload: Uint8Array, frameTimeMs: number) {
69
72
 
70
- // RICLog.debug(`rxOtherMsgType payload ${RICUtils.bufferToHex(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 SystemTypeGeneric 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
  };
@@ -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
 
@@ -98,7 +98,7 @@ export default class SystemTypeMarty implements RaftSystemType {
98
98
 
99
99
  // Other message type
100
100
  rxOtherMsgType(payload: Uint8Array, frameTimeMs: number) {
101
- // RICLog.debug(`onRxROSSerialMsg payload ${RICUtils.bufferToHex(payload)}`);
101
+ // RICLog.debug(`onRxROSSerialMsg payload ${RaftUtils.bufferToHex(payload)}`);
102
102
  RaftLog.verbose(`onRxROSSerialMsg payloadLen ${payload.length}`);
103
103
  const topicIDs = this._ricStateInfo.updateFromROSSerialMsg(payload, this._commsStats, this._addOnManager, frameTimeMs);
104
104
 
@@ -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": "@robdobsn/raftjs",
3
- "version": "1.5.0",
3
+ "version": "1.5.5",
4
4
  "description": "Javascript/TS library for Raft library",
5
5
  "main": "dist/web/main.js",
6
6
  "types": "dist/web/main.d.ts",
@@ -36,12 +36,12 @@
36
36
  "@typescript-eslint/eslint-plugin": "^8.6.0",
37
37
  "eslint": "^9.4.0",
38
38
  "react-native-ble-plx": "^3.2.0",
39
- "typescript": "^5.4.5"
39
+ "typescript": "^5.4.5",
40
+ "text-encoding": "^0.7.0"
40
41
  },
41
42
  "dependencies": {
42
43
  "@types/text-encoding": "^0.0.39",
43
44
  "isomorphic-ws": "^5.0.0",
44
- "text-encoding": "^0.7.0",
45
45
  "tslib": "^2.6.2"
46
46
  },
47
47
  "peerDependencies": {
@@ -103,7 +103,8 @@ export default class AttributeHandler {
103
103
  devAttrsState[attrDef.n] = {
104
104
  name: attrDef.n,
105
105
  newAttribute: true,
106
- newData: true,
106
+ newData: false,
107
+ numNewValues: 0,
107
108
  values: [],
108
109
  units: decodeAttrUnitsEncoding(attrDef.u || ""),
109
110
  range: attrDef.r || [0, 0],
@@ -122,6 +123,7 @@ export default class AttributeHandler {
122
123
  // Add the new values
123
124
  devAttrsState[attrDef.n].values.push(...newAttrValues[attrIdx]);
124
125
  devAttrsState[attrDef.n].newData = newAttrValues[attrIdx].length > 0;
126
+ devAttrsState[attrDef.n].numNewValues = newAttrValues[attrIdx].length;
125
127
  }
126
128
 
127
129
  // Handle the timestamps with increments if specified
@@ -239,6 +241,10 @@ export default class AttributeHandler {
239
241
  // Move buffer position if using relative positioning
240
242
  msgBufIdx += attrUsesAbsPos ? 0 : numBytesConsumed;
241
243
 
244
+ // if (attrDef.n === "amb0") {
245
+ // console.log(`${new Date().toISOString()} ${attrDef.n} ${attrValues}`);
246
+ // }
247
+
242
248
  // Return the value
243
249
  return { values: attrValues, newMsgBufIdx: msgBufIdx };
244
250
  }
@@ -474,7 +474,7 @@ export default class RaftChannelPhoneBLE implements RaftChannel {
474
474
  const rxFrame = RaftUtils.atob(msgFrameBase64!);
475
475
 
476
476
  // Debug
477
- // RaftLog.debug('_onMsgRx from BLE ' + RICUtils.bufferToHex(rxFrame));
477
+ // RaftLog.debug('_onMsgRx from BLE ' + RaftUtils.bufferToHex(rxFrame));
478
478
 
479
479
  // Send
480
480
  if (rxFrame !== null && this._raftMsgHandler) {