@robotical/raftjs 2.0.11 → 2.1.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.
- package/dist/react-native/RaftChannelSimulated.js +1 -1
- package/dist/react-native/RaftChannelSimulated.js.map +1 -1
- package/dist/react-native/RaftChannelWebSerial.js +1 -1
- package/dist/react-native/RaftChannelWebSerial.js.map +1 -1
- package/dist/react-native/RaftDeviceManager.d.ts +18 -0
- package/dist/react-native/RaftDeviceManager.js +82 -1
- package/dist/react-native/RaftDeviceManager.js.map +1 -1
- package/dist/react-native/main.d.ts +1 -0
- package/dist/react-native/main.js.map +1 -1
- package/dist/web/RaftChannelSimulated.js +1 -1
- package/dist/web/RaftChannelSimulated.js.map +1 -1
- package/dist/web/RaftChannelWebSerial.js +1 -1
- package/dist/web/RaftChannelWebSerial.js.map +1 -1
- package/dist/web/RaftDeviceManager.d.ts +18 -0
- package/dist/web/RaftDeviceManager.js +82 -1
- package/dist/web/RaftDeviceManager.js.map +1 -1
- package/dist/web/main.d.ts +1 -0
- package/dist/web/main.js.map +1 -1
- package/package.json +1 -1
- package/src/RaftChannelSimulated.ts +1 -1
- package/src/RaftChannelWebSerial.ts +1 -1
- package/src/RaftDeviceManager.ts +125 -1
- package/src/main.ts +1 -0
package/src/RaftDeviceManager.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
//
|
|
8
8
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
9
9
|
|
|
10
|
-
import { DeviceAttributeState, DevicesState, DeviceState, getDeviceKey } from "./RaftDeviceStates";
|
|
10
|
+
import { DeviceAttributeState, DeviceAttributesState, DevicesState, DeviceState, getDeviceKey } from "./RaftDeviceStates";
|
|
11
11
|
import { DeviceMsgJson } from "./RaftDeviceMsg";
|
|
12
12
|
import { RaftOKFail } from './RaftTypes';
|
|
13
13
|
import { DeviceTypeInfo, DeviceTypeAction, DeviceTypeInfoRecs, RaftDevTypeInfoResponse } from "./RaftDeviceInfo";
|
|
@@ -17,6 +17,18 @@ import RaftDeviceMgrIF from "./RaftDeviceMgrIF";
|
|
|
17
17
|
import { structPack } from "./RaftStruct";
|
|
18
18
|
// import RaftUtils from "./RaftUtils";
|
|
19
19
|
|
|
20
|
+
export interface DeviceDecodedData {
|
|
21
|
+
deviceKey: string;
|
|
22
|
+
busName: string;
|
|
23
|
+
deviceAddress: string;
|
|
24
|
+
deviceType: string;
|
|
25
|
+
attrGroupName?: string;
|
|
26
|
+
attrValues: Record<string, number[]>;
|
|
27
|
+
timestampsUs: number[];
|
|
28
|
+
markers?: Record<string, unknown>;
|
|
29
|
+
fromOfflineBuffer?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
20
32
|
export class DeviceManager implements RaftDeviceMgrIF{
|
|
21
33
|
|
|
22
34
|
// Max data points to store
|
|
@@ -45,6 +57,7 @@ export class DeviceManager implements RaftDeviceMgrIF{
|
|
|
45
57
|
private _newDeviceCallbacks: Array<(deviceKey: string, state: DeviceState) => void> = [];
|
|
46
58
|
private _newDeviceAttributeCallbacks: Array<(deviceKey: string, attrState: DeviceAttributeState) => void> = [];
|
|
47
59
|
private _newAttributeDataCallbacks: Array<(deviceKey: string, attrState: DeviceAttributeState) => void> = [];
|
|
60
|
+
private _decodedDataCallbacks: Array<(decoded: DeviceDecodedData) => void> = [];
|
|
48
61
|
|
|
49
62
|
// Debug message index (to help debug with async messages)
|
|
50
63
|
private _debugMsgIndex = 0;
|
|
@@ -146,6 +159,16 @@ export class DeviceManager implements RaftDeviceMgrIF{
|
|
|
146
159
|
this._newAttributeDataCallbacks = this._newAttributeDataCallbacks.filter((cb) => cb !== callback);
|
|
147
160
|
}
|
|
148
161
|
|
|
162
|
+
public addDecodedDataCallback(callback: (decoded: DeviceDecodedData) => void): void {
|
|
163
|
+
if (!this._decodedDataCallbacks.includes(callback)) {
|
|
164
|
+
this._decodedDataCallbacks.push(callback);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
public removeDecodedDataCallback(callback: (decoded: DeviceDecodedData) => void): void {
|
|
169
|
+
this._decodedDataCallbacks = this._decodedDataCallbacks.filter((cb) => cb !== callback);
|
|
170
|
+
}
|
|
171
|
+
|
|
149
172
|
////////////////////////////////////////////////////////////////////////////
|
|
150
173
|
// Set the friendly name for the device
|
|
151
174
|
////////////////////////////////////////////////////////////////////////////
|
|
@@ -293,6 +316,8 @@ export class DeviceManager implements RaftDeviceMgrIF{
|
|
|
293
316
|
// Iterate over attribute groups
|
|
294
317
|
const attrGroupDataLen = sectionLen - sectionHeaderLen;
|
|
295
318
|
const attrGroupStartPos = attrGroupPos;
|
|
319
|
+
const attrLengthsBefore = this.snapshotAttrLengths(deviceState.deviceAttributes, pollRespMetadata);
|
|
320
|
+
const timelineLenBefore = deviceState.deviceTimeline.timestampsUs.length;
|
|
296
321
|
while (attrGroupPos < attrGroupStartPos + attrGroupDataLen) {
|
|
297
322
|
|
|
298
323
|
// Add bounds checking
|
|
@@ -328,6 +353,10 @@ export class DeviceManager implements RaftDeviceMgrIF{
|
|
|
328
353
|
|
|
329
354
|
// console.log(`DevMan.handleClientMsgBinary group done debugIdx ${debugMsgIndex} attrGroupPos ${attrGroupPos} sectionLen ${sectionLen} msgPos ${msgPos} rxMsgLen ${rxMsg.length} remainingLen ${remainingLen}`);
|
|
330
355
|
}
|
|
356
|
+
|
|
357
|
+
// Inform decoded-data callbacks
|
|
358
|
+
this.emitDecodedData(deviceKey, busNum.toString(), devAddr.toString(), deviceState,
|
|
359
|
+
pollRespMetadata, attrLengthsBefore, timelineLenBefore);
|
|
331
360
|
} else {
|
|
332
361
|
console.warn(`DevMan.handleClientMsgBinary debugIdx ${debugMsgIndex} deviceState incomplete for device ${deviceKey}, skipping attribute processing`);
|
|
333
362
|
}
|
|
@@ -441,6 +470,8 @@ export class DeviceManager implements RaftDeviceMgrIF{
|
|
|
441
470
|
return;
|
|
442
471
|
}
|
|
443
472
|
|
|
473
|
+
const markers = this.extractMarkers(attrGroups);
|
|
474
|
+
|
|
444
475
|
// Iterate attribute groups
|
|
445
476
|
Object.entries(attrGroups).forEach(([attrGroupName, msgHexStr]) => {
|
|
446
477
|
|
|
@@ -463,6 +494,9 @@ export class DeviceManager implements RaftDeviceMgrIF{
|
|
|
463
494
|
// Iterate over attributes in the group
|
|
464
495
|
const pollRespMetadata = deviceState.deviceTypeInfo!.resp!;
|
|
465
496
|
|
|
497
|
+
const attrLengthsBefore = this.snapshotAttrLengths(deviceState.deviceAttributes, pollRespMetadata);
|
|
498
|
+
const timelineLenBefore = deviceState.deviceTimeline.timestampsUs.length;
|
|
499
|
+
|
|
466
500
|
// Loop
|
|
467
501
|
while (msgBufIdx < msgBytes.length) {
|
|
468
502
|
|
|
@@ -475,6 +509,9 @@ export class DeviceManager implements RaftDeviceMgrIF{
|
|
|
475
509
|
msgBufIdx = newMsgBufIdx;
|
|
476
510
|
deviceState.stateChanged = true;
|
|
477
511
|
}
|
|
512
|
+
|
|
513
|
+
this.emitDecodedData(deviceKey, busName, devAddr, deviceState, pollRespMetadata,
|
|
514
|
+
attrLengthsBefore, timelineLenBefore, attrGroupName, markers);
|
|
478
515
|
});
|
|
479
516
|
});
|
|
480
517
|
});
|
|
@@ -712,4 +749,91 @@ export class DeviceManager implements RaftDeviceMgrIF{
|
|
|
712
749
|
}
|
|
713
750
|
return bytes;
|
|
714
751
|
}
|
|
752
|
+
|
|
753
|
+
////////////////////////////////////////////////////////////////////////////
|
|
754
|
+
// Helpers for decoded data callbacks
|
|
755
|
+
////////////////////////////////////////////////////////////////////////////
|
|
756
|
+
|
|
757
|
+
private snapshotAttrLengths(deviceAttrs: DeviceAttributesState, pollRespMetadata: DeviceTypeInfo["resp"]): Record<string, number> {
|
|
758
|
+
const lengths: Record<string, number> = {};
|
|
759
|
+
if (!pollRespMetadata) {
|
|
760
|
+
return lengths;
|
|
761
|
+
}
|
|
762
|
+
pollRespMetadata.a.forEach((attr) => {
|
|
763
|
+
lengths[attr.n] = deviceAttrs[attr.n]?.values.length || 0;
|
|
764
|
+
});
|
|
765
|
+
return lengths;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
private emitDecodedData(
|
|
769
|
+
deviceKey: string,
|
|
770
|
+
busName: string,
|
|
771
|
+
devAddr: string,
|
|
772
|
+
deviceState: DeviceState,
|
|
773
|
+
pollRespMetadata: DeviceTypeInfo["resp"],
|
|
774
|
+
attrLengthsBefore: Record<string, number>,
|
|
775
|
+
timelineLenBefore: number,
|
|
776
|
+
attrGroupName = "",
|
|
777
|
+
markers?: Record<string, unknown>,
|
|
778
|
+
): void {
|
|
779
|
+
|
|
780
|
+
if (!pollRespMetadata) {
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
const attrValues: Record<string, number[]> = {};
|
|
785
|
+
let hasValues = false;
|
|
786
|
+
|
|
787
|
+
pollRespMetadata.a.forEach((attr) => {
|
|
788
|
+
const attrState = deviceState.deviceAttributes[attr.n];
|
|
789
|
+
if (!attrState) {
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
const prevLen = attrLengthsBefore[attr.n] || 0;
|
|
793
|
+
if (attrState.values.length > prevLen) {
|
|
794
|
+
attrValues[attr.n] = attrState.values.slice(prevLen);
|
|
795
|
+
hasValues = hasValues || attrValues[attr.n].length > 0;
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
if (!hasValues) {
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
const timestampsUs = deviceState.deviceTimeline.timestampsUs.slice(timelineLenBefore);
|
|
804
|
+
|
|
805
|
+
const decoded: DeviceDecodedData = {
|
|
806
|
+
deviceKey,
|
|
807
|
+
busName,
|
|
808
|
+
deviceAddress: devAddr,
|
|
809
|
+
deviceType: deviceState.deviceType,
|
|
810
|
+
attrGroupName: attrGroupName || undefined,
|
|
811
|
+
attrValues,
|
|
812
|
+
timestampsUs,
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
if (markers && Object.keys(markers).length > 0) {
|
|
816
|
+
decoded.markers = markers;
|
|
817
|
+
decoded.fromOfflineBuffer = this.isTruthy(markers["_buf"]);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
this._decodedDataCallbacks.forEach((cb) => cb(decoded));
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
private extractMarkers(attrGroups: any): Record<string, unknown> {
|
|
824
|
+
const markers: Record<string, unknown> = {};
|
|
825
|
+
if (!attrGroups || typeof attrGroups !== "object") {
|
|
826
|
+
return markers;
|
|
827
|
+
}
|
|
828
|
+
Object.entries(attrGroups).forEach(([key, value]) => {
|
|
829
|
+
if (key.startsWith("_") && key !== "_t" && key !== "_o") {
|
|
830
|
+
markers[key] = value;
|
|
831
|
+
}
|
|
832
|
+
});
|
|
833
|
+
return markers;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
private isTruthy(val: unknown): boolean {
|
|
837
|
+
return val === true || val === 1 || val === "1";
|
|
838
|
+
}
|
|
715
839
|
}
|
package/src/main.ts
CHANGED
|
@@ -27,6 +27,7 @@ export { default as RaftUtils } from './RaftUtils';
|
|
|
27
27
|
export { default as RaftSysTypeManager } from './RaftSysTypeManager';
|
|
28
28
|
export { default as RaftDeviceMgrIF } from './RaftDeviceMgrIF';
|
|
29
29
|
export { DeviceManager as RaftDeviceManager } from './RaftDeviceManager';
|
|
30
|
+
export type { DeviceDecodedData } from './RaftDeviceManager';
|
|
30
31
|
|
|
31
32
|
export * from './RaftTypes';
|
|
32
33
|
export * from './RaftSystemType';
|