miravo 0.6.0 → 0.6.2
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/LICENSE +199 -0
- package/README.md +29 -59
- package/bin/miravo.js +84 -0
- package/package.json +21 -37
- package/console-dist/assets/activity-DsWeRq4h.js +0 -1
- package/console-dist/assets/api-4AqKvsm9.js +0 -1
- package/console-dist/assets/arrow-right-Ea_UhTNi.js +0 -1
- package/console-dist/assets/arrow-up-down-DFSjzzl2.js +0 -1
- package/console-dist/assets/blueprint-card-classes-DBFCDy0M.js +0 -1
- package/console-dist/assets/box-C1WaoOMF.js +0 -1
- package/console-dist/assets/card-BjeP32PN.js +0 -1
- package/console-dist/assets/catalog-BJzyzbLR.js +0 -1
- package/console-dist/assets/catalog-DKjEm-c4.js +0 -1
- package/console-dist/assets/catalog-template-icons-BrUeHaCY.js +0 -1
- package/console-dist/assets/checkbox-DZlJXTE4.js +0 -1
- package/console-dist/assets/chunk-OE4NN4TA-CEjpfhS6.js +0 -3
- package/console-dist/assets/combobox-BGnuCYxO.js +0 -1
- package/console-dist/assets/control-CPhvwx9o.js +0 -1
- package/console-dist/assets/control-Cg2up9NA.js +0 -1
- package/console-dist/assets/copy-button-WkbNkMcd.js +0 -1
- package/console-dist/assets/createLucideIcon-Bwxw859K.js +0 -1
- package/console-dist/assets/deploy-tab-JeWDwPoZ.js +0 -1
- package/console-dist/assets/dist-BhbDML0a.js +0 -1
- package/console-dist/assets/dist-Cy8XTNFT.js +0 -2
- package/console-dist/assets/download-DQ6NH16U.js +0 -1
- package/console-dist/assets/engine-store-CrLnz692.js +0 -1
- package/console-dist/assets/events-CXm29Ok4.js +0 -1
- package/console-dist/assets/events-D01IxhnP.js +0 -1
- package/console-dist/assets/fira-code-cyrillic-ext-wght-normal-DhYMMuQd.woff2 +0 -0
- package/console-dist/assets/fira-code-cyrillic-wght-normal-Y3u8pIsh.woff2 +0 -0
- package/console-dist/assets/fira-code-greek-ext-wght-normal-wWus70Ix.woff2 +0 -0
- package/console-dist/assets/fira-code-greek-wght-normal-B2SviObF.woff2 +0 -0
- package/console-dist/assets/fira-code-latin-ext-wght-normal-Dvfvaomy.woff2 +0 -0
- package/console-dist/assets/fira-code-latin-wght-normal-CHoedHDv.woff2 +0 -0
- package/console-dist/assets/fira-code-symbols2-wght-normal-CE6EOz_n.woff2 +0 -0
- package/console-dist/assets/fleet-CfxbKXt9.js +0 -1
- package/console-dist/assets/fleet-lotMGVqe.js +0 -1
- package/console-dist/assets/format-kXTonpDJ.js +0 -1
- package/console-dist/assets/gauge-Ci8zNZlk.js +0 -1
- package/console-dist/assets/get-error-message-3Q5Q-2G5.js +0 -1
- package/console-dist/assets/index-CVPKSDvJ.js +0 -12
- package/console-dist/assets/index-DJkgDeun.css +0 -2
- package/console-dist/assets/input-BWEQFptx.js +0 -1
- package/console-dist/assets/instance-detail-C5IVwuh3.js +0 -1
- package/console-dist/assets/karla-latin-ext-wght-normal-Dq0rrjgs.woff2 +0 -0
- package/console-dist/assets/karla-latin-wght-normal-C3-ma4ov.woff2 +0 -0
- package/console-dist/assets/label-uephX5ZG.js +0 -1
- package/console-dist/assets/layers-CUsLQ1fq.js +0 -1
- package/console-dist/assets/login-C3RJli0m.js +0 -126
- package/console-dist/assets/models-B_UioWQ5.js +0 -1
- package/console-dist/assets/models-_IPlPiZ7.js +0 -1
- package/console-dist/assets/not-found-B8gAm08S.js +0 -1
- package/console-dist/assets/platform-targets-R3T-4eJ7.js +0 -1
- package/console-dist/assets/platforms-BWh0BQ3Y.js +0 -1
- package/console-dist/assets/platforms-DStNbtVc.js +0 -1
- package/console-dist/assets/proxy-CsnYqnPp.js +0 -9
- package/console-dist/assets/query-keys-BvtE7BMs.js +0 -1
- package/console-dist/assets/radio-CoHegOv5.js +0 -1
- package/console-dist/assets/rolldown-runtime-COnpUsM8.js +0 -1
- package/console-dist/assets/schibsted-grotesk-latin-ext-wght-normal-hsMS0n0O.woff2 +0 -0
- package/console-dist/assets/schibsted-grotesk-latin-wght-normal-Bb8VGrTG.woff2 +0 -0
- package/console-dist/assets/select-CeO4vP0G.js +0 -1
- package/console-dist/assets/select-display-items-CIzY8953.js +0 -1
- package/console-dist/assets/server-D9Kfn8fQ.js +0 -1
- package/console-dist/assets/shallow-6lGjQhtJ.js +0 -1
- package/console-dist/assets/tags-CiXOIHtY.js +0 -4
- package/console-dist/assets/tags-FQCXIxrP.js +0 -1
- package/console-dist/assets/tooltip-HGLF366Q.js +0 -1
- package/console-dist/assets/transition-nav-link-Df4Rk6vV.js +0 -1
- package/console-dist/assets/transition-types-CPlGtM8w.js +0 -1
- package/console-dist/assets/triangle-alert-adNk_sea.js +0 -1
- package/console-dist/assets/use-platform-stream-DGbK1k2L.js +0 -2
- package/console-dist/assets/use-transition-navigate-CCpcWXB0.js +0 -2
- package/console-dist/assets/validation-Blvud9_O.js +0 -1
- package/console-dist/assets/vendor-charts-CAZdaPlq.js +0 -60
- package/console-dist/assets/vendor-table-wd8JuMmT.js +0 -4
- package/console-dist/assets/vendor-ui-ByahnaY0.js +0 -1
- package/console-dist/favicon.svg +0 -37
- package/console-dist/index.html +0 -82
- package/console-dist/miravo-logo.png +0 -0
- package/src/__tests__/integration/executable-methods-runner.ts +0 -262
- package/src/__tests__/integration/executable-methods.integration.ts +0 -2348
- package/src/__tests__/integration/opcua-concurrent-clients.integration.ts +0 -314
- package/src/commands/adapter.ts +0 -249
- package/src/commands/apply.test.ts +0 -62
- package/src/commands/apply.ts +0 -216
- package/src/commands/cleanup.test.ts +0 -34
- package/src/commands/cleanup.ts +0 -201
- package/src/commands/cli-test-setup.ts +0 -91
- package/src/commands/export.test.ts +0 -51
- package/src/commands/export.ts +0 -404
- package/src/commands/fork.ts +0 -219
- package/src/commands/inject.test.ts +0 -57
- package/src/commands/inject.ts +0 -212
- package/src/commands/load.ts +0 -167
- package/src/commands/logs.ts +0 -173
- package/src/commands/models.test.ts +0 -162
- package/src/commands/models.ts +0 -338
- package/src/commands/pause.ts +0 -67
- package/src/commands/platforms.test.ts +0 -186
- package/src/commands/platforms.ts +0 -371
- package/src/commands/ps.ts +0 -116
- package/src/commands/remove.ts +0 -38
- package/src/commands/reset.ts +0 -44
- package/src/commands/rm.ts +0 -97
- package/src/commands/spawn.ts +0 -45
- package/src/commands/speed.ts +0 -40
- package/src/commands/start/adapter-config.ts +0 -157
- package/src/commands/start/catalog-le-dt.test.ts +0 -50
- package/src/commands/start/catalog-le-dt.ts +0 -187
- package/src/commands/start/catalog-model-schema.ts +0 -89
- package/src/commands/start/catalog-template-detail.ts +0 -54
- package/src/commands/start/daemon.ts +0 -255
- package/src/commands/start/display.ts +0 -150
- package/src/commands/start/engine-setup.ts +0 -247
- package/src/commands/start/events.ts +0 -126
- package/src/commands/start/index.ts +0 -897
- package/src/commands/start/protocol-plans.ts +0 -239
- package/src/commands/start/template-loader.ts +0 -197
- package/src/commands/start/template-resolver.ts +0 -185
- package/src/commands/start/types.ts +0 -73
- package/src/commands/start.test.ts +0 -480
- package/src/commands/status.test.ts +0 -20
- package/src/commands/status.ts +0 -470
- package/src/commands/stop.test.ts +0 -84
- package/src/commands/stop.ts +0 -169
- package/src/commands/templates.test.ts +0 -58
- package/src/commands/templates.ts +0 -277
- package/src/index.ts +0 -166
- package/src/lib/admin-auth.ts +0 -157
- package/src/lib/admin-client.test.ts +0 -51
- package/src/lib/admin-client.ts +0 -326
- package/src/lib/admin-platform-routes.ts +0 -1017
- package/src/lib/admin-platform-stream.test.ts +0 -434
- package/src/lib/admin-platform-stream.ts +0 -788
- package/src/lib/admin-responses.ts +0 -211
- package/src/lib/admin-server.test.ts +0 -781
- package/src/lib/admin-server.ts +0 -797
- package/src/lib/auth-store.ts +0 -87
- package/src/lib/daemon-registry.test.ts +0 -429
- package/src/lib/daemon-registry.ts +0 -343
- package/src/lib/le/le-apply.test.ts +0 -591
- package/src/lib/le/le-apply.ts +0 -832
- package/src/lib/le/le-auth.ts +0 -89
- package/src/lib/le/le-cleanup.test.ts +0 -168
- package/src/lib/le/le-cleanup.ts +0 -399
- package/src/lib/le/le-cli-helpers.ts +0 -77
- package/src/lib/le/le-client.ts +0 -184
- package/src/lib/le/le-concurrency.test.ts +0 -157
- package/src/lib/le/le-concurrency.ts +0 -78
- package/src/lib/le/le-connection-test.ts +0 -42
- package/src/lib/le/le-devicehub-properties.test.ts +0 -53
- package/src/lib/le/le-devicehub-properties.ts +0 -33
- package/src/lib/le/le-devicehub.ts +0 -213
- package/src/lib/le/le-digital-twins.ts +0 -285
- package/src/lib/le/le-drivers.ts +0 -23
- package/src/lib/le/le-endpoint.ts +0 -40
- package/src/lib/le/le-environments.test.ts +0 -73
- package/src/lib/le/le-environments.ts +0 -156
- package/src/lib/le/le-markers.ts +0 -87
- package/src/lib/le/le-plan.test.ts +0 -26
- package/src/lib/le/le-plan.ts +0 -109
- package/src/lib/le/le-platform-operations.test.ts +0 -198
- package/src/lib/le/le-platform-operations.ts +0 -340
- package/src/lib/le/le-static-model-schema.ts +0 -78
- package/src/lib/le/le-static-planner.test.ts +0 -255
- package/src/lib/le/le-static-planner.ts +0 -442
- package/src/lib/le/le-template-exporter.test.ts +0 -527
- package/src/lib/le/le-template-exporter.ts +0 -459
- package/src/lib/le/le-value-types.ts +0 -23
- package/src/lib/mqtt-client.ts +0 -115
- package/src/lib/parse.test.ts +0 -123
- package/src/lib/parse.ts +0 -87
- package/src/lib/resolve-simulation.test.ts +0 -118
- package/src/lib/resolve-simulation.ts +0 -181
- package/src/lib/session-store.ts +0 -110
- package/src/lib/shutdown.test.ts +0 -562
- package/src/lib/shutdown.ts +0 -621
- package/src/lib/template-category.test.ts +0 -71
- package/src/lib/template-category.ts +0 -72
- package/src/lib/template-locator.ts +0 -55
- package/src/lib/template-utils.ts +0 -45
- package/src/lib/ws-hub.ts +0 -281
- package/src/logger.test.ts +0 -172
- package/src/logger.ts +0 -402
- package/src/output.test.ts +0 -64
- package/src/output.ts +0 -160
package/console-dist/favicon.svg
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
<svg width="64" height="64" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
-
<defs>
|
|
3
|
-
<!-- Subtle mirror gradient -->
|
|
4
|
-
<linearGradient id="mirror" x1="0" y1="0" x2="0" y2="1">
|
|
5
|
-
<stop offset="0%" stop-color="#f6d28a"/>
|
|
6
|
-
<stop offset="50%" stop-color="#e5a218"/>
|
|
7
|
-
<stop offset="100%" stop-color="#c58514"/>
|
|
8
|
-
</linearGradient>
|
|
9
|
-
</defs>
|
|
10
|
-
|
|
11
|
-
<!-- Left M shape -->
|
|
12
|
-
<path d="M10 12 L30 12 L21 28 L10 28 Z"
|
|
13
|
-
fill="#e5a218"
|
|
14
|
-
stroke="#e5a218"
|
|
15
|
-
stroke-width="1.2"
|
|
16
|
-
stroke-linejoin="round"/>
|
|
17
|
-
<path d="M10 28 L21 28 L21 52 L10 48 Z"
|
|
18
|
-
fill="#e5a218"
|
|
19
|
-
stroke="#e5a218"
|
|
20
|
-
stroke-width="1.2"
|
|
21
|
-
stroke-linejoin="round"/>
|
|
22
|
-
|
|
23
|
-
<!-- Right mirrored M -->
|
|
24
|
-
<path d="M54 12 L34 12 L43 28 L54 28 Z"
|
|
25
|
-
fill="#e5a218"
|
|
26
|
-
stroke="#e5a218"
|
|
27
|
-
stroke-width="1.2"
|
|
28
|
-
stroke-linejoin="round"/>
|
|
29
|
-
<path d="M54 28 L43 28 L43 52 L54 48 Z"
|
|
30
|
-
fill="#e5a218"
|
|
31
|
-
stroke="#e5a218"
|
|
32
|
-
stroke-width="1.2"
|
|
33
|
-
stroke-linejoin="round"/>
|
|
34
|
-
|
|
35
|
-
<!-- Mirror axis (thin + subtle reflective feel) -->
|
|
36
|
-
<rect x="31.5" y="10" width="1" height="44" rx="0.5" fill="url(#mirror)" opacity="0.9"/>
|
|
37
|
-
</svg>
|
package/console-dist/index.html
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<link rel="preload" href="/assets/fira-code-latin-wght-normal-CHoedHDv.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
|
5
|
-
<link rel="preload" href="/assets/karla-latin-wght-normal-C3-ma4ov.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
|
6
|
-
<link rel="preload" href="/assets/schibsted-grotesk-latin-wght-normal-Bb8VGrTG.woff2" as="font" type="font/woff2" crossorigin="anonymous">
|
|
7
|
-
|
|
8
|
-
<meta charset="UTF-8" />
|
|
9
|
-
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
10
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
11
|
-
<meta name="theme-color" content="#0b0f12" />
|
|
12
|
-
<style>
|
|
13
|
-
html,
|
|
14
|
-
body,
|
|
15
|
-
#root {
|
|
16
|
-
height: 100%;
|
|
17
|
-
}
|
|
18
|
-
html,
|
|
19
|
-
body {
|
|
20
|
-
margin: 0;
|
|
21
|
-
background: #0b0f12;
|
|
22
|
-
color-scheme: dark;
|
|
23
|
-
}
|
|
24
|
-
</style>
|
|
25
|
-
<title>Miravo</title>
|
|
26
|
-
<script type="module" crossorigin src="/assets/index-CVPKSDvJ.js"></script>
|
|
27
|
-
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-COnpUsM8.js">
|
|
28
|
-
<link rel="modulepreload" crossorigin href="/assets/vendor-charts-CAZdaPlq.js">
|
|
29
|
-
<link rel="modulepreload" crossorigin href="/assets/chunk-OE4NN4TA-CEjpfhS6.js">
|
|
30
|
-
<link rel="modulepreload" crossorigin href="/assets/vendor-ui-ByahnaY0.js">
|
|
31
|
-
<link rel="modulepreload" crossorigin href="/assets/api-4AqKvsm9.js">
|
|
32
|
-
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-Bwxw859K.js">
|
|
33
|
-
<link rel="modulepreload" crossorigin href="/assets/query-keys-BvtE7BMs.js">
|
|
34
|
-
<link rel="modulepreload" crossorigin href="/assets/input-BWEQFptx.js">
|
|
35
|
-
<link rel="modulepreload" crossorigin href="/assets/proxy-CsnYqnPp.js">
|
|
36
|
-
<link rel="modulepreload" crossorigin href="/assets/activity-DsWeRq4h.js">
|
|
37
|
-
<link rel="modulepreload" crossorigin href="/assets/arrow-right-Ea_UhTNi.js">
|
|
38
|
-
<link rel="modulepreload" crossorigin href="/assets/select-CeO4vP0G.js">
|
|
39
|
-
<link rel="modulepreload" crossorigin href="/assets/platform-targets-R3T-4eJ7.js">
|
|
40
|
-
<link rel="modulepreload" crossorigin href="/assets/dist-BhbDML0a.js">
|
|
41
|
-
<link rel="modulepreload" crossorigin href="/assets/tooltip-HGLF366Q.js">
|
|
42
|
-
<link rel="modulepreload" crossorigin href="/assets/copy-button-WkbNkMcd.js">
|
|
43
|
-
<link rel="modulepreload" crossorigin href="/assets/checkbox-DZlJXTE4.js">
|
|
44
|
-
<link rel="modulepreload" crossorigin href="/assets/radio-CoHegOv5.js">
|
|
45
|
-
<link rel="modulepreload" crossorigin href="/assets/triangle-alert-adNk_sea.js">
|
|
46
|
-
<link rel="modulepreload" crossorigin href="/assets/format-kXTonpDJ.js">
|
|
47
|
-
<link rel="modulepreload" crossorigin href="/assets/label-uephX5ZG.js">
|
|
48
|
-
<link rel="modulepreload" crossorigin href="/assets/use-platform-stream-DGbK1k2L.js">
|
|
49
|
-
<link rel="modulepreload" crossorigin href="/assets/catalog-template-icons-BrUeHaCY.js">
|
|
50
|
-
<link rel="modulepreload" crossorigin href="/assets/layers-CUsLQ1fq.js">
|
|
51
|
-
<link rel="modulepreload" crossorigin href="/assets/server-D9Kfn8fQ.js">
|
|
52
|
-
<link rel="modulepreload" crossorigin href="/assets/dist-Cy8XTNFT.js">
|
|
53
|
-
<link rel="modulepreload" crossorigin href="/assets/platforms-BWh0BQ3Y.js">
|
|
54
|
-
<link rel="modulepreload" crossorigin href="/assets/vendor-table-wd8JuMmT.js">
|
|
55
|
-
<link rel="modulepreload" crossorigin href="/assets/arrow-up-down-DFSjzzl2.js">
|
|
56
|
-
<link rel="modulepreload" crossorigin href="/assets/download-DQ6NH16U.js">
|
|
57
|
-
<link rel="modulepreload" crossorigin href="/assets/engine-store-CrLnz692.js">
|
|
58
|
-
<link rel="modulepreload" crossorigin href="/assets/get-error-message-3Q5Q-2G5.js">
|
|
59
|
-
<link rel="modulepreload" crossorigin href="/assets/card-BjeP32PN.js">
|
|
60
|
-
<link rel="modulepreload" crossorigin href="/assets/combobox-BGnuCYxO.js">
|
|
61
|
-
<link rel="modulepreload" crossorigin href="/assets/tags-CiXOIHtY.js">
|
|
62
|
-
<link rel="modulepreload" crossorigin href="/assets/box-C1WaoOMF.js">
|
|
63
|
-
<link rel="modulepreload" crossorigin href="/assets/blueprint-card-classes-DBFCDy0M.js">
|
|
64
|
-
<link rel="modulepreload" crossorigin href="/assets/shallow-6lGjQhtJ.js">
|
|
65
|
-
<link rel="modulepreload" crossorigin href="/assets/use-transition-navigate-CCpcWXB0.js">
|
|
66
|
-
<link rel="modulepreload" crossorigin href="/assets/transition-nav-link-Df4Rk6vV.js">
|
|
67
|
-
<link rel="modulepreload" crossorigin href="/assets/validation-Blvud9_O.js">
|
|
68
|
-
<link rel="modulepreload" crossorigin href="/assets/control-CPhvwx9o.js">
|
|
69
|
-
<link rel="modulepreload" crossorigin href="/assets/deploy-tab-JeWDwPoZ.js">
|
|
70
|
-
<link rel="modulepreload" crossorigin href="/assets/models-B_UioWQ5.js">
|
|
71
|
-
<link rel="modulepreload" crossorigin href="/assets/catalog-BJzyzbLR.js">
|
|
72
|
-
<link rel="modulepreload" crossorigin href="/assets/gauge-Ci8zNZlk.js">
|
|
73
|
-
<link rel="modulepreload" crossorigin href="/assets/select-display-items-CIzY8953.js">
|
|
74
|
-
<link rel="modulepreload" crossorigin href="/assets/transition-types-CPlGtM8w.js">
|
|
75
|
-
<link rel="modulepreload" crossorigin href="/assets/fleet-CfxbKXt9.js">
|
|
76
|
-
<link rel="modulepreload" crossorigin href="/assets/events-D01IxhnP.js">
|
|
77
|
-
<link rel="stylesheet" crossorigin href="/assets/index-DJkgDeun.css">
|
|
78
|
-
</head>
|
|
79
|
-
<body>
|
|
80
|
-
<div id="root"></div>
|
|
81
|
-
</body>
|
|
82
|
-
</html>
|
|
Binary file
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createControlPlane,
|
|
3
|
-
createEngine,
|
|
4
|
-
loadTemplate,
|
|
5
|
-
loadTwinModel,
|
|
6
|
-
resolveModelPath,
|
|
7
|
-
} from "@miravo/core";
|
|
8
|
-
import { MQTTAdapter } from "@miravo/mqtt";
|
|
9
|
-
import { OPCUAAdapter } from "@miravo/opcua";
|
|
10
|
-
import type { MiravoTemplate, TwinModel } from "@miravo/shared";
|
|
11
|
-
import { startAdminServer } from "../../lib/admin-server.ts";
|
|
12
|
-
import { createSessionStore } from "../../lib/session-store.ts";
|
|
13
|
-
import { buildUNSBasePath, forEachTwin } from "../../lib/template-utils.ts";
|
|
14
|
-
|
|
15
|
-
interface RunnerArgs {
|
|
16
|
-
readonly template: string;
|
|
17
|
-
readonly modelsDir: string;
|
|
18
|
-
readonly readyFile: string;
|
|
19
|
-
readonly rbeEnabled: boolean;
|
|
20
|
-
readonly rbeDeadband: number;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
interface ReadyHealthPayload {
|
|
24
|
-
readonly status?: unknown;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function parseArgs(argv: readonly string[]): RunnerArgs {
|
|
28
|
-
const values = new Map<string, string>();
|
|
29
|
-
for (let index = 0; index < argv.length; index += 2) {
|
|
30
|
-
const key = argv[index];
|
|
31
|
-
const value = argv[index + 1];
|
|
32
|
-
if (!key?.startsWith("--") || value === undefined) {
|
|
33
|
-
throw new Error(
|
|
34
|
-
"Invalid smoke runner arguments. Expected --template <path> --models-dir <path> --ready-file <path>.",
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
values.set(key.slice(2), value);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const template = values.get("template");
|
|
41
|
-
const modelsDir = values.get("models-dir");
|
|
42
|
-
const readyFile = values.get("ready-file");
|
|
43
|
-
if (!template || !modelsDir || !readyFile) {
|
|
44
|
-
throw new Error(
|
|
45
|
-
"Missing smoke runner arguments. Provide --template, --models-dir, and --ready-file.",
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const rbeEnabled = values.get("rbe-enabled") === "true";
|
|
50
|
-
const rbeDeadband = Number.parseFloat(values.get("rbe-deadband") ?? "0");
|
|
51
|
-
|
|
52
|
-
return { template, modelsDir, readyFile, rbeEnabled, rbeDeadband };
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function resolveSimulationName(template: MiravoTemplate): string {
|
|
56
|
-
const namespace = template.namespace;
|
|
57
|
-
if (!namespace) {
|
|
58
|
-
throw new Error("Smoke template is missing namespace metadata.");
|
|
59
|
-
}
|
|
60
|
-
if ("enterprise" in namespace) {
|
|
61
|
-
return `${namespace.enterprise}-${namespace.site}`.toLowerCase();
|
|
62
|
-
}
|
|
63
|
-
return namespace.prefix.toLowerCase();
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async function loadModels(
|
|
67
|
-
template: MiravoTemplate,
|
|
68
|
-
modelsDir: string,
|
|
69
|
-
): Promise<Map<string, TwinModel>> {
|
|
70
|
-
const models = new Map<string, TwinModel>();
|
|
71
|
-
if (template.models) {
|
|
72
|
-
for (const inlineModel of template.models) {
|
|
73
|
-
models.set(inlineModel.model.name, inlineModel);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const referencedModelNames = new Set<string>();
|
|
78
|
-
forEachTwin(template, (_area, _line, twin) => {
|
|
79
|
-
referencedModelNames.add(twin.model);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
for (const modelName of referencedModelNames) {
|
|
83
|
-
if (models.has(modelName)) {
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
const modelPath = await resolveModelPath(modelName, [modelsDir]);
|
|
87
|
-
const model = await loadTwinModel(modelPath);
|
|
88
|
-
models.set(modelName, model);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
return models;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async function waitForAdminReady(adminUrl: string, timeoutMs: number): Promise<void> {
|
|
95
|
-
const deadline = Date.now() + timeoutMs;
|
|
96
|
-
while (Date.now() < deadline) {
|
|
97
|
-
try {
|
|
98
|
-
const response = await fetch(new URL("/readyz", `${adminUrl}/`));
|
|
99
|
-
if (response.status === 200) {
|
|
100
|
-
const payload = (await response.json()) as ReadyHealthPayload;
|
|
101
|
-
if (payload.status === "ok") {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
} catch {
|
|
106
|
-
// Admin server can still be binding or the engine may not be running yet.
|
|
107
|
-
}
|
|
108
|
-
await Bun.sleep(25);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
throw new Error(`Smoke runtime did not report ready within ${timeoutMs}ms.`);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async function main(): Promise<void> {
|
|
115
|
-
const args = parseArgs(process.argv.slice(2));
|
|
116
|
-
const template = await loadTemplate(args.template);
|
|
117
|
-
const models = await loadModels(template, args.modelsDir);
|
|
118
|
-
const simulationName = resolveSimulationName(template);
|
|
119
|
-
const tickIntervalMs = template.settings?.tick_interval_ms ?? 100;
|
|
120
|
-
const timeMultiplier = template.settings?.time_multiplier ?? 1;
|
|
121
|
-
const seed = template.settings?.seed ?? 42;
|
|
122
|
-
|
|
123
|
-
const engine = createEngine({
|
|
124
|
-
simulationName,
|
|
125
|
-
seed,
|
|
126
|
-
tickIntervalMs,
|
|
127
|
-
timeMultiplier,
|
|
128
|
-
templateMetadata: {
|
|
129
|
-
name: template.name,
|
|
130
|
-
path: args.template,
|
|
131
|
-
},
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
for (const [, model] of models) {
|
|
135
|
-
engine.runtime.registerModel(model);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
forEachTwin(template, (area, line, twin) => {
|
|
139
|
-
engine.runtime.spawn(twin.model, twin.count, {
|
|
140
|
-
variation: twin.variation,
|
|
141
|
-
unsBasePath: buildUNSBasePath(template, area.name, line.name),
|
|
142
|
-
...(twin.parameters !== undefined ? { parameterOverrides: twin.parameters } : {}),
|
|
143
|
-
...(twin.starting_hours !== undefined ? { startingHours: twin.starting_hours } : {}),
|
|
144
|
-
});
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
const mqttAdapter = new MQTTAdapter(engine.bus);
|
|
148
|
-
await mqttAdapter.start({
|
|
149
|
-
name: "mqtt",
|
|
150
|
-
enabled: true,
|
|
151
|
-
embedded: true,
|
|
152
|
-
host: "127.0.0.1",
|
|
153
|
-
port: 0,
|
|
154
|
-
retain: false,
|
|
155
|
-
simulationName,
|
|
156
|
-
...(args.rbeEnabled ? { rbe: { enabled: true, deadband: args.rbeDeadband } } : {}),
|
|
157
|
-
});
|
|
158
|
-
engine.registerAdapter(mqttAdapter);
|
|
159
|
-
|
|
160
|
-
const opcuaAdapter = new OPCUAAdapter(engine.bus, engine);
|
|
161
|
-
await opcuaAdapter.start({
|
|
162
|
-
name: "opcua",
|
|
163
|
-
enabled: true,
|
|
164
|
-
host: "127.0.0.1",
|
|
165
|
-
port: 0,
|
|
166
|
-
security: "none",
|
|
167
|
-
simulationName,
|
|
168
|
-
});
|
|
169
|
-
engine.registerAdapter(opcuaAdapter);
|
|
170
|
-
|
|
171
|
-
const transport = mqttAdapter.getControlTransport();
|
|
172
|
-
if (!transport) {
|
|
173
|
-
throw new Error("Smoke runtime failed to resolve MQTT control transport.");
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const controlPlane = createControlPlane({
|
|
177
|
-
simulationName,
|
|
178
|
-
engine,
|
|
179
|
-
transport,
|
|
180
|
-
bus: engine.bus,
|
|
181
|
-
});
|
|
182
|
-
controlPlane.start();
|
|
183
|
-
|
|
184
|
-
let lastTickProgressAt = performance.now();
|
|
185
|
-
const onTickProgress = () => {
|
|
186
|
-
lastTickProgressAt = performance.now();
|
|
187
|
-
};
|
|
188
|
-
engine.bus.on("tick:complete", onTickProgress);
|
|
189
|
-
|
|
190
|
-
const adminServer = startAdminServer({
|
|
191
|
-
engine,
|
|
192
|
-
network: { host: "127.0.0.1", port: 0, tickIntervalMs },
|
|
193
|
-
protocols: {
|
|
194
|
-
getLastTickProgressAt: () => lastTickProgressAt,
|
|
195
|
-
},
|
|
196
|
-
ws: {
|
|
197
|
-
bus: engine.bus,
|
|
198
|
-
},
|
|
199
|
-
auth: {
|
|
200
|
-
verifyPassword: async () => true,
|
|
201
|
-
isDefaultPassword: false,
|
|
202
|
-
sessionStore: createSessionStore(),
|
|
203
|
-
changePassword: async () => {},
|
|
204
|
-
},
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
await engine.start();
|
|
208
|
-
await waitForAdminReady(adminServer.endpoint, Math.max(5_000, tickIntervalMs * 20));
|
|
209
|
-
|
|
210
|
-
const [instanceId, instance] = [...engine.runtime.getInstances()][0] ?? [];
|
|
211
|
-
if (!instanceId || !instance) {
|
|
212
|
-
throw new Error("Smoke runtime did not spawn any instances from the template.");
|
|
213
|
-
}
|
|
214
|
-
if (!mqttAdapter.brokerUrl) {
|
|
215
|
-
throw new Error("Smoke runtime did not expose an MQTT broker URL.");
|
|
216
|
-
}
|
|
217
|
-
if (!opcuaAdapter.endpointUrl) {
|
|
218
|
-
throw new Error("Smoke runtime did not expose an OPC UA endpoint URL.");
|
|
219
|
-
}
|
|
220
|
-
if (opcuaAdapter.port <= 0) {
|
|
221
|
-
throw new Error("Smoke runtime did not expose an OPC UA port.");
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
await Bun.write(
|
|
225
|
-
args.readyFile,
|
|
226
|
-
JSON.stringify({
|
|
227
|
-
simulationName,
|
|
228
|
-
adminUrl: adminServer.endpoint,
|
|
229
|
-
mqttBrokerUrl: mqttAdapter.brokerUrl,
|
|
230
|
-
opcuaEndpointUrl: opcuaAdapter.endpointUrl,
|
|
231
|
-
instanceId,
|
|
232
|
-
instancePath: instance.browsePath.join("/"),
|
|
233
|
-
}),
|
|
234
|
-
);
|
|
235
|
-
|
|
236
|
-
let shuttingDown = false;
|
|
237
|
-
const shutdown = async () => {
|
|
238
|
-
if (shuttingDown) {
|
|
239
|
-
return;
|
|
240
|
-
}
|
|
241
|
-
shuttingDown = true;
|
|
242
|
-
adminServer.stop();
|
|
243
|
-
engine.bus.off("tick:complete", onTickProgress);
|
|
244
|
-
controlPlane.stop();
|
|
245
|
-
await engine.stop("smoke runner shutdown");
|
|
246
|
-
process.exit(0);
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
process.once("SIGINT", () => {
|
|
250
|
-
void shutdown();
|
|
251
|
-
});
|
|
252
|
-
process.once("SIGTERM", () => {
|
|
253
|
-
void shutdown();
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
await new Promise(() => {});
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
void main().catch((error) => {
|
|
260
|
-
console.error(error instanceof Error ? (error.stack ?? error.message) : String(error));
|
|
261
|
-
process.exit(1);
|
|
262
|
-
});
|