vrack2-core 0.0.1 → 1.0.1

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.
Files changed (148) hide show
  1. package/README.md +33 -4
  2. package/docs/Bootstrap.md +77 -0
  3. package/docs/Container.md +124 -0
  4. package/docs/Device.md +272 -0
  5. package/docs/FastStart.md +111 -0
  6. package/docs/Structure.md +148 -0
  7. package/lib/Bootstrap.d.ts +79 -0
  8. package/lib/Bootstrap.js +103 -0
  9. package/lib/Container.d.ts +202 -6
  10. package/lib/Container.js +295 -27
  11. package/lib/IServiceStructure.d.ts +8 -0
  12. package/lib/IStructureDevice.d.ts +5 -0
  13. package/lib/ImportManager.d.ts +85 -3
  14. package/lib/ImportManager.js +122 -16
  15. package/lib/MainProcess.d.ts +30 -3
  16. package/lib/MainProcess.js +28 -6
  17. package/lib/Utility.d.ts +15 -21
  18. package/lib/Utility.js +40 -40
  19. package/lib/actions/Action.d.ts +10 -0
  20. package/lib/actions/Action.js +10 -0
  21. package/lib/actions/BasicAction.d.ts +60 -0
  22. package/lib/actions/BasicAction.js +62 -0
  23. package/lib/actions/GlobalAction.d.ts +5 -0
  24. package/lib/actions/GlobalAction.js +5 -0
  25. package/lib/actions/IAction.d.ts +7 -0
  26. package/lib/actions/ILocalAction.d.ts +7 -0
  27. package/lib/boot/BootClass.d.ts +93 -0
  28. package/lib/boot/BootClass.js +101 -0
  29. package/lib/boot/DeviceFileStorage.d.ts +38 -0
  30. package/lib/boot/DeviceFileStorage.js +112 -0
  31. package/lib/boot/DeviceManager.d.ts +190 -0
  32. package/lib/boot/DeviceManager.js +311 -0
  33. package/lib/boot/DeviceMetrics.d.ts +82 -0
  34. package/lib/boot/DeviceMetrics.js +128 -0
  35. package/lib/boot/StructureStorage.d.ts +59 -0
  36. package/lib/boot/StructureStorage.js +125 -0
  37. package/lib/errors/CoreError.d.ts +42 -25
  38. package/lib/errors/CoreError.js +44 -24
  39. package/lib/errors/ErrorManager.d.ts +18 -20
  40. package/lib/errors/ErrorManager.js +23 -22
  41. package/lib/index.d.ts +20 -4
  42. package/lib/index.js +28 -4
  43. package/lib/metrics/BasicMetric.d.ts +49 -0
  44. package/lib/metrics/BasicMetric.js +79 -0
  45. package/lib/metrics/IMetricSettings.d.ts +32 -0
  46. package/lib/metrics/IMetricSettings.js +2 -0
  47. package/lib/metrics/IvMs.d.ts +9 -0
  48. package/lib/metrics/IvMs.js +22 -0
  49. package/lib/metrics/IvS.d.ts +9 -0
  50. package/lib/metrics/IvS.js +22 -0
  51. package/lib/metrics/IvUs.d.ts +9 -0
  52. package/lib/metrics/IvUs.js +22 -0
  53. package/lib/metrics/Metric.d.ts +17 -0
  54. package/lib/metrics/Metric.js +27 -0
  55. package/lib/ports/BasicPort.d.ts +39 -0
  56. package/lib/ports/BasicPort.js +39 -0
  57. package/lib/ports/ILocalPort.d.ts +7 -0
  58. package/lib/ports/IPort.d.ts +7 -0
  59. package/lib/ports/Port.d.ts +10 -0
  60. package/lib/ports/Port.js +10 -0
  61. package/lib/ports/ReturnPort.d.ts +5 -0
  62. package/lib/ports/ReturnPort.js +5 -0
  63. package/lib/service/Device.d.ts +213 -78
  64. package/lib/service/Device.js +185 -83
  65. package/lib/service/DeviceConnect.d.ts +4 -8
  66. package/lib/service/DeviceConnect.js +4 -8
  67. package/lib/service/DevicePort.d.ts +15 -6
  68. package/lib/service/DevicePort.js +29 -12
  69. package/lib/service/IDeviceEvent.d.ts +4 -1
  70. package/lib/validator/IValidationProblem.d.ts +7 -0
  71. package/lib/validator/IValidationRule.d.ts +12 -0
  72. package/lib/validator/IValidationSubrule.d.ts +2 -0
  73. package/lib/validator/Rule.d.ts +6 -2
  74. package/lib/validator/Rule.js +12 -2
  75. package/lib/validator/Validator.d.ts +48 -3
  76. package/lib/validator/Validator.js +70 -18
  77. package/lib/validator/types/AnyType.d.ts +17 -0
  78. package/lib/validator/types/AnyType.js +34 -0
  79. package/lib/validator/types/ArrayType.d.ts +37 -4
  80. package/lib/validator/types/ArrayType.js +42 -6
  81. package/lib/validator/types/BasicType.d.ts +67 -7
  82. package/lib/validator/types/BasicType.js +74 -8
  83. package/lib/validator/types/BooleanType.d.ts +23 -0
  84. package/lib/validator/types/BooleanType.js +47 -0
  85. package/lib/validator/types/FunctionType.d.ts +17 -0
  86. package/lib/validator/types/FunctionType.js +38 -0
  87. package/lib/validator/types/NumberType.d.ts +40 -5
  88. package/lib/validator/types/NumberType.js +53 -14
  89. package/lib/validator/types/ObjectType.d.ts +32 -5
  90. package/lib/validator/types/ObjectType.js +42 -8
  91. package/lib/validator/types/StringType.d.ts +30 -5
  92. package/lib/validator/types/StringType.js +33 -7
  93. package/package.json +15 -14
  94. package/src/Bootstrap.ts +122 -0
  95. package/src/Container.ts +411 -43
  96. package/src/IServiceStructure.ts +9 -0
  97. package/src/IStructureDevice.ts +5 -0
  98. package/src/ImportManager.ts +119 -11
  99. package/src/MainProcess.ts +53 -8
  100. package/src/Utility.ts +35 -36
  101. package/src/actions/Action.ts +12 -0
  102. package/src/actions/BasicAction.ts +63 -0
  103. package/src/actions/GlobalAction.ts +5 -0
  104. package/src/actions/IAction.ts +7 -0
  105. package/src/actions/ILocalAction.ts +7 -0
  106. package/src/boot/BootClass.ts +117 -0
  107. package/src/boot/DeviceFileStorage.ts +96 -0
  108. package/src/boot/DeviceManager.ts +346 -0
  109. package/src/boot/DeviceMetrics.ts +129 -0
  110. package/src/boot/StructureStorage.ts +108 -0
  111. package/src/errors/CoreError.ts +52 -26
  112. package/src/errors/ErrorManager.ts +46 -33
  113. package/src/index.ts +30 -6
  114. package/src/metrics/BasicMetric.ts +84 -0
  115. package/src/metrics/IMetricSettings.ts +38 -0
  116. package/src/metrics/IvMs.ts +18 -0
  117. package/src/metrics/IvS.ts +18 -0
  118. package/src/metrics/IvUs.ts +17 -0
  119. package/src/metrics/Metric.ts +25 -0
  120. package/src/ports/BasicPort.ts +39 -0
  121. package/src/ports/ILocalPort.ts +7 -0
  122. package/src/ports/IPort.ts +7 -0
  123. package/src/ports/Port.ts +11 -1
  124. package/src/ports/ReturnPort.ts +5 -0
  125. package/src/service/Device.ts +234 -103
  126. package/src/service/DeviceConnect.ts +4 -8
  127. package/src/service/DevicePort.ts +30 -11
  128. package/src/service/IDeviceEvent.ts +4 -1
  129. package/src/validator/IValidationProblem.ts +7 -0
  130. package/src/validator/IValidationRule.ts +12 -0
  131. package/src/validator/IValidationSubrule.ts +3 -0
  132. package/src/validator/Rule.ts +16 -2
  133. package/src/validator/Validator.ts +74 -23
  134. package/src/validator/types/AnyType.ts +32 -0
  135. package/src/validator/types/ArrayType.ts +43 -7
  136. package/src/validator/types/BasicType.ts +78 -9
  137. package/src/validator/types/BooleanType.ts +49 -0
  138. package/src/validator/types/FunctionType.ts +39 -0
  139. package/src/validator/types/NumberType.ts +53 -15
  140. package/src/validator/types/ObjectType.ts +52 -14
  141. package/src/validator/types/StringType.ts +34 -10
  142. package/docs/RU-README.md +0 -6
  143. package/lib/DeviceManager.d.ts +0 -32
  144. package/lib/DeviceManager.js +0 -143
  145. package/lib/test.d.ts +0 -1
  146. package/lib/test.js +0 -58
  147. package/src/DeviceManager.ts +0 -124
  148. package/src/test.ts +0 -82
@@ -0,0 +1,311 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ const path_1 = __importDefault(require("path"));
39
+ const fs_1 = __importDefault(require("fs"));
40
+ const ErrorManager_1 = __importDefault(require("../errors/ErrorManager"));
41
+ const Rule_1 = __importDefault(require("../validator/Rule"));
42
+ const CoreError_1 = __importDefault(require("../errors/CoreError"));
43
+ const BootClass_1 = __importDefault(require("./BootClass"));
44
+ const ImportManager_1 = __importDefault(require("../ImportManager"));
45
+ const Validator_1 = __importDefault(require("../validator/Validator"));
46
+ ErrorManager_1.default.register('DeviceManager', 'S5dBTBKTnVbF', 'DM_DEVICE_NOT_FOUND', 'Device not found', {
47
+ device: Rule_1.default.string().require().example('Master').description('Device name')
48
+ });
49
+ ErrorManager_1.default.register('DeviceManager', '2CJSDE95V9O1', 'DM_LIST_NOT_FOUND', 'list.json not found', {
50
+ vendor: Rule_1.default.string().require().example('vrack').description('Device group name')
51
+ });
52
+ ErrorManager_1.default.register('DeviceManager', 'BPX96F93ZCJA', 'DM_LIST_INCORRECT', 'list.json is not correct', {
53
+ vendor: Rule_1.default.string().require().example('vrack').description('Device group name')
54
+ });
55
+ ErrorManager_1.default.register('DeviceManager', 'H1NDNVCOLWST', 'DM_VENDOR_NOT_FOUND', 'Vendor not found', {
56
+ vendor: Rule_1.default.string().require().example('vrack').description('Vendor name')
57
+ });
58
+ ErrorManager_1.default.register('DeviceManager', 'HQ62LW1YLTDE', 'DM_GET_INFO_EXCEPTION', 'Error retrieving device data, see error in attachment', {});
59
+ /**
60
+ * BootClass which generates a list of available devices for the container.
61
+ * Provides the ability to initialize devices and provide information about them
62
+ *
63
+ *
64
+ * @see get
65
+ */
66
+ class DeviceManager extends BootClass_1.default {
67
+ constructor() {
68
+ super(...arguments);
69
+ /**
70
+ * Contains a list of devices and their full path to the class
71
+ * Like a:
72
+ *
73
+ * ```js
74
+ * {
75
+ * "vendorname.Devicename": '/path/to/js/file.js'
76
+ * }
77
+ * ```
78
+ * */
79
+ this.devices = new Map();
80
+ /**
81
+ * Vendor array.
82
+ *
83
+ * @see IDeviceVendor
84
+ */
85
+ this.vendorList = [];
86
+ }
87
+ checkOptions() {
88
+ return {
89
+ dir: Rule_1.default.string().require().default('./devices'),
90
+ systemDir: Rule_1.default.string().require().default(ImportManager_1.default.systemPath()),
91
+ };
92
+ }
93
+ process() {
94
+ this.updateDeviceList();
95
+ }
96
+ /**
97
+ * Return vendor list
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * ['vrack', 'basic', 'net']
102
+ * ```
103
+ */
104
+ getVendorList() {
105
+ const result = [];
106
+ for (const dgroup of this.vendorList)
107
+ result.push(dgroup.name);
108
+ return result;
109
+ }
110
+ /**
111
+ * Returns a list of devices from a specific vendor
112
+ *
113
+ * @param vendor Vendor name
114
+ * @see getVendorList()
115
+ */
116
+ getVendorDeviceList(vendor) {
117
+ const vgroup = this.findVendor(vendor);
118
+ if (typeof vgroup === "boolean")
119
+ throw ErrorManager_1.default.make('DM_VENDOR_NOT_FOUND', { vendor }).setTrace(new Error());
120
+ return vgroup.deviceList;
121
+ }
122
+ /**
123
+ * Exports all basic device parameters and collects them in one object
124
+ * Used to generate documentation for the device
125
+ *
126
+ * @see IDeivceInfo
127
+ */
128
+ getDeviceInfo(vendor, device) {
129
+ return __awaiter(this, void 0, void 0, function* () {
130
+ const di = [vendor, device].join('.');
131
+ const DeviceClass = yield this.get(di);
132
+ const dev = new DeviceClass('1', di, this);
133
+ // Заполняем значения по умолчанию валидатором
134
+ // Это нужно динамических портов которые определяются через options
135
+ const rules = dev.checkOptions();
136
+ Validator_1.default.validate(rules, dev.options);
137
+ const result = { actions: {}, metrics: {}, inputs: {}, outputs: {}, options: {}, description: '' };
138
+ try {
139
+ const preOptions = dev.checkOptions();
140
+ for (const oName in preOptions)
141
+ result.options[oName] = preOptions[oName].export();
142
+ const dInputs = dev.inputs();
143
+ for (const iName in dInputs)
144
+ result.inputs[iName] = dInputs[iName].export();
145
+ const dOutputs = dev.outputs();
146
+ for (const oName in dOutputs)
147
+ result.outputs[oName] = dOutputs[oName].export();
148
+ const dActions = dev.actions();
149
+ for (const aName in dActions)
150
+ result.actions[aName] = dActions[aName].export();
151
+ const dMetrics = dev.metrics();
152
+ for (const mName in dMetrics)
153
+ result.metrics[mName] = dMetrics[mName].export();
154
+ result.description = dev.description();
155
+ }
156
+ catch (error) {
157
+ throw ErrorManager_1.default.make('DM_GET_INFO_EXCEPTION').setTrace(new Error).add(error);
158
+ }
159
+ return result;
160
+ });
161
+ }
162
+ /**
163
+ * Method for updating the device list
164
+ * Updates the available device lists.
165
+ *
166
+ * Searches the directory specified in `options.dir` and adds all directories in it as vendors.
167
+ * Each folder attempts to read the list.json file to get a list of vendor devices
168
+ *
169
+ * Two types of list.json file definition are supported
170
+ *
171
+ * First type - array:
172
+ *
173
+ * ```json
174
+ * ['Device1', 'Device2', 'Device3']
175
+ * ```
176
+ * Second type - Object
177
+ * This approach allows you to point to devices that are deeper than the vendor's root folder
178
+ *
179
+ * ```json
180
+ * {
181
+ * "Master": "devices/Master",
182
+ * "Interval": "devices/Interval",
183
+ * "Guard": "devices/Guard",
184
+ * }
185
+ * ```
186
+ *
187
+ * @see arrayDeviceListPrepare()
188
+ * @see objectDeviceListPrepare()
189
+ */
190
+ updateDeviceList() {
191
+ this.vendorList = [];
192
+ this.devices.clear();
193
+ const dirs = ImportManager_1.default.dirList(path_1.default.join(this.options.systemDir, this.options.dir)).sort();
194
+ for (const vendor of dirs) {
195
+ const group = {
196
+ name: vendor,
197
+ dir: this.options.dir,
198
+ deviceList: [],
199
+ errors: [],
200
+ description: ''
201
+ };
202
+ this.vendorList.push(group);
203
+ const listPath = path_1.default.join(this.options.systemDir, this.options.dir, vendor, 'list.json');
204
+ if (!fs_1.default.existsSync(listPath)) {
205
+ group.errors.push(ErrorManager_1.default.make('DM_LIST_NOT_FOUND', { vendor }).setTrace(new Error));
206
+ continue;
207
+ }
208
+ try {
209
+ const list = JSON.parse(fs_1.default.readFileSync(listPath).toString('utf-8'));
210
+ if (Array.isArray(list)) { // if device list like a [ 'DeviceName', 'DeviceTwo' ]
211
+ group.deviceList = this.arrayDeviceListPrepare(list, group);
212
+ }
213
+ else if (typeof list === "object") { // if device list lie a { DeviceID?: 'PathToDevice' }
214
+ group.deviceList = this.objectDeviceListPrepare(list, group);
215
+ }
216
+ else
217
+ throw new Error();
218
+ }
219
+ catch (err) {
220
+ if (err instanceof CoreError_1.default)
221
+ group.errors.push(err);
222
+ else
223
+ group.errors.push(ErrorManager_1.default.make('DM_LIST_INCORRECT', { vendor }).setTrace(new Error));
224
+ }
225
+ }
226
+ }
227
+ /**
228
+ * Return class of device
229
+ *
230
+ * Requires special device string of path
231
+ * example "vrack.System" where "vrack" is vendor and "System" is device class
232
+ * @param {string} device Device path string
233
+ */
234
+ get(device, updateList = true) {
235
+ return __awaiter(this, void 0, void 0, function* () {
236
+ const p = this.devices.get(device); // return device path or undefined
237
+ if (typeof p === 'string') {
238
+ const deviceClass = yield Promise.resolve(`${p}`).then(s => __importStar(require(s))); // try import
239
+ if (deviceClass.default)
240
+ return deviceClass.default;
241
+ }
242
+ // Устройство не найдено, но не исключено что если перестроить дерево
243
+ // вендоров и устройств все будет так же
244
+ // По умолчанию мы попытаемся обновить дерево
245
+ if (updateList) {
246
+ yield this.updateDeviceList();
247
+ return yield this.get(device, false);
248
+ }
249
+ throw ErrorManager_1.default.make('DM_DEVICE_NOT_FOUND', { device });
250
+ });
251
+ }
252
+ /**
253
+ * Find vendor by name
254
+ *
255
+ * Not found if return boolean
256
+ */
257
+ findVendor(vendor) {
258
+ for (const dgroup of this.vendorList)
259
+ if (dgroup.name === vendor)
260
+ return dgroup;
261
+ return false;
262
+ }
263
+ /**
264
+ * Processes a list of devices as an Array
265
+ *
266
+ * Takes an Array of type
267
+ * ```
268
+ * ['DeviceName', 'DeviceName2']
269
+ * ```
270
+ * @return {Array<string>} Sorted list
271
+ */
272
+ arrayDeviceListPrepare(list, group) {
273
+ for (const name of list) {
274
+ const reqPath = path_1.default.join(this.options.systemDir, this.options.dir, group.name, name);
275
+ if (!fs_1.default.existsSync(reqPath + '.js')) {
276
+ group.errors.push(ErrorManager_1.default.make('DM_DEVICE_NOT_FOUND', { device: name }));
277
+ }
278
+ this.devices.set(group.name + '.' + name, reqPath);
279
+ }
280
+ list.sort();
281
+ return list;
282
+ }
283
+ /**
284
+ * Processes a list of devices as an object
285
+ *
286
+ * Takes an object of type
287
+ * ```
288
+ * {
289
+ * DeviceName: 'path/to/Device'
290
+ * }
291
+ * ```
292
+ *
293
+ * return keys of list
294
+ * ```
295
+ * ['DeviceName']
296
+ * ```
297
+ *
298
+ * Set in this.devices for device name requiere path
299
+ */
300
+ objectDeviceListPrepare(list, group) {
301
+ for (const name in list) {
302
+ const reqPath = path_1.default.join(this.options.systemDir, this.options.dir, group.name, list[name]);
303
+ if (!fs_1.default.existsSync(reqPath + '.js')) {
304
+ group.errors.push(ErrorManager_1.default.make('DM_DEVICE_NOT_FOUND', { device: name }).setTrace(new Error));
305
+ }
306
+ this.devices.set(group.name + '.' + name, reqPath);
307
+ }
308
+ return Object.keys(list).sort();
309
+ }
310
+ }
311
+ exports.default = DeviceManager;
@@ -0,0 +1,82 @@
1
+ import { Interval, SingleDB } from "vrack-db";
2
+ import IDeviceEvent from "../service/IDeviceEvent";
3
+ import BootClass from "./BootClass";
4
+ import IMetricSettings from "../metrics/IMetricSettings";
5
+ /**
6
+ * A class to support metrics inside devices
7
+ * Using a database vrack-db. Collects and stores container metrics
8
+ *
9
+ * @see SingleDB
10
+ *
11
+ * Uses the `device.metric` and `device.register.metric` events
12
+ *
13
+ * @see deviceMetric()
14
+ * @see deviceRegiterMetric()
15
+ */
16
+ export default class DeviceMetrics extends BootClass {
17
+ /**
18
+ * VRack-DB class instance
19
+ */
20
+ DB: SingleDB;
21
+ process(): void;
22
+ /**
23
+ * Checks if the metric exists in the device
24
+ *
25
+ * @param device Device ID
26
+ * @param name Registered metric name
27
+ */
28
+ has(device: string, name: string): boolean;
29
+ /**
30
+ * Read device metric from the database
31
+ *
32
+ * @param device Device ID
33
+ * @param name Registered metric name
34
+ * @param period Period in the format 'now-6h:now' @see SingleDB.read
35
+ * @param precision Accuracy interval '15m', '5s', '1h' or count of metrics 10, 200, 1500
36
+ * @param precision func Data aggregation function @see SingleDB.read
37
+ */
38
+ read(device: string, name: string, period: string, precision: string | number, func?: string): import("vrack-db").IMetricReadResult;
39
+ /**
40
+ * Registers the device metric
41
+ *
42
+ * When a device is initialized - the container gets a list of
43
+ * device metrics and passes them to the `device.register.metric` event for each metric.
44
+ *
45
+ * @param nEvent Object like a { device: 'Device ID', data: 'metric.name', trace: IMetricSettings object}
46
+ * @see IMetricSettings
47
+ * @see registerMetric
48
+ */
49
+ protected deviceRegiterMetric(nEvent: IDeviceEvent): void;
50
+ /**
51
+ * @see deviceRegiterMetric
52
+ * */
53
+ protected registerMetric(path: string, metric: IMetricSettings): void;
54
+ /**
55
+ * A method of writing a metric to a database.
56
+ *
57
+ * @param nEvent Object like a { device: 'Device ID', data: 'metric.name', trace: { value: metric value 123, modify: function of vrack db modify } }
58
+ * @example
59
+ * ```ts
60
+ * deviceMetric({
61
+ * device: 'Device ID',
62
+ * data: 'metric.name',
63
+ * trace: { value: 5.25, modify: 'last'}
64
+ * })
65
+ * ```
66
+ */
67
+ protected deviceMetric(nEvent: IDeviceEvent): void;
68
+ /**
69
+ * Selects the interval class depending on the specified minimal time unit
70
+ *
71
+ * @param interval s | ms | us
72
+ *
73
+ */
74
+ protected selectInterval(interval: string): typeof Interval;
75
+ /**
76
+ * Return metric path
77
+ *
78
+ * @param device Device ID
79
+ * @param name Metric name
80
+ */
81
+ protected getMetricPath(device: string, name: string): string;
82
+ }
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright © 2025 Boris Bobylev. All rights reserved.
4
+ * Licensed under the Apache License, Version 2.0
5
+ */
6
+ var __importDefault = (this && this.__importDefault) || function (mod) {
7
+ return (mod && mod.__esModule) ? mod : { "default": mod };
8
+ };
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ const vrack_db_1 = require("vrack-db");
11
+ const BootClass_1 = __importDefault(require("./BootClass"));
12
+ /**
13
+ * A class to support metrics inside devices
14
+ * Using a database vrack-db. Collects and stores container metrics
15
+ *
16
+ * @see SingleDB
17
+ *
18
+ * Uses the `device.metric` and `device.register.metric` events
19
+ *
20
+ * @see deviceMetric()
21
+ * @see deviceRegiterMetric()
22
+ */
23
+ class DeviceMetrics extends BootClass_1.default {
24
+ constructor() {
25
+ super(...arguments);
26
+ /**
27
+ * VRack-DB class instance
28
+ */
29
+ this.DB = new vrack_db_1.SingleDB();
30
+ }
31
+ process() {
32
+ this.Container.on('device.metric', this.deviceMetric.bind(this));
33
+ this.Container.on('device.register.metric', this.deviceRegiterMetric.bind(this));
34
+ }
35
+ /**
36
+ * Checks if the metric exists in the device
37
+ *
38
+ * @param device Device ID
39
+ * @param name Registered metric name
40
+ */
41
+ has(device, name) {
42
+ const path = this.getMetricPath(device, name);
43
+ if (!this.DB.has(path))
44
+ return false;
45
+ return true;
46
+ }
47
+ /**
48
+ * Read device metric from the database
49
+ *
50
+ * @param device Device ID
51
+ * @param name Registered metric name
52
+ * @param period Period in the format 'now-6h:now' @see SingleDB.read
53
+ * @param precision Accuracy interval '15m', '5s', '1h' or count of metrics 10, 200, 1500
54
+ * @param precision func Data aggregation function @see SingleDB.read
55
+ */
56
+ read(device, name, period, precision, func) {
57
+ const path = this.getMetricPath(device, name);
58
+ return this.DB.read(path, period, precision, func);
59
+ }
60
+ /**
61
+ * Registers the device metric
62
+ *
63
+ * When a device is initialized - the container gets a list of
64
+ * device metrics and passes them to the `device.register.metric` event for each metric.
65
+ *
66
+ * @param nEvent Object like a { device: 'Device ID', data: 'metric.name', trace: IMetricSettings object}
67
+ * @see IMetricSettings
68
+ * @see registerMetric
69
+ */
70
+ deviceRegiterMetric(nEvent) {
71
+ this.registerMetric(this.getMetricPath(nEvent.device, nEvent.data), nEvent.trace);
72
+ }
73
+ /**
74
+ * @see deviceRegiterMetric
75
+ * */
76
+ registerMetric(path, metric) {
77
+ this.DB.metric({
78
+ name: path,
79
+ retentions: metric.retentions,
80
+ tStorage: metric.tType,
81
+ vStorage: metric.vType,
82
+ CInterval: this.selectInterval(metric.interval)
83
+ });
84
+ }
85
+ /**
86
+ * A method of writing a metric to a database.
87
+ *
88
+ * @param nEvent Object like a { device: 'Device ID', data: 'metric.name', trace: { value: metric value 123, modify: function of vrack db modify } }
89
+ * @example
90
+ * ```ts
91
+ * deviceMetric({
92
+ * device: 'Device ID',
93
+ * data: 'metric.name',
94
+ * trace: { value: 5.25, modify: 'last'}
95
+ * })
96
+ * ```
97
+ */
98
+ deviceMetric(nEvent) {
99
+ const path = this.getMetricPath(nEvent.device, nEvent.data);
100
+ if (!this.DB.has(path))
101
+ return;
102
+ this.DB.write(path, nEvent.trace.value, 0, nEvent.trace.modify);
103
+ }
104
+ /**
105
+ * Selects the interval class depending on the specified minimal time unit
106
+ *
107
+ * @param interval s | ms | us
108
+ *
109
+ */
110
+ selectInterval(interval) {
111
+ switch (interval) {
112
+ case 's': return vrack_db_1.Interval;
113
+ case 'ms': return vrack_db_1.IntervalMs;
114
+ case 'us': return vrack_db_1.IntervalUs;
115
+ }
116
+ return vrack_db_1.Interval;
117
+ }
118
+ /**
119
+ * Return metric path
120
+ *
121
+ * @param device Device ID
122
+ * @param name Metric name
123
+ */
124
+ getMetricPath(device, name) {
125
+ return (device + '.' + name).toLowerCase();
126
+ }
127
+ }
128
+ exports.default = DeviceMetrics;
@@ -0,0 +1,59 @@
1
+ import BootClass from "./BootClass";
2
+ import BasicType from "../validator/types/BasicType";
3
+ import { IContainerStructure } from "../Container";
4
+ /**
5
+ * A boot class for storing the structure of a container.
6
+ *
7
+ * When a container is created, it is assigned a unique identifier.
8
+ * This identifier is used as parameters of methods.
9
+ *
10
+ * @see getById
11
+ * @see updateById
12
+ *
13
+ * When the container is loaded it calls “beforeLoaded”.
14
+ * At this point it updates the structure from disk to the structure
15
+ * of the container itself and writes the changes
16
+ *
17
+ * @see beforeLoadedUpdate
18
+ *
19
+ * */
20
+ export default class StructureStorage extends BootClass {
21
+ checkOptions(): {
22
+ [key: string]: BasicType;
23
+ };
24
+ process(): void;
25
+ /**
26
+ * Updates the structure on disk using the structure of
27
+ * the container itself when it is loaded
28
+ *
29
+ *
30
+ * @see StructureStorage.process
31
+ */
32
+ beforeLoadedUpdate(): Promise<void>;
33
+ /**
34
+ * Returns structure by container identifier
35
+ *
36
+ * @param id Container ID
37
+ */
38
+ getById(id: string): Promise<IContainerStructure>;
39
+ /**
40
+ * Updating the container structure
41
+ *
42
+ * @param id Container ID
43
+ * @param structure updated container structure object
44
+ */
45
+ updateById(id: string, structure: IContainerStructure): Promise<void>;
46
+ /**
47
+ * Updates the display structure parameter from the file structure
48
+ *
49
+ * @param cStruct now container structure
50
+ * @param structure new structure
51
+ */
52
+ protected updateStructure(cStruct: IContainerStructure, structure: IContainerStructure, id: string): void;
53
+ /**
54
+ * Forms the path to the structure file by its identifier
55
+ *
56
+ * @param id Container ID
57
+ */
58
+ protected makeFilePath(id: string): string;
59
+ }