vrack2-core 0.0.1 → 1.0.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/README.md +25 -4
- package/docs/Bootstrap.md +77 -0
- package/docs/Container.md +124 -0
- package/docs/Device.md +272 -0
- package/docs/FastStart.md +111 -0
- package/docs/Structure.md +148 -0
- package/lib/Bootstrap.d.ts +79 -0
- package/lib/Bootstrap.js +103 -0
- package/lib/Container.d.ts +202 -6
- package/lib/Container.js +295 -27
- package/lib/IServiceStructure.d.ts +8 -0
- package/lib/IStructureDevice.d.ts +5 -0
- package/lib/ImportManager.d.ts +85 -3
- package/lib/ImportManager.js +122 -16
- package/lib/MainProcess.d.ts +30 -3
- package/lib/MainProcess.js +28 -6
- package/lib/Utility.d.ts +15 -21
- package/lib/Utility.js +40 -40
- package/lib/actions/Action.d.ts +10 -0
- package/lib/actions/Action.js +10 -0
- package/lib/actions/BasicAction.d.ts +60 -0
- package/lib/actions/BasicAction.js +62 -0
- package/lib/actions/GlobalAction.d.ts +5 -0
- package/lib/actions/GlobalAction.js +5 -0
- package/lib/actions/IAction.d.ts +7 -0
- package/lib/actions/ILocalAction.d.ts +7 -0
- package/lib/boot/BootClass.d.ts +93 -0
- package/lib/boot/BootClass.js +101 -0
- package/lib/boot/DeviceFileStorage.d.ts +38 -0
- package/lib/boot/DeviceFileStorage.js +112 -0
- package/lib/boot/DeviceManager.d.ts +190 -0
- package/lib/boot/DeviceManager.js +306 -0
- package/lib/boot/DeviceMetrics.d.ts +82 -0
- package/lib/boot/DeviceMetrics.js +128 -0
- package/lib/boot/StructureStorage.d.ts +59 -0
- package/lib/boot/StructureStorage.js +125 -0
- package/lib/errors/CoreError.d.ts +42 -25
- package/lib/errors/CoreError.js +44 -24
- package/lib/errors/ErrorManager.d.ts +18 -20
- package/lib/errors/ErrorManager.js +23 -22
- package/lib/index.d.ts +20 -4
- package/lib/index.js +28 -4
- package/lib/metrics/BasicMetric.d.ts +49 -0
- package/lib/metrics/BasicMetric.js +79 -0
- package/lib/metrics/IMetricSettings.d.ts +32 -0
- package/lib/metrics/IMetricSettings.js +2 -0
- package/lib/metrics/IvMs.d.ts +9 -0
- package/lib/metrics/IvMs.js +22 -0
- package/lib/metrics/IvS.d.ts +9 -0
- package/lib/metrics/IvS.js +22 -0
- package/lib/metrics/IvUs.d.ts +9 -0
- package/lib/metrics/IvUs.js +22 -0
- package/lib/metrics/Metric.d.ts +17 -0
- package/lib/metrics/Metric.js +27 -0
- package/lib/ports/BasicPort.d.ts +39 -0
- package/lib/ports/BasicPort.js +39 -0
- package/lib/ports/ILocalPort.d.ts +7 -0
- package/lib/ports/IPort.d.ts +7 -0
- package/lib/ports/Port.d.ts +10 -0
- package/lib/ports/Port.js +10 -0
- package/lib/ports/ReturnPort.d.ts +5 -0
- package/lib/ports/ReturnPort.js +5 -0
- package/lib/service/Device.d.ts +213 -78
- package/lib/service/Device.js +185 -83
- package/lib/service/DeviceConnect.d.ts +4 -8
- package/lib/service/DeviceConnect.js +4 -8
- package/lib/service/DevicePort.d.ts +15 -6
- package/lib/service/DevicePort.js +29 -12
- package/lib/service/IDeviceEvent.d.ts +4 -1
- package/lib/validator/IValidationProblem.d.ts +7 -0
- package/lib/validator/IValidationRule.d.ts +12 -0
- package/lib/validator/IValidationSubrule.d.ts +2 -0
- package/lib/validator/Rule.d.ts +6 -2
- package/lib/validator/Rule.js +12 -2
- package/lib/validator/Validator.d.ts +48 -3
- package/lib/validator/Validator.js +70 -18
- package/lib/validator/types/AnyType.d.ts +17 -0
- package/lib/validator/types/AnyType.js +34 -0
- package/lib/validator/types/ArrayType.d.ts +37 -4
- package/lib/validator/types/ArrayType.js +42 -6
- package/lib/validator/types/BasicType.d.ts +67 -7
- package/lib/validator/types/BasicType.js +74 -8
- package/lib/validator/types/BooleanType.d.ts +23 -0
- package/lib/validator/types/BooleanType.js +47 -0
- package/lib/validator/types/FunctionType.d.ts +17 -0
- package/lib/validator/types/FunctionType.js +38 -0
- package/lib/validator/types/NumberType.d.ts +40 -5
- package/lib/validator/types/NumberType.js +53 -14
- package/lib/validator/types/ObjectType.d.ts +32 -5
- package/lib/validator/types/ObjectType.js +42 -8
- package/lib/validator/types/StringType.d.ts +30 -5
- package/lib/validator/types/StringType.js +33 -7
- package/package.json +10 -9
- package/src/Bootstrap.ts +122 -0
- package/src/Container.ts +411 -43
- package/src/IServiceStructure.ts +9 -0
- package/src/IStructureDevice.ts +5 -0
- package/src/ImportManager.ts +119 -11
- package/src/MainProcess.ts +53 -8
- package/src/Utility.ts +35 -36
- package/src/actions/Action.ts +12 -0
- package/src/actions/BasicAction.ts +63 -0
- package/src/actions/GlobalAction.ts +5 -0
- package/src/actions/IAction.ts +7 -0
- package/src/actions/ILocalAction.ts +7 -0
- package/src/boot/BootClass.ts +117 -0
- package/src/boot/DeviceFileStorage.ts +96 -0
- package/src/boot/DeviceManager.ts +339 -0
- package/src/boot/DeviceMetrics.ts +129 -0
- package/src/boot/StructureStorage.ts +108 -0
- package/src/errors/CoreError.ts +52 -26
- package/src/errors/ErrorManager.ts +46 -33
- package/src/index.ts +30 -6
- package/src/metrics/BasicMetric.ts +84 -0
- package/src/metrics/IMetricSettings.ts +38 -0
- package/src/metrics/IvMs.ts +18 -0
- package/src/metrics/IvS.ts +18 -0
- package/src/metrics/IvUs.ts +17 -0
- package/src/metrics/Metric.ts +25 -0
- package/src/ports/BasicPort.ts +39 -0
- package/src/ports/ILocalPort.ts +7 -0
- package/src/ports/IPort.ts +7 -0
- package/src/ports/Port.ts +11 -1
- package/src/ports/ReturnPort.ts +5 -0
- package/src/service/Device.ts +234 -103
- package/src/service/DeviceConnect.ts +4 -8
- package/src/service/DevicePort.ts +30 -11
- package/src/service/IDeviceEvent.ts +4 -1
- package/src/validator/IValidationProblem.ts +7 -0
- package/src/validator/IValidationRule.ts +12 -0
- package/src/validator/IValidationSubrule.ts +3 -0
- package/src/validator/Rule.ts +16 -2
- package/src/validator/Validator.ts +74 -23
- package/src/validator/types/AnyType.ts +32 -0
- package/src/validator/types/ArrayType.ts +43 -7
- package/src/validator/types/BasicType.ts +78 -9
- package/src/validator/types/BooleanType.ts +49 -0
- package/src/validator/types/FunctionType.ts +39 -0
- package/src/validator/types/NumberType.ts +53 -15
- package/src/validator/types/ObjectType.ts +52 -14
- package/src/validator/types/StringType.ts +34 -10
- package/docs/RU-README.md +0 -6
- package/lib/DeviceManager.d.ts +0 -32
- package/lib/DeviceManager.js +0 -143
- package/lib/test.d.ts +0 -1
- package/lib/test.js +0 -58
- package/src/DeviceManager.ts +0 -124
- package/src/test.ts +0 -82
package/lib/Container.js
CHANGED
|
@@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
const events_1 = __importDefault(require("events"));
|
|
16
|
+
const DeviceManager_1 = __importDefault(require("./boot/DeviceManager"));
|
|
16
17
|
const ErrorManager_1 = __importDefault(require("./errors/ErrorManager"));
|
|
17
18
|
const Rule_1 = __importDefault(require("./validator/Rule"));
|
|
18
19
|
const CoreError_1 = __importDefault(require("./errors/CoreError"));
|
|
@@ -20,6 +21,9 @@ const Validator_1 = __importDefault(require("./validator/Validator"));
|
|
|
20
21
|
const ImportManager_1 = __importDefault(require("./ImportManager"));
|
|
21
22
|
const DevicePort_1 = __importDefault(require("./service/DevicePort"));
|
|
22
23
|
const DeviceConnect_1 = __importDefault(require("./service/DeviceConnect"));
|
|
24
|
+
const Utility_1 = __importDefault(require("./Utility"));
|
|
25
|
+
const fs_1 = require("fs");
|
|
26
|
+
/***** ******** DEVICE ERROR ********************/
|
|
23
27
|
ErrorManager_1.default.register('Container', 'FBDRkSAWnlcc', 'CTR_ERROR_INIT_DEVICE', 'Device initialization error', {
|
|
24
28
|
deviceConfig: Rule_1.default.object().description('Device configuration')
|
|
25
29
|
});
|
|
@@ -32,9 +36,24 @@ ErrorManager_1.default.register('Container', '2RZznI3JDNUW', 'CTR_ERROR_PREPARE_
|
|
|
32
36
|
message: Rule_1.default.string().description('Exception error string')
|
|
33
37
|
});
|
|
34
38
|
ErrorManager_1.default.register('Container', 'NDW2oD7mFxqB', 'CTR_DEVICE_ACTION_NF', 'Action on device not found', {
|
|
39
|
+
device: Rule_1.default.string().description('Device ID'),
|
|
35
40
|
action: Rule_1.default.string().description('Action name'),
|
|
36
|
-
method: Rule_1.default.string().description('Method name')
|
|
41
|
+
method: Rule_1.default.string().description('Method name'),
|
|
37
42
|
});
|
|
43
|
+
ErrorManager_1.default.register('Container', 'XOXLMVCN9OBI', 'CTR_DEVICE_NF', 'Device in container found', {
|
|
44
|
+
device: Rule_1.default.string().description('Device ID'),
|
|
45
|
+
});
|
|
46
|
+
ErrorManager_1.default.register('Container', '570RD59JEYVN', 'CTR_DEVICE_ACTION_HANDLER_NF', 'Device handler action not found', {
|
|
47
|
+
device: Rule_1.default.string().description('Device ID'),
|
|
48
|
+
action: Rule_1.default.string().description('Device action name'),
|
|
49
|
+
});
|
|
50
|
+
ErrorManager_1.default.register('Container', 'RJV0KT2DFZBZ', 'CTR_DEVICE_PROCESS_EXCEPTION', 'During process execution - the device threw an exception', {
|
|
51
|
+
device: Rule_1.default.string().description('Device ID'),
|
|
52
|
+
});
|
|
53
|
+
ErrorManager_1.default.register('Container', 'K65XWSYOBVFG', 'CTR_DEVICE_PROCESS_PROMISE_EXCEPTION', 'During processPromise execution - the device threw an exception', {
|
|
54
|
+
device: Rule_1.default.string().description('Device ID'),
|
|
55
|
+
});
|
|
56
|
+
/***** ******** PORTS ERROR ********************/
|
|
38
57
|
ErrorManager_1.default.register('Container', 'jkIpU1p4z5uz', 'CTR_INCORRECT_DYNAMIC_PN', 'Incorrect dynamic port name', {
|
|
39
58
|
port: Rule_1.default.string().description('Incorrect port name')
|
|
40
59
|
});
|
|
@@ -45,6 +64,10 @@ ErrorManager_1.default.register('Container', 'qPevPU6SRJ18', 'CTR_INPUT_HANDLER_
|
|
|
45
64
|
port: Rule_1.default.string().description('Port name for handler'),
|
|
46
65
|
handler: Rule_1.default.string().description('Handler name')
|
|
47
66
|
});
|
|
67
|
+
ErrorManager_1.default.register('Container', 'QlcUh744VzAG', 'CTR_DEVICE_PORT_NF', 'Port on device not found', {
|
|
68
|
+
port: Rule_1.default.string().description('Port name'),
|
|
69
|
+
});
|
|
70
|
+
/***** ******** CONNECTION ERROR ********************/
|
|
48
71
|
ErrorManager_1.default.register('Container', 'Kp74OuVGNU0u', 'CTR_CONNECTION_INCORRECT', 'Incorrect connection format', {
|
|
49
72
|
connection: Rule_1.default.string().description('Connection string'),
|
|
50
73
|
error: Rule_1.default.string().description('String of error problem'),
|
|
@@ -57,58 +80,234 @@ ErrorManager_1.default.register('Container', 'CwFj1G47H45E', 'CTR_CONNECTION_POR
|
|
|
57
80
|
connection: Rule_1.default.string().description('Connection string'),
|
|
58
81
|
port: Rule_1.default.string().description('Port name not found')
|
|
59
82
|
});
|
|
83
|
+
ErrorManager_1.default.register('Container', 'XR1K10R0OOUC', 'CTR_INCOMPATIBLE_PORTS', 'Incompatible ports', {
|
|
84
|
+
connection: Rule_1.default.string().description('Connection string'),
|
|
85
|
+
});
|
|
86
|
+
ErrorManager_1.default.register('Container', 'MmVoDOQwaYkx', 'CTR_INCORRECT_BOOSTRAP', 'The required DeviceManager class is not specified correctly', {});
|
|
87
|
+
ErrorManager_1.default.register('Container', 'e090R0MLyb7y', 'CTR_CONF_EXTENDS_PROBLEM', 'Problem with extending service configuration.', {});
|
|
88
|
+
/**
|
|
89
|
+
* Service Load Class. It loads all devices in the list,
|
|
90
|
+
* establishes connections between them, and performs device startup.
|
|
91
|
+
*
|
|
92
|
+
* This class is a bit complicated for a simple description.
|
|
93
|
+
* It is recommended to familiarize yourself with the source code
|
|
94
|
+
*/
|
|
60
95
|
class Container extends events_1.default {
|
|
61
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Create container needed service structure & device manager
|
|
98
|
+
*
|
|
99
|
+
* @param service Service structure
|
|
100
|
+
* @param bootstrap Bootstrap class Object
|
|
101
|
+
*
|
|
102
|
+
* */
|
|
103
|
+
constructor(id, service, Bootstrap, confFile) {
|
|
62
104
|
super();
|
|
105
|
+
/** Unique service ID */
|
|
106
|
+
this.id = '';
|
|
107
|
+
/** List of devices in container */
|
|
63
108
|
this.devices = {};
|
|
64
|
-
|
|
65
|
-
this.
|
|
109
|
+
/** inited flag */
|
|
110
|
+
this.inited = false;
|
|
111
|
+
/** run flag */
|
|
112
|
+
this.runned = false;
|
|
113
|
+
/**
|
|
114
|
+
* Container structure
|
|
115
|
+
*/
|
|
116
|
+
this.structure = {};
|
|
117
|
+
this.id = id;
|
|
118
|
+
this.service = service;
|
|
66
119
|
this.deviceActions = {};
|
|
120
|
+
this.deviceMetrics = {};
|
|
121
|
+
this.confFile = confFile;
|
|
122
|
+
this.Bootstrap = Bootstrap;
|
|
67
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Run container
|
|
126
|
+
*/
|
|
68
127
|
run() {
|
|
69
128
|
return __awaiter(this, void 0, void 0, function* () {
|
|
70
|
-
|
|
129
|
+
yield this.init();
|
|
130
|
+
yield this.runProcess();
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Extends service from config file
|
|
135
|
+
*
|
|
136
|
+
* Sometimes there is a need to override the settings of some devices.
|
|
137
|
+
* To do this, you can use a special configuration file of the service.
|
|
138
|
+
* It contains the same as the main service file and replaces with its settings
|
|
139
|
+
* and parameters the settings and parameters of the main service.
|
|
140
|
+
*
|
|
141
|
+
* @see init()
|
|
142
|
+
*/
|
|
143
|
+
fillConfFile() {
|
|
144
|
+
if (!this.confFile || !(0, fs_1.existsSync)(this.confFile))
|
|
145
|
+
return;
|
|
146
|
+
const conf = ImportManager_1.default.importJSON(this.confFile);
|
|
147
|
+
if (conf.devices === undefined || !Array.isArray(conf.devices))
|
|
148
|
+
conf.devices = [];
|
|
149
|
+
for (const device of conf.devices) {
|
|
150
|
+
if (!device.id || device.options === undefined || typeof device.options !== 'object')
|
|
151
|
+
continue;
|
|
152
|
+
for (const cdev of this.service.devices) {
|
|
153
|
+
if (cdev.id === device.id) {
|
|
154
|
+
for (const pname in device.options)
|
|
155
|
+
cdev.options[pname] = device.options[pname];
|
|
156
|
+
if (device.connections)
|
|
157
|
+
cdev.connections = device.connections;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Creates device classes. Preprocesses the device,
|
|
164
|
+
* then adds ports to it and creates connections between ports.
|
|
165
|
+
*
|
|
166
|
+
* When adding and creating devices, ports and connections,
|
|
167
|
+
* the service structure is also created
|
|
168
|
+
*
|
|
169
|
+
* 1. Init device
|
|
170
|
+
* 2. Init individual device connections
|
|
171
|
+
* 3. Init other connections
|
|
172
|
+
*
|
|
173
|
+
* @see structure
|
|
174
|
+
*/
|
|
175
|
+
init() {
|
|
176
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
177
|
+
if (this.inited)
|
|
178
|
+
return;
|
|
179
|
+
this.inited = true;
|
|
180
|
+
this.emit('configure');
|
|
181
|
+
try {
|
|
182
|
+
this.fillConfFile();
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
if (err instanceof Error) {
|
|
186
|
+
const ner = ErrorManager_1.default.make('CTR_CONF_EXTENDS_PROBLEM', {}).setTrace(err).add(err);
|
|
187
|
+
throw ner;
|
|
188
|
+
}
|
|
189
|
+
throw err;
|
|
190
|
+
}
|
|
191
|
+
this.emit('beforeInit');
|
|
192
|
+
this.emit('init');
|
|
193
|
+
for (const device of this.service.devices) {
|
|
71
194
|
try {
|
|
195
|
+
this.emit('initDevice', device);
|
|
72
196
|
yield this.initDevice(device);
|
|
73
197
|
}
|
|
74
198
|
catch (error) {
|
|
75
199
|
const ner = ErrorManager_1.default.make('CTR_ERROR_INIT_DEVICE', { deviceConfig: device });
|
|
76
|
-
|
|
77
|
-
ner.add(error);
|
|
200
|
+
ner.add(error);
|
|
78
201
|
throw ner;
|
|
79
202
|
}
|
|
80
203
|
}
|
|
81
|
-
|
|
204
|
+
this.emit('afterInit');
|
|
205
|
+
this.emit('beforeConnections');
|
|
206
|
+
this.emit('connections');
|
|
207
|
+
for (const device of this.service.devices) {
|
|
208
|
+
if (!device.connections)
|
|
209
|
+
continue;
|
|
210
|
+
for (const conn of device.connections) {
|
|
211
|
+
this.emit('connection', conn);
|
|
212
|
+
this.initConnection(conn);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (Array.isArray(this.service.connections)) {
|
|
216
|
+
for (const conn of this.service.connections) {
|
|
217
|
+
this.initConnection(conn);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
this.emit('afterConnections');
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Run process & processPromise of all devices
|
|
225
|
+
*/
|
|
226
|
+
runProcess() {
|
|
227
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
228
|
+
if (this.runned)
|
|
229
|
+
return;
|
|
230
|
+
this.runned = true;
|
|
231
|
+
this.emit('beforeProcess');
|
|
232
|
+
for (const key in this.devices) {
|
|
82
233
|
try {
|
|
83
|
-
|
|
234
|
+
this.emit('process', key);
|
|
235
|
+
this.devices[key].process();
|
|
84
236
|
}
|
|
85
237
|
catch (error) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
238
|
+
throw ErrorManager_1.default.make('CTR_DEVICE_PROCESS_EXCEPTION', { device: key }).add(error);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
this.emit('afterProcess');
|
|
242
|
+
this.emit('beforeProcessPromise');
|
|
243
|
+
for (const key in this.devices) {
|
|
244
|
+
try {
|
|
245
|
+
this.emit('processPromise', key);
|
|
246
|
+
yield this.devices[key].processPromise();
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
throw ErrorManager_1.default.make('CTR_DEVICE_PROCESS_PROMISE_EXCEPTION', { device: key }).add(error);
|
|
90
250
|
}
|
|
91
251
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
yield this.devices[key].processPromise();
|
|
96
|
-
// const cs = await this.DeviceManager.get('vrack.Master')
|
|
97
|
-
// const cse = new cs()
|
|
98
|
-
// console.log(cse)
|
|
99
|
-
// cse.run()
|
|
252
|
+
this.emit('afterProcessPromise');
|
|
253
|
+
this.emit('beforeLoaded');
|
|
254
|
+
this.emit('loaded');
|
|
100
255
|
});
|
|
101
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Check device action and run him
|
|
259
|
+
*
|
|
260
|
+
* @param device Device ID
|
|
261
|
+
* @param action Device action (as 'action.name')
|
|
262
|
+
* @param data Data for action
|
|
263
|
+
*/
|
|
264
|
+
deviceAction(device, action, data) {
|
|
265
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
266
|
+
if (!this.deviceActions[device])
|
|
267
|
+
throw ErrorManager_1.default.make('CTR_DEVICE_NF', { device });
|
|
268
|
+
const deviceClass = this.devices[device];
|
|
269
|
+
const deviceActions = this.deviceActions[device];
|
|
270
|
+
const method = ImportManager_1.default.camelize('action.' + action);
|
|
271
|
+
if (!deviceActions[action])
|
|
272
|
+
throw ErrorManager_1.default.make('CTR_DEVICE_ACTION_NF', { device, action, method });
|
|
273
|
+
if (!deviceClass[method])
|
|
274
|
+
throw ErrorManager_1.default.make('CTR_DEVICE_ACTION_HANDLER_NF', { device, action });
|
|
275
|
+
const actionExport = deviceActions[action].exportRaw();
|
|
276
|
+
Validator_1.default.validate(actionExport.requirements, data);
|
|
277
|
+
return yield deviceClass[method](data);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Return structure
|
|
282
|
+
*/
|
|
283
|
+
getStructure() {
|
|
284
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
285
|
+
return this.structure;
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Init one device
|
|
290
|
+
*
|
|
291
|
+
* 1. Make device class object
|
|
292
|
+
* 2. Fill device options
|
|
293
|
+
* 3. Run device prepareOptions method
|
|
294
|
+
* 4. Validating device options
|
|
295
|
+
* 5. Check device actions
|
|
296
|
+
* 6. make device inputs ports
|
|
297
|
+
* 7. make device outputs ports
|
|
298
|
+
**/
|
|
102
299
|
initDevice(dconf) {
|
|
103
300
|
return __awaiter(this, void 0, void 0, function* () {
|
|
104
|
-
const
|
|
301
|
+
const DM = this.Bootstrap.getBootClass('DeviceManager', DeviceManager_1.default);
|
|
302
|
+
const cs = yield DM.get(dconf.type);
|
|
105
303
|
//
|
|
106
|
-
if (dconf.id === undefined || !dconf.id || typeof dconf.id !== 'string') {
|
|
304
|
+
if (dconf.id === undefined || !dconf.id || typeof dconf.id !== 'string' || !Utility_1.default.isDeviceName(dconf.id)) {
|
|
107
305
|
throw ErrorManager_1.default.make('CTR_INCORRECT_DEVICE_ID');
|
|
108
306
|
}
|
|
109
307
|
// Device id is dublicated
|
|
110
308
|
if (dconf.id in this.devices)
|
|
111
309
|
throw ErrorManager_1.default.make('CTR_DEVICE_DUBLICATE');
|
|
310
|
+
// Create device
|
|
112
311
|
const dev = new cs(dconf.id, dconf.type, this);
|
|
113
312
|
this.devices[dconf.id] = dev;
|
|
114
313
|
// Fill options
|
|
@@ -130,6 +329,17 @@ class Container extends events_1.default {
|
|
|
130
329
|
const rules = dev.checkOptions();
|
|
131
330
|
// Validating
|
|
132
331
|
Validator_1.default.validate(rules, dev.options);
|
|
332
|
+
/** create structure */
|
|
333
|
+
this.structure[dconf.id] = {
|
|
334
|
+
id: dconf.id,
|
|
335
|
+
type: dconf.type,
|
|
336
|
+
actions: {},
|
|
337
|
+
outputs: {},
|
|
338
|
+
inputs: {},
|
|
339
|
+
ports: [],
|
|
340
|
+
settings: {},
|
|
341
|
+
metrics: {},
|
|
342
|
+
};
|
|
133
343
|
dev.preProcess();
|
|
134
344
|
// Check actions
|
|
135
345
|
this.deviceActions[dev.id] = dev.actions();
|
|
@@ -137,9 +347,18 @@ class Container extends events_1.default {
|
|
|
137
347
|
const method = ImportManager_1.default.camelize('action.' + action);
|
|
138
348
|
if (!(method in dev))
|
|
139
349
|
throw ErrorManager_1.default.make('CTR_DEVICE_ACTION_NF', { action, method });
|
|
350
|
+
// add structure device action
|
|
351
|
+
this.structure[dconf.id].actions[action] = this.deviceActions[dev.id][action].export();
|
|
352
|
+
}
|
|
353
|
+
this.structure[dconf.id].settings = dev.settings();
|
|
354
|
+
// Make Metrics
|
|
355
|
+
this.deviceMetrics[dev.id] = dev.metrics();
|
|
356
|
+
for (const metric in this.deviceMetrics[dev.id]) {
|
|
357
|
+
const raw = this.deviceMetrics[dev.id][metric].export();
|
|
358
|
+
const nEvent = { device: dev.id, data: metric, trace: raw };
|
|
359
|
+
this.emit('device.register.metric', nEvent);
|
|
360
|
+
this.structure[dconf.id].metrics[metric] = raw;
|
|
140
361
|
}
|
|
141
|
-
// make ports
|
|
142
|
-
// prepare ports
|
|
143
362
|
// make inputPorts
|
|
144
363
|
const iPorts = dev.inputs();
|
|
145
364
|
for (const key in iPorts) {
|
|
@@ -151,10 +370,14 @@ class Container extends events_1.default {
|
|
|
151
370
|
this.checkInputHandler(subkey, handler, dev);
|
|
152
371
|
const ndp = new DevicePort_1.default(subkey, pList[subkey]);
|
|
153
372
|
dev.ports.input[subkey] = ndp;
|
|
373
|
+
// add structure device input ports
|
|
374
|
+
this.structure[dconf.id].inputs[subkey] = [];
|
|
375
|
+
this.structure[dconf.id].ports.push(Object.assign({ port: subkey, direct: 'input' }, pList[subkey]));
|
|
154
376
|
if (handler in dev)
|
|
155
377
|
ndp.push = dev[handler].bind(dev);
|
|
156
378
|
}
|
|
157
379
|
}
|
|
380
|
+
// make output ports
|
|
158
381
|
const oPorts = dev.outputs();
|
|
159
382
|
for (const key in oPorts) {
|
|
160
383
|
const exp = oPorts[key].export();
|
|
@@ -163,17 +386,31 @@ class Container extends events_1.default {
|
|
|
163
386
|
this.checkPortName(subkey);
|
|
164
387
|
const ndp = new DevicePort_1.default(subkey, pList[subkey]);
|
|
165
388
|
dev.ports.output[subkey] = ndp;
|
|
389
|
+
// add structure device output ports
|
|
390
|
+
this.structure[dconf.id].outputs[subkey] = [];
|
|
391
|
+
this.structure[dconf.id].ports.push(Object.assign({ port: subkey, direct: 'output' }, pList[subkey]));
|
|
166
392
|
}
|
|
167
393
|
}
|
|
168
394
|
});
|
|
169
395
|
}
|
|
396
|
+
/**
|
|
397
|
+
* Check device input handler
|
|
398
|
+
* Make CTR_INPUT_HANDLER_NF error if not exists
|
|
399
|
+
* @see initDevice make inputPorts
|
|
400
|
+
*/
|
|
170
401
|
checkInputHandler(port, handler, device) {
|
|
171
402
|
if (!(handler in device))
|
|
172
403
|
throw ErrorManager_1.default.make('CTR_INPUT_HANDLER_NF', { port, handler });
|
|
173
404
|
}
|
|
405
|
+
/**
|
|
406
|
+
* Init device connection
|
|
407
|
+
*
|
|
408
|
+
* @param conn Device connection string like a "DevID.port -> DevIDTO.port"
|
|
409
|
+
*/
|
|
174
410
|
initConnection(conn) {
|
|
175
|
-
|
|
411
|
+
try {
|
|
176
412
|
const cc = this.toConnection(conn);
|
|
413
|
+
this.emit('connection', cc);
|
|
177
414
|
if (!(cc.outputDevice in this.devices))
|
|
178
415
|
throw ErrorManager_1.default.make('CTR_CONNECTION_DEVICE_NF', { connection: conn, device: cc.outputDevice });
|
|
179
416
|
if (!(cc.outputPort in this.devices[cc.outputDevice].ports.output))
|
|
@@ -182,11 +419,31 @@ class Container extends events_1.default {
|
|
|
182
419
|
throw ErrorManager_1.default.make('CTR_CONNECTION_DEVICE_NF', { connection: conn, device: cc.inputDevice });
|
|
183
420
|
if (!(cc.inputPort in this.devices[cc.inputDevice].ports.input))
|
|
184
421
|
throw ErrorManager_1.default.make('CTR_CONNECTION_PORT_NF', { connection: conn, port: cc.inputPort });
|
|
422
|
+
if (this.devices[cc.inputDevice].ports.input[cc.inputPort].type !== this.devices[cc.outputDevice].ports.output[cc.outputPort].type)
|
|
423
|
+
throw ErrorManager_1.default.make('CTR_INCOMPATIBLE_PORTS', { connection: conn });
|
|
185
424
|
const outPort = this.devices[cc.outputDevice].ports.output[cc.outputPort];
|
|
186
425
|
const inPort = this.devices[cc.inputDevice].ports.input[cc.inputPort];
|
|
426
|
+
// Set structure connections
|
|
427
|
+
if (this.structure[cc.outputDevice].outputs[cc.outputPort] === undefined)
|
|
428
|
+
this.structure[cc.outputDevice].outputs[cc.outputPort] = [];
|
|
429
|
+
this.structure[cc.outputDevice].outputs[cc.outputPort].push({ device: cc.inputDevice, port: cc.inputPort });
|
|
430
|
+
if (this.structure[cc.inputDevice].inputs[cc.inputPort] === undefined)
|
|
431
|
+
this.structure[cc.inputDevice].inputs[cc.inputPort] = [];
|
|
432
|
+
this.structure[cc.inputDevice].inputs[cc.inputPort].push({ device: cc.outputDevice, port: cc.outputPort });
|
|
187
433
|
new DeviceConnect_1.default(outPort, inPort);
|
|
188
|
-
}
|
|
434
|
+
}
|
|
435
|
+
catch (error) {
|
|
436
|
+
const ner = ErrorManager_1.default.make('CTR_ERROR_INIT_CONNECTION', { connection: conn });
|
|
437
|
+
if (error instanceof CoreError_1.default)
|
|
438
|
+
ner.add(error);
|
|
439
|
+
throw ner;
|
|
440
|
+
}
|
|
189
441
|
}
|
|
442
|
+
/**
|
|
443
|
+
* Container Helper - parse connection string to format object
|
|
444
|
+
*
|
|
445
|
+
* @return Connection object
|
|
446
|
+
*/
|
|
190
447
|
toConnection(con) {
|
|
191
448
|
var _a, _b;
|
|
192
449
|
const act = con.split('->');
|
|
@@ -211,10 +468,21 @@ class Container extends events_1.default {
|
|
|
211
468
|
};
|
|
212
469
|
return result;
|
|
213
470
|
}
|
|
471
|
+
/**
|
|
472
|
+
* Check Port name (strict format a-zA-Z0-9.)
|
|
473
|
+
*
|
|
474
|
+
* @param port Port name
|
|
475
|
+
*/
|
|
214
476
|
checkPortName(port) {
|
|
215
477
|
if (!port.match(/[a-zA-Z0-9.]/))
|
|
216
478
|
throw ErrorManager_1.default.make('CTR_INCORRECT_PN', { port });
|
|
217
479
|
}
|
|
480
|
+
/**
|
|
481
|
+
* Convert dynamic port to ports list
|
|
482
|
+
*
|
|
483
|
+
* @param name Port name with %d symbols
|
|
484
|
+
* @param iPort IPort object (port settings)
|
|
485
|
+
*/
|
|
218
486
|
getPortList(name, iPort) {
|
|
219
487
|
const result = {};
|
|
220
488
|
if (!iPort.dynamic) {
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import IStructureDevice from "./IStructureDevice";
|
|
2
|
+
/** Basic service file structure */
|
|
2
3
|
export default interface IServiceStructure {
|
|
4
|
+
/**
|
|
5
|
+
* Devices list
|
|
6
|
+
* @see IStructureDevice
|
|
7
|
+
*/
|
|
3
8
|
devices: Array<IStructureDevice>;
|
|
9
|
+
/**
|
|
10
|
+
* Connections list
|
|
11
|
+
*/
|
|
4
12
|
connections: Array<string>;
|
|
5
13
|
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
export default interface IStructureDevice {
|
|
2
|
+
/** Device ID */
|
|
2
3
|
id: string;
|
|
4
|
+
/** Device type in VRack style like a 'vendor.Device' */
|
|
3
5
|
type: string;
|
|
6
|
+
/** Device options */
|
|
4
7
|
options: {
|
|
5
8
|
[key: string]: any;
|
|
6
9
|
};
|
|
10
|
+
/** Device connections */
|
|
11
|
+
connections?: Array<string>;
|
|
7
12
|
}
|
package/lib/ImportManager.d.ts
CHANGED
|
@@ -5,11 +5,93 @@ export default class ImportManager {
|
|
|
5
5
|
* @param {string} path Full or relative path to file
|
|
6
6
|
*/
|
|
7
7
|
static importPath(raPath: string): Promise<any>;
|
|
8
|
+
/**
|
|
9
|
+
* Import class like a vrack2 device style
|
|
10
|
+
*
|
|
11
|
+
* Разделяюет переданную строку пути на 2 части.
|
|
12
|
+
* Первая честь является названием модуля, а вторая часть классом внутри него
|
|
13
|
+
*
|
|
14
|
+
* @example ImportManager.importClass('vrack2-core.Container')
|
|
15
|
+
*/
|
|
8
16
|
static importClass(cs: string): Promise<any>;
|
|
9
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Attempts to open a file and use its contents as json
|
|
19
|
+
*
|
|
20
|
+
* Returns the result of parsing json
|
|
21
|
+
*
|
|
22
|
+
* @returns {any} json parsing result
|
|
23
|
+
*/
|
|
24
|
+
static importJSON(filePath: string): any;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the class name in the style of import vrack
|
|
27
|
+
*
|
|
28
|
+
* return `Container` from 'vrack2-core.Container' string
|
|
29
|
+
*
|
|
30
|
+
* @param cs Import class string
|
|
31
|
+
*
|
|
32
|
+
*/
|
|
33
|
+
static importClassName(cs: string): string | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Returns the vendor name in the style of import vrack
|
|
36
|
+
*
|
|
37
|
+
* return `vrack2-core` from 'vrack2-core.Container' string
|
|
38
|
+
*
|
|
39
|
+
* @param cs Import class string
|
|
40
|
+
*/
|
|
41
|
+
static importVendorName(cs: string): string | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Returns a list of directories in the specified directory.
|
|
44
|
+
*
|
|
45
|
+
* @param dir path to directory
|
|
46
|
+
*/
|
|
47
|
+
static dirList(dir: string): string[];
|
|
48
|
+
/**
|
|
49
|
+
* Returns a list of files in the specified directory.
|
|
50
|
+
*
|
|
51
|
+
* @param dir path to directory
|
|
52
|
+
*/
|
|
53
|
+
static fileList(dir: string): string[];
|
|
54
|
+
/**
|
|
55
|
+
* Checks if a path is a directory
|
|
56
|
+
*
|
|
57
|
+
* @param dir path to directory
|
|
58
|
+
*/
|
|
59
|
+
static isDir(dir: string): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Checks if a path is a directory
|
|
62
|
+
*
|
|
63
|
+
* @param f path to file
|
|
64
|
+
*/
|
|
65
|
+
static isFile(f: string): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Try JSON parse
|
|
68
|
+
*
|
|
69
|
+
* Returns an CoreError[IM_JSON_INCORRECT] if there is a parsing error.
|
|
70
|
+
*
|
|
71
|
+
* @param jsonRaw JSON raw string
|
|
72
|
+
*
|
|
73
|
+
*/
|
|
10
74
|
static tryJsonParse(jsonRaw: string): any;
|
|
11
|
-
|
|
12
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Return directory where VRack was launched from
|
|
77
|
+
*/
|
|
13
78
|
static systemPath(): string;
|
|
79
|
+
/**
|
|
80
|
+
* Camelize string for input & action handlers
|
|
81
|
+
*
|
|
82
|
+
* Splits a string with a dot and returns the string
|
|
83
|
+
* with capital letters starting from the second word
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* ImportManager.camelize('input.device.port') // return inputDevicePort
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* @param text Like a `input.device.port` string
|
|
91
|
+
*/
|
|
92
|
+
static camelize(text: string): string;
|
|
93
|
+
/**
|
|
94
|
+
* Try import method
|
|
95
|
+
*/
|
|
14
96
|
protected static tryImport(p: string): Promise<any>;
|
|
15
97
|
}
|