@uns-kit/cli 2.0.69 → 2.0.71

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 (61) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +168 -168
  3. package/dist/index.js +84 -59
  4. package/package.json +6 -6
  5. package/templates/api/src/examples/api-example.ts +155 -155
  6. package/templates/azure-pipelines.yml +21 -21
  7. package/templates/codegen/codegen.ts +15 -15
  8. package/templates/codegen/src/uns/uns-tags.ts +1 -1
  9. package/templates/codegen/src/uns/uns-topics.ts +1 -1
  10. package/templates/config-files/config-docker.json +32 -32
  11. package/templates/config-files/config-localhost.json +32 -32
  12. package/templates/cron/AGENTS.md +20 -20
  13. package/templates/cron/src/examples/cron-example.ts +71 -71
  14. package/templates/default/.prettierignore +1 -1
  15. package/templates/default/.prettierrc +7 -7
  16. package/templates/default/AGENTS.md +20 -20
  17. package/templates/default/README.md +112 -107
  18. package/templates/default/config.json +35 -35
  19. package/templates/default/eslint.config.js +30 -30
  20. package/templates/default/gitignore +51 -51
  21. package/templates/default/package.json +46 -46
  22. package/templates/default/src/config/project.config.extension.example +23 -23
  23. package/templates/default/src/config/project.config.extension.ts +6 -6
  24. package/templates/default/src/examples/data-example.ts +96 -95
  25. package/templates/default/src/examples/load-test-data.ts +110 -110
  26. package/templates/default/src/examples/schema-system-metadata-example.ts +124 -125
  27. package/templates/default/src/examples/subasset-example.ts +75 -76
  28. package/templates/default/src/examples/table-example.ts +108 -107
  29. package/templates/default/src/examples/table-window-load-test.ts +445 -446
  30. package/templates/default/src/examples/uns-gateway-cli.ts +10 -10
  31. package/templates/default/src/index.ts +66 -41
  32. package/templates/default/src/uns/uns-assets.ts +12 -12
  33. package/templates/default/src/uns/uns-dictionary.generated.ts +758 -758
  34. package/templates/default/src/uns/uns-measurements.generated.ts +366 -366
  35. package/templates/default/src/uns/uns-tags.ts +2 -2
  36. package/templates/default/src/uns/uns-topics.ts +2 -2
  37. package/templates/default/tsconfig.json +29 -29
  38. package/templates/python/app/README.md +8 -8
  39. package/templates/python/examples/README.md +134 -134
  40. package/templates/python/examples/api_handler.py +28 -28
  41. package/templates/python/examples/data_publish.py +11 -11
  42. package/templates/python/examples/data_subscribe.py +8 -8
  43. package/templates/python/examples/data_transformer.py +17 -17
  44. package/templates/python/examples/table_transformer.py +15 -15
  45. package/templates/python/gateway/cli.py +75 -75
  46. package/templates/python/gateway/client.py +155 -155
  47. package/templates/python/gateway/manager.py +97 -97
  48. package/templates/python/gitignore +47 -47
  49. package/templates/python/proto/uns-gateway.proto +105 -105
  50. package/templates/python/pyproject.toml +4 -4
  51. package/templates/python/runtime.json +4 -4
  52. package/templates/python/scripts/setup.sh +87 -87
  53. package/templates/uns-dictionary/uns-dictionary.json +650 -650
  54. package/templates/uns-measurements/uns-measurements.json +360 -360
  55. package/templates/vscode/.vscode/launch.json +164 -164
  56. package/templates/vscode/.vscode/settings.json +9 -9
  57. package/templates/vscode/.vscode/tasks.json +27 -27
  58. package/templates/vscode/uns-kit.code-workspace +13 -13
  59. package/templates/python/gen/__init__.py +0 -1
  60. package/templates/python/gen/uns_gateway_pb2.py +0 -70
  61. package/templates/python/gen/uns_gateway_pb2_grpc.py +0 -312
@@ -1,110 +1,110 @@
1
- /**
2
- * Load the configuration from a file.
3
- * On the server, this file is provided by the `uns-datahub-controller`.
4
- * In the development environment, you are responsible for creating and maintaining this file and its contents.
5
- */
6
- import readline from "readline";
7
- import { ConfigFile, getLogger } from "@uns-kit/core";
8
- import UnsMqttProxy from "@uns-kit/core/uns-mqtt/uns-mqtt-proxy.js";
9
-
10
- const logger = getLogger(import.meta.url);
11
-
12
- /**
13
- * Produces a smooth oscillating value to mimic a real-world sensor signal.
14
- * Combines fast and slow sine waves plus tiny ripple so that subsequent values
15
- * rise and fall without appearing purely random.
16
- */
17
- function simulateSensorValue(step: number): number {
18
- const baseValue = 42; // arbitrary midpoint for the simulated signal
19
- const fastCycle = Math.sin(step / 5) * 3;
20
- const slowCycle = Math.sin(step / 25) * 6;
21
- const ripple = Math.sin(step / 2 + Math.PI / 4) * 0.5;
22
- const value = baseValue + fastCycle + slowCycle + ripple;
23
-
24
- return Number(value.toFixed(2));
25
- }
26
-
27
- /**
28
- * This script initializes an MQTT output proxy for load testing purposes.
29
- * It sets up a connection to the specified MQTT broker and configures
30
- * a proxy instance. The load test is designed to evaluate the performance
31
- * and reliability of the MQTT broker under simulated load conditions.
32
- */
33
- async function main() {
34
- try {
35
- const config = await ConfigFile.loadConfig();
36
- const outputHost = (config.output?.host)!;
37
-
38
- const mqttOutput = new UnsMqttProxy(
39
- outputHost,
40
- "loadTest",
41
- "templateUnsRttLoadTest",
42
- { publishThrottlingDelay: 0 },
43
- true
44
- );
45
-
46
- const rl = readline.createInterface({
47
- input: process.stdin,
48
- output: process.stdout,
49
- });
50
-
51
- await new Promise((resolve) => setTimeout(resolve, 1000));
52
-
53
- rl.question(`Would you like to continue with load-test on ${outputHost}? (Y/n) `, async (answer) => {
54
- if (answer.toLowerCase() === "y" || answer.trim() === "") {
55
- rl.question("How many iterations should be run? (default is 100) ", async (iterations) => {
56
- const maxIntervals = parseInt(iterations) || 100;
57
-
58
- rl.question("What should be the delay between intervals in milliseconds? (default is 0 ms) ", async (intervalDelay) => {
59
- const delay = parseInt(intervalDelay) || 0;
60
-
61
- logger.info(`Starting load test with ${maxIntervals} messages and ${delay} ms delay...`);
62
-
63
- let count = 0;
64
- const startTime = Date.now();
65
-
66
- while (count < maxIntervals) {
67
- try {
68
- const currentDate = new Date();
69
- const sensorValue = simulateSensorValue(count);
70
- const rawData = `${count},${currentDate.getTime()},${sensorValue}`;
71
- await mqttOutput.publishMessage("raw/data", rawData);
72
- } catch (error) {
73
- const reason = error instanceof Error ? error : new Error(String(error));
74
- logger.error("Error publishing message:", reason.message);
75
- }
76
-
77
- count++;
78
- if (delay > 0) {
79
- await new Promise((resolve) => setTimeout(resolve, delay));
80
- }
81
- }
82
-
83
- logger.info(`Sleeping for 50ms.`);
84
- await new Promise((resolve) => setTimeout(resolve, 50));
85
-
86
- const endTime = Date.now();
87
- const duration = (endTime - startTime) / 1000;
88
- const messagesPerSecond = maxIntervals / duration;
89
-
90
- logger.info(`Load test completed in ${duration.toFixed(2)} seconds.`);
91
- logger.info(`Message rate: ${messagesPerSecond.toFixed(2)} msg/s.`);
92
-
93
- rl.close();
94
- process.exit(0);
95
- });
96
- });
97
- } else {
98
- logger.info("Load test aborted.");
99
- rl.close();
100
- process.exit(0);
101
- }
102
- });
103
- } catch (error) {
104
- const reason = error instanceof Error ? error : new Error(String(error));
105
- logger.error("Error initializing load test:", reason.message);
106
- process.exit(1);
107
- }
108
- }
109
-
110
- main();
1
+ /**
2
+ * Load the configuration from a file.
3
+ * On the server, this file is provided by the `uns-datahub-controller`.
4
+ * In the development environment, you are responsible for creating and maintaining this file and its contents.
5
+ */
6
+ import readline from "readline";
7
+ import { ConfigFile, getLogger } from "@uns-kit/core";
8
+ import UnsMqttProxy from "@uns-kit/core/uns-mqtt/uns-mqtt-proxy.js";
9
+
10
+ const logger = getLogger(import.meta.url);
11
+
12
+ /**
13
+ * Produces a smooth oscillating value to mimic a real-world sensor signal.
14
+ * Combines fast and slow sine waves plus tiny ripple so that subsequent values
15
+ * rise and fall without appearing purely random.
16
+ */
17
+ function simulateSensorValue(step: number): number {
18
+ const baseValue = 42; // arbitrary midpoint for the simulated signal
19
+ const fastCycle = Math.sin(step / 5) * 3;
20
+ const slowCycle = Math.sin(step / 25) * 6;
21
+ const ripple = Math.sin(step / 2 + Math.PI / 4) * 0.5;
22
+ const value = baseValue + fastCycle + slowCycle + ripple;
23
+
24
+ return Number(value.toFixed(2));
25
+ }
26
+
27
+ /**
28
+ * This script initializes an MQTT output proxy for load testing purposes.
29
+ * It sets up a connection to the specified MQTT broker and configures
30
+ * a proxy instance. The load test is designed to evaluate the performance
31
+ * and reliability of the MQTT broker under simulated load conditions.
32
+ */
33
+ async function main() {
34
+ try {
35
+ const config = await ConfigFile.loadConfig();
36
+ const outputHost = (config.output?.host)!;
37
+
38
+ const mqttOutput = new UnsMqttProxy(
39
+ outputHost,
40
+ "loadTest",
41
+ "templateUnsRttLoadTest",
42
+ { publishThrottlingDelay: 0 },
43
+ true
44
+ );
45
+
46
+ const rl = readline.createInterface({
47
+ input: process.stdin,
48
+ output: process.stdout,
49
+ });
50
+
51
+ await new Promise((resolve) => setTimeout(resolve, 1000));
52
+
53
+ rl.question(`Would you like to continue with load-test on ${outputHost}? (Y/n) `, async (answer) => {
54
+ if (answer.toLowerCase() === "y" || answer.trim() === "") {
55
+ rl.question("How many iterations should be run? (default is 100) ", async (iterations) => {
56
+ const maxIntervals = parseInt(iterations) || 100;
57
+
58
+ rl.question("What should be the delay between intervals in milliseconds? (default is 0 ms) ", async (intervalDelay) => {
59
+ const delay = parseInt(intervalDelay) || 0;
60
+
61
+ logger.info(`Starting load test with ${maxIntervals} messages and ${delay} ms delay...`);
62
+
63
+ let count = 0;
64
+ const startTime = Date.now();
65
+
66
+ while (count < maxIntervals) {
67
+ try {
68
+ const currentDate = new Date();
69
+ const sensorValue = simulateSensorValue(count);
70
+ const rawData = `${count},${currentDate.getTime()},${sensorValue}`;
71
+ await mqttOutput.publishMessage("raw/data", rawData);
72
+ } catch (error) {
73
+ const reason = error instanceof Error ? error : new Error(String(error));
74
+ logger.error("Error publishing message:", reason.message);
75
+ }
76
+
77
+ count++;
78
+ if (delay > 0) {
79
+ await new Promise((resolve) => setTimeout(resolve, delay));
80
+ }
81
+ }
82
+
83
+ await mqttOutput.flush();
84
+ await mqttOutput.stop();
85
+
86
+ const endTime = Date.now();
87
+ const duration = (endTime - startTime) / 1000;
88
+ const messagesPerSecond = maxIntervals / duration;
89
+
90
+ logger.info(`Load test completed in ${duration.toFixed(2)} seconds.`);
91
+ logger.info(`Message rate: ${messagesPerSecond.toFixed(2)} msg/s.`);
92
+
93
+ rl.close();
94
+ process.exit(0);
95
+ });
96
+ });
97
+ } else {
98
+ logger.info("Load test aborted.");
99
+ rl.close();
100
+ process.exit(0);
101
+ }
102
+ });
103
+ } catch (error) {
104
+ const reason = error instanceof Error ? error : new Error(String(error));
105
+ logger.error("Error initializing load test:", reason.message);
106
+ process.exit(1);
107
+ }
108
+ }
109
+
110
+ main();
@@ -1,125 +1,124 @@
1
- /**
2
- * Example: publish schema-system metadata for object relationships and lifecycle timing.
3
- *
4
- * This is producer metadata. The controller stores these fields in
5
- * attribute_schema.schema_json and can later materialize relationship evidence
6
- * into object_id_relationship edges.
7
- */
8
- import { ConfigFile, UnsProxyProcess, getLogger } from "@uns-kit/core";
9
- import { registerAttributeDescriptions, registerObjectTypeDescriptions } from "@uns-kit/core/uns/uns-dictionary-registry.js";
10
- import type { ISO8601 } from "@uns-kit/core/uns/uns-interfaces.js";
11
- import { UnsTopics } from "@uns-kit/core/uns/uns-topics.js";
12
- import {
13
- GeneratedAttributeDescriptions,
14
- GeneratedObjectTypeDescriptions,
15
- GeneratedObjectTypes,
16
- } from "../uns/uns-dictionary.generated.js";
17
- import { resolveGeneratedAsset } from "../uns/uns-assets.js";
18
-
19
- const logger = getLogger(import.meta.url);
20
-
21
- const config = await ConfigFile.loadConfig();
22
- registerObjectTypeDescriptions(GeneratedObjectTypeDescriptions);
23
- registerAttributeDescriptions(GeneratedAttributeDescriptions);
24
-
25
- const unsProxyProcess = new UnsProxyProcess(config.infra.host!, {
26
- processName: config.uns.processName!,
27
- });
28
-
29
- const mqttOutput = await unsProxyProcess.createUnsMqttProxy(
30
- config.output?.host!,
31
- "templateSchemaMetadataOutput",
32
- config.uns.instanceMode!,
33
- config.uns.handover!,
34
- { publishThrottlingDelay: 1000 },
35
- );
36
-
37
- const now = new Date();
38
- const time = now.toISOString() as ISO8601;
39
- const topic: UnsTopics = "enterprise/site/area/line/";
40
- const asset = resolveGeneratedAsset("asset");
41
- const materialObjectType = GeneratedObjectTypes["material"];
42
- const currentMaterialId = "1124";
43
- const previousMaterialId = "112";
44
- const mergedParentMaterialIds = ["1122", "1123"];
45
-
46
- try {
47
- await mqttOutput.publishMqttMessage({
48
- topic,
49
- asset,
50
- assetDescription: "Example production line",
51
- objectType: materialObjectType,
52
- objectId: currentMaterialId,
53
- attributes: [
54
- {
55
- attribute: "previous-material",
56
- description: "Previous material ObjectId before this process stage.",
57
- valueType: "string",
58
- systemRole: "relationship-evidence",
59
- relationshipEvidence: {
60
- relationshipKey: "material-renumbering",
61
- ownerEndpoint: "target",
62
- valueEndpoint: "source",
63
- sourceObjectType: materialObjectType,
64
- targetObjectType: materialObjectType,
65
- sourceObjectIdFrom: "value",
66
- targetObjectIdFrom: "ownerObjectId",
67
- observedAtFrom: "packetTimestamp",
68
- defaultStatus: "suggested",
69
- },
70
- data: {
71
- dataGroup: "material-lineage",
72
- time,
73
- value: previousMaterialId,
74
- },
75
- },
76
- {
77
- attribute: "previous-materials",
78
- description: "Previous material ObjectIds that were joined into this material.",
79
- valueType: "array<string>",
80
- systemRole: "relationship-evidence",
81
- relationshipEvidence: {
82
- relationshipKey: "material-merge",
83
- ownerEndpoint: "target",
84
- valueEndpoint: "source",
85
- sourceObjectType: materialObjectType,
86
- targetObjectType: materialObjectType,
87
- sourceObjectIdFrom: "value[]",
88
- targetObjectIdFrom: "ownerObjectId",
89
- observedAtFrom: "packetTimestamp",
90
- defaultStatus: "suggested",
91
- },
92
- data: {
93
- dataGroup: "material-lineage",
94
- time,
95
- currentMaterialObjectId: currentMaterialId,
96
- operationId: "weld-1122-1123",
97
- value: mergedParentMaterialIds,
98
- },
99
- },
100
- {
101
- attribute: "process-state",
102
- description: "Material lifecycle state in this process stage.",
103
- valueType: "string",
104
- systemRole: "lifecycle-time-source",
105
- lifecycle: {
106
- timestampFrom: "packetTimestamp",
107
- startValues: ["entered", "processing"],
108
- endValues: ["done", "exited"],
109
- },
110
- validityMode: "lifecycle",
111
- lifecycleEndValue: "done",
112
- data: {
113
- dataGroup: "material-lifecycle",
114
- time,
115
- value: "processing",
116
- },
117
- },
118
- ],
119
- });
120
-
121
- logger.info(`Published schema-system metadata example for material ${currentMaterialId}.`);
122
- } finally {
123
- await mqttOutput.stop();
124
- unsProxyProcess.shutdown();
125
- }
1
+ /**
2
+ * Example: publish schema-system metadata for object relationships and lifecycle timing.
3
+ *
4
+ * This is producer metadata. The controller stores these fields in
5
+ * attribute_schema.schema_json and can later materialize relationship evidence
6
+ * into object_id_relationship edges.
7
+ */
8
+ import { ConfigFile, UnsProxyProcess, getLogger } from "@uns-kit/core";
9
+ import { registerAttributeDescriptions, registerObjectTypeDescriptions } from "@uns-kit/core/uns/uns-dictionary-registry.js";
10
+ import type { ISO8601 } from "@uns-kit/core/uns/uns-interfaces.js";
11
+ import { UnsTopics } from "@uns-kit/core/uns/uns-topics.js";
12
+ import {
13
+ GeneratedAttributeDescriptions,
14
+ GeneratedObjectTypeDescriptions,
15
+ GeneratedObjectTypes,
16
+ } from "../uns/uns-dictionary.generated.js";
17
+ import { resolveGeneratedAsset } from "../uns/uns-assets.js";
18
+
19
+ const logger = getLogger(import.meta.url);
20
+
21
+ const config = await ConfigFile.loadConfig();
22
+ registerObjectTypeDescriptions(GeneratedObjectTypeDescriptions);
23
+ registerAttributeDescriptions(GeneratedAttributeDescriptions);
24
+
25
+ const unsProxyProcess = new UnsProxyProcess(config.infra.host!, {
26
+ processName: config.uns.processName!,
27
+ });
28
+
29
+ const mqttOutput = await unsProxyProcess.createUnsMqttProxy(
30
+ config.output?.host!,
31
+ "templateSchemaMetadataOutput",
32
+ config.uns.instanceMode!,
33
+ config.uns.handover!,
34
+ { publishThrottlingDelay: 1000 },
35
+ );
36
+
37
+ const now = new Date();
38
+ const time = now.toISOString() as ISO8601;
39
+ const topic: UnsTopics = "enterprise/site/area/line/";
40
+ const asset = resolveGeneratedAsset("asset");
41
+ const materialObjectType = GeneratedObjectTypes["material"];
42
+ const currentMaterialId = "1124";
43
+ const previousMaterialId = "112";
44
+ const mergedParentMaterialIds = ["1122", "1123"];
45
+
46
+ try {
47
+ await mqttOutput.publishMqttMessage({
48
+ topic,
49
+ asset,
50
+ assetDescription: "Example production line",
51
+ objectType: materialObjectType,
52
+ objectId: currentMaterialId,
53
+ attributes: [
54
+ {
55
+ attribute: "previous-material",
56
+ description: "Previous material ObjectId before this process stage.",
57
+ valueType: "string",
58
+ systemRole: "relationship-evidence",
59
+ relationshipEvidence: {
60
+ relationshipKey: "material-renumbering",
61
+ ownerEndpoint: "target",
62
+ valueEndpoint: "source",
63
+ sourceObjectType: materialObjectType,
64
+ targetObjectType: materialObjectType,
65
+ sourceObjectIdFrom: "value",
66
+ targetObjectIdFrom: "ownerObjectId",
67
+ observedAtFrom: "packetTimestamp",
68
+ defaultStatus: "suggested",
69
+ },
70
+ data: {
71
+ dataGroup: "material-lineage",
72
+ time,
73
+ value: previousMaterialId,
74
+ },
75
+ },
76
+ {
77
+ attribute: "previous-materials",
78
+ description: "Previous material ObjectIds that were joined into this material.",
79
+ valueType: "array<string>",
80
+ systemRole: "relationship-evidence",
81
+ relationshipEvidence: {
82
+ relationshipKey: "material-merge",
83
+ ownerEndpoint: "target",
84
+ valueEndpoint: "source",
85
+ sourceObjectType: materialObjectType,
86
+ targetObjectType: materialObjectType,
87
+ sourceObjectIdFrom: "value[]",
88
+ targetObjectIdFrom: "ownerObjectId",
89
+ observedAtFrom: "packetTimestamp",
90
+ defaultStatus: "suggested",
91
+ },
92
+ data: {
93
+ dataGroup: "material-lineage",
94
+ time,
95
+ currentMaterialObjectId: currentMaterialId,
96
+ operationId: "weld-1122-1123",
97
+ value: mergedParentMaterialIds,
98
+ },
99
+ },
100
+ {
101
+ attribute: "process-state",
102
+ description: "Material lifecycle state in this process stage.",
103
+ valueType: "string",
104
+ systemRole: "lifecycle-time-source",
105
+ lifecycle: {
106
+ timestampFrom: "packetTimestamp",
107
+ startValues: ["entered", "processing"],
108
+ endValues: ["done", "exited"],
109
+ },
110
+ validityMode: "lifecycle",
111
+ lifecycleEndValue: "done",
112
+ data: {
113
+ dataGroup: "material-lifecycle",
114
+ time,
115
+ value: "processing",
116
+ },
117
+ },
118
+ ],
119
+ });
120
+
121
+ logger.info(`Published schema-system metadata example for material ${currentMaterialId}.`);
122
+ } finally {
123
+ await unsProxyProcess.shutdown();
124
+ }
@@ -1,76 +1,75 @@
1
- /**
2
- * Example: publish a sub-asset under an existing parent asset.
3
- *
4
- * V1 sub-assets use the normal UNS publish fields:
5
- * - topic is the full parent asset path
6
- * - asset is only the leaf sub-asset name
7
- */
8
- import { ConfigFile, UnsProxyProcess, getLogger } from "@uns-kit/core";
9
- import { registerAttributeDescriptions, registerObjectTypeDescriptions } from "@uns-kit/core/uns/uns-dictionary-registry.js";
10
- import type { ISO8601 } from "@uns-kit/core/uns/uns-interfaces.js";
11
- import { UnsTopics } from "@uns-kit/core/uns/uns-topics.js";
12
- import { GeneratedPhysicalMeasurements } from "../uns/uns-measurements.generated.js";
13
- import {
14
- GeneratedAttributeDescriptions,
15
- GeneratedAttributesByType,
16
- GeneratedObjectTypeDescriptions,
17
- GeneratedObjectTypes,
18
- } from "../uns/uns-dictionary.generated.js";
19
- import { resolveGeneratedAsset } from "../uns/uns-assets.js";
20
-
21
- const logger = getLogger(import.meta.url);
22
-
23
- const config = await ConfigFile.loadConfig();
24
- registerObjectTypeDescriptions(GeneratedObjectTypeDescriptions);
25
- registerAttributeDescriptions(GeneratedAttributeDescriptions);
26
-
27
- const unsProxyProcess = new UnsProxyProcess(config.infra.host!, {
28
- processName: config.uns.processName!,
29
- });
30
-
31
- const mqttOutput = await unsProxyProcess.createUnsMqttProxy(
32
- config.output?.host!,
33
- "templateSubassetExampleOutput",
34
- config.uns.instanceMode!,
35
- config.uns.handover!,
36
- { publishThrottlingDelay: 1000 },
37
- );
38
-
39
- try {
40
- const parentAssetTopic: UnsTopics = "enterprise/site/area/line-1/";
41
- const subAsset = resolveGeneratedAsset("pump-1");
42
- const now = new Date();
43
- const time = now.toISOString() as ISO8601;
44
- const intervalStart = new Date(now.getTime() - 1000).toISOString() as ISO8601;
45
- const intervalEnd = time;
46
-
47
- await mqttOutput.publishMqttMessage({
48
- topic: parentAssetTopic,
49
- asset: subAsset,
50
- assetDescription: "Example pump owned by a separate microservice",
51
- objectType: GeneratedObjectTypes["equipment"],
52
- objectId: "main",
53
- attributes: {
54
- attribute: GeneratedAttributesByType["equipment"]["temperature"],
55
- description: "Example sub-asset temperature",
56
- valueType: "number",
57
- presentationKind: "chart",
58
- defaultAggregation: "last",
59
- data: {
60
- time,
61
- value: 42,
62
- uom: GeneratedPhysicalMeasurements.Celsius,
63
- intervalStart,
64
- intervalEnd,
65
- },
66
- },
67
- });
68
-
69
- logger.info(
70
- "Published sub-asset example to " +
71
- `${parentAssetTopic}${subAsset}/equipment/main/temperature`,
72
- );
73
- } finally {
74
- await mqttOutput.stop();
75
- unsProxyProcess.shutdown();
76
- }
1
+ /**
2
+ * Example: publish a sub-asset under an existing parent asset.
3
+ *
4
+ * V1 sub-assets use the normal UNS publish fields:
5
+ * - topic is the full parent asset path
6
+ * - asset is only the leaf sub-asset name
7
+ */
8
+ import { ConfigFile, UnsProxyProcess, getLogger } from "@uns-kit/core";
9
+ import { registerAttributeDescriptions, registerObjectTypeDescriptions } from "@uns-kit/core/uns/uns-dictionary-registry.js";
10
+ import type { ISO8601 } from "@uns-kit/core/uns/uns-interfaces.js";
11
+ import { UnsTopics } from "@uns-kit/core/uns/uns-topics.js";
12
+ import { GeneratedPhysicalMeasurements } from "../uns/uns-measurements.generated.js";
13
+ import {
14
+ GeneratedAttributeDescriptions,
15
+ GeneratedAttributesByType,
16
+ GeneratedObjectTypeDescriptions,
17
+ GeneratedObjectTypes,
18
+ } from "../uns/uns-dictionary.generated.js";
19
+ import { resolveGeneratedAsset } from "../uns/uns-assets.js";
20
+
21
+ const logger = getLogger(import.meta.url);
22
+
23
+ const config = await ConfigFile.loadConfig();
24
+ registerObjectTypeDescriptions(GeneratedObjectTypeDescriptions);
25
+ registerAttributeDescriptions(GeneratedAttributeDescriptions);
26
+
27
+ const unsProxyProcess = new UnsProxyProcess(config.infra.host!, {
28
+ processName: config.uns.processName!,
29
+ });
30
+
31
+ const mqttOutput = await unsProxyProcess.createUnsMqttProxy(
32
+ config.output?.host!,
33
+ "templateSubassetExampleOutput",
34
+ config.uns.instanceMode!,
35
+ config.uns.handover!,
36
+ { publishThrottlingDelay: 1000 },
37
+ );
38
+
39
+ try {
40
+ const parentAssetTopic: UnsTopics = "enterprise/site/area/line-1/";
41
+ const subAsset = resolveGeneratedAsset("pump-1");
42
+ const now = new Date();
43
+ const time = now.toISOString() as ISO8601;
44
+ const intervalStart = new Date(now.getTime() - 1000).toISOString() as ISO8601;
45
+ const intervalEnd = time;
46
+
47
+ await mqttOutput.publishMqttMessage({
48
+ topic: parentAssetTopic,
49
+ asset: subAsset,
50
+ assetDescription: "Example pump owned by a separate microservice",
51
+ objectType: GeneratedObjectTypes["equipment"],
52
+ objectId: "main",
53
+ attributes: {
54
+ attribute: GeneratedAttributesByType["equipment"]["temperature"],
55
+ description: "Example sub-asset temperature",
56
+ valueType: "number",
57
+ presentationKind: "chart",
58
+ defaultAggregation: "last",
59
+ data: {
60
+ time,
61
+ value: 42,
62
+ uom: GeneratedPhysicalMeasurements.Celsius,
63
+ intervalStart,
64
+ intervalEnd,
65
+ },
66
+ },
67
+ });
68
+
69
+ logger.info(
70
+ "Published sub-asset example to " +
71
+ `${parentAssetTopic}${subAsset}/equipment/main/temperature`,
72
+ );
73
+ } finally {
74
+ await unsProxyProcess.shutdown();
75
+ }