@robotical/raftjs 2.0.4 → 2.0.6
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.d.ts +10 -0
- package/dist/react-native/RaftChannelSimulated.js +327 -79
- package/dist/react-native/RaftChannelSimulated.js.map +1 -1
- package/dist/react-native/RaftCustomAttrHandler.d.ts +2 -0
- package/dist/react-native/RaftCustomAttrHandler.js +54 -26
- package/dist/react-native/RaftCustomAttrHandler.js.map +1 -1
- package/dist/react-native/RaftDeviceInfo.d.ts +2 -0
- package/dist/web/RaftChannelSimulated.d.ts +10 -0
- package/dist/web/RaftChannelSimulated.js +327 -79
- package/dist/web/RaftChannelSimulated.js.map +1 -1
- package/dist/web/RaftCustomAttrHandler.d.ts +2 -0
- package/dist/web/RaftCustomAttrHandler.js +54 -26
- package/dist/web/RaftCustomAttrHandler.js.map +1 -1
- package/dist/web/RaftDeviceInfo.d.ts +2 -0
- package/package.json +1 -1
- package/src/RaftChannelSimulated.ts +413 -79
- package/src/RaftCustomAttrHandler.ts +81 -35
- package/src/RaftDeviceInfo.ts +2 -0
|
@@ -7,23 +7,32 @@
|
|
|
7
7
|
//
|
|
8
8
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
9
9
|
|
|
10
|
-
import { DeviceTypePollRespMetadata } from "./RaftDeviceInfo";
|
|
10
|
+
import { CustomFunctionDefinition, DeviceTypePollRespMetadata } from "./RaftDeviceInfo";
|
|
11
|
+
|
|
12
|
+
type CustomAttrJsFn = (
|
|
13
|
+
buf: Uint8Array,
|
|
14
|
+
attrValues: Record<string, number[]>,
|
|
15
|
+
attrValueVecs: number[][],
|
|
16
|
+
pollRespMetadata: DeviceTypePollRespMetadata,
|
|
17
|
+
msgBuffer: Uint8Array,
|
|
18
|
+
msgBufIdx: number,
|
|
19
|
+
numMsgBytes: number
|
|
20
|
+
) => void;
|
|
11
21
|
|
|
12
22
|
export default class CustomAttrHandler {
|
|
23
|
+
|
|
24
|
+
private _jsFunctionCache = new Map<string, CustomAttrJsFn>();
|
|
13
25
|
|
|
14
26
|
public handleAttr(pollRespMetadata: DeviceTypePollRespMetadata, msgBuffer: Uint8Array, msgBufIdx: number): number[][] {
|
|
15
27
|
|
|
16
|
-
//
|
|
17
|
-
// int N=(buf[0]+32-buf[2])%32;int k=3;int i=0;while(i<N){out.Red=(buf[k]<<16)|(buf[k+1]<<8)|buf[k+2];out.IR=(buf[k+3]<<16)|(buf[k+4]<<8)|buf[k+5];k+=6;i++;next;}
|
|
18
|
-
|
|
19
|
-
// Number of bytes in the each message
|
|
28
|
+
// Number of bytes in each message
|
|
20
29
|
const numMsgBytes = pollRespMetadata.b;
|
|
21
30
|
|
|
22
31
|
// Create a vector for each attribute in the metadata
|
|
23
|
-
const attrValueVecs: [][] = [];
|
|
32
|
+
const attrValueVecs: number[][] = [];
|
|
24
33
|
|
|
25
34
|
// Reference to each vector by attribute name
|
|
26
|
-
const attrValues:
|
|
35
|
+
const attrValues: Record<string, number[]> = {};
|
|
27
36
|
|
|
28
37
|
// Add attributes to the vector
|
|
29
38
|
for (let attrIdx = 0; attrIdx < pollRespMetadata.a.length; attrIdx++) {
|
|
@@ -31,41 +40,78 @@ export default class CustomAttrHandler {
|
|
|
31
40
|
attrValues[pollRespMetadata.a[attrIdx].n] = attrValueVecs[attrIdx];
|
|
32
41
|
}
|
|
33
42
|
|
|
34
|
-
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
const customFnDef = pollRespMetadata.c;
|
|
44
|
+
if (!customFnDef) {
|
|
45
|
+
return attrValueVecs;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Provide the message buffer sliced to the data portion
|
|
49
|
+
const buf = msgBuffer.slice(msgBufIdx);
|
|
50
|
+
if (buf.length < numMsgBytes) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Execute supplied JS implementation if provided
|
|
55
|
+
if (customFnDef.j && customFnDef.j.trim().length > 0) {
|
|
56
|
+
const jsFn = this.getOrCompileJsFunction(customFnDef);
|
|
57
|
+
if (!jsFn) {
|
|
58
|
+
return attrValueVecs;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
jsFn(buf, attrValues, attrValueVecs, pollRespMetadata, msgBuffer, msgBufIdx, numMsgBytes);
|
|
62
|
+
} catch (err) {
|
|
63
|
+
console.error(`CustomAttrHandler JS function ${customFnDef.n} execution failed`, err);
|
|
41
64
|
}
|
|
65
|
+
return attrValueVecs;
|
|
66
|
+
}
|
|
42
67
|
|
|
68
|
+
// Custom code for each device type handled natively
|
|
69
|
+
if (customFnDef.n === "max30101_fifo") {
|
|
43
70
|
// Generated code ...
|
|
44
|
-
const N=(buf[0]+32-buf[2])%32;
|
|
45
|
-
let k=3;
|
|
46
|
-
let i=0;
|
|
47
|
-
while (i<N) {
|
|
48
|
-
attrValues[
|
|
49
|
-
attrValues[
|
|
50
|
-
|
|
71
|
+
const N = (buf[0] + 32 - buf[2]) % 32;
|
|
72
|
+
let k = 3;
|
|
73
|
+
let i = 0;
|
|
74
|
+
while (i < N) {
|
|
75
|
+
attrValues["Red"].push(0);
|
|
76
|
+
attrValues["Red"][attrValues["Red"].length - 1] = (buf[k] << 16) | (buf[k + 1] << 8) | buf[k + 2];
|
|
77
|
+
attrValues["IR"].push(0);
|
|
78
|
+
attrValues["IR"][attrValues["IR"].length - 1] = (buf[k + 3] << 16) | (buf[k + 4] << 8) | buf[k + 5];
|
|
79
|
+
k += 6;
|
|
51
80
|
i++;
|
|
52
|
-
;
|
|
53
|
-
}
|
|
54
|
-
} else if (pollRespMetadata.c!.n === "gravity_o2_calc") {
|
|
55
|
-
// Get the buffer
|
|
56
|
-
const buf = msgBuffer.slice(msgBufIdx);
|
|
57
|
-
if (buf.length < numMsgBytes) {
|
|
58
|
-
return [];
|
|
59
81
|
}
|
|
60
|
-
|
|
61
|
-
// Implement the pseudo-code:
|
|
62
|
-
// float key = 20.9/120.0; float val = key * (buf[0] + (buf[1]/10.0) + (buf[2]/100.0)); out.oxygen = val;
|
|
82
|
+
} else if (customFnDef.n === "gravity_o2_calc") {
|
|
63
83
|
const key = 20.9 / 120.0;
|
|
64
|
-
const val = key * (buf[0] +
|
|
65
|
-
|
|
66
|
-
// Add the value to the oxygen attribute
|
|
67
|
-
attrValues['oxygen'].push(val);
|
|
84
|
+
const val = key * (buf[0] + buf[1] / 10.0 + buf[2] / 100.0);
|
|
85
|
+
attrValues["oxygen"].push(val);
|
|
68
86
|
}
|
|
69
87
|
return attrValueVecs;
|
|
70
88
|
}
|
|
89
|
+
|
|
90
|
+
private getOrCompileJsFunction(customFnDef: CustomFunctionDefinition): CustomAttrJsFn | null {
|
|
91
|
+
if (!customFnDef.j) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const cacheKey = `${customFnDef.n}::${customFnDef.j}`;
|
|
95
|
+
const cachedFn = this._jsFunctionCache.get(cacheKey);
|
|
96
|
+
if (cachedFn) {
|
|
97
|
+
return cachedFn;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const compiledFn = new Function(
|
|
101
|
+
"buf",
|
|
102
|
+
"attrValues",
|
|
103
|
+
"attrValueVecs",
|
|
104
|
+
"pollRespMetadata",
|
|
105
|
+
"msgBuffer",
|
|
106
|
+
"msgBufIdx",
|
|
107
|
+
"numMsgBytes",
|
|
108
|
+
customFnDef.j
|
|
109
|
+
) as CustomAttrJsFn;
|
|
110
|
+
this._jsFunctionCache.set(cacheKey, compiledFn);
|
|
111
|
+
return compiledFn;
|
|
112
|
+
} catch (err) {
|
|
113
|
+
console.error(`CustomAttrHandler failed to compile JS function ${customFnDef.n}`, err);
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
71
117
|
}
|
package/src/RaftDeviceInfo.ts
CHANGED
|
@@ -73,11 +73,13 @@ export interface DeviceTypeAttribute {
|
|
|
73
73
|
vf?: boolean | number; // Display attribute value in the device info panel
|
|
74
74
|
vft?: string; // Attribute validity based on the value of another named attribute
|
|
75
75
|
lut?: Array<LUTRow>; // Lookup table for the attribute value - each row is a lookup table for a range of values e.g. [{"r":"0x20-0x30","v":0},{"r":"1,2,3","v":42},{r:"","v":1}]
|
|
76
|
+
resolution?: string;
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
export interface CustomFunctionDefinition {
|
|
79
80
|
n: string; // Function name
|
|
80
81
|
c: string; // Function pseudo-code
|
|
82
|
+
j?: string; // Optional JavaScript implementation
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
export interface DeviceTypePollRespMetadata {
|