motion-master-client 0.0.76 → 0.0.85
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/README.md +227 -138
- package/package.json +1 -1
- package/src/cli.d.ts +1 -1
- package/src/cli.js +160 -160
- package/src/index.d.ts +30 -28
- package/src/index.js +33 -31
- package/src/index.js.map +1 -1
- package/src/lib/cia402.d.ts +184 -182
- package/src/lib/cia402.js +393 -391
- package/src/lib/cia402.js.map +1 -1
- package/src/lib/config-file.d.ts +13 -13
- package/src/lib/config-file.js +49 -49
- package/src/lib/data-monitoring.d.ts +12 -12
- package/src/lib/data-monitoring.js +33 -33
- package/src/lib/device-log-line.d.ts +5 -5
- package/src/lib/device-log-line.js +2 -2
- package/src/lib/device-parameter.d.ts +56 -56
- package/src/lib/device-parameter.js +38 -38
- package/src/lib/device.d.ts +46 -9
- package/src/lib/device.js +166 -2
- package/src/lib/device.js.map +1 -1
- package/src/lib/encoder-register.d.ts +16 -16
- package/src/lib/encoder-register.js +116 -116
- package/src/lib/hardware-description.d.ts +46 -46
- package/src/lib/hardware-description.js +109 -109
- package/src/lib/integro-encoder-calibration.d.ts +31 -0
- package/src/lib/integro-encoder-calibration.js +196 -0
- package/src/lib/integro-encoder-calibration.js.map +1 -0
- package/src/lib/logger.d.ts +1 -1
- package/src/lib/logger.js +7 -7
- package/src/lib/monitoring-config.d.ts +31 -31
- package/src/lib/monitoring-config.js +2 -2
- package/src/lib/monitoring-entry.d.ts +9 -9
- package/src/lib/monitoring-entry.js +2 -2
- package/src/lib/motion-master-client.d.ts +77 -77
- package/src/lib/motion-master-client.js +196 -196
- package/src/lib/motion-master-pub-sub-client.d.ts +17 -17
- package/src/lib/motion-master-pub-sub-client.js +72 -72
- package/src/lib/motion-master-pub-sub-client.js.map +1 -1
- package/src/lib/motion-master-pub-sub-socket.d.ts +42 -42
- package/src/lib/motion-master-pub-sub-socket.js +2 -2
- package/src/lib/motion-master-pub-sub-web-socket.d.ts +18 -18
- package/src/lib/motion-master-pub-sub-web-socket.js +65 -65
- package/src/lib/motion-master-pub-sub-worker-socket.d.ts +18 -18
- package/src/lib/motion-master-pub-sub-worker-socket.js +47 -47
- package/src/lib/motion-master-req-res-client.d.ts +1104 -1062
- package/src/lib/motion-master-req-res-client.js +2137 -1992
- package/src/lib/motion-master-req-res-client.js.map +1 -1
- package/src/lib/motion-master-req-res-socket.d.ts +60 -60
- package/src/lib/motion-master-req-res-socket.js +2 -2
- package/src/lib/motion-master-req-res-web-socket.d.ts +28 -28
- package/src/lib/motion-master-req-res-web-socket.js +97 -97
- package/src/lib/motion-master-req-res-worker-socket.d.ts +24 -24
- package/src/lib/motion-master-req-res-worker-socket.js +71 -71
- package/src/lib/motion-master.proto.d.ts +5183 -5183
- package/src/lib/motion-master.proto.js +53218 -53218
- package/src/lib/operators.d.ts +20 -20
- package/src/lib/operators.js +82 -83
- package/src/lib/operators.js.map +1 -1
- package/src/lib/options.d.ts +10 -10
- package/src/lib/options.js +13 -13
- package/src/lib/os-command.d.ts +387 -173
- package/src/lib/os-command.js +555 -269
- package/src/lib/os-command.js.map +1 -1
- package/src/lib/parameter.d.ts +156 -138
- package/src/lib/parameter.js +377 -152
- package/src/lib/parameter.js.map +1 -1
- package/src/lib/product-id-range.d.ts +7 -7
- package/src/lib/product-id-range.js +11 -11
- package/src/lib/request-status-resolver.d.ts +4 -4
- package/src/lib/request-status-resolver.js +344 -344
- package/src/lib/somanet-product.d.ts +37 -0
- package/src/lib/somanet-product.js +126 -0
- package/src/lib/somanet-product.js.map +1 -0
- package/src/lib/system-log-line.d.ts +9 -9
- package/src/lib/system-log-line.js +2 -2
- package/src/lib/types.d.ts +141 -141
- package/src/lib/types.js +28 -28
- package/src/lib/urls.d.ts +3 -3
- package/src/lib/urls.js +9 -9
- package/src/lib/util.d.ts +21 -45
- package/src/lib/util.js +113 -379
- package/src/lib/util.js.map +1 -1
- package/src/lib/web-socket-connection-close-codes.d.ts +8 -8
- package/src/lib/web-socket-connection-close-codes.js +88 -88
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
import { Observable } from "rxjs";
|
|
2
|
-
import { MonitoringConfig } from "./monitoring-config";
|
|
3
|
-
import { MotionMasterPubSubClient } from "./motion-master-pub-sub-client";
|
|
4
|
-
import { MotionMasterPubSubSocket } from "./motion-master-pub-sub-socket";
|
|
5
|
-
import { MotionMasterReqResClient } from "./motion-master-req-res-client";
|
|
6
|
-
import { MotionMasterReqResSocket } from "./motion-master-req-res-socket";
|
|
7
|
-
import { DeviceParameterIds, DeviceRef, ParameterValueType } from "./types";
|
|
8
|
-
import { DeviceParameter } from "./device-parameter";
|
|
9
|
-
export declare function createMotionMasterClient(hostname: string): MotionMasterClient;
|
|
10
|
-
export declare class MotionMasterClient {
|
|
11
|
-
readonly reqResSocket: MotionMasterReqResSocket;
|
|
12
|
-
readonly pubSubSocket: MotionMasterPubSubSocket;
|
|
13
|
-
readonly request: MotionMasterReqResClient;
|
|
14
|
-
readonly monitor: MotionMasterPubSubClient;
|
|
15
|
-
private systemEventSubscription?;
|
|
16
|
-
constructor(reqResSocket: MotionMasterReqResSocket, pubSubSocket: MotionMasterPubSubSocket);
|
|
17
|
-
/**
|
|
18
|
-
* This observable will emit true when both req/res and pub/sub sockets are opened.
|
|
19
|
-
* If any socket gets closed, this observable will emit false.
|
|
20
|
-
* This is a hot observable that will on subscription emit the last value of sockets opened.
|
|
21
|
-
*/
|
|
22
|
-
socketsOpened$: Observable<boolean>;
|
|
23
|
-
/**
|
|
24
|
-
* Client is ready when both req/res and pub/sub sockets are opened.
|
|
25
|
-
* This observable will emit whenever the sockets opened property changes to true.
|
|
26
|
-
*/
|
|
27
|
-
ready$: Observable<true>;
|
|
28
|
-
/**
|
|
29
|
-
* This observable will emit only once when both req/res and pub/sub sockets are opened.
|
|
30
|
-
* NOTE: This observable might never emit and it doesn't timeout.
|
|
31
|
-
*/
|
|
32
|
-
onceReady$: Observable<true>;
|
|
33
|
-
/**
|
|
34
|
-
* Client is ready when both req/res and pub/sub sockets are opened.
|
|
35
|
-
* If both sockets are already opened, this function will immediately resolve to true.
|
|
36
|
-
* Otherwise, it will wait up to requestTimeout for both sockets to open, or throw an error.
|
|
37
|
-
*/
|
|
38
|
-
whenReady(requestTimeout?: number): Promise<true>;
|
|
39
|
-
/**
|
|
40
|
-
* Start monitoring.
|
|
41
|
-
*
|
|
42
|
-
* Note that the returned observable will never complete on its own.
|
|
43
|
-
*
|
|
44
|
-
* If you unsubscribe from it, the teardown code will send a request to the master to stop the monitoring.
|
|
45
|
-
* That means you will end up with an observable that is not complete, but it won't emit any values.
|
|
46
|
-
* This is fine when you want to use the monitoring observable directly in the template with async pipe,
|
|
47
|
-
* which will unsubscribe automatically and stop the monitoring when you leave the component.
|
|
48
|
-
*
|
|
49
|
-
* If you need to complete the observable so that, for example, the toArray() operator works as expected, then use the {@link DataMonitoring} class,
|
|
50
|
-
* which has a stop method. It can optionally buffer data for exporting as CSV or performing statistics on it.
|
|
51
|
-
*
|
|
52
|
-
* @param ids Device parameter IDs to monitor.
|
|
53
|
-
* @param monitoringInterval At what interval should the master application send values.
|
|
54
|
-
* @param config Configure the topic, buffer size, distinct.
|
|
55
|
-
* @param requestTimeout How long will the client wait for the master to confirm that monitoring has started.
|
|
56
|
-
* @returns An observable of an array of parameter values.
|
|
57
|
-
*/
|
|
58
|
-
startMonitoring(ids: DeviceParameterIds, monitoringInterval: number, config?: MonitoringConfig, requestTimeout?: number): Observable<ParameterValueType[]>;
|
|
59
|
-
/**
|
|
60
|
-
* TODO: return device parameters instead of just parameters
|
|
61
|
-
* get parameters from ESI uprfront, and then when parameters are received
|
|
62
|
-
* from motion master just concatenate (spread operator) props from ESI and props from parameter
|
|
63
|
-
* assign device parameter id like 0x1018:00.12345
|
|
64
|
-
* when assembling device parameter, get parameter from device in ESI based on product code, see ESI service
|
|
65
|
-
* this should probably done for other get parameters functions, get ESI file from device or prepared, get data from it
|
|
66
|
-
*/
|
|
67
|
-
startMonitoringDeviceParameters(ids: DeviceParameterIds, monitoringInterval: number, config?: MonitoringConfig, requestTimeout?: number): Observable<DeviceParameter[]>;
|
|
68
|
-
startMonitoringValue<T extends ParameterValueType = number>(id: string | [DeviceRef, number, number], monitoringInterval: number, config?: MonitoringConfig, requestTimeout?: number): Observable<T>;
|
|
69
|
-
trackTargetReached(deviceRef: DeviceRef, monitoringInterval?: number): Observable<boolean>;
|
|
70
|
-
waitUntilTargetReached(deviceRef: DeviceRef, monitoringInterval?: number): Observable<true>;
|
|
71
|
-
whenTargetReached(deviceRef: DeviceRef, monitoringInterval?: number): Promise<true>;
|
|
72
|
-
subscribeToSystemEvent(): void;
|
|
73
|
-
stopMonitoring(messageId: string): void;
|
|
74
|
-
stopMonitoringAll(): void;
|
|
75
|
-
closeSockets(): void;
|
|
76
|
-
reopenSockets(): void;
|
|
77
|
-
}
|
|
1
|
+
import { Observable } from "rxjs";
|
|
2
|
+
import { MonitoringConfig } from "./monitoring-config";
|
|
3
|
+
import { MotionMasterPubSubClient } from "./motion-master-pub-sub-client";
|
|
4
|
+
import { MotionMasterPubSubSocket } from "./motion-master-pub-sub-socket";
|
|
5
|
+
import { MotionMasterReqResClient } from "./motion-master-req-res-client";
|
|
6
|
+
import { MotionMasterReqResSocket } from "./motion-master-req-res-socket";
|
|
7
|
+
import { DeviceParameterIds, DeviceRef, ParameterValueType } from "./types";
|
|
8
|
+
import { DeviceParameter } from "./device-parameter";
|
|
9
|
+
export declare function createMotionMasterClient(hostname: string): MotionMasterClient;
|
|
10
|
+
export declare class MotionMasterClient {
|
|
11
|
+
readonly reqResSocket: MotionMasterReqResSocket;
|
|
12
|
+
readonly pubSubSocket: MotionMasterPubSubSocket;
|
|
13
|
+
readonly request: MotionMasterReqResClient;
|
|
14
|
+
readonly monitor: MotionMasterPubSubClient;
|
|
15
|
+
private systemEventSubscription?;
|
|
16
|
+
constructor(reqResSocket: MotionMasterReqResSocket, pubSubSocket: MotionMasterPubSubSocket);
|
|
17
|
+
/**
|
|
18
|
+
* This observable will emit true when both req/res and pub/sub sockets are opened.
|
|
19
|
+
* If any socket gets closed, this observable will emit false.
|
|
20
|
+
* This is a hot observable that will on subscription emit the last value of sockets opened.
|
|
21
|
+
*/
|
|
22
|
+
socketsOpened$: Observable<boolean>;
|
|
23
|
+
/**
|
|
24
|
+
* Client is ready when both req/res and pub/sub sockets are opened.
|
|
25
|
+
* This observable will emit whenever the sockets opened property changes to true.
|
|
26
|
+
*/
|
|
27
|
+
ready$: Observable<true>;
|
|
28
|
+
/**
|
|
29
|
+
* This observable will emit only once when both req/res and pub/sub sockets are opened.
|
|
30
|
+
* NOTE: This observable might never emit and it doesn't timeout.
|
|
31
|
+
*/
|
|
32
|
+
onceReady$: Observable<true>;
|
|
33
|
+
/**
|
|
34
|
+
* Client is ready when both req/res and pub/sub sockets are opened.
|
|
35
|
+
* If both sockets are already opened, this function will immediately resolve to true.
|
|
36
|
+
* Otherwise, it will wait up to requestTimeout for both sockets to open, or throw an error.
|
|
37
|
+
*/
|
|
38
|
+
whenReady(requestTimeout?: number): Promise<true>;
|
|
39
|
+
/**
|
|
40
|
+
* Start monitoring.
|
|
41
|
+
*
|
|
42
|
+
* Note that the returned observable will never complete on its own.
|
|
43
|
+
*
|
|
44
|
+
* If you unsubscribe from it, the teardown code will send a request to the master to stop the monitoring.
|
|
45
|
+
* That means you will end up with an observable that is not complete, but it won't emit any values.
|
|
46
|
+
* This is fine when you want to use the monitoring observable directly in the template with async pipe,
|
|
47
|
+
* which will unsubscribe automatically and stop the monitoring when you leave the component.
|
|
48
|
+
*
|
|
49
|
+
* If you need to complete the observable so that, for example, the toArray() operator works as expected, then use the {@link DataMonitoring} class,
|
|
50
|
+
* which has a stop method. It can optionally buffer data for exporting as CSV or performing statistics on it.
|
|
51
|
+
*
|
|
52
|
+
* @param ids Device parameter IDs to monitor.
|
|
53
|
+
* @param monitoringInterval At what interval should the master application send values.
|
|
54
|
+
* @param config Configure the topic, buffer size, distinct.
|
|
55
|
+
* @param requestTimeout How long will the client wait for the master to confirm that monitoring has started.
|
|
56
|
+
* @returns An observable of an array of parameter values.
|
|
57
|
+
*/
|
|
58
|
+
startMonitoring(ids: DeviceParameterIds, monitoringInterval: number, config?: MonitoringConfig, requestTimeout?: number): Observable<ParameterValueType[]>;
|
|
59
|
+
/**
|
|
60
|
+
* TODO: return device parameters instead of just parameters
|
|
61
|
+
* get parameters from ESI uprfront, and then when parameters are received
|
|
62
|
+
* from motion master just concatenate (spread operator) props from ESI and props from parameter
|
|
63
|
+
* assign device parameter id like 0x1018:00.12345
|
|
64
|
+
* when assembling device parameter, get parameter from device in ESI based on product code, see ESI service
|
|
65
|
+
* this should probably done for other get parameters functions, get ESI file from device or prepared, get data from it
|
|
66
|
+
*/
|
|
67
|
+
startMonitoringDeviceParameters(ids: DeviceParameterIds, monitoringInterval: number, config?: MonitoringConfig, requestTimeout?: number): Observable<DeviceParameter[]>;
|
|
68
|
+
startMonitoringValue<T extends ParameterValueType = number>(id: string | [DeviceRef, number, number], monitoringInterval: number, config?: MonitoringConfig, requestTimeout?: number): Observable<T>;
|
|
69
|
+
trackTargetReached(deviceRef: DeviceRef, monitoringInterval?: number): Observable<boolean>;
|
|
70
|
+
waitUntilTargetReached(deviceRef: DeviceRef, monitoringInterval?: number): Observable<true>;
|
|
71
|
+
whenTargetReached(deviceRef: DeviceRef, monitoringInterval?: number): Promise<true>;
|
|
72
|
+
subscribeToSystemEvent(): void;
|
|
73
|
+
stopMonitoring(messageId: string): void;
|
|
74
|
+
stopMonitoringAll(): void;
|
|
75
|
+
closeSockets(): void;
|
|
76
|
+
reopenSockets(): void;
|
|
77
|
+
}
|
|
@@ -1,197 +1,197 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MotionMasterClient = exports.createMotionMasterClient = void 0;
|
|
4
|
-
const rxjs_1 = require("rxjs");
|
|
5
|
-
const uuid_1 = require("uuid");
|
|
6
|
-
const motion_master_pub_sub_client_1 = require("./motion-master-pub-sub-client");
|
|
7
|
-
const motion_master_pub_sub_web_socket_1 = require("./motion-master-pub-sub-web-socket");
|
|
8
|
-
const motion_master_req_res_client_1 = require("./motion-master-req-res-client");
|
|
9
|
-
const motion_master_req_res_web_socket_1 = require("./motion-master-req-res-web-socket");
|
|
10
|
-
const operators_1 = require("./operators");
|
|
11
|
-
const types_1 = require("./types");
|
|
12
|
-
function createMotionMasterClient(hostname) {
|
|
13
|
-
const reqResSocket = new motion_master_req_res_web_socket_1.MotionMasterReqResWebSocket();
|
|
14
|
-
const pubSubSocket = new motion_master_pub_sub_web_socket_1.MotionMasterPubSubWebSocket();
|
|
15
|
-
const client = new MotionMasterClient(reqResSocket, pubSubSocket);
|
|
16
|
-
const clientId = (0, uuid_1.v4)();
|
|
17
|
-
reqResSocket.open(`ws://${hostname}:63524?clientId=${clientId}`);
|
|
18
|
-
pubSubSocket.open(`ws://${hostname}:63525?clientId=${clientId}`);
|
|
19
|
-
return client;
|
|
20
|
-
}
|
|
21
|
-
exports.createMotionMasterClient = createMotionMasterClient;
|
|
22
|
-
class MotionMasterClient {
|
|
23
|
-
constructor(reqResSocket, pubSubSocket) {
|
|
24
|
-
this.reqResSocket = reqResSocket;
|
|
25
|
-
this.pubSubSocket = pubSubSocket;
|
|
26
|
-
/**
|
|
27
|
-
* This observable will emit true when both req/res and pub/sub sockets are opened.
|
|
28
|
-
* If any socket gets closed, this observable will emit false.
|
|
29
|
-
* This is a hot observable that will on subscription emit the last value of sockets opened.
|
|
30
|
-
*/
|
|
31
|
-
this.socketsOpened$ = (0, rxjs_1.combineLatest)([this.reqResSocket.opened$, this.pubSubSocket.opened$]).pipe((0, rxjs_1.map)(([reqResSocketOpened, pubSubSocketOpened]) => reqResSocketOpened && pubSubSocketOpened));
|
|
32
|
-
/**
|
|
33
|
-
* Client is ready when both req/res and pub/sub sockets are opened.
|
|
34
|
-
* This observable will emit whenever the sockets opened property changes to true.
|
|
35
|
-
*/
|
|
36
|
-
this.ready$ = this.socketsOpened$.pipe((0, rxjs_1.filter)(Boolean));
|
|
37
|
-
/**
|
|
38
|
-
* This observable will emit only once when both req/res and pub/sub sockets are opened.
|
|
39
|
-
* NOTE: This observable might never emit and it doesn't timeout.
|
|
40
|
-
*/
|
|
41
|
-
this.onceReady$ = this.ready$.pipe((0, rxjs_1.first)());
|
|
42
|
-
this.request = new motion_master_req_res_client_1.MotionMasterReqResClient(this.reqResSocket);
|
|
43
|
-
this.monitor = new motion_master_pub_sub_client_1.MotionMasterPubSubClient(this.pubSubSocket);
|
|
44
|
-
this.subscribeToSystemEvent();
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Client is ready when both req/res and pub/sub sockets are opened.
|
|
48
|
-
* If both sockets are already opened, this function will immediately resolve to true.
|
|
49
|
-
* Otherwise, it will wait up to requestTimeout for both sockets to open, or throw an error.
|
|
50
|
-
*/
|
|
51
|
-
whenReady(requestTimeout = 5000) {
|
|
52
|
-
return (0, rxjs_1.firstValueFrom)(this.ready$.pipe((0, rxjs_1.timeout)(requestTimeout)));
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Start monitoring.
|
|
56
|
-
*
|
|
57
|
-
* Note that the returned observable will never complete on its own.
|
|
58
|
-
*
|
|
59
|
-
* If you unsubscribe from it, the teardown code will send a request to the master to stop the monitoring.
|
|
60
|
-
* That means you will end up with an observable that is not complete, but it won't emit any values.
|
|
61
|
-
* This is fine when you want to use the monitoring observable directly in the template with async pipe,
|
|
62
|
-
* which will unsubscribe automatically and stop the monitoring when you leave the component.
|
|
63
|
-
*
|
|
64
|
-
* If you need to complete the observable so that, for example, the toArray() operator works as expected, then use the {@link DataMonitoring} class,
|
|
65
|
-
* which has a stop method. It can optionally buffer data for exporting as CSV or performing statistics on it.
|
|
66
|
-
*
|
|
67
|
-
* @param ids Device parameter IDs to monitor.
|
|
68
|
-
* @param monitoringInterval At what interval should the master application send values.
|
|
69
|
-
* @param config Configure the topic, buffer size, distinct.
|
|
70
|
-
* @param requestTimeout How long will the client wait for the master to confirm that monitoring has started.
|
|
71
|
-
* @returns An observable of an array of parameter values.
|
|
72
|
-
*/
|
|
73
|
-
startMonitoring(ids, monitoringInterval, config, requestTimeout = 5000) {
|
|
74
|
-
return (0, rxjs_1.defer)(() => {
|
|
75
|
-
var _a, _b;
|
|
76
|
-
const topic = (_a = config === null || config === void 0 ? void 0 : config.topic) !== null && _a !== void 0 ? _a : (0, uuid_1.v4)();
|
|
77
|
-
const messageId = (_b = config === null || config === void 0 ? void 0 : config.messageId) !== null && _b !== void 0 ? _b : (0, uuid_1.v4)();
|
|
78
|
-
if (!config) {
|
|
79
|
-
config = { messageId, topic, bufferSize: 1, distinct: false };
|
|
80
|
-
}
|
|
81
|
-
this.request.resolveGetParameterValuesIds(ids).pipe((0, rxjs_1.mergeMap)((refs) => {
|
|
82
|
-
if ((new Set(refs.map(([deviceAddress]) => deviceAddress))).size !== 1) {
|
|
83
|
-
throw new Error('Start monitoring only supports a single device');
|
|
84
|
-
}
|
|
85
|
-
// Skipping write-only (wo) parameters is necessary because Motion Master does not initiate monitoring when the requested list contains such parameters.
|
|
86
|
-
// For now, this serves as a temporary solution until Motion Master is fixed.
|
|
87
|
-
refs = refs.filter(([, index]) => index !== 0x1024);
|
|
88
|
-
const deviceAddress = refs[0][0];
|
|
89
|
-
const props = {
|
|
90
|
-
getDeviceParameterValues: {
|
|
91
|
-
deviceAddress,
|
|
92
|
-
parameters: refs.map(([, index, subindex]) => ({ index, subindex, loadFromCache: false })),
|
|
93
|
-
sendProgress: false,
|
|
94
|
-
},
|
|
95
|
-
interval: monitoringInterval,
|
|
96
|
-
topic,
|
|
97
|
-
};
|
|
98
|
-
return this.request.startMonitoringDeviceParameterValues(props, requestTimeout, messageId);
|
|
99
|
-
})).subscribe();
|
|
100
|
-
this.monitor.subscribe(config);
|
|
101
|
-
const values$ = this.monitor.socket.data$.pipe((0, operators_1.selectMotionMasterMessageByTopic)(config.topic), (0, operators_1.mapMonitoringParameterValuesStatusMessageToParameterValues)());
|
|
102
|
-
return new rxjs_1.Observable((observer) => {
|
|
103
|
-
const subscription = values$.subscribe(observer).add(() => {
|
|
104
|
-
this.stopMonitoring(messageId);
|
|
105
|
-
});
|
|
106
|
-
return subscription;
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* TODO: return device parameters instead of just parameters
|
|
112
|
-
* get parameters from ESI uprfront, and then when parameters are received
|
|
113
|
-
* from motion master just concatenate (spread operator) props from ESI and props from parameter
|
|
114
|
-
* assign device parameter id like 0x1018:00.12345
|
|
115
|
-
* when assembling device parameter, get parameter from device in ESI based on product code, see ESI service
|
|
116
|
-
* this should probably done for other get parameters functions, get ESI file from device or prepared, get data from it
|
|
117
|
-
*/
|
|
118
|
-
startMonitoringDeviceParameters(ids, monitoringInterval, config, requestTimeout = 5000) {
|
|
119
|
-
return (0, rxjs_1.defer)(() => {
|
|
120
|
-
var _a, _b;
|
|
121
|
-
const topic = (_a = config === null || config === void 0 ? void 0 : config.topic) !== null && _a !== void 0 ? _a : (0, uuid_1.v4)();
|
|
122
|
-
const messageId = (_b = config === null || config === void 0 ? void 0 : config.messageId) !== null && _b !== void 0 ? _b : (0, uuid_1.v4)();
|
|
123
|
-
if (!config) {
|
|
124
|
-
config = { messageId, topic, bufferSize: 1, distinct: false };
|
|
125
|
-
}
|
|
126
|
-
this.request.resolveGetParameterValuesIds(ids).pipe((0, rxjs_1.mergeMap)((refs) => {
|
|
127
|
-
if ((new Set(refs.map(([deviceAddress]) => deviceAddress))).size !== 1) {
|
|
128
|
-
throw new Error('Start monitoring only supports a single device');
|
|
129
|
-
}
|
|
130
|
-
// Skipping write-only (wo) parameters is necessary because Motion Master does not initiate monitoring when the requested list contains such parameters.
|
|
131
|
-
// For now, this serves as a temporary solution until Motion Master is fixed.
|
|
132
|
-
refs = refs.filter(([, index]) => index !== 0x1024);
|
|
133
|
-
const deviceAddress = refs[0][0];
|
|
134
|
-
const props = {
|
|
135
|
-
getDeviceParameterValues: {
|
|
136
|
-
deviceAddress,
|
|
137
|
-
parameters: refs.map(([, index, subindex]) => ({ index, subindex, loadFromCache: false })),
|
|
138
|
-
sendProgress: false,
|
|
139
|
-
},
|
|
140
|
-
interval: monitoringInterval,
|
|
141
|
-
topic,
|
|
142
|
-
};
|
|
143
|
-
return this.request.startMonitoringDeviceParameterValues(props, requestTimeout, messageId);
|
|
144
|
-
})).subscribe();
|
|
145
|
-
this.monitor.subscribe(config);
|
|
146
|
-
const values$ = this.monitor.socket.data$.pipe((0, operators_1.selectMotionMasterMessageByTopic)(config.topic), (0, operators_1.mapMonitoringParameterValuesStatusMessageToDeviceParameters)(this.request));
|
|
147
|
-
return new rxjs_1.Observable((observer) => {
|
|
148
|
-
const subscription = values$.subscribe(observer).add(() => {
|
|
149
|
-
this.stopMonitoring(messageId);
|
|
150
|
-
});
|
|
151
|
-
return subscription;
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
startMonitoringValue(id, monitoringInterval, config, requestTimeout = 5000) {
|
|
156
|
-
const ids = typeof id === 'string' ? [id] : [id];
|
|
157
|
-
return this.startMonitoring(ids, monitoringInterval, config, requestTimeout).pipe((0, rxjs_1.map)((parameters) => { var _a; return ((_a = parameters[0]) !== null && _a !== void 0 ? _a : 0); }));
|
|
158
|
-
}
|
|
159
|
-
trackTargetReached(deviceRef, monitoringInterval = 20) {
|
|
160
|
-
return this.startMonitoringValue([deviceRef, 0x6041, 0], monitoringInterval).pipe((0, rxjs_1.map)((value) => (value & 0x0400) > 0), // tr = target reached bit
|
|
161
|
-
(0, rxjs_1.distinctUntilChanged)());
|
|
162
|
-
}
|
|
163
|
-
waitUntilTargetReached(deviceRef, monitoringInterval = 20) {
|
|
164
|
-
return this.trackTargetReached(deviceRef, monitoringInterval).pipe((0, rxjs_1.filter)(Boolean), (0, rxjs_1.first)());
|
|
165
|
-
}
|
|
166
|
-
whenTargetReached(deviceRef, monitoringInterval = 20) {
|
|
167
|
-
return (0, rxjs_1.firstValueFrom)(this.waitUntilTargetReached(deviceRef, monitoringInterval));
|
|
168
|
-
}
|
|
169
|
-
subscribeToSystemEvent() {
|
|
170
|
-
this.systemEventSubscription = this.monitor.systemEvent$.subscribe(systemEvent => {
|
|
171
|
-
if (systemEvent.state === types_1.MotionMasterMessage.Status.SystemEvent.State.DEINITIALIZING) {
|
|
172
|
-
this.request.clearDevicesInformation();
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
stopMonitoring(messageId) {
|
|
177
|
-
this.request.stopMonitoringDeviceParameterValues({ startMonitoringRequestId: messageId });
|
|
178
|
-
this.monitor.unsubscribe(messageId);
|
|
179
|
-
}
|
|
180
|
-
stopMonitoringAll() {
|
|
181
|
-
this.monitor.messageIds.forEach(this.stopMonitoring);
|
|
182
|
-
}
|
|
183
|
-
closeSockets() {
|
|
184
|
-
var _a;
|
|
185
|
-
(_a = this.systemEventSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
186
|
-
this.request.clearDevicesInformation();
|
|
187
|
-
this.reqResSocket.close();
|
|
188
|
-
this.pubSubSocket.close();
|
|
189
|
-
}
|
|
190
|
-
reopenSockets() {
|
|
191
|
-
this.reqResSocket.reopen();
|
|
192
|
-
this.pubSubSocket.reopen();
|
|
193
|
-
this.subscribeToSystemEvent();
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
exports.MotionMasterClient = MotionMasterClient;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MotionMasterClient = exports.createMotionMasterClient = void 0;
|
|
4
|
+
const rxjs_1 = require("rxjs");
|
|
5
|
+
const uuid_1 = require("uuid");
|
|
6
|
+
const motion_master_pub_sub_client_1 = require("./motion-master-pub-sub-client");
|
|
7
|
+
const motion_master_pub_sub_web_socket_1 = require("./motion-master-pub-sub-web-socket");
|
|
8
|
+
const motion_master_req_res_client_1 = require("./motion-master-req-res-client");
|
|
9
|
+
const motion_master_req_res_web_socket_1 = require("./motion-master-req-res-web-socket");
|
|
10
|
+
const operators_1 = require("./operators");
|
|
11
|
+
const types_1 = require("./types");
|
|
12
|
+
function createMotionMasterClient(hostname) {
|
|
13
|
+
const reqResSocket = new motion_master_req_res_web_socket_1.MotionMasterReqResWebSocket();
|
|
14
|
+
const pubSubSocket = new motion_master_pub_sub_web_socket_1.MotionMasterPubSubWebSocket();
|
|
15
|
+
const client = new MotionMasterClient(reqResSocket, pubSubSocket);
|
|
16
|
+
const clientId = (0, uuid_1.v4)();
|
|
17
|
+
reqResSocket.open(`ws://${hostname}:63524?clientId=${clientId}`);
|
|
18
|
+
pubSubSocket.open(`ws://${hostname}:63525?clientId=${clientId}`);
|
|
19
|
+
return client;
|
|
20
|
+
}
|
|
21
|
+
exports.createMotionMasterClient = createMotionMasterClient;
|
|
22
|
+
class MotionMasterClient {
|
|
23
|
+
constructor(reqResSocket, pubSubSocket) {
|
|
24
|
+
this.reqResSocket = reqResSocket;
|
|
25
|
+
this.pubSubSocket = pubSubSocket;
|
|
26
|
+
/**
|
|
27
|
+
* This observable will emit true when both req/res and pub/sub sockets are opened.
|
|
28
|
+
* If any socket gets closed, this observable will emit false.
|
|
29
|
+
* This is a hot observable that will on subscription emit the last value of sockets opened.
|
|
30
|
+
*/
|
|
31
|
+
this.socketsOpened$ = (0, rxjs_1.combineLatest)([this.reqResSocket.opened$, this.pubSubSocket.opened$]).pipe((0, rxjs_1.map)(([reqResSocketOpened, pubSubSocketOpened]) => reqResSocketOpened && pubSubSocketOpened));
|
|
32
|
+
/**
|
|
33
|
+
* Client is ready when both req/res and pub/sub sockets are opened.
|
|
34
|
+
* This observable will emit whenever the sockets opened property changes to true.
|
|
35
|
+
*/
|
|
36
|
+
this.ready$ = this.socketsOpened$.pipe((0, rxjs_1.filter)(Boolean));
|
|
37
|
+
/**
|
|
38
|
+
* This observable will emit only once when both req/res and pub/sub sockets are opened.
|
|
39
|
+
* NOTE: This observable might never emit and it doesn't timeout.
|
|
40
|
+
*/
|
|
41
|
+
this.onceReady$ = this.ready$.pipe((0, rxjs_1.first)());
|
|
42
|
+
this.request = new motion_master_req_res_client_1.MotionMasterReqResClient(this.reqResSocket);
|
|
43
|
+
this.monitor = new motion_master_pub_sub_client_1.MotionMasterPubSubClient(this.pubSubSocket);
|
|
44
|
+
this.subscribeToSystemEvent();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Client is ready when both req/res and pub/sub sockets are opened.
|
|
48
|
+
* If both sockets are already opened, this function will immediately resolve to true.
|
|
49
|
+
* Otherwise, it will wait up to requestTimeout for both sockets to open, or throw an error.
|
|
50
|
+
*/
|
|
51
|
+
whenReady(requestTimeout = 5000) {
|
|
52
|
+
return (0, rxjs_1.firstValueFrom)(this.ready$.pipe((0, rxjs_1.timeout)(requestTimeout)));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Start monitoring.
|
|
56
|
+
*
|
|
57
|
+
* Note that the returned observable will never complete on its own.
|
|
58
|
+
*
|
|
59
|
+
* If you unsubscribe from it, the teardown code will send a request to the master to stop the monitoring.
|
|
60
|
+
* That means you will end up with an observable that is not complete, but it won't emit any values.
|
|
61
|
+
* This is fine when you want to use the monitoring observable directly in the template with async pipe,
|
|
62
|
+
* which will unsubscribe automatically and stop the monitoring when you leave the component.
|
|
63
|
+
*
|
|
64
|
+
* If you need to complete the observable so that, for example, the toArray() operator works as expected, then use the {@link DataMonitoring} class,
|
|
65
|
+
* which has a stop method. It can optionally buffer data for exporting as CSV or performing statistics on it.
|
|
66
|
+
*
|
|
67
|
+
* @param ids Device parameter IDs to monitor.
|
|
68
|
+
* @param monitoringInterval At what interval should the master application send values.
|
|
69
|
+
* @param config Configure the topic, buffer size, distinct.
|
|
70
|
+
* @param requestTimeout How long will the client wait for the master to confirm that monitoring has started.
|
|
71
|
+
* @returns An observable of an array of parameter values.
|
|
72
|
+
*/
|
|
73
|
+
startMonitoring(ids, monitoringInterval, config, requestTimeout = 5000) {
|
|
74
|
+
return (0, rxjs_1.defer)(() => {
|
|
75
|
+
var _a, _b;
|
|
76
|
+
const topic = (_a = config === null || config === void 0 ? void 0 : config.topic) !== null && _a !== void 0 ? _a : (0, uuid_1.v4)();
|
|
77
|
+
const messageId = (_b = config === null || config === void 0 ? void 0 : config.messageId) !== null && _b !== void 0 ? _b : (0, uuid_1.v4)();
|
|
78
|
+
if (!config) {
|
|
79
|
+
config = { messageId, topic, bufferSize: 1, distinct: false };
|
|
80
|
+
}
|
|
81
|
+
this.request.resolveGetParameterValuesIds(ids).pipe((0, rxjs_1.mergeMap)((refs) => {
|
|
82
|
+
if ((new Set(refs.map(([deviceAddress]) => deviceAddress))).size !== 1) {
|
|
83
|
+
throw new Error('Start monitoring only supports a single device');
|
|
84
|
+
}
|
|
85
|
+
// Skipping write-only (wo) parameters is necessary because Motion Master does not initiate monitoring when the requested list contains such parameters.
|
|
86
|
+
// For now, this serves as a temporary solution until Motion Master is fixed.
|
|
87
|
+
refs = refs.filter(([, index]) => index !== 0x1024);
|
|
88
|
+
const deviceAddress = refs[0][0];
|
|
89
|
+
const props = {
|
|
90
|
+
getDeviceParameterValues: {
|
|
91
|
+
deviceAddress,
|
|
92
|
+
parameters: refs.map(([, index, subindex]) => ({ index, subindex, loadFromCache: false })),
|
|
93
|
+
sendProgress: false,
|
|
94
|
+
},
|
|
95
|
+
interval: monitoringInterval,
|
|
96
|
+
topic,
|
|
97
|
+
};
|
|
98
|
+
return this.request.startMonitoringDeviceParameterValues(props, requestTimeout, messageId);
|
|
99
|
+
})).subscribe();
|
|
100
|
+
this.monitor.subscribe(config);
|
|
101
|
+
const values$ = this.monitor.socket.data$.pipe((0, operators_1.selectMotionMasterMessageByTopic)(config.topic), (0, operators_1.mapMonitoringParameterValuesStatusMessageToParameterValues)());
|
|
102
|
+
return new rxjs_1.Observable((observer) => {
|
|
103
|
+
const subscription = values$.subscribe(observer).add(() => {
|
|
104
|
+
this.stopMonitoring(messageId);
|
|
105
|
+
});
|
|
106
|
+
return subscription;
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* TODO: return device parameters instead of just parameters
|
|
112
|
+
* get parameters from ESI uprfront, and then when parameters are received
|
|
113
|
+
* from motion master just concatenate (spread operator) props from ESI and props from parameter
|
|
114
|
+
* assign device parameter id like 0x1018:00.12345
|
|
115
|
+
* when assembling device parameter, get parameter from device in ESI based on product code, see ESI service
|
|
116
|
+
* this should probably done for other get parameters functions, get ESI file from device or prepared, get data from it
|
|
117
|
+
*/
|
|
118
|
+
startMonitoringDeviceParameters(ids, monitoringInterval, config, requestTimeout = 5000) {
|
|
119
|
+
return (0, rxjs_1.defer)(() => {
|
|
120
|
+
var _a, _b;
|
|
121
|
+
const topic = (_a = config === null || config === void 0 ? void 0 : config.topic) !== null && _a !== void 0 ? _a : (0, uuid_1.v4)();
|
|
122
|
+
const messageId = (_b = config === null || config === void 0 ? void 0 : config.messageId) !== null && _b !== void 0 ? _b : (0, uuid_1.v4)();
|
|
123
|
+
if (!config) {
|
|
124
|
+
config = { messageId, topic, bufferSize: 1, distinct: false };
|
|
125
|
+
}
|
|
126
|
+
this.request.resolveGetParameterValuesIds(ids).pipe((0, rxjs_1.mergeMap)((refs) => {
|
|
127
|
+
if ((new Set(refs.map(([deviceAddress]) => deviceAddress))).size !== 1) {
|
|
128
|
+
throw new Error('Start monitoring only supports a single device');
|
|
129
|
+
}
|
|
130
|
+
// Skipping write-only (wo) parameters is necessary because Motion Master does not initiate monitoring when the requested list contains such parameters.
|
|
131
|
+
// For now, this serves as a temporary solution until Motion Master is fixed.
|
|
132
|
+
refs = refs.filter(([, index]) => index !== 0x1024);
|
|
133
|
+
const deviceAddress = refs[0][0];
|
|
134
|
+
const props = {
|
|
135
|
+
getDeviceParameterValues: {
|
|
136
|
+
deviceAddress,
|
|
137
|
+
parameters: refs.map(([, index, subindex]) => ({ index, subindex, loadFromCache: false })),
|
|
138
|
+
sendProgress: false,
|
|
139
|
+
},
|
|
140
|
+
interval: monitoringInterval,
|
|
141
|
+
topic,
|
|
142
|
+
};
|
|
143
|
+
return this.request.startMonitoringDeviceParameterValues(props, requestTimeout, messageId);
|
|
144
|
+
})).subscribe();
|
|
145
|
+
this.monitor.subscribe(config);
|
|
146
|
+
const values$ = this.monitor.socket.data$.pipe((0, operators_1.selectMotionMasterMessageByTopic)(config.topic), (0, operators_1.mapMonitoringParameterValuesStatusMessageToDeviceParameters)(this.request));
|
|
147
|
+
return new rxjs_1.Observable((observer) => {
|
|
148
|
+
const subscription = values$.subscribe(observer).add(() => {
|
|
149
|
+
this.stopMonitoring(messageId);
|
|
150
|
+
});
|
|
151
|
+
return subscription;
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
startMonitoringValue(id, monitoringInterval, config, requestTimeout = 5000) {
|
|
156
|
+
const ids = typeof id === 'string' ? [id] : [id];
|
|
157
|
+
return this.startMonitoring(ids, monitoringInterval, config, requestTimeout).pipe((0, rxjs_1.map)((parameters) => { var _a; return ((_a = parameters[0]) !== null && _a !== void 0 ? _a : 0); }));
|
|
158
|
+
}
|
|
159
|
+
trackTargetReached(deviceRef, monitoringInterval = 20) {
|
|
160
|
+
return this.startMonitoringValue([deviceRef, 0x6041, 0], monitoringInterval).pipe((0, rxjs_1.map)((value) => (value & 0x0400) > 0), // tr = target reached bit
|
|
161
|
+
(0, rxjs_1.distinctUntilChanged)());
|
|
162
|
+
}
|
|
163
|
+
waitUntilTargetReached(deviceRef, monitoringInterval = 20) {
|
|
164
|
+
return this.trackTargetReached(deviceRef, monitoringInterval).pipe((0, rxjs_1.filter)(Boolean), (0, rxjs_1.first)());
|
|
165
|
+
}
|
|
166
|
+
whenTargetReached(deviceRef, monitoringInterval = 20) {
|
|
167
|
+
return (0, rxjs_1.firstValueFrom)(this.waitUntilTargetReached(deviceRef, monitoringInterval));
|
|
168
|
+
}
|
|
169
|
+
subscribeToSystemEvent() {
|
|
170
|
+
this.systemEventSubscription = this.monitor.systemEvent$.subscribe(systemEvent => {
|
|
171
|
+
if (systemEvent.state === types_1.MotionMasterMessage.Status.SystemEvent.State.DEINITIALIZING) {
|
|
172
|
+
this.request.clearDevicesInformation();
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
stopMonitoring(messageId) {
|
|
177
|
+
this.request.stopMonitoringDeviceParameterValues({ startMonitoringRequestId: messageId });
|
|
178
|
+
this.monitor.unsubscribe(messageId);
|
|
179
|
+
}
|
|
180
|
+
stopMonitoringAll() {
|
|
181
|
+
this.monitor.messageIds.forEach(this.stopMonitoring);
|
|
182
|
+
}
|
|
183
|
+
closeSockets() {
|
|
184
|
+
var _a;
|
|
185
|
+
(_a = this.systemEventSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
186
|
+
this.request.clearDevicesInformation();
|
|
187
|
+
this.reqResSocket.close();
|
|
188
|
+
this.pubSubSocket.close();
|
|
189
|
+
}
|
|
190
|
+
reopenSockets() {
|
|
191
|
+
this.reqResSocket.reopen();
|
|
192
|
+
this.pubSubSocket.reopen();
|
|
193
|
+
this.subscribeToSystemEvent();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
exports.MotionMasterClient = MotionMasterClient;
|
|
197
197
|
//# sourceMappingURL=motion-master-client.js.map
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { Observable, Subject } from "rxjs";
|
|
2
|
-
import { MonitoringConfig } from "./monitoring-config";
|
|
3
|
-
import { MotionMasterPubSubSocket } from "./motion-master-pub-sub-socket";
|
|
4
|
-
import { IMotionMasterMessage, MotionMasterMessage } from "./types";
|
|
5
|
-
export declare class MotionMasterPubSubClient {
|
|
6
|
-
readonly socket: MotionMasterPubSubSocket;
|
|
7
|
-
readonly data$: Subject<[string, IMotionMasterMessage[]]>;
|
|
8
|
-
private subscriptions;
|
|
9
|
-
readonly notification$: Observable<IMotionMasterMessage>;
|
|
10
|
-
readonly systemEvent$: Observable<MotionMasterMessage.Status.ISystemEvent>;
|
|
11
|
-
readonly deviceEvent$: Observable<MotionMasterMessage.Status.IDeviceEvent>;
|
|
12
|
-
constructor(socket: MotionMasterPubSubSocket);
|
|
13
|
-
get messageIds(): string[];
|
|
14
|
-
subscribe(config: MonitoringConfig): string;
|
|
15
|
-
unsubscribe(messageId: string): void;
|
|
16
|
-
unsubscribeAll(): void;
|
|
17
|
-
}
|
|
1
|
+
import { Observable, Subject } from "rxjs";
|
|
2
|
+
import { MonitoringConfig } from "./monitoring-config";
|
|
3
|
+
import { MotionMasterPubSubSocket } from "./motion-master-pub-sub-socket";
|
|
4
|
+
import { IMotionMasterMessage, MotionMasterMessage } from "./types";
|
|
5
|
+
export declare class MotionMasterPubSubClient {
|
|
6
|
+
readonly socket: MotionMasterPubSubSocket;
|
|
7
|
+
readonly data$: Subject<[string, IMotionMasterMessage[]]>;
|
|
8
|
+
private subscriptions;
|
|
9
|
+
readonly notification$: Observable<IMotionMasterMessage>;
|
|
10
|
+
readonly systemEvent$: Observable<MotionMasterMessage.Status.ISystemEvent>;
|
|
11
|
+
readonly deviceEvent$: Observable<MotionMasterMessage.Status.IDeviceEvent>;
|
|
12
|
+
constructor(socket: MotionMasterPubSubSocket);
|
|
13
|
+
get messageIds(): string[];
|
|
14
|
+
subscribe(config: MonitoringConfig): string;
|
|
15
|
+
unsubscribe(messageId: string): void;
|
|
16
|
+
unsubscribeAll(): void;
|
|
17
|
+
}
|