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/README.md
CHANGED
|
@@ -1,6 +1,27 @@
|
|
|
1
|
-
VRack2
|
|
2
|
-
|
|
1
|
+
VRack2 Core
|
|
2
|
+
============
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
Фреймворк для создания событийно-ориентированных сервисов на JavaScript/TypeScript. Определяет правила организации кода, структуру файлов и предоставляет базовые компоненты для их реализации.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Оптимально использовать VRack2 Core в составе VRack2, но допускается и самостоятельное использование.
|
|
7
|
+
|
|
8
|
+
Если вы хотите попробовать данный подход - настоятельно рекомендуется использовать вначале [VRack2](https://github.com/VRack2/vrack2) и его документацию.
|
|
9
|
+
|
|
10
|
+
--------
|
|
11
|
+
|
|
12
|
+
**Использовать эту документацию имеет смысл только для более глубокого изучения устройства VRack2 или для создания сервиса независимого от VRack2**
|
|
13
|
+
|
|
14
|
+
-------
|
|
15
|
+
|
|
16
|
+
- [VRack2](https://github.com/VRack2/vrack2) - Официальный репозиторий
|
|
17
|
+
- [VRack2-service](https://github.com/VRack2/vrack2-service) - Репозиторий для запуска сервисов на основе VRack2-Core, включая официальный VRack2.
|
|
18
|
+
- [VRack2 Manager](https://github.com/VRack2/vrack2-manager) - Интерфейс для работы с сервисами VRack2
|
|
19
|
+
|
|
20
|
+
Основная документация для VRack2-Core на данный момент не готова. Часть документации в виде черновиков уже есть.
|
|
21
|
+
|
|
22
|
+
**Документы для глубокого погружения:**
|
|
23
|
+
|
|
24
|
+
<!-- 1. [Быстрый старт](./docs/FastStart.md) - -->
|
|
25
|
+
1. [Общая структура](./docs/Structure.md)
|
|
26
|
+
2. [Контейнер](./docs/Container.md)
|
|
27
|
+
3. [Bootstrap Классы](./docs/Bootstrap.md)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Bootstrap Классы
|
|
2
|
+
|
|
3
|
+
Bootstrap классы предоставляют механизм для расширения функционала сервисов без использования устройств. Они инициализируются после создания контейнера, но до его запуска, позволяя подписываться на события контейнера и изменять его поведение.
|
|
4
|
+
|
|
5
|
+
## Основные возможности
|
|
6
|
+
|
|
7
|
+
- Расширение возможностей контейнера
|
|
8
|
+
- Изменение стандартного поведения контейнера
|
|
9
|
+
- Замена стандартных Bootstrap классов
|
|
10
|
+
- Интеграция с основным процессом загрузки
|
|
11
|
+
|
|
12
|
+
## Стандартные Bootstrap Классы
|
|
13
|
+
|
|
14
|
+
Следующие классы являются обязательными для загрузки контейнера:
|
|
15
|
+
|
|
16
|
+
| Класс | Описание |
|
|
17
|
+
|-------------------|----------|
|
|
18
|
+
| **DeviceManager** | Предоставляет информацию об устройствах (списки, информация об устройстве, создание экземпляров) |
|
|
19
|
+
| **DeviceFileStorage** | Обеспечивает сохранение и восстановление сохраняемых данных устройств |
|
|
20
|
+
| **DeviceMetrics** | Отвечает за сохранение метрик устройств |
|
|
21
|
+
| **StructureStorage** | Обеспечивает обновление структуры контейнера |
|
|
22
|
+
|
|
23
|
+
*Примечание:* Несмотря на обязательность этих классов, их можно заменить пользовательскими реализациями с аналогичным интерфейсом.
|
|
24
|
+
|
|
25
|
+
## Настройка Bootstrap Классов
|
|
26
|
+
|
|
27
|
+
Загрузкой Bootstrap классов занимается класс `MainProcess`. При его инициализации можно:
|
|
28
|
+
|
|
29
|
+
1. Заменить список классов на пользовательский
|
|
30
|
+
2. Изменить настройки, передаваемые в эти классы
|
|
31
|
+
|
|
32
|
+
### Пример конфигурации
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
const MainProcessEx = new MainProcessClass({
|
|
36
|
+
id,
|
|
37
|
+
service,
|
|
38
|
+
bootstrap: {
|
|
39
|
+
DeviceManager: {
|
|
40
|
+
path: 'vrack2-core.DeviceManager',
|
|
41
|
+
options: { storageDir: './storage' }
|
|
42
|
+
},
|
|
43
|
+
DeviceStorage: {
|
|
44
|
+
path: 'vrack2-core.DeviceFileStorage',
|
|
45
|
+
options: {}
|
|
46
|
+
},
|
|
47
|
+
StructureStorage: {
|
|
48
|
+
path: 'vrack2-core.StructureStorage',
|
|
49
|
+
options: {}
|
|
50
|
+
},
|
|
51
|
+
DeviceMetrics: {
|
|
52
|
+
path: 'vrack2-core.DeviceMetrics',
|
|
53
|
+
options: {}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Примечания:**
|
|
60
|
+
- Bootstrap классы привязываются к идентификатору
|
|
61
|
+
- Пути указываются в формате `ImportManager`
|
|
62
|
+
- Классы должны быть оформлены как npm модули
|
|
63
|
+
|
|
64
|
+
## Создание пользовательских Bootstrap Классов
|
|
65
|
+
|
|
66
|
+
Все Bootstrap классы должны наследовать базовый класс `vrack2-core.BootClass`.
|
|
67
|
+
|
|
68
|
+
### Структура класса
|
|
69
|
+
|
|
70
|
+
1. **checkOptions()** - метод для переопределения параметров (аналогично классу устройства)
|
|
71
|
+
2. **process()** и **processPromise()** - методы для реализации основной логики класса
|
|
72
|
+
|
|
73
|
+
В методах `process()` и `processPromise()` доступен объект `Container`, для которого запускается класс
|
|
74
|
+
|
|
75
|
+
### Рекомендации
|
|
76
|
+
|
|
77
|
+
Для разработки собственных Bootstrap классов рекомендуется изучить существующие реализации в VRack2 Core.
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
|
|
2
|
+
# Container
|
|
3
|
+
|
|
4
|
+
Класс `Container` представляет собой контейнер для управления устройствами, их соединениями и взаимодействием в рамках сервиса.
|
|
5
|
+
|
|
6
|
+
Контейнер создается внутри класса `MainProcess`. Это сделано для удобного правильного инциализирования классов `Bootstrap` и `Container` которые содержат ссылки внутри себя на друг друга.
|
|
7
|
+
|
|
8
|
+
Это центральный компонент, который:
|
|
9
|
+
|
|
10
|
+
- Инициализирует устройства согласно объекту сервиса (обычно получается из файла сервиса)
|
|
11
|
+
- Устанавливает соединения между портами устройств
|
|
12
|
+
- Управляет жизненным циклом устройств
|
|
13
|
+
- Обрабатывает действия и метрики устройств
|
|
14
|
+
- Предоставляет структуру сервиса
|
|
15
|
+
|
|
16
|
+
Контейнер наследуется от `EventEmitter` и эмитирует различные события на разных этапах работы.
|
|
17
|
+
|
|
18
|
+
Функционал контейнера может расширяться с помощью [bootstrap классов](./Bootstrap.md). Он обязательно требует реализцию всех базовых bootstrap классов. Например `DeviceManager` предоставляет контейнеру возможность загружать классы устройств и инициализировать их, только с помощью него он знает что-то о наличии устройств.
|
|
19
|
+
|
|
20
|
+
### Конструктор
|
|
21
|
+
```typescript
|
|
22
|
+
constructor(id: string, service: IServiceStructure, Bootstrap: Bootstrap, confFile?: string)
|
|
23
|
+
```
|
|
24
|
+
- `id` - уникальный ID сервиса
|
|
25
|
+
- `service` - структура сервиса
|
|
26
|
+
- `Bootstrap` - класс Bootstrap для контейнера
|
|
27
|
+
- `confFile` - (опционально) путь к файлу конфигурации
|
|
28
|
+
|
|
29
|
+
### init()
|
|
30
|
+
Инициализирует контейнер:
|
|
31
|
+
1. Загружает дополнительные конфигурации (если указаны)
|
|
32
|
+
2. Инициализирует устройства
|
|
33
|
+
3. Устанавливает соединения между устройствами
|
|
34
|
+
|
|
35
|
+
### run()
|
|
36
|
+
Запускает контейнер:
|
|
37
|
+
1. Запускает процессы устройств
|
|
38
|
+
|
|
39
|
+
## Обработка ошибок
|
|
40
|
+
Контейнер определяет множество ошибок через ErrorManager:
|
|
41
|
+
|
|
42
|
+
### Ошибки устройств:
|
|
43
|
+
- `CTR_ERROR_INIT_DEVICE` - ошибка инициализации устройства (общая ошибка инициализации устройства. См. Вложенные ошибки)
|
|
44
|
+
- `CTR_INCORRECT_DEVICE_ID` - некорректный ID устройства
|
|
45
|
+
- `CTR_DEVICE_DUBLICATE` - дублирование ID устройства
|
|
46
|
+
- `CTR_ERROR_PREPARE_OPTIONS` - ошибка подготовки параметров
|
|
47
|
+
- `CTR_DEVICE_ACTION_NF` - действие устройства не найдено
|
|
48
|
+
- `CTR_DEVICE_NF` - устройство не найдено
|
|
49
|
+
- `CTR_DEVICE_ACTION_HANDLER_NF` - обработчик действия не найден
|
|
50
|
+
- `CTR_DEVICE_PROCESS_EXCEPTION` - исключение при выполнении process
|
|
51
|
+
- `CTR_DEVICE_PROCESS_PROMISE_EXCEPTION` - исключение при выполнении processPromise
|
|
52
|
+
|
|
53
|
+
### Ошибки портов:
|
|
54
|
+
- `CTR_INCORRECT_DYNAMIC_PN` - некорректное имя динамического порта
|
|
55
|
+
- `CTR_INCORRECT_PN` - некорректное имя порта
|
|
56
|
+
- `CTR_INPUT_HANDLER_NF` - обработчик входа не найден
|
|
57
|
+
- `CTR_DEVICE_PORT_NF` - порт на устройстве не найден
|
|
58
|
+
|
|
59
|
+
### Ошибки соединений:
|
|
60
|
+
- `CTR_CONNECTION_INCORRECT` - некорректный формат соединения
|
|
61
|
+
- `CTR_CONNECTION_DEVICE_NF` - устройство соединения не найдено
|
|
62
|
+
- `CTR_CONNECTION_PORT_NF` - порт соединения не найден
|
|
63
|
+
- `CTR_INCOMPATIBLE_PORTS` - несовместимые порты
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Внутренние события
|
|
67
|
+
|
|
68
|
+
События указаны в порядке их запуска. Bootstrap классы могут подписываться на событий контейнера что бы расширять его возможности. Так делают часть стандартных bootstrap классов.
|
|
69
|
+
|
|
70
|
+
1. **configure** - Запускается первым, перед заполнением файла конфигурации
|
|
71
|
+
2. **beforeInit** - Перед началом инициализации
|
|
72
|
+
3. **init** - Начало инициализации устройств
|
|
73
|
+
4. **initDevice(device)** - Будет выполнятся для каждого инициализируемого устройства
|
|
74
|
+
5. **afterInit** - После окончания инициализации устройств
|
|
75
|
+
6. **beforeConnections** - Перед началом инциализации соединений
|
|
76
|
+
7. **connections** - Начало инициализации соединений
|
|
77
|
+
8. **connection(conn)** - Будет выполнено для каждого соединения
|
|
78
|
+
9. **afterConnections** - После окончания инциализаций соеднинений
|
|
79
|
+
10. **beforeProcess** - Перед выполнением `process` для каждого устройства
|
|
80
|
+
11. **process(DeviceID)** - Будет выполнено для каждого устройства перед запуском `process`
|
|
81
|
+
12. **afterProcess** - После окончания всех запусков `process`
|
|
82
|
+
13. **beforeProcessPromise** - Перед выполнением `processPromise` каждого устройства
|
|
83
|
+
14. **processPromise(DeviceID)** - Будет выполнено для каждого устройства перед запуском `processPromise`
|
|
84
|
+
15. **afterProcessPromise** - После окончания всех запусков `processPromise`
|
|
85
|
+
16. **beforeLoaded** - Перед окончанием загрузки контейнера
|
|
86
|
+
17. **loaded** - После окончания загрузки контейнера
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
Описания структур передаваемых в указаных выше события
|
|
90
|
+
|
|
91
|
+
### initDevice(device)
|
|
92
|
+
|
|
93
|
+
Объект в виде структуры `IStructureDevice`
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
export default interface IStructureDevice {
|
|
97
|
+
/** Device ID */
|
|
98
|
+
id: string;
|
|
99
|
+
/** Device type in VRack style like a 'vendor.Device' */
|
|
100
|
+
type: string;
|
|
101
|
+
/** Device options */
|
|
102
|
+
options: { [key: string]: any; };
|
|
103
|
+
/** Device connections */
|
|
104
|
+
connections?: Array<string>
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
### connection(сс)
|
|
110
|
+
|
|
111
|
+
Объект в виде структуры:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
interface: {
|
|
115
|
+
outputDevice: string;
|
|
116
|
+
outputPort: string;
|
|
117
|
+
inputDevice: string;
|
|
118
|
+
inputPort: string;
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### process(DeviceID) & processPromise(DeviceID)
|
|
123
|
+
|
|
124
|
+
**DeviceID** - Строковый уникальный идентификатор устройсва. Доступ к любому устройсту внутри контейнера можно получить так `ContainerClass.devices[DeviceID]` или внутри устройства `this.Container.devices[DeviceID]`
|
package/docs/Device.md
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# Документация для класса `Device`
|
|
2
|
+
|
|
3
|
+
## Общее описание
|
|
4
|
+
Класс `Device` представляет базовый класс для всех устройств в системе. Это абстрактный класс, который определяет:
|
|
5
|
+
- Основные свойства и методы всех устройств
|
|
6
|
+
- Механизмы взаимодействия с контейнером
|
|
7
|
+
- Систему портов для связи между устройствами
|
|
8
|
+
- Обработку действий и метрик
|
|
9
|
+
- Систему событий и сообщений
|
|
10
|
+
|
|
11
|
+
Устройства наследуются от этого класса и реализуют свою специфическую логику.
|
|
12
|
+
|
|
13
|
+
## Основные свойства
|
|
14
|
+
|
|
15
|
+
Основные свойства устройства назнаются контейнером при инициализации устройства согласно файлу сервиса.
|
|
16
|
+
|
|
17
|
+
- **id** *string* - Уникальный идентификатор устройства в рамках контейнера. Обычно начинается с заглавной буквы.
|
|
18
|
+
- **type** *string* - Тип устройства в формате "вендор.Устройство".
|
|
19
|
+
- **Container** *Container* - Ссылка на контейнер, который создал устройство
|
|
20
|
+
- **options** *any* - Параметры устройства
|
|
21
|
+
|
|
22
|
+
## Переопределяемые методы и свойства
|
|
23
|
+
|
|
24
|
+
#### preProcess()
|
|
25
|
+
Вызывается на этапе инициализации устройства (до создания соединений). Тут еще есть возможность поменять количество портов, создать обработчики для входящих портов, или например обработчики для экшенов. На этом этапе только создается класс и назначаются основные свойства.
|
|
26
|
+
|
|
27
|
+
#### process()
|
|
28
|
+
Основной метод запуска устройства (после инициализации всех соединений).
|
|
29
|
+
|
|
30
|
+
#### processPromise()
|
|
31
|
+
Асинхронная версия process() - контейнер ждет завершения всех processPromise().
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
### ports
|
|
35
|
+
Объект для управления портами устройства:
|
|
36
|
+
```typescript
|
|
37
|
+
ports: {
|
|
38
|
+
input: { [key: string]: DevicePort } // Входные порты
|
|
39
|
+
output: { [key: string]: DevicePort } // Выходные порты
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Container
|
|
44
|
+
Ссылка на контейнер, в котором находится устройство.
|
|
45
|
+
```typescript
|
|
46
|
+
Container: Container;
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### options
|
|
50
|
+
Параметры устройства, которые проверяются методом `checkOptions()`.
|
|
51
|
+
```typescript
|
|
52
|
+
options: { [key: string]: any } = {};
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### shares
|
|
56
|
+
Быстро обновляемые данные устройства, которые отправляются подписчикам после вызова `render()`.
|
|
57
|
+
```typescript
|
|
58
|
+
shares: any = {};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### storage
|
|
62
|
+
Данные устройства, которые сохраняются между сеансами работы.
|
|
63
|
+
```typescript
|
|
64
|
+
storage: any = {}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Основные методы
|
|
68
|
+
|
|
69
|
+
### Конструктор
|
|
70
|
+
```typescript
|
|
71
|
+
constructor(id: string, type: string, Container: Container)
|
|
72
|
+
```
|
|
73
|
+
- `id` - уникальный ID устройства
|
|
74
|
+
- `type` - тип устройства
|
|
75
|
+
- `Container` - ссылка на контейнер
|
|
76
|
+
|
|
77
|
+
### settings()
|
|
78
|
+
Возвращает настройки устройства, включая список каналов связи.
|
|
79
|
+
```typescript
|
|
80
|
+
settings(): IDeviceSettings {
|
|
81
|
+
return {
|
|
82
|
+
channels: ['terminal', 'notify', 'event', 'action', 'alert', 'error', 'render']
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### description()
|
|
88
|
+
Возвращает описание устройства (может содержать markdown).
|
|
89
|
+
```typescript
|
|
90
|
+
description(): string {
|
|
91
|
+
return ''
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### actions()
|
|
96
|
+
Определяет список действий, которые можно выполнять с устройством.
|
|
97
|
+
```typescript
|
|
98
|
+
actions(): { [key: string]: BasicAction } { return {} }
|
|
99
|
+
// Пример:
|
|
100
|
+
// return {
|
|
101
|
+
// 'test.action': Action.global().requirements({
|
|
102
|
+
// id: Rule.string().require().default('www').description('Some id')
|
|
103
|
+
// }).description('Test action')
|
|
104
|
+
// }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### metrics()
|
|
108
|
+
Определяет метрики устройства.
|
|
109
|
+
```typescript
|
|
110
|
+
metrics(): { [key: string]: BasicMetric } { return {} }
|
|
111
|
+
// Пример:
|
|
112
|
+
// return {
|
|
113
|
+
// 'temperature': Metric.inS().retentions('1s:6h').description('Temperature metric')
|
|
114
|
+
// }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### checkOptions()
|
|
118
|
+
Определяет правила валидации параметров устройства.
|
|
119
|
+
```typescript
|
|
120
|
+
checkOptions(): { [key: string]: BasicType } { return {} }
|
|
121
|
+
// Пример:
|
|
122
|
+
// return {
|
|
123
|
+
// timeout: Rule.number().integer().min(0).description('Interval timeout').example(0)
|
|
124
|
+
// }
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### inputs() / outputs()
|
|
128
|
+
Определяют входные и выходные порты устройства.
|
|
129
|
+
```typescript
|
|
130
|
+
inputs(): { [key: string]: BasicPort } { return {} }
|
|
131
|
+
outputs(): { [key: string]: BasicPort } { return {} }
|
|
132
|
+
// Пример:
|
|
133
|
+
// return {
|
|
134
|
+
// 'sensor.temperature': Port.standart(),
|
|
135
|
+
// 'control.setpoint': Port.standart()
|
|
136
|
+
// }
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Жизненный цикл устройства
|
|
140
|
+
|
|
141
|
+
#### preProcess()
|
|
142
|
+
Вызывается на этапе инициализации устройства (до создания соединений).
|
|
143
|
+
|
|
144
|
+
#### process()
|
|
145
|
+
Основной метод запуска устройства (после инициализации всех соединений).
|
|
146
|
+
|
|
147
|
+
#### processPromise()
|
|
148
|
+
Асинхронная версия process() - контейнер ждет завершения всех processPromise().
|
|
149
|
+
|
|
150
|
+
### Методы работы с данными
|
|
151
|
+
|
|
152
|
+
#### render()
|
|
153
|
+
Отправляет данные из `shares` подписчикам.
|
|
154
|
+
|
|
155
|
+
#### save()
|
|
156
|
+
Сохраняет данные из `storage`.
|
|
157
|
+
|
|
158
|
+
#### metric()
|
|
159
|
+
Записывает значение метрики.
|
|
160
|
+
```typescript
|
|
161
|
+
metric(path: string, value: number, modify: 'last' | 'first' | 'max' | 'min' | 'avg' | 'sum' = 'last')
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Методы сообщений
|
|
165
|
+
|
|
166
|
+
#### terminal() / notify() / event() / alert() / error()
|
|
167
|
+
Отправляют сообщения разных типов.
|
|
168
|
+
```typescript
|
|
169
|
+
terminal(data: string, trace: { [key: string]: any }, ...args: any[])
|
|
170
|
+
notify(data: string, trace: { [key: string]: any }, ...args: any[])
|
|
171
|
+
// и т.д.
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Вспомогательные методы
|
|
175
|
+
|
|
176
|
+
#### addInputHandler()
|
|
177
|
+
Добавляет обработчик для входного порта.
|
|
178
|
+
```typescript
|
|
179
|
+
addInputHandler(name: string, action: (data: any) => any)
|
|
180
|
+
// Пример:
|
|
181
|
+
// this.addInputHandler('control.setpoint', (value) => { ... })
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
#### addActionHandler()
|
|
185
|
+
Добавляет обработчик для действия.
|
|
186
|
+
```typescript
|
|
187
|
+
addActionHandler(name: string, action: (data: any) => any)
|
|
188
|
+
// Пример:
|
|
189
|
+
// this.addActionHandler('set.temperature', (data) => { ... })
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### terminate()
|
|
193
|
+
Сигнализирует о критической ошибке и необходимости остановки устройства.
|
|
194
|
+
```typescript
|
|
195
|
+
terminate(error: Error, action: string)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Интерфейсы
|
|
199
|
+
|
|
200
|
+
### IDeviceSettings
|
|
201
|
+
Настройки устройства:
|
|
202
|
+
```typescript
|
|
203
|
+
interface IDeviceSettings {
|
|
204
|
+
channels: Array<'terminal' | 'notify' | 'event' | 'action' | 'alert' | 'error' | 'render'>;
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### IDeviceEvent
|
|
209
|
+
Структура события устройства:
|
|
210
|
+
```typescript
|
|
211
|
+
interface IDeviceEvent {
|
|
212
|
+
device: string; // ID устройства
|
|
213
|
+
data: string; // Данные события
|
|
214
|
+
trace: { [key: string]: any }; // Дополнительная информация
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Пример использования
|
|
219
|
+
```typescript
|
|
220
|
+
class TemperatureSensor extends Device {
|
|
221
|
+
private currentTemp = 0;
|
|
222
|
+
|
|
223
|
+
description(): string {
|
|
224
|
+
return 'Датчик температуры с возможностью установки уставки';
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
actions() {
|
|
228
|
+
return {
|
|
229
|
+
'set.temperature': Action.global()
|
|
230
|
+
.requirements({
|
|
231
|
+
value: Rule.number().min(-50).max(100).description('Температура')
|
|
232
|
+
})
|
|
233
|
+
.description('Установка температуры')
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
metrics() {
|
|
238
|
+
return {
|
|
239
|
+
'temperature': Metric.inS().retentions('1s:6h').description('Текущая температура')
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
inputs() {
|
|
244
|
+
return {
|
|
245
|
+
'control.setpoint': Port.standart()
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
process() {
|
|
250
|
+
// Чтение температуры каждую секунду
|
|
251
|
+
setInterval(() => {
|
|
252
|
+
this.currentTemp = readTemperature();
|
|
253
|
+
this.metric('temperature', this.currentTemp);
|
|
254
|
+
this.render();
|
|
255
|
+
}, 1000);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Обработчик действия
|
|
259
|
+
actionSetTemperature(data: { value: number }) {
|
|
260
|
+
this.currentTemp = data.value;
|
|
261
|
+
return { status: 'ok' };
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Класс `Device` предоставляет мощную основу для создания различных устройств с поддержкой:
|
|
267
|
+
- Валидации параметров
|
|
268
|
+
- Действий с внешним интерфейсом
|
|
269
|
+
- Метрик для мониторинга
|
|
270
|
+
- Портов для связи между устройствами
|
|
271
|
+
- Различных типов сообщений
|
|
272
|
+
- Жизненного цикла устройства
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Быстрый старт
|
|
2
|
+
=============
|
|
3
|
+
|
|
4
|
+
Если вы хотите вначале быстро запустить и попробовать свое первое приложение вне VRack2, это хороший вариант для вас.
|
|
5
|
+
|
|
6
|
+
Для начала создадим папку:
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
mkdir myvapp
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Перейдем в нее и проинициализируем npm
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
cd ./myvapp
|
|
16
|
+
npm init
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Можете просто нажимать Enter пока конфигуратор npm не закончит свою работу
|
|
20
|
+
|
|
21
|
+
Установить vrack2-core:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install vrack2-core
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Создадим еще необходимые директории
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
mkdir ./devices
|
|
31
|
+
mkdir ./storage
|
|
32
|
+
mkdir ./structure
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
Создадим файл запуска нашего сервиса `index.js` с содержимым
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
import { ImportManager, MainProcess } from "vrack2-core";
|
|
40
|
+
import { isMainThread, workerData } from "worker_threads";
|
|
41
|
+
// Класс MainProcess
|
|
42
|
+
let MainProcessPath = 'vrack2-core.MainProcess'
|
|
43
|
+
// Файл структуры сервиса
|
|
44
|
+
let processFile = './service.json'
|
|
45
|
+
// Идентификатор контейнера - должен быть уникален только в случае запуска нескольких контейнеров
|
|
46
|
+
let id = 'containerID'
|
|
47
|
+
|
|
48
|
+
async function run (){
|
|
49
|
+
// Импортируем JSON file
|
|
50
|
+
const service = await ImportManager.importJSON(processFile)
|
|
51
|
+
// Импортируем класс MainProcess
|
|
52
|
+
const MainProcessClass = await ImportManager.importClass(MainProcessPath)
|
|
53
|
+
// Создаем экземпляр
|
|
54
|
+
const MainProcessEx = new MainProcessClass({ id, service })
|
|
55
|
+
|
|
56
|
+
MainProcessEx.run()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Запуск
|
|
60
|
+
run()
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Отредактируем файл `package.json` и добавим скрипт запуска
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
"scripts": {
|
|
67
|
+
"start": "node ./index",
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Пришло время добавить набор устройств. Создадим папку:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
mkdir ./devices/myvendor
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Создадим файл `Interval.js`
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
take ./devices/myvendor/Interval.js
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Добавим содержимое:
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Создадим файл `Debug.js`
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
take ./devices/myvendor/Debug.js
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Добавим содержимое:
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Осталось добавить файл сервиса `service.json` с содержимым:
|
|
102
|
+
|
|
103
|
+
```JSON
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Теперь можно запустить сервис:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm run start
|
|
111
|
+
```
|