@wms-js/lib 0.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/LICENSE +21 -0
- package/README.md +16 -0
- package/dist/command/ack-match.d.ts +5 -0
- package/dist/command/ack-match.js +9 -0
- package/dist/command/ack-match.js.map +1 -0
- package/dist/command/session.d.ts +23 -0
- package/dist/command/session.js +98 -0
- package/dist/command/session.js.map +1 -0
- package/dist/command/types.d.ts +14 -0
- package/dist/command/types.js +2 -0
- package/dist/command/types.js.map +1 -0
- package/dist/commands/name.d.ts +25 -0
- package/dist/commands/name.js +209 -0
- package/dist/commands/name.js.map +1 -0
- package/dist/controller.d.ts +26 -0
- package/dist/controller.js +108 -0
- package/dist/controller.js.map +1 -0
- package/dist/frame/errors.d.ts +4 -0
- package/dist/frame/errors.js +9 -0
- package/dist/frame/errors.js.map +1 -0
- package/dist/frame/parser.d.ts +13 -0
- package/dist/frame/parser.js +69 -0
- package/dist/frame/parser.js.map +1 -0
- package/dist/frame/serializer.d.ts +1 -0
- package/dist/frame/serializer.js +5 -0
- package/dist/frame/serializer.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/logger.d.ts +15 -0
- package/dist/logging/logger.js +60 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/network/events.d.ts +6 -0
- package/dist/network/events.js +24 -0
- package/dist/network/events.js.map +1 -0
- package/dist/network/manager.d.ts +36 -0
- package/dist/network/manager.js +281 -0
- package/dist/network/manager.js.map +1 -0
- package/dist/network/types.d.ts +35 -0
- package/dist/network/types.js +2 -0
- package/dist/network/types.js.map +1 -0
- package/dist/parsers/device-scan-response.d.ts +10 -0
- package/dist/parsers/device-scan-response.js +24 -0
- package/dist/parsers/device-scan-response.js.map +1 -0
- package/dist/parsers/device-scan.d.ts +6 -0
- package/dist/parsers/device-scan.js +14 -0
- package/dist/parsers/device-scan.js.map +1 -0
- package/dist/parsers/device-status.d.ts +14 -0
- package/dist/parsers/device-status.js +23 -0
- package/dist/parsers/device-status.js.map +1 -0
- package/dist/parsers/move-response.d.ts +8 -0
- package/dist/parsers/move-response.js +16 -0
- package/dist/parsers/move-response.js.map +1 -0
- package/dist/parsers/network-join.d.ts +8 -0
- package/dist/parsers/network-join.js +29 -0
- package/dist/parsers/network-join.js.map +1 -0
- package/dist/parsers/network-params.d.ts +7 -0
- package/dist/parsers/network-params.js +19 -0
- package/dist/parsers/network-params.js.map +1 -0
- package/dist/parsers/wave-request.d.ts +5 -0
- package/dist/parsers/wave-request.js +13 -0
- package/dist/parsers/wave-request.js.map +1 -0
- package/dist/parsers/wave-response.d.ts +6 -0
- package/dist/parsers/wave-response.js +14 -0
- package/dist/parsers/wave-response.js.map +1 -0
- package/dist/parsers/weather-station.d.ts +9 -0
- package/dist/parsers/weather-station.js +30 -0
- package/dist/parsers/weather-station.js.map +1 -0
- package/dist/routing/broadcast-router.d.ts +9 -0
- package/dist/routing/broadcast-router.js +40 -0
- package/dist/routing/broadcast-router.js.map +1 -0
- package/dist/serial/driver.d.ts +8 -0
- package/dist/serial/driver.js +2 -0
- package/dist/serial/driver.js.map +1 -0
- package/dist/testing/mock-serial.d.ts +22 -0
- package/dist/testing/mock-serial.js +62 -0
- package/dist/testing/mock-serial.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare function getDeviceTypeName(code: string): string;
|
|
2
|
+
export interface DeviceScanResponse {
|
|
3
|
+
serialNumber: string;
|
|
4
|
+
panId: string;
|
|
5
|
+
deviceType: string;
|
|
6
|
+
deviceTypeName: string;
|
|
7
|
+
unknown: string;
|
|
8
|
+
raw: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function deviceScanResponseMatcher(frame: string): DeviceScanResponse | null;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const DEVICE_TYPE_NAMES = {
|
|
2
|
+
"25": "Shade",
|
|
3
|
+
};
|
|
4
|
+
export function getDeviceTypeName(code) {
|
|
5
|
+
return DEVICE_TYPE_NAMES[code] ?? "Unknown";
|
|
6
|
+
}
|
|
7
|
+
export function deviceScanResponseMatcher(frame) {
|
|
8
|
+
if (frame.length < 57)
|
|
9
|
+
return null;
|
|
10
|
+
if (frame[0] !== "r")
|
|
11
|
+
return null;
|
|
12
|
+
if (frame.slice(7, 11) !== "7021")
|
|
13
|
+
return null;
|
|
14
|
+
const deviceType = frame.slice(15, 17);
|
|
15
|
+
return {
|
|
16
|
+
serialNumber: frame.slice(1, 7),
|
|
17
|
+
panId: frame.slice(11, 15),
|
|
18
|
+
deviceType,
|
|
19
|
+
deviceTypeName: getDeviceTypeName(deviceType),
|
|
20
|
+
unknown: frame.slice(17, 57),
|
|
21
|
+
raw: frame,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=device-scan-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-scan-response.js","sourceRoot":"","sources":["../../src/parsers/device-scan-response.ts"],"names":[],"mappings":"AAAA,MAAM,iBAAiB,GAA2B;IAChD,IAAI,EAAE,OAAO;CACd,CAAA;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,iBAAiB,CAAC,IAAI,CAAC,IAAI,SAAS,CAAA;AAC7C,CAAC;AAWD,MAAM,UAAU,yBAAyB,CAAC,KAAa;IACrD,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAA;IAClC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAA;IAE9C,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACtC,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC;QAC1B,UAAU;QACV,cAAc,EAAE,iBAAiB,CAAC,UAAU,CAAC;QAC7C,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC;QAC5B,GAAG,EAAE,KAAK;KACX,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function deviceScanMatcher(frame) {
|
|
2
|
+
if (frame.length < 17)
|
|
3
|
+
return null;
|
|
4
|
+
if (frame[0] !== "r")
|
|
5
|
+
return null;
|
|
6
|
+
if (frame.slice(7, 11) !== "7020")
|
|
7
|
+
return null;
|
|
8
|
+
return {
|
|
9
|
+
serialNumber: frame.slice(1, 7),
|
|
10
|
+
panId: frame.slice(11, 15),
|
|
11
|
+
raw: frame,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=device-scan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-scan.js","sourceRoot":"","sources":["../../src/parsers/device-scan.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAA;IAClC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAA;IAE9C,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC;QAC1B,GAAG,EAAE,KAAK;KACX,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type DeviceDirection = "opening" | "closing" | "stopped";
|
|
2
|
+
export interface DeviceStatus {
|
|
3
|
+
serialNumber: string;
|
|
4
|
+
deviceType: string;
|
|
5
|
+
deviceTypeName: string;
|
|
6
|
+
position: number;
|
|
7
|
+
inclination: number;
|
|
8
|
+
valance1: number;
|
|
9
|
+
valance2: number;
|
|
10
|
+
moving: boolean;
|
|
11
|
+
direction: DeviceDirection;
|
|
12
|
+
raw: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function deviceStatusMatcher(frame: string): DeviceStatus | null;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getDeviceTypeName } from "./device-scan-response.js";
|
|
2
|
+
export function deviceStatusMatcher(frame) {
|
|
3
|
+
if (frame.length < 29)
|
|
4
|
+
return null;
|
|
5
|
+
if (frame[0] !== "r")
|
|
6
|
+
return null;
|
|
7
|
+
if (frame.slice(7, 11) !== "8011")
|
|
8
|
+
return null;
|
|
9
|
+
const deviceType = frame.slice(17, 19);
|
|
10
|
+
return {
|
|
11
|
+
serialNumber: frame.slice(1, 7),
|
|
12
|
+
deviceType,
|
|
13
|
+
deviceTypeName: getDeviceTypeName(deviceType),
|
|
14
|
+
position: Math.round(parseInt(frame.slice(19, 21), 16) / 2),
|
|
15
|
+
inclination: parseInt(frame.slice(21, 23), 16) - 127,
|
|
16
|
+
valance1: parseInt(frame.slice(23, 25), 16),
|
|
17
|
+
valance2: parseInt(frame.slice(25, 27), 16),
|
|
18
|
+
moving: frame.slice(27, 29) === "01",
|
|
19
|
+
direction: "stopped",
|
|
20
|
+
raw: frame,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=device-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-status.js","sourceRoot":"","sources":["../../src/parsers/device-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAiB7D,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAA;IAClC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAA;IAE9C,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACtC,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,UAAU;QACV,cAAc,EAAE,iBAAiB,CAAC,UAAU,CAAC;QAC7C,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;QAC3D,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG;QACpD,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI;QACpC,SAAS,EAAE,SAAS;QACpB,GAAG,EAAE,KAAK;KACX,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function moveResponseMatcher(frame) {
|
|
2
|
+
if (frame.length < 25)
|
|
3
|
+
return null;
|
|
4
|
+
if (frame[0] !== "r")
|
|
5
|
+
return null;
|
|
6
|
+
if (frame.slice(7, 11) !== "7071")
|
|
7
|
+
return null;
|
|
8
|
+
return {
|
|
9
|
+
serialNumber: frame.slice(1, 7),
|
|
10
|
+
subCommand: parseInt(frame.slice(17, 19), 16) & 0x03,
|
|
11
|
+
previousPosition: Math.round(parseInt(frame.slice(21, 23), 16) / 2),
|
|
12
|
+
previousInclination: parseInt(frame.slice(23, 25), 16) - 127,
|
|
13
|
+
raw: frame,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=move-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move-response.js","sourceRoot":"","sources":["../../src/parsers/move-response.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAA;IAClC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAA;IAE9C,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI;QACpD,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;QACnE,mBAAmB,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG;QAC5D,GAAG,EAAE,KAAK;KACX,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function networkJoinMatcher(frame) {
|
|
2
|
+
if (frame.length < 51)
|
|
3
|
+
return null;
|
|
4
|
+
if (frame[0] !== "r")
|
|
5
|
+
return null;
|
|
6
|
+
if (frame.slice(7, 11) !== "5018")
|
|
7
|
+
return null;
|
|
8
|
+
if (frame.slice(47, 49) !== "FF")
|
|
9
|
+
return null;
|
|
10
|
+
const channelHex = frame.slice(49, 51);
|
|
11
|
+
const channel = Number.parseInt(channelHex, 16);
|
|
12
|
+
if (Number.isNaN(channel) || channel < 11 || channel > 26)
|
|
13
|
+
return null;
|
|
14
|
+
return {
|
|
15
|
+
serialNumber: frame.slice(1, 7),
|
|
16
|
+
panId: frame.slice(11, 15),
|
|
17
|
+
key: decodeKey(frame.slice(15, 47)),
|
|
18
|
+
channel,
|
|
19
|
+
raw: frame,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function decodeKey(hex) {
|
|
23
|
+
let out = "";
|
|
24
|
+
for (let i = hex.length - 2; i >= 0; i -= 2) {
|
|
25
|
+
out += hex.slice(i, i + 2);
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=network-join.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-join.js","sourceRoot":"","sources":["../../src/parsers/network-join.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAA;IAClC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAA;IAC9C,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAE7C,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACtC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IAE/C,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,EAAE,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,IAAI,CAAA;IAEtE,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC;QAC1B,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACnC,OAAO;QACP,GAAG,EAAE,KAAK;KACX,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,GAAG,GAAG,EAAE,CAAA;IACZ,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5C,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;IAC5B,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function networkParamsMatcher(frame) {
|
|
2
|
+
if (frame.length < 21)
|
|
3
|
+
return null;
|
|
4
|
+
if (frame[0] !== "r")
|
|
5
|
+
return null;
|
|
6
|
+
if (frame.slice(7, 11) !== "5060")
|
|
7
|
+
return null;
|
|
8
|
+
const channelHex = frame.slice(17, 19);
|
|
9
|
+
const channel = Number.parseInt(channelHex, 16);
|
|
10
|
+
if (Number.isNaN(channel) || channel < 11 || channel > 26)
|
|
11
|
+
return null;
|
|
12
|
+
return {
|
|
13
|
+
serialNumber: frame.slice(1, 7),
|
|
14
|
+
panId: frame.slice(11, 15),
|
|
15
|
+
channel,
|
|
16
|
+
raw: frame,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=network-params.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-params.js","sourceRoot":"","sources":["../../src/parsers/network-params.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAA;IAClC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAA;IAE9C,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACtC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IAE/C,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,OAAO,GAAG,EAAE,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,IAAI,CAAA;IAEtE,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC;QAC1B,OAAO;QACP,GAAG,EAAE,KAAK;KACX,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function waveRequestMatcher(frame) {
|
|
2
|
+
if (frame.length < 11)
|
|
3
|
+
return null;
|
|
4
|
+
if (frame[0] !== "r")
|
|
5
|
+
return null;
|
|
6
|
+
if (frame.slice(7, 11) !== "7050")
|
|
7
|
+
return null;
|
|
8
|
+
return {
|
|
9
|
+
serialNumber: frame.slice(1, 7),
|
|
10
|
+
raw: frame,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=wave-request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wave-request.js","sourceRoot":"","sources":["../../src/parsers/wave-request.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAA;IAClC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAA;IAE9C,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,GAAG,EAAE,KAAK;KACX,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function waveResponseMatcher(frame) {
|
|
2
|
+
if (frame.length < 15)
|
|
3
|
+
return null;
|
|
4
|
+
if (frame[0] !== "r")
|
|
5
|
+
return null;
|
|
6
|
+
if (frame.slice(7, 11) !== "50AC")
|
|
7
|
+
return null;
|
|
8
|
+
return {
|
|
9
|
+
serialNumber: frame.slice(1, 7),
|
|
10
|
+
code: frame.slice(11, 15),
|
|
11
|
+
raw: frame,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=wave-response.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wave-response.js","sourceRoot":"","sources":["../../src/parsers/wave-response.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAA;IAClC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAA;IAE9C,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC;QACzB,GAAG,EAAE,KAAK;KACX,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface WeatherStationMessage {
|
|
2
|
+
serialNumber: string;
|
|
3
|
+
windSpeed: number;
|
|
4
|
+
temperature: number | null;
|
|
5
|
+
rain: boolean;
|
|
6
|
+
illuminance: number | null;
|
|
7
|
+
raw: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function weatherStationMatcher(frame: string): WeatherStationMessage | null;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export function weatherStationMatcher(frame) {
|
|
2
|
+
if (frame.length < 31)
|
|
3
|
+
return null;
|
|
4
|
+
if (frame[0] !== "r")
|
|
5
|
+
return null;
|
|
6
|
+
if (frame.slice(7, 11) !== "7080")
|
|
7
|
+
return null;
|
|
8
|
+
const ww = parseInt(frame.slice(13, 15), 16);
|
|
9
|
+
const l1 = parseInt(frame.slice(15, 17), 16);
|
|
10
|
+
const l2 = parseInt(frame.slice(23, 25), 16);
|
|
11
|
+
const rain = frame.slice(25, 27) === "C8";
|
|
12
|
+
const tRaw = parseInt(frame.slice(29, 31), 16);
|
|
13
|
+
const temperature = Number.isFinite(tRaw) ? +(tRaw / 2 - 35).toFixed(1) : null;
|
|
14
|
+
const illuminance = (() => {
|
|
15
|
+
if (!Number.isFinite(l1) || !Number.isFinite(l2))
|
|
16
|
+
return null;
|
|
17
|
+
if (l1 === 0)
|
|
18
|
+
return l2 * 2;
|
|
19
|
+
return l1 * l2 * 2;
|
|
20
|
+
})();
|
|
21
|
+
return {
|
|
22
|
+
serialNumber: frame.slice(1, 7),
|
|
23
|
+
windSpeed: ww,
|
|
24
|
+
temperature,
|
|
25
|
+
rain,
|
|
26
|
+
illuminance,
|
|
27
|
+
raw: frame,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=weather-station.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"weather-station.js","sourceRoot":"","sources":["../../src/parsers/weather-station.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,IAAI,CAAA;IAClC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG;QAAE,OAAO,IAAI,CAAA;IACjC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAA;IAE9C,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;IAC5C,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;IAC5C,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;IAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI,CAAA;IACzC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;IAC9C,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9E,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE;QACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YAAE,OAAO,IAAI,CAAA;QAC7D,IAAI,EAAE,KAAK,CAAC;YAAE,OAAO,EAAE,GAAG,CAAC,CAAA;QAC3B,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IACpB,CAAC,CAAC,EAAE,CAAA;IAEJ,OAAO;QACL,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,SAAS,EAAE,EAAE;QACb,WAAW;QACX,IAAI;QACJ,WAAW;QACX,GAAG,EAAE,KAAK;KACX,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type RadioController } from "../controller.js";
|
|
2
|
+
export declare class BroadcastRouter {
|
|
3
|
+
private radio;
|
|
4
|
+
private entries;
|
|
5
|
+
private unsubBroadcast;
|
|
6
|
+
constructor(radio: RadioController);
|
|
7
|
+
on<T>(matcher: (frame: string) => T | null, handler: (msg: T) => void): () => void;
|
|
8
|
+
private dispatch;
|
|
9
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export class BroadcastRouter {
|
|
2
|
+
radio;
|
|
3
|
+
entries = [];
|
|
4
|
+
unsubBroadcast = null;
|
|
5
|
+
constructor(radio) {
|
|
6
|
+
this.radio = radio;
|
|
7
|
+
}
|
|
8
|
+
on(matcher, handler) {
|
|
9
|
+
const entry = {
|
|
10
|
+
matcher: matcher,
|
|
11
|
+
handler: handler,
|
|
12
|
+
};
|
|
13
|
+
this.entries.push(entry);
|
|
14
|
+
if (this.unsubBroadcast === null) {
|
|
15
|
+
this.unsubBroadcast = this.radio.onBroadcast((frame) => {
|
|
16
|
+
this.dispatch(frame);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return () => {
|
|
20
|
+
const idx = this.entries.indexOf(entry);
|
|
21
|
+
if (idx !== -1) {
|
|
22
|
+
this.entries.splice(idx, 1);
|
|
23
|
+
}
|
|
24
|
+
if (this.entries.length === 0 && this.unsubBroadcast !== null) {
|
|
25
|
+
this.unsubBroadcast();
|
|
26
|
+
this.unsubBroadcast = null;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
dispatch(frame) {
|
|
31
|
+
for (const entry of this.entries) {
|
|
32
|
+
const result = entry.matcher(frame);
|
|
33
|
+
if (result !== null) {
|
|
34
|
+
entry.handler(result);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=broadcast-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broadcast-router.js","sourceRoot":"","sources":["../../src/routing/broadcast-router.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,eAAe;IAClB,KAAK,CAAiB;IACtB,OAAO,GAAoB,EAAE,CAAA;IAC7B,cAAc,GAAwB,IAAI,CAAA;IAElD,YAAY,KAAsB;QAChC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,EAAE,CAAI,OAAoC,EAAE,OAAyB;QACnE,MAAM,KAAK,GAAkB;YAC3B,OAAO,EAAE,OAAqC;YAC9C,OAAO,EAAE,OAAiC;SAC3C,CAAA;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAExB,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACjC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE;gBACrD,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;YACtB,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,GAAG,EAAE;YACV,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;YACvC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACf,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;YAC7B,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;gBAC9D,IAAI,CAAC,cAAc,EAAE,CAAA;gBACrB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAA;YAC5B,CAAC;QACH,CAAC,CAAA;IACH,CAAC;IAEO,QAAQ,CAAC,KAAa;QAC5B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;YACnC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;gBACrB,OAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface SerialDriver {
|
|
2
|
+
open(path: string): Promise<void>;
|
|
3
|
+
close(): Promise<void>;
|
|
4
|
+
write(data: Uint8Array): Promise<void>;
|
|
5
|
+
onData(handler: (data: Uint8Array) => void): () => void;
|
|
6
|
+
onError(handler: (error: Error) => void): () => void;
|
|
7
|
+
onClose(handler: () => void): () => void;
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"driver.js","sourceRoot":"","sources":["../../src/serial/driver.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type SerialDriver } from "../serial/driver.js";
|
|
2
|
+
export declare class MockSerialDriver implements SerialDriver {
|
|
3
|
+
private dataHandlers;
|
|
4
|
+
private errorHandlers;
|
|
5
|
+
private closeHandlers;
|
|
6
|
+
private _isOpen;
|
|
7
|
+
private _writes;
|
|
8
|
+
private _path;
|
|
9
|
+
get isOpen(): boolean;
|
|
10
|
+
get path(): string;
|
|
11
|
+
open(path: string): Promise<void>;
|
|
12
|
+
close(): Promise<void>;
|
|
13
|
+
write(data: Uint8Array): Promise<void>;
|
|
14
|
+
onData(handler: (data: Uint8Array) => void): () => void;
|
|
15
|
+
onError(handler: (error: Error) => void): () => void;
|
|
16
|
+
onClose(handler: () => void): () => void;
|
|
17
|
+
simulateData(data: Uint8Array): void;
|
|
18
|
+
simulateError(error: Error): void;
|
|
19
|
+
simulateClose(): void;
|
|
20
|
+
getWrites(): Uint8Array[];
|
|
21
|
+
clearWrites(): void;
|
|
22
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export class MockSerialDriver {
|
|
2
|
+
dataHandlers = new Set();
|
|
3
|
+
errorHandlers = new Set();
|
|
4
|
+
closeHandlers = new Set();
|
|
5
|
+
_isOpen = false;
|
|
6
|
+
_writes = [];
|
|
7
|
+
_path = "";
|
|
8
|
+
get isOpen() {
|
|
9
|
+
return this._isOpen;
|
|
10
|
+
}
|
|
11
|
+
get path() {
|
|
12
|
+
return this._path;
|
|
13
|
+
}
|
|
14
|
+
async open(path) {
|
|
15
|
+
this._path = path;
|
|
16
|
+
this._isOpen = true;
|
|
17
|
+
}
|
|
18
|
+
async close() {
|
|
19
|
+
this._isOpen = false;
|
|
20
|
+
this._writes = [];
|
|
21
|
+
this.dataHandlers.clear();
|
|
22
|
+
this.errorHandlers.clear();
|
|
23
|
+
this.closeHandlers.clear();
|
|
24
|
+
}
|
|
25
|
+
async write(data) {
|
|
26
|
+
this._writes.push(data);
|
|
27
|
+
}
|
|
28
|
+
onData(handler) {
|
|
29
|
+
this.dataHandlers.add(handler);
|
|
30
|
+
return () => { this.dataHandlers.delete(handler); };
|
|
31
|
+
}
|
|
32
|
+
onError(handler) {
|
|
33
|
+
this.errorHandlers.add(handler);
|
|
34
|
+
return () => { this.errorHandlers.delete(handler); };
|
|
35
|
+
}
|
|
36
|
+
onClose(handler) {
|
|
37
|
+
this.closeHandlers.add(handler);
|
|
38
|
+
return () => { this.closeHandlers.delete(handler); };
|
|
39
|
+
}
|
|
40
|
+
simulateData(data) {
|
|
41
|
+
for (const handler of this.dataHandlers) {
|
|
42
|
+
handler(data);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
simulateError(error) {
|
|
46
|
+
for (const handler of this.errorHandlers) {
|
|
47
|
+
handler(error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
simulateClose() {
|
|
51
|
+
for (const handler of this.closeHandlers) {
|
|
52
|
+
handler();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
getWrites() {
|
|
56
|
+
return [...this._writes];
|
|
57
|
+
}
|
|
58
|
+
clearWrites() {
|
|
59
|
+
this._writes = [];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=mock-serial.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-serial.js","sourceRoot":"","sources":["../../src/testing/mock-serial.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,gBAAgB;IACnB,YAAY,GAAG,IAAI,GAAG,EAA8B,CAAA;IACpD,aAAa,GAAG,IAAI,GAAG,EAA0B,CAAA;IACjD,aAAa,GAAG,IAAI,GAAG,EAAc,CAAA;IACrC,OAAO,GAAG,KAAK,CAAA;IACf,OAAO,GAAiB,EAAE,CAAA;IAC1B,KAAK,GAAG,EAAE,CAAA;IAElB,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACjB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;IACrB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACpB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAA;QACjB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAA;QACzB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAA;QAC1B,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAA;IAC5B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAgB;QAC1B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACzB,CAAC;IAED,MAAM,CAAC,OAAmC;QACxC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC9B,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA,CAAC,CAAC,CAAA;IACpD,CAAC;IAED,OAAO,CAAC,OAA+B;QACrC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC/B,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA,CAAC,CAAC,CAAA;IACrD,CAAC;IAED,OAAO,CAAC,OAAmB;QACzB,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC/B,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA,CAAC,CAAC,CAAA;IACrD,CAAC;IAED,YAAY,CAAC,IAAgB;QAC3B,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,CAAA;QACf,CAAC;IACH,CAAC;IAED,aAAa,CAAC,KAAY;QACxB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACzC,OAAO,CAAC,KAAK,CAAC,CAAA;QAChB,CAAC;IACH,CAAC;IAED,aAAa;QACX,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACzC,OAAO,EAAE,CAAA;QACX,CAAC;IACH,CAAC;IAED,SAAS;QACP,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAA;IAC1B,CAAC;IAED,WAAW;QACT,IAAI,CAAC,OAAO,GAAG,EAAE,CAAA;IACnB,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@wms-js/lib",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./src/index.ts",
|
|
9
|
+
"import": "./src/index.ts"
|
|
10
|
+
},
|
|
11
|
+
"./*": "./src/*"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"package.json",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc",
|
|
24
|
+
"prepublishOnly": "tsc"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "25.9.3"
|
|
28
|
+
}
|
|
29
|
+
}
|