motion-master-client 0.0.55 → 0.0.56
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/.babelrc +3 -0
- package/.eslintrc.json +18 -0
- package/README.md +123 -123
- package/jest.config.ts +16 -0
- package/motion-master.proto +1861 -0
- package/package.json +6 -21
- package/project.json +45 -0
- package/src/{index.d.ts → index.ts} +26 -26
- package/src/lib/cia402.spec.ts +77 -0
- package/src/lib/cia402.ts +414 -0
- package/src/lib/config-file.spec.ts +114 -0
- package/src/lib/config-file.ts +63 -0
- package/src/lib/device-log-line.ts +5 -0
- package/src/lib/device-parameter.spec.ts +85 -0
- package/src/lib/device-parameter.ts +79 -0
- package/src/lib/device.ts +10 -0
- package/src/lib/hardware-description.spec.ts +253 -0
- package/src/lib/hardware-description.ts +129 -0
- package/src/lib/logger.ts +5 -0
- package/src/lib/monitoring-config.ts +6 -0
- package/src/lib/{monitoring-entry.d.ts → monitoring-entry.ts} +10 -9
- package/src/lib/motion-master-client.ts +266 -0
- package/src/lib/motion-master-pub-sub-client.ts +100 -0
- package/src/lib/motion-master-pub-sub-socket.ts +46 -0
- package/src/lib/motion-master-pub-sub-web-socket.ts +77 -0
- package/src/lib/motion-master-pub-sub-worker-socket.ts +57 -0
- package/src/lib/motion-master-req-res-client.spec.ts +740 -0
- package/src/lib/motion-master-req-res-client.ts +2211 -0
- package/src/lib/motion-master-req-res-socket.ts +68 -0
- package/src/lib/motion-master-req-res-web-socket.ts +123 -0
- package/src/lib/motion-master-req-res-worker-socket.ts +89 -0
- package/src/lib/motion-master.proto.d.ts +5183 -5083
- package/src/lib/motion-master.proto.js +53218 -52284
- package/src/lib/operators.ts +108 -0
- package/src/lib/options.ts +12 -0
- package/src/lib/parameter.spec.ts +160 -0
- package/src/lib/parameter.ts +170 -0
- package/src/lib/product-id-range.ts +8 -0
- package/src/lib/request-status-resolver.ts +403 -0
- package/src/lib/system-log-line.ts +9 -0
- package/src/lib/{types.d.ts → types.ts} +141 -209
- package/src/lib/urls.ts +6 -0
- package/src/lib/util.ts +332 -0
- package/src/lib/web-socket-connection-close-codes.ts +85 -0
- package/tsconfig.json +23 -0
- package/tsconfig.lib.json +10 -0
- package/tsconfig.spec.json +20 -0
- package/typedoc.json +10 -0
- package/src/index.js +0 -30
- package/src/index.js.map +0 -1
- package/src/lib/cia402.d.ts +0 -182
- package/src/lib/cia402.js +0 -392
- package/src/lib/cia402.js.map +0 -1
- package/src/lib/config-file.d.ts +0 -13
- package/src/lib/config-file.js +0 -50
- package/src/lib/config-file.js.map +0 -1
- package/src/lib/device-log-line.d.ts +0 -5
- package/src/lib/device-log-line.js +0 -3
- package/src/lib/device-log-line.js.map +0 -1
- package/src/lib/device-parameter.d.ts +0 -56
- package/src/lib/device-parameter.js +0 -39
- package/src/lib/device-parameter.js.map +0 -1
- package/src/lib/device.d.ts +0 -9
- package/src/lib/device.js +0 -3
- package/src/lib/device.js.map +0 -1
- package/src/lib/hardware-description.d.ts +0 -41
- package/src/lib/hardware-description.js +0 -94
- package/src/lib/hardware-description.js.map +0 -1
- package/src/lib/logger.d.ts +0 -1
- package/src/lib/logger.js +0 -8
- package/src/lib/logger.js.map +0 -1
- package/src/lib/monitoring-config.d.ts +0 -6
- package/src/lib/monitoring-config.js +0 -3
- package/src/lib/monitoring-config.js.map +0 -1
- package/src/lib/monitoring-entry.js +0 -3
- package/src/lib/monitoring-entry.js.map +0 -1
- package/src/lib/motion-master-client.d.ts +0 -56
- package/src/lib/motion-master-client.js +0 -167
- package/src/lib/motion-master-client.js.map +0 -1
- package/src/lib/motion-master-pub-sub-client.d.ts +0 -17
- package/src/lib/motion-master-pub-sub-client.js +0 -73
- package/src/lib/motion-master-pub-sub-client.js.map +0 -1
- package/src/lib/motion-master-pub-sub-socket.d.ts +0 -42
- package/src/lib/motion-master-pub-sub-socket.js +0 -3
- package/src/lib/motion-master-pub-sub-socket.js.map +0 -1
- package/src/lib/motion-master-pub-sub-web-socket.d.ts +0 -18
- package/src/lib/motion-master-pub-sub-web-socket.js +0 -66
- package/src/lib/motion-master-pub-sub-web-socket.js.map +0 -1
- package/src/lib/motion-master-pub-sub-worker-socket.d.ts +0 -18
- package/src/lib/motion-master-pub-sub-worker-socket.js +0 -48
- package/src/lib/motion-master-pub-sub-worker-socket.js.map +0 -1
- package/src/lib/motion-master-req-res-client.d.ts +0 -947
- package/src/lib/motion-master-req-res-client.js +0 -1735
- package/src/lib/motion-master-req-res-client.js.map +0 -1
- package/src/lib/motion-master-req-res-socket.d.ts +0 -60
- package/src/lib/motion-master-req-res-socket.js +0 -3
- package/src/lib/motion-master-req-res-socket.js.map +0 -1
- package/src/lib/motion-master-req-res-web-socket.d.ts +0 -28
- package/src/lib/motion-master-req-res-web-socket.js +0 -98
- package/src/lib/motion-master-req-res-web-socket.js.map +0 -1
- package/src/lib/motion-master-req-res-worker-socket.d.ts +0 -24
- package/src/lib/motion-master-req-res-worker-socket.js +0 -72
- package/src/lib/motion-master-req-res-worker-socket.js.map +0 -1
- package/src/lib/operators.d.ts +0 -20
- package/src/lib/operators.js +0 -84
- package/src/lib/operators.js.map +0 -1
- package/src/lib/options.d.ts +0 -10
- package/src/lib/options.js +0 -14
- package/src/lib/options.js.map +0 -1
- package/src/lib/parameter.d.ts +0 -72
- package/src/lib/parameter.js +0 -119
- package/src/lib/parameter.js.map +0 -1
- package/src/lib/product-id-range.d.ts +0 -7
- package/src/lib/product-id-range.js +0 -12
- package/src/lib/product-id-range.js.map +0 -1
- package/src/lib/request-status-resolver.d.ts +0 -4
- package/src/lib/request-status-resolver.js +0 -345
- package/src/lib/request-status-resolver.js.map +0 -1
- package/src/lib/system-log-line.d.ts +0 -9
- package/src/lib/system-log-line.js +0 -3
- package/src/lib/system-log-line.js.map +0 -1
- package/src/lib/types.js +0 -29
- package/src/lib/types.js.map +0 -1
- package/src/lib/urls.d.ts +0 -3
- package/src/lib/urls.js +0 -10
- package/src/lib/urls.js.map +0 -1
- package/src/lib/util.d.ts +0 -42
- package/src/lib/util.js +0 -327
- package/src/lib/util.js.map +0 -1
- package/src/lib/web-socket-connection-close-codes.d.ts +0 -8
- package/src/lib/web-socket-connection-close-codes.js +0 -89
- package/src/lib/web-socket-connection-close-codes.js.map +0 -1
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { BehaviorSubject, Observable } from "rxjs";
|
|
2
|
+
import { IMotionMasterMessage } from "./types";
|
|
3
|
+
|
|
4
|
+
export interface MotionMasterReqResSocket {
|
|
5
|
+
/**
|
|
6
|
+
* Emits a boolean value when socket gets opened or closed.
|
|
7
|
+
*/
|
|
8
|
+
readonly opened$: BehaviorSubject<boolean>;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Emits close events with code and reason data.
|
|
12
|
+
* @link https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close_event
|
|
13
|
+
*/
|
|
14
|
+
readonly close$: Observable<{ code: number; reason: string; }>
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Motion Master is considered alive when it sends messages in regular time interval.
|
|
18
|
+
*/
|
|
19
|
+
readonly alive$: BehaviorSubject<boolean>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Decoded message instances coming from Motion Master.
|
|
23
|
+
*/
|
|
24
|
+
readonly message$: Observable<IMotionMasterMessage>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* URL set in call to open.
|
|
28
|
+
*/
|
|
29
|
+
get url(): string | undefined;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Send ping system messages to Motion Master with a fixed time delay between each call.
|
|
33
|
+
*/
|
|
34
|
+
get pingSystemInterval(): number | undefined;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* How long in milliseconds to consider Motion Master alive.
|
|
38
|
+
*/
|
|
39
|
+
get systemAliveTimeout(): number | undefined;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Open socket.
|
|
43
|
+
*
|
|
44
|
+
* The connected$ and eventually alive$ observables will emit true values.
|
|
45
|
+
*/
|
|
46
|
+
open(url: string, pingSystemInterval?: number, systemAliveTimeout?: number): void;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Close socket.
|
|
50
|
+
*
|
|
51
|
+
* The opened$ and alive$ observables will emit false values.
|
|
52
|
+
*/
|
|
53
|
+
close(): void;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Reopen socket.
|
|
57
|
+
*
|
|
58
|
+
* Reopen if closed using the same url, pingSystemInterval, and systemAliveTimeout previously set in open.
|
|
59
|
+
*/
|
|
60
|
+
reopen(): void;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Send an instance of a message.
|
|
64
|
+
*
|
|
65
|
+
* Subscribe to the message$ observable in order to receive the response messages.
|
|
66
|
+
*/
|
|
67
|
+
send(message: IMotionMasterMessage): void;
|
|
68
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { BehaviorSubject, filter, interval, map, Subject, Subscription, tap } from "rxjs";
|
|
2
|
+
import { webSocket, WebSocketSubject, WebSocketSubjectConfig } from "rxjs/webSocket";
|
|
3
|
+
import { logger } from "./logger";
|
|
4
|
+
import { MotionMasterReqResSocket } from "./motion-master-req-res-socket";
|
|
5
|
+
import { IMotionMasterMessage, MotionMasterMessage } from "./types";
|
|
6
|
+
import { convertMotionMasterMessageToLoggerContext, createPlainObjectFromMotionMasterMessage } from "./util";
|
|
7
|
+
|
|
8
|
+
export class MotionMasterReqResWebSocket implements MotionMasterReqResSocket {
|
|
9
|
+
|
|
10
|
+
readonly opened$ = new BehaviorSubject<boolean>(false);
|
|
11
|
+
|
|
12
|
+
readonly close$ = new Subject<{ code: number; reason: string; }>;
|
|
13
|
+
|
|
14
|
+
readonly alive$ = new BehaviorSubject<boolean>(false);
|
|
15
|
+
|
|
16
|
+
readonly message$ = new Subject<IMotionMasterMessage>();
|
|
17
|
+
|
|
18
|
+
private aliveTimeoutId = 0;
|
|
19
|
+
|
|
20
|
+
private pingSystemObserver = { next: () => this.send({ request: { pingSystem: {} } }) };
|
|
21
|
+
|
|
22
|
+
private pingSystemSubscription?: Subscription;
|
|
23
|
+
|
|
24
|
+
private webSocket$?: WebSocketSubject<Uint8Array>;
|
|
25
|
+
|
|
26
|
+
private _url?: string;
|
|
27
|
+
private _pingSystemInterval?: number;
|
|
28
|
+
private _systemAliveTimeout?: number;
|
|
29
|
+
|
|
30
|
+
get url(): string | undefined {
|
|
31
|
+
return this._url;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get pingSystemInterval(): number | undefined {
|
|
35
|
+
return this._pingSystemInterval;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get systemAliveTimeout(): number | undefined {
|
|
39
|
+
return this._systemAliveTimeout;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
open(url: string, pingSystemInterval = 250, systemAliveTimeout = 1000): void {
|
|
43
|
+
this._url = url;
|
|
44
|
+
this._pingSystemInterval = pingSystemInterval;
|
|
45
|
+
this._systemAliveTimeout = systemAliveTimeout;
|
|
46
|
+
|
|
47
|
+
this.webSocket$ = this.createWebSocket(url, pingSystemInterval);
|
|
48
|
+
|
|
49
|
+
this.webSocket$?.pipe(
|
|
50
|
+
map((data: Uint8Array) => MotionMasterMessage.decode(data)),
|
|
51
|
+
tap(() => this.keepalive(systemAliveTimeout)),
|
|
52
|
+
filter((message) => !(message.status?.systemPong)),
|
|
53
|
+
map(message => createPlainObjectFromMotionMasterMessage(message)),
|
|
54
|
+
tap((message) => {
|
|
55
|
+
const context = convertMotionMasterMessageToLoggerContext(message);
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
57
|
+
logger.info(context as any, `Received ${context.name}`);
|
|
58
|
+
}),
|
|
59
|
+
).subscribe({
|
|
60
|
+
next: (message) => this.message$.next(message),
|
|
61
|
+
error: () => {
|
|
62
|
+
// ignore, clients will receive close$ event instead
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
close(): void {
|
|
68
|
+
this.webSocket$?.complete();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
reopen() {
|
|
72
|
+
if (this.url && this.opened$.value === false) {
|
|
73
|
+
this.open(this.url, this.pingSystemInterval, this.systemAliveTimeout);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
send(message: IMotionMasterMessage): void {
|
|
78
|
+
if (!message.request?.pingSystem) {
|
|
79
|
+
const context = convertMotionMasterMessageToLoggerContext(message);
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
|
+
logger.info(context as any, `Send ${context.name}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
this.webSocket$?.next(MotionMasterMessage.encode(message).finish());
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private createWebSocket(url: string, pingSystemInterval = 250) {
|
|
88
|
+
const webSocketConfig: WebSocketSubjectConfig<Uint8Array> = {
|
|
89
|
+
binaryType: 'arraybuffer',
|
|
90
|
+
closeObserver: {
|
|
91
|
+
next: (ev: CloseEvent) => {
|
|
92
|
+
this.pingSystemSubscription?.unsubscribe();
|
|
93
|
+
clearTimeout(this.aliveTimeoutId);
|
|
94
|
+
this.alive$.next(false);
|
|
95
|
+
this.opened$.next(false);
|
|
96
|
+
this.close$.next({ code: ev.code, reason: ev.reason });
|
|
97
|
+
logger.info(`Connection closed ${url}`);
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
deserializer: (e: MessageEvent) => new Uint8Array(e.data as unknown as Iterable<number>),
|
|
101
|
+
openObserver: {
|
|
102
|
+
next: () => {
|
|
103
|
+
this.pingSystemSubscription = interval(pingSystemInterval).subscribe(this.pingSystemObserver);
|
|
104
|
+
this.opened$.next(true);
|
|
105
|
+
logger.info(`Connection opened ${url}`);
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
serializer: (value: Uint8Array) => value,
|
|
109
|
+
url,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
return webSocket(webSocketConfig);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private keepalive(systemAliveTimeout = 1000) {
|
|
116
|
+
if (this.alive$.getValue() === false) {
|
|
117
|
+
this.alive$.next(true);
|
|
118
|
+
}
|
|
119
|
+
clearTimeout(this.aliveTimeoutId);
|
|
120
|
+
this.aliveTimeoutId = setTimeout(() => this.alive$.next(false), systemAliveTimeout) as unknown as number;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { BehaviorSubject, Subject } from "rxjs";
|
|
2
|
+
import { logger } from "./logger";
|
|
3
|
+
import { MotionMasterReqResSocket } from "./motion-master-req-res-socket";
|
|
4
|
+
import { IMotionMasterMessage } from "./types";
|
|
5
|
+
import { convertMotionMasterMessageToLoggerContext } from "./util";
|
|
6
|
+
|
|
7
|
+
export class MotionMasterReqResWorkerSocket implements MotionMasterReqResSocket {
|
|
8
|
+
|
|
9
|
+
readonly opened$ = new BehaviorSubject<boolean>(false);
|
|
10
|
+
|
|
11
|
+
readonly close$ = new Subject<{ code: number, reason: string }>();
|
|
12
|
+
|
|
13
|
+
readonly alive$ = new BehaviorSubject<boolean>(false);
|
|
14
|
+
|
|
15
|
+
readonly message$ = new Subject<IMotionMasterMessage>();
|
|
16
|
+
|
|
17
|
+
private _url?: string;
|
|
18
|
+
private _pingSystemInterval?: number;
|
|
19
|
+
private _systemAliveTimeout?: number;
|
|
20
|
+
|
|
21
|
+
constructor(
|
|
22
|
+
public readonly worker: Worker,
|
|
23
|
+
) { }
|
|
24
|
+
|
|
25
|
+
get url(): string | undefined {
|
|
26
|
+
return this._url;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get pingSystemInterval(): number | undefined {
|
|
30
|
+
return this._pingSystemInterval;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get systemAliveTimeout(): number | undefined {
|
|
34
|
+
return this._systemAliveTimeout;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
open(url: string, pingSystemInterval = 250, systemAliveTimeout = 1000): void {
|
|
38
|
+
this._url = url;
|
|
39
|
+
this._pingSystemInterval = pingSystemInterval;
|
|
40
|
+
this._systemAliveTimeout = systemAliveTimeout;
|
|
41
|
+
|
|
42
|
+
this.worker.onmessage = ({ data }) => {
|
|
43
|
+
if ('opened' in data) {
|
|
44
|
+
const { opened } = data;
|
|
45
|
+
this.opened$.next(opened);
|
|
46
|
+
logger.info(opened ? `Opened req/res 🔌 ${url}` : `Closed req/res 🔌 ${url}`);
|
|
47
|
+
} else if ('alive' in data) {
|
|
48
|
+
const { alive } = data;
|
|
49
|
+
this.alive$.next(alive);
|
|
50
|
+
logger.info(alive ? `System is alive 💓` : 'System is as dead as 🦤');
|
|
51
|
+
} else if ('message' in data) {
|
|
52
|
+
const { message } = data;
|
|
53
|
+
|
|
54
|
+
const context = convertMotionMasterMessageToLoggerContext(message);
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
56
|
+
logger.info(context as any, `Received ${context.name}`);
|
|
57
|
+
|
|
58
|
+
this.message$.next(message);
|
|
59
|
+
} else if ('close' in data) {
|
|
60
|
+
const { close } = data;
|
|
61
|
+
this.close$.next(close);
|
|
62
|
+
logger.info(`Close event received on req/res 🔌 ${url} ${JSON.stringify(close)}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this.worker.postMessage({
|
|
67
|
+
open: { url, pingSystemInterval, systemAliveTimeout },
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
reopen() {
|
|
72
|
+
if (this.url && this.opened$.value === false) {
|
|
73
|
+
this.open(this.url, this.pingSystemInterval, this.systemAliveTimeout);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
close(): void {
|
|
78
|
+
this.worker.postMessage({ close: true });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
send(message: IMotionMasterMessage): void {
|
|
82
|
+
const context = convertMotionMasterMessageToLoggerContext(message);
|
|
83
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
84
|
+
logger.info(context as any, `Send ${context.name}`);
|
|
85
|
+
|
|
86
|
+
this.worker.postMessage({ message });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
}
|