@uns-kit/core 1.0.2 → 1.0.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"uns-interfaces.js","sourceRoot":"","sources":["../../src/uns/uns-interfaces.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,YAAY,GAAG,+CAA+C,CAAC;IACrE,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAGD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC","sourcesContent":["import { UnsAttributeType } from \"../graphql/schema.js\";\nimport { MeasurementUnit } from \"./uns-measurements.js\";\nimport { UnsTags } from \"./uns-tags.js\";\nimport type { UnsObjectId, UnsObjectType } from \"./uns-object.js\";\nimport { UnsTopics } from \"./uns-topics.js\";\nimport { knownUnsAttributes, KnownAttributesByObjectType } from \"./uns-attributes.js\";\n\nexport type ISO8601 = `${number}-${string}-${string}T${string}:${string}:${string}.${string}Z`;\nexport function isIOS8601Type(value: string): value is ISO8601 {\n const iso8601Regex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\n return iso8601Regex.test(value);\n}\nexport type UnsAttribute = typeof knownUnsAttributes[number] | (string & {});\n\nexport const valueTypes = [\"string\", \"number\"];\nexport type ValueTypeString = typeof valueTypes[number];\nexport type ValueType = string | number;\n\nexport interface IUnsParameters {\n mqttSubToTopics?: string | string[];\n username?: string;\n password?: string;\n mqttSSL?: boolean;\n publishThrottlingDelay?: number; // Delay in milliseconds; default is 1ms\n subscribeThrottlingDelay?: number; // Delay in milliseconds; default is 1ms\n}\n\nexport interface IUnsProcessParameters {\n processName?: string | undefined;\n mqttSubToTopics?: string | string[];\n username?: string;\n password?: string;\n mqttSSL?: boolean;\n}\n\nexport interface UnsEvents {\n // Emitters in MqttProxy, UnsMqttProxy\n input: { topic: string; message: string, packet: any };\n mqttProxyStatus: { event: string, value: number, uom: MeasurementUnit, statusTopic: string };\n \n // Emitters in MqttProxy\n error: { code: number; message: string };\n \n // Emitters in UnsMqttProxy\n mqttWorker: { command: string, instanceName: string; batchSize: number, referenceHash: string };\n\n // Emitter in UnsCronProxy\n cronEvent: {};\n\n // Emitters in UnsApiProxy\n apiGetEvent: {req: any, res: any};\n\n // Emitters in UnsProxy\n unsProxyProducedTopics: { producedTopics: ITopicObject[], statusTopic: string };\n\n // Emitters in UnsProxy\n unsProxyProducedApiEndpoints: { producedApiEndpoints: IApiObject[], statusTopic: string };\n}\n\nexport interface IUnsExtendedData extends IUnsData {\n valueType: ValueTypeString;\n}\n\nexport interface IUnsData {\n time: ISO8601;\n value: ValueType;\n dataGroup?: string;\n uom?: MeasurementUnit;\n foreignEventKey?: string;\n}\n\nexport interface IUnsEvent {\n time: ISO8601;\n dataGroup?: string;\n details?: string;\n uniqueEventId?: string;\n}\n\nexport interface IUnsTable {\n time: ISO8601;\n values: Record<string, string | number | undefined | null>\n dataGroup?: string;\n}\n\nexport interface IUnsCommand {\n time: ISO8601;\n details?: string;\n}\n\nexport interface IMqttMessage {\n topic: UnsTopics;\n attribute: UnsAttribute;\n objectType?: UnsObjectType;\n objectId?: UnsObjectId;\n description?: string;\n tags?: UnsTags[];\n packet: IUnsPacket;\n attributeNeedsPersistence?: boolean | null;\n}\n\n// This interface represents a packet for a UNS system\nexport interface IUnsPacket {\n // The message object of the packet\n message: IUnsExtendedMessage;\n \n // The HMAC signature of the message\n messageSignature?: string;\n\n // Automatically calculated interval between two packets in ms\n interval?: number;\n\n // Current library version\n readonly version: string;\n\n // Autogenerated sequence number\n sequenceId?: number;\n}\n\nexport interface IUnsPackatParameters {\n\n}\n\nexport interface IUnsMessage {\n command?: IUnsCommand;\n data?: IUnsData;\n event?: IUnsEvent;\n table?: IUnsTable;\n expiresAt?: ISO8601;\n createdAt?: ISO8601;\n}\n\nexport interface IUnsExtendedMessage extends IUnsMessage {\n data?: IUnsExtendedData;\n}\n\nexport interface ITopicObject {\n timestamp: string;\n attribute:string;\n attributeType: UnsAttributeType;\n topic:string;\n description:string;\n dataGroup:string;\n tags:string[] | null;\n attributeNeedsPersistence: boolean | null;\n objectType?: UnsObjectType;\n objectId?: UnsObjectId;\n}\n\n// API Interfaces below\nexport interface IApiObject {\n timestamp: string;\n attribute:string;\n topic:string;\n attributeType: UnsAttributeType;\n apiDescription?: string; // Optional description for the API endpoint\n apiHost: string; // Hostname of the service\n apiEndpoint: string; // API endpoint for virtual topics\n apiSwaggerEndpoint: string; // Swagger endpoint for API documentation\n apiMethod: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\"; // HTTP method for API endpoint\n apiQueryParams: QueryParamDef[]; // query parameters for the API endpoint\n}\n\nexport interface QueryParamDef {\n name: string;\n type: \"string\" | \"number\" | \"boolean\";\n required?: boolean;\n description?: string;\n}\n\nexport interface IApiProxyOptions {\n jwtSecret?: string;\n jwks?: {\n wellKnownJwksUrl: string;\n activeKidUrl?: string;\n cacheTtlMs?: number;\n algorithms?: (\"RS256\" | \"RS384\" | \"RS512\")[];\n };\n}\n\nexport interface IGetEndpointOptions {\n apiDescription?: string;\n tags?: string[];\n queryParams?: QueryParamDef[];\n}\n"]}
1
+ {"version":3,"file":"uns-interfaces.js","sourceRoot":"","sources":["../../src/uns/uns-interfaces.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,MAAM,YAAY,GAAG,+CAA+C,CAAC;IACrE,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAID,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC","sourcesContent":["import { UnsAttributeType } from \"../graphql/schema.js\";\nimport { MeasurementUnit } from \"./uns-measurements.js\";\nimport { UnsTags } from \"./uns-tags.js\";\nimport type { UnsObjectId, UnsObjectType } from \"./uns-object.js\";\nimport type { UnsAsset } from \"./uns-asset.js\";\nimport { UnsTopics } from \"./uns-topics.js\";\nimport { knownUnsAttributes, type KnownUnsAttributeName } from \"./uns-attributes.js\";\n\nexport type ISO8601 = `${number}-${string}-${string}T${string}:${string}:${string}.${string}Z`;\nexport function isIOS8601Type(value: string): value is ISO8601 {\n const iso8601Regex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\n return iso8601Regex.test(value);\n}\n// Known attribute names (with IntelliSense) while still allowing arbitrary strings.\nexport type UnsAttribute = KnownUnsAttributeName | (string & {});\n\nexport const valueTypes = [\"string\", \"number\"];\nexport type ValueTypeString = typeof valueTypes[number];\nexport type ValueType = string | number;\n\nexport interface IUnsParameters {\n mqttSubToTopics?: string | string[];\n username?: string;\n password?: string;\n mqttSSL?: boolean;\n publishThrottlingDelay?: number; // Delay in milliseconds; default is 1ms\n subscribeThrottlingDelay?: number; // Delay in milliseconds; default is 1ms\n}\n\nexport interface IUnsProcessParameters {\n processName?: string | undefined;\n mqttSubToTopics?: string | string[];\n username?: string;\n password?: string;\n mqttSSL?: boolean;\n}\n\nexport interface UnsEvents {\n // Emitters in MqttProxy, UnsMqttProxy\n input: { topic: string; message: string, packet: any };\n mqttProxyStatus: { event: string, value: number, uom: MeasurementUnit, statusTopic: string };\n \n // Emitters in MqttProxy\n error: { code: number; message: string };\n \n // Emitters in UnsMqttProxy\n mqttWorker: { command: string, instanceName: string; batchSize: number, referenceHash: string };\n\n // Emitter in UnsCronProxy\n cronEvent: {};\n\n // Emitters in UnsApiProxy\n apiGetEvent: {req: any, res: any};\n\n // Emitters in UnsProxy\n unsProxyProducedTopics: { producedTopics: ITopicObject[], statusTopic: string };\n\n // Emitters in UnsProxy\n unsProxyProducedApiEndpoints: { producedApiEndpoints: IApiObject[], statusTopic: string };\n}\n\nexport interface IUnsExtendedData extends IUnsData {\n valueType: ValueTypeString;\n}\n\nexport interface IUnsData {\n time: ISO8601;\n value: ValueType;\n dataGroup?: string;\n uom?: MeasurementUnit;\n foreignEventKey?: string;\n}\n\nexport interface IUnsEvent {\n time: ISO8601;\n dataGroup?: string;\n details?: string;\n uniqueEventId?: string;\n}\n\nexport interface IUnsTable {\n time: ISO8601;\n values: Record<string, string | number | undefined | null>\n dataGroup?: string;\n}\n\nexport interface IUnsCommand {\n time: ISO8601;\n details?: string;\n}\n\nexport interface IMqttMessage {\n topic: UnsTopics;\n attribute: UnsAttribute;\n asset?: UnsAsset;\n objectType?: UnsObjectType;\n objectId?: UnsObjectId;\n description?: string;\n tags?: UnsTags[];\n packet: IUnsPacket;\n attributeNeedsPersistence?: boolean | null;\n}\n\n// This interface represents a packet for a UNS system\nexport interface IUnsPacket {\n // The message object of the packet\n message: IUnsExtendedMessage;\n \n // The HMAC signature of the message\n messageSignature?: string;\n\n // Automatically calculated interval between two packets in ms\n interval?: number;\n\n // Current library version\n readonly version: string;\n\n // Autogenerated sequence number\n sequenceId?: number;\n}\n\nexport interface IUnsPackatParameters {\n\n}\n\nexport interface IUnsMessage {\n command?: IUnsCommand;\n data?: IUnsData;\n event?: IUnsEvent;\n table?: IUnsTable;\n expiresAt?: ISO8601;\n createdAt?: ISO8601;\n}\n\nexport interface IUnsExtendedMessage extends IUnsMessage {\n data?: IUnsExtendedData;\n}\n\nexport interface ITopicObject {\n timestamp: string;\n attribute:string;\n attributeType: UnsAttributeType;\n topic:string;\n description:string;\n dataGroup:string;\n tags:string[] | null;\n attributeNeedsPersistence: boolean | null;\n asset?: UnsAsset;\n objectType?: UnsObjectType;\n objectId?: UnsObjectId;\n}\n\n// API Interfaces below\nexport interface IApiObject {\n timestamp: string;\n attribute:string;\n topic:string;\n attributeType: UnsAttributeType;\n apiDescription?: string; // Optional description for the API endpoint\n apiHost: string; // Hostname of the service\n apiEndpoint: string; // API endpoint for virtual topics\n apiSwaggerEndpoint: string; // Swagger endpoint for API documentation\n apiMethod: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\"; // HTTP method for API endpoint\n apiQueryParams: QueryParamDef[]; // query parameters for the API endpoint\n}\n\nexport interface QueryParamDef {\n name: string;\n type: \"string\" | \"number\" | \"boolean\";\n required?: boolean;\n description?: string;\n}\n\nexport interface IApiProxyOptions {\n jwtSecret?: string;\n jwks?: {\n wellKnownJwksUrl: string;\n activeKidUrl?: string;\n cacheTtlMs?: number;\n algorithms?: (\"RS256\" | \"RS384\" | \"RS512\")[];\n };\n}\n\nexport interface IGetEndpointOptions {\n apiDescription?: string;\n tags?: string[];\n queryParams?: QueryParamDef[];\n}\n"]}
@@ -1,4 +1,43 @@
1
1
  export declare const knownUnsObjectTypes: readonly ["equipment", "material", "personnel", "process-segment", "product-definition", "product-quality", "work-definition", "resource-status", "energy-resource", "utility-resource", "fluid-resource", "consumable-resource", "line", "area", "site", "enterprise", "asset", "sensor"];
2
- export type UnsObjectType = "" | typeof knownUnsObjectTypes[number] | (string & {});
2
+ export declare const ObjectTypes: {
3
+ /** Physical equipment (machines, furnaces, sensors) */
4
+ readonly Equipment: "equipment";
5
+ /** Material lots/batches/raw materials */
6
+ readonly Material: "material";
7
+ /** Operators/supervisors/technologists */
8
+ readonly Personnel: "personnel";
9
+ /** Process step or activity (e.g., rolling, cooling) */
10
+ readonly ProcessSegment: "process-segment";
11
+ /** Product specs/recipes/definitions */
12
+ readonly ProductDefinition: "product-definition";
13
+ /** Quality indicators/results for a product */
14
+ readonly ProductQuality: "product-quality";
15
+ /** Work/task definitions or workflows */
16
+ readonly WorkDefinition: "work-definition";
17
+ /** Status of any resource (material/personnel/equipment) */
18
+ readonly ResourceStatus: "resource-status";
19
+ /** Energy carriers (electricity/steam/gas) */
20
+ readonly EnergyResource: "energy-resource";
21
+ /** Utilities (water/air/nitrogen/etc.) */
22
+ readonly UtilityResource: "utility-resource";
23
+ /** Fluids/gases (non-energy) used in process */
24
+ readonly FluidResource: "fluid-resource";
25
+ /** Consumables (lubricants/cleaners) */
26
+ readonly ConsumableResource: "consumable-resource";
27
+ /** Production line/work unit */
28
+ readonly Line: "line";
29
+ /** Area/department within a site */
30
+ readonly Area: "area";
31
+ /** Plant/site identifier */
32
+ readonly Site: "site";
33
+ /** Enterprise/company identifier */
34
+ readonly Enterprise: "enterprise";
35
+ /** Generic asset placeholder */
36
+ readonly Asset: "asset";
37
+ /** Sensor as a distinct object */
38
+ readonly Sensor: "sensor";
39
+ };
40
+ export type KnownUnsObjectTypeName = typeof knownUnsObjectTypes[number];
41
+ export type UnsObjectType = "" | KnownUnsObjectTypeName | (string & {});
3
42
  export type UnsObjectId = "main" | "" | (string & {});
4
43
  //# sourceMappingURL=uns-object.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uns-object.d.ts","sourceRoot":"","sources":["../../src/uns/uns-object.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mBAAmB,4RAqBtB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,EAAE,GAAG,OAAO,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAGpF,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"uns-object.d.ts","sourceRoot":"","sources":["../../src/uns/uns-object.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,mBAAmB,4RAoBtB,CAAC;AAGX,eAAO,MAAM,WAAW;IACtB,uDAAuD;;IAEvD,0CAA0C;;IAE1C,0CAA0C;;IAE1C,wDAAwD;;IAExD,wCAAwC;;IAExC,+CAA+C;;IAE/C,yCAAyC;;IAEzC,4DAA4D;;IAE5D,8CAA8C;;IAE9C,0CAA0C;;IAE1C,gDAAgD;;IAEhD,wCAAwC;;IAExC,gCAAgC;;IAEhC,oCAAoC;;IAEpC,4BAA4B;;IAE5B,oCAAoC;;IAEpC,gCAAgC;;IAEhC,kCAAkC;;CAE1B,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAAG,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAExE,MAAM,MAAM,aAAa,GAAG,EAAE,GAAG,sBAAsB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAGxE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC"}
@@ -1,7 +1,5 @@
1
- // Extend this list to add curated IntelliSense hints for object types.
2
- // Based on ISA-95-aligned categories plus commonly used UNS structural nodes.
1
+ // ISA-95-aligned object types (add your own as needed).
3
2
  export const knownUnsObjectTypes = [
4
- // ISA-95-aligned types
5
3
  "equipment",
6
4
  "material",
7
5
  "personnel",
@@ -14,7 +12,7 @@ export const knownUnsObjectTypes = [
14
12
  "utility-resource",
15
13
  "fluid-resource",
16
14
  "consumable-resource",
17
- // Common structural or legacy types used in templates/examples
15
+ // Common structural/legacy types used in templates/examples
18
16
  "line",
19
17
  "area",
20
18
  "site",
@@ -22,4 +20,43 @@ export const knownUnsObjectTypes = [
22
20
  "asset",
23
21
  "sensor",
24
22
  ];
23
+ // Convenient constants for IntelliSense and to avoid string literals.
24
+ export const ObjectTypes = {
25
+ /** Physical equipment (machines, furnaces, sensors) */
26
+ Equipment: "equipment",
27
+ /** Material lots/batches/raw materials */
28
+ Material: "material",
29
+ /** Operators/supervisors/technologists */
30
+ Personnel: "personnel",
31
+ /** Process step or activity (e.g., rolling, cooling) */
32
+ ProcessSegment: "process-segment",
33
+ /** Product specs/recipes/definitions */
34
+ ProductDefinition: "product-definition",
35
+ /** Quality indicators/results for a product */
36
+ ProductQuality: "product-quality",
37
+ /** Work/task definitions or workflows */
38
+ WorkDefinition: "work-definition",
39
+ /** Status of any resource (material/personnel/equipment) */
40
+ ResourceStatus: "resource-status",
41
+ /** Energy carriers (electricity/steam/gas) */
42
+ EnergyResource: "energy-resource",
43
+ /** Utilities (water/air/nitrogen/etc.) */
44
+ UtilityResource: "utility-resource",
45
+ /** Fluids/gases (non-energy) used in process */
46
+ FluidResource: "fluid-resource",
47
+ /** Consumables (lubricants/cleaners) */
48
+ ConsumableResource: "consumable-resource",
49
+ /** Production line/work unit */
50
+ Line: "line",
51
+ /** Area/department within a site */
52
+ Area: "area",
53
+ /** Plant/site identifier */
54
+ Site: "site",
55
+ /** Enterprise/company identifier */
56
+ Enterprise: "enterprise",
57
+ /** Generic asset placeholder */
58
+ Asset: "asset",
59
+ /** Sensor as a distinct object */
60
+ Sensor: "sensor",
61
+ };
25
62
  //# sourceMappingURL=uns-object.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"uns-object.js","sourceRoot":"","sources":["../../src/uns/uns-object.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,8EAA8E;AAC9E,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,uBAAuB;IACvB,WAAW;IACX,UAAU;IACV,WAAW;IACX,iBAAiB;IACjB,oBAAoB;IACpB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,kBAAkB;IAClB,gBAAgB;IAChB,qBAAqB;IACrB,+DAA+D;IAC/D,MAAM;IACN,MAAM;IACN,MAAM;IACN,YAAY;IACZ,OAAO;IACP,QAAQ;CACA,CAAC","sourcesContent":["// Extend this list to add curated IntelliSense hints for object types.\n// Based on ISA-95-aligned categories plus commonly used UNS structural nodes.\nexport const knownUnsObjectTypes = [\n // ISA-95-aligned types\n \"equipment\",\n \"material\",\n \"personnel\",\n \"process-segment\",\n \"product-definition\",\n \"product-quality\",\n \"work-definition\",\n \"resource-status\",\n \"energy-resource\",\n \"utility-resource\",\n \"fluid-resource\",\n \"consumable-resource\",\n // Common structural or legacy types used in templates/examples\n \"line\",\n \"area\",\n \"site\",\n \"enterprise\",\n \"asset\",\n \"sensor\",\n] as const;\n\nexport type UnsObjectType = \"\" | typeof knownUnsObjectTypes[number] | (string & {});\n\n// Default object id is \"main\" when none is provided.\nexport type UnsObjectId = \"main\" | \"\" | (string & {});\n"]}
1
+ {"version":3,"file":"uns-object.js","sourceRoot":"","sources":["../../src/uns/uns-object.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,WAAW;IACX,UAAU;IACV,WAAW;IACX,iBAAiB;IACjB,oBAAoB;IACpB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,kBAAkB;IAClB,gBAAgB;IAChB,qBAAqB;IACrB,4DAA4D;IAC5D,MAAM;IACN,MAAM;IACN,MAAM;IACN,YAAY;IACZ,OAAO;IACP,QAAQ;CACA,CAAC;AAEX,sEAAsE;AACtE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,uDAAuD;IACvD,SAAS,EAAE,WAAW;IACtB,0CAA0C;IAC1C,QAAQ,EAAE,UAAU;IACpB,0CAA0C;IAC1C,SAAS,EAAE,WAAW;IACtB,wDAAwD;IACxD,cAAc,EAAE,iBAAiB;IACjC,wCAAwC;IACxC,iBAAiB,EAAE,oBAAoB;IACvC,+CAA+C;IAC/C,cAAc,EAAE,iBAAiB;IACjC,yCAAyC;IACzC,cAAc,EAAE,iBAAiB;IACjC,4DAA4D;IAC5D,cAAc,EAAE,iBAAiB;IACjC,8CAA8C;IAC9C,cAAc,EAAE,iBAAiB;IACjC,0CAA0C;IAC1C,eAAe,EAAE,kBAAkB;IACnC,gDAAgD;IAChD,aAAa,EAAE,gBAAgB;IAC/B,wCAAwC;IACxC,kBAAkB,EAAE,qBAAqB;IACzC,gCAAgC;IAChC,IAAI,EAAE,MAAM;IACZ,oCAAoC;IACpC,IAAI,EAAE,MAAM;IACZ,4BAA4B;IAC5B,IAAI,EAAE,MAAM;IACZ,oCAAoC;IACpC,UAAU,EAAE,YAAY;IACxB,gCAAgC;IAChC,KAAK,EAAE,OAAO;IACd,kCAAkC;IAClC,MAAM,EAAE,QAAQ;CACR,CAAC","sourcesContent":["// ISA-95-aligned object types (add your own as needed).\nexport const knownUnsObjectTypes = [\n \"equipment\",\n \"material\",\n \"personnel\",\n \"process-segment\",\n \"product-definition\",\n \"product-quality\",\n \"work-definition\",\n \"resource-status\",\n \"energy-resource\",\n \"utility-resource\",\n \"fluid-resource\",\n \"consumable-resource\",\n // Common structural/legacy types used in templates/examples\n \"line\",\n \"area\",\n \"site\",\n \"enterprise\",\n \"asset\",\n \"sensor\",\n] as const;\n\n// Convenient constants for IntelliSense and to avoid string literals.\nexport const ObjectTypes = {\n /** Physical equipment (machines, furnaces, sensors) */\n Equipment: \"equipment\",\n /** Material lots/batches/raw materials */\n Material: \"material\",\n /** Operators/supervisors/technologists */\n Personnel: \"personnel\",\n /** Process step or activity (e.g., rolling, cooling) */\n ProcessSegment: \"process-segment\",\n /** Product specs/recipes/definitions */\n ProductDefinition: \"product-definition\",\n /** Quality indicators/results for a product */\n ProductQuality: \"product-quality\",\n /** Work/task definitions or workflows */\n WorkDefinition: \"work-definition\",\n /** Status of any resource (material/personnel/equipment) */\n ResourceStatus: \"resource-status\",\n /** Energy carriers (electricity/steam/gas) */\n EnergyResource: \"energy-resource\",\n /** Utilities (water/air/nitrogen/etc.) */\n UtilityResource: \"utility-resource\",\n /** Fluids/gases (non-energy) used in process */\n FluidResource: \"fluid-resource\",\n /** Consumables (lubricants/cleaners) */\n ConsumableResource: \"consumable-resource\",\n /** Production line/work unit */\n Line: \"line\",\n /** Area/department within a site */\n Area: \"area\",\n /** Plant/site identifier */\n Site: \"site\",\n /** Enterprise/company identifier */\n Enterprise: \"enterprise\",\n /** Generic asset placeholder */\n Asset: \"asset\",\n /** Sensor as a distinct object */\n Sensor: \"sensor\",\n} as const;\n\nexport type KnownUnsObjectTypeName = typeof knownUnsObjectTypes[number];\n\nexport type UnsObjectType = \"\" | KnownUnsObjectTypeName | (string & {});\n\n// Default object id is \"main\" when none is provided.\nexport type UnsObjectId = \"main\" | \"\" | (string & {});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"uns-proxy.d.ts","sourceRoot":"","sources":["../../src/uns/uns-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,MAAM,CAAC,OAAO,OAAO,QAAQ;IAC3B,OAAO,CAAC,eAAe,CAA+B;IAC/C,KAAK,EAAE,eAAe,CAAC,SAAS,CAAC,CAAoC;IAC5E,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACtC,SAAS,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACzC,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,oBAAoB,CAAsC;;IAUlE;;OAEG;YACW,kBAAkB;IAgBhC;;OAEG;YACW,wBAAwB;IAgBtC;;;;OAIG;IACH,SAAS,CAAC,mBAAmB,CAAC,WAAW,EAAE,YAAY,GAAG,IAAI;IAsB9D;;OAEG;IACH,SAAS,CAAC,mBAAmB,CAAC,SAAS,EAAE,UAAU,GAAG,IAAI;IAuB1D,SAAS,CAAC,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAQ1D,IAAI;CASlB"}
1
+ {"version":3,"file":"uns-proxy.d.ts","sourceRoot":"","sources":["../../src/uns/uns-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,MAAM,CAAC,OAAO,OAAO,QAAQ;IAC3B,OAAO,CAAC,eAAe,CAA+B;IAC/C,KAAK,EAAE,eAAe,CAAC,SAAS,CAAC,CAAoC;IAC5E,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACtC,SAAS,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACzC,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,oBAAoB,CAAsC;;IAUlE;;OAEG;YACW,kBAAkB;IAgBhC;;OAEG;YACW,wBAAwB;IAgBtC;;;;OAIG;IACH,SAAS,CAAC,mBAAmB,CAAC,WAAW,EAAE,YAAY,GAAG,IAAI;IAuB9D;;OAEG;IACH,SAAS,CAAC,mBAAmB,CAAC,SAAS,EAAE,UAAU,GAAG,IAAI;IAuB1D,SAAS,CAAC,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAQ1D,IAAI;CASlB"}
@@ -71,6 +71,7 @@ export default class UnsProxy {
71
71
  tags: topicObject.tags,
72
72
  attributeNeedsPersistence: topicObject.attributeNeedsPersistence ?? true,
73
73
  dataGroup: topicObject.dataGroup ?? "",
74
+ asset: topicObject.asset,
74
75
  objectType: topicObject.objectType,
75
76
  objectId: topicObject.objectId
76
77
  });
@@ -1 +1 @@
1
- {"version":3,"file":"uns-proxy.js","sourceRoot":"","sources":["../../src/uns/uns-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import { IApiObject, ITopicObject, UnsEvents } from \"./uns-interfaces.js\";\nimport logger from \"../logger.js\";\nimport { UnsEventEmitter } from \"./uns-event-emitter.js\";\nimport { UnsPacket } from \"./uns-packet.js\";\n\nexport default class UnsProxy {\n private publishInterval: NodeJS.Timeout | null = null;\n public event: UnsEventEmitter<UnsEvents> = new UnsEventEmitter<UnsEvents>();\n protected instanceStatusTopic: string;\n protected instanceNameWithSuffix: string; //was prot\n private producedTopics: Map<string, ITopicObject> = new Map();\n private producedApiEndpoints: Map<string, IApiObject> = new Map();\n\n constructor() {\n // Set up interval to publish produced topics every 60 seconds.\n this.publishInterval = setInterval(() => {\n this.emitProducedTopics();\n this.emitProducedApiEndpoints();\n }, 60000); \n }\n \n /**\n * Publishes the list of produced topics to the MQTT broker.\n */\n private async emitProducedTopics(): Promise<void> {\n if (this.instanceStatusTopic !== \"\") {\n const topicsArray = [...this.producedTopics.values()];\n if (topicsArray.length > 0) {\n try {\n if (topicsArray.length > 0) {\n this.event.emit(\"unsProxyProducedTopics\", { producedTopics: topicsArray, statusTopic: this.instanceStatusTopic + \"topics\" });\n }\n } catch (error) {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing produced topics: ${error.message}`);\n }\n logger.debug(`${this.instanceNameWithSuffix} - Published produced topics.`);\n }\n }\n }\n\n /**\n * Publishes the list of produced API endpoints to the MQTT broker.\n */\n private async emitProducedApiEndpoints(): Promise<void> {\n if (this.instanceStatusTopic !== \"\") {\n const apiEndpointsArray = [...this.producedApiEndpoints.values()];\n if (apiEndpointsArray.length > 0) {\n try {\n if (apiEndpointsArray.length > 0) {\n this.event.emit(\"unsProxyProducedApiEndpoints\", { producedApiEndpoints: apiEndpointsArray, statusTopic: this.instanceStatusTopic + \"api-endpoints\" });\n }\n } catch (error) {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing produced API endpoints: ${error.message}`);\n }\n logger.debug(`${this.instanceNameWithSuffix} - Published produced API endpoints.`);\n }\n }\n }\n\n /**\n * Registers a unique topic so that it is tracked and published only once.\n *\n * @param topicObject - The object containing topic details.\n */\n protected registerUniqueTopic(topicObject: ITopicObject): void {\n if (this.instanceStatusTopic !== \"\") {\n const fullTopic = `${topicObject.topic}${topicObject.attribute}`;\n if (!this.producedTopics.has(fullTopic)) {\n this.producedTopics.set(fullTopic, {\n timestamp: topicObject.timestamp,\n topic: topicObject.topic,\n attribute: topicObject.attribute,\n attributeType: topicObject.attributeType,\n description: topicObject.description,\n tags: topicObject.tags,\n attributeNeedsPersistence: topicObject.attributeNeedsPersistence ?? true,\n dataGroup: topicObject.dataGroup ?? \"\",\n objectType: topicObject.objectType,\n objectId: topicObject.objectId\n });\n this.emitProducedTopics();\n logger.info(`${this.instanceNameWithSuffix} - Registered new topic: ${fullTopic}`);\n }\n }\n } \n\n /**\n * Registers an API endpoint to handle requests for a specific topic and attribute.\n */\n protected registerApiEndpoint(apiObject: IApiObject): void {\n if (this.instanceStatusTopic !== \"\") {\n const fullTopic = `${apiObject.topic}${apiObject.attribute}`;\n if (!this.producedApiEndpoints.has(fullTopic)) {\n const time = UnsPacket.formatToISO8601(new Date());\n this.producedApiEndpoints.set(fullTopic, {\n timestamp: time,\n topic: apiObject.topic,\n attribute: apiObject.attribute,\n apiHost: apiObject.apiHost,\n apiEndpoint: apiObject.apiEndpoint,\n apiMethod: apiObject.apiMethod,\n apiQueryParams: apiObject.apiQueryParams,\n apiDescription: apiObject.apiDescription,\n attributeType: apiObject.attributeType,\n apiSwaggerEndpoint: apiObject.apiSwaggerEndpoint\n });\n this.emitProducedApiEndpoints();\n logger.info(`${this.instanceNameWithSuffix} - Registered new api endpoint: /${fullTopic}`);\n }\n }\n }\n\n protected unregisterApiEndpoint(topic: string, attribute: string): void {\n const fullTopic = `${topic}${attribute}`;\n if (this.producedApiEndpoints.has(fullTopic)) {\n this.producedApiEndpoints.delete(fullTopic);\n this.emitProducedApiEndpoints();\n logger.info(`${this.instanceNameWithSuffix} - Unregistered API endpoint: ${fullTopic}`);\n }\n }\n public async stop() {\n // Clear the publishing interval.\n if (this.publishInterval) {\n clearInterval(this.publishInterval);\n this.publishInterval = null;\n }\n\n }\n\n}\n"]}
1
+ {"version":3,"file":"uns-proxy.js","sourceRoot":"","sources":["../../src/uns/uns-proxy.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,CAAC,OAAO,OAAO,QAAQ;IACnB,eAAe,GAA0B,IAAI,CAAC;IAC/C,KAAK,GAA+B,IAAI,eAAe,EAAa,CAAC;IAClE,mBAAmB,CAAS;IAC5B,sBAAsB,CAAS,CAAC,UAAU;IAC5C,cAAc,GAA8B,IAAI,GAAG,EAAE,CAAC;IACtD,oBAAoB,GAA4B,IAAI,GAAG,EAAE,CAAC;IAElE;QACE,+DAA+D;QAC/D,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC,GAAG,EAAE;YACtC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAClC,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,kBAAkB;QAC9B,IAAI,IAAI,CAAC,mBAAmB,KAAK,EAAE,EAAE,CAAC;YACpC,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;YACtD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBACH,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC3B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,IAAI,CAAC,mBAAmB,GAAG,QAAQ,EAAE,CAAC,CAAC;oBAC/H,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,sBAAsB,wCAAwC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBACtG,CAAC;gBACD,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,sBAAsB,+BAA+B,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,wBAAwB;QACpC,IAAI,IAAI,CAAC,mBAAmB,KAAK,EAAE,EAAE,CAAC;YACpC,MAAM,iBAAiB,GAAG,CAAC,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC;YAClE,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjC,IAAI,CAAC;oBACH,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACjC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,8BAA8B,EAAE,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,WAAW,EAAE,IAAI,CAAC,mBAAmB,GAAG,eAAe,EAAE,CAAC,CAAC;oBACxJ,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,sBAAsB,+CAA+C,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC7G,CAAC;gBACD,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,sBAAsB,sCAAsC,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACO,mBAAmB,CAAC,WAAyB;QACrD,IAAI,IAAI,CAAC,mBAAmB,KAAK,EAAE,EAAE,CAAC;YACpC,MAAM,SAAS,GAAG,GAAG,WAAW,CAAC,KAAK,GAAG,WAAW,CAAC,SAAS,EAAE,CAAC;YACjE,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE;oBACjC,SAAS,EAAE,WAAW,CAAC,SAAS;oBAChC,KAAK,EAAE,WAAW,CAAC,KAAK;oBACxB,SAAS,EAAE,WAAW,CAAC,SAAS;oBAClC,aAAa,EAAE,WAAW,CAAC,aAAa;oBACxC,WAAW,EAAE,WAAW,CAAC,WAAW;oBACpC,IAAI,EAAE,WAAW,CAAC,IAAI;oBACtB,yBAAyB,EAAE,WAAW,CAAC,yBAAyB,IAAI,IAAI;oBACxE,SAAS,EAAE,WAAW,CAAC,SAAS,IAAI,EAAE;oBACtC,KAAK,EAAE,WAAW,CAAC,KAAK;oBACxB,UAAU,EAAE,WAAW,CAAC,UAAU;oBAClC,QAAQ,EAAE,WAAW,CAAC,QAAQ;iBAC/B,CAAC,CAAC;gBACD,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC1B,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,sBAAsB,4BAA4B,SAAS,EAAE,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACO,mBAAmB,CAAC,SAAqB;QACjD,IAAI,IAAI,CAAC,mBAAmB,KAAK,EAAE,EAAE,CAAC;YACpC,MAAM,SAAS,GAAG,GAAG,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC;YAC7D,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC9C,MAAM,IAAI,GAAG,SAAS,CAAC,eAAe,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;gBACnD,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,SAAS,EAAE;oBACvC,SAAS,EAAE,IAAI;oBACf,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,SAAS,EAAE,SAAS,CAAC,SAAS;oBAC9B,OAAO,EAAE,SAAS,CAAC,OAAO;oBAC1B,WAAW,EAAE,SAAS,CAAC,WAAW;oBAClC,SAAS,EAAE,SAAS,CAAC,SAAS;oBAC9B,cAAc,EAAE,SAAS,CAAC,cAAc;oBACxC,cAAc,EAAE,SAAS,CAAC,cAAc;oBACxC,aAAa,EAAE,SAAS,CAAC,aAAa;oBACtC,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;iBACjD,CAAC,CAAC;gBACH,IAAI,CAAC,wBAAwB,EAAE,CAAC;gBAChC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,sBAAsB,oCAAoC,SAAS,EAAE,CAAC,CAAC;YAC7F,CAAC;QACH,CAAC;IACH,CAAC;IAES,qBAAqB,CAAC,KAAa,EAAE,SAAiB;QAC9D,MAAM,SAAS,GAAG,GAAG,KAAK,GAAG,SAAS,EAAE,CAAC;QACzC,IAAI,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC5C,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,sBAAsB,iCAAiC,SAAS,EAAE,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC;IACM,KAAK,CAAC,IAAI;QACf,iCAAiC;QACjC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACpC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC9B,CAAC;IAEH,CAAC;CAEF","sourcesContent":["import { IApiObject, ITopicObject, UnsEvents } from \"./uns-interfaces.js\";\nimport logger from \"../logger.js\";\nimport { UnsEventEmitter } from \"./uns-event-emitter.js\";\nimport { UnsPacket } from \"./uns-packet.js\";\n\nexport default class UnsProxy {\n private publishInterval: NodeJS.Timeout | null = null;\n public event: UnsEventEmitter<UnsEvents> = new UnsEventEmitter<UnsEvents>();\n protected instanceStatusTopic: string;\n protected instanceNameWithSuffix: string; //was prot\n private producedTopics: Map<string, ITopicObject> = new Map();\n private producedApiEndpoints: Map<string, IApiObject> = new Map();\n\n constructor() {\n // Set up interval to publish produced topics every 60 seconds.\n this.publishInterval = setInterval(() => {\n this.emitProducedTopics();\n this.emitProducedApiEndpoints();\n }, 60000); \n }\n \n /**\n * Publishes the list of produced topics to the MQTT broker.\n */\n private async emitProducedTopics(): Promise<void> {\n if (this.instanceStatusTopic !== \"\") {\n const topicsArray = [...this.producedTopics.values()];\n if (topicsArray.length > 0) {\n try {\n if (topicsArray.length > 0) {\n this.event.emit(\"unsProxyProducedTopics\", { producedTopics: topicsArray, statusTopic: this.instanceStatusTopic + \"topics\" });\n }\n } catch (error) {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing produced topics: ${error.message}`);\n }\n logger.debug(`${this.instanceNameWithSuffix} - Published produced topics.`);\n }\n }\n }\n\n /**\n * Publishes the list of produced API endpoints to the MQTT broker.\n */\n private async emitProducedApiEndpoints(): Promise<void> {\n if (this.instanceStatusTopic !== \"\") {\n const apiEndpointsArray = [...this.producedApiEndpoints.values()];\n if (apiEndpointsArray.length > 0) {\n try {\n if (apiEndpointsArray.length > 0) {\n this.event.emit(\"unsProxyProducedApiEndpoints\", { producedApiEndpoints: apiEndpointsArray, statusTopic: this.instanceStatusTopic + \"api-endpoints\" });\n }\n } catch (error) {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing produced API endpoints: ${error.message}`);\n }\n logger.debug(`${this.instanceNameWithSuffix} - Published produced API endpoints.`);\n }\n }\n }\n\n /**\n * Registers a unique topic so that it is tracked and published only once.\n *\n * @param topicObject - The object containing topic details.\n */\n protected registerUniqueTopic(topicObject: ITopicObject): void {\n if (this.instanceStatusTopic !== \"\") {\n const fullTopic = `${topicObject.topic}${topicObject.attribute}`;\n if (!this.producedTopics.has(fullTopic)) {\n this.producedTopics.set(fullTopic, {\n timestamp: topicObject.timestamp,\n topic: topicObject.topic,\n attribute: topicObject.attribute,\n attributeType: topicObject.attributeType,\n description: topicObject.description,\n tags: topicObject.tags,\n attributeNeedsPersistence: topicObject.attributeNeedsPersistence ?? true,\n dataGroup: topicObject.dataGroup ?? \"\",\n asset: topicObject.asset,\n objectType: topicObject.objectType,\n objectId: topicObject.objectId\n });\n this.emitProducedTopics();\n logger.info(`${this.instanceNameWithSuffix} - Registered new topic: ${fullTopic}`);\n }\n }\n } \n\n /**\n * Registers an API endpoint to handle requests for a specific topic and attribute.\n */\n protected registerApiEndpoint(apiObject: IApiObject): void {\n if (this.instanceStatusTopic !== \"\") {\n const fullTopic = `${apiObject.topic}${apiObject.attribute}`;\n if (!this.producedApiEndpoints.has(fullTopic)) {\n const time = UnsPacket.formatToISO8601(new Date());\n this.producedApiEndpoints.set(fullTopic, {\n timestamp: time,\n topic: apiObject.topic,\n attribute: apiObject.attribute,\n apiHost: apiObject.apiHost,\n apiEndpoint: apiObject.apiEndpoint,\n apiMethod: apiObject.apiMethod,\n apiQueryParams: apiObject.apiQueryParams,\n apiDescription: apiObject.apiDescription,\n attributeType: apiObject.attributeType,\n apiSwaggerEndpoint: apiObject.apiSwaggerEndpoint\n });\n this.emitProducedApiEndpoints();\n logger.info(`${this.instanceNameWithSuffix} - Registered new api endpoint: /${fullTopic}`);\n }\n }\n }\n\n protected unregisterApiEndpoint(topic: string, attribute: string): void {\n const fullTopic = `${topic}${attribute}`;\n if (this.producedApiEndpoints.has(fullTopic)) {\n this.producedApiEndpoints.delete(fullTopic);\n this.emitProducedApiEndpoints();\n logger.info(`${this.instanceNameWithSuffix} - Unregistered API endpoint: ${fullTopic}`);\n }\n }\n public async stop() {\n // Clear the publishing interval.\n if (this.publishInterval) {\n clearInterval(this.publishInterval);\n this.publishInterval = null;\n }\n\n }\n\n}\n"]}
@@ -21,8 +21,7 @@ export default class UnsMqttProxy extends UnsProxy {
21
21
  */
22
22
  private resolveObjectIdentity;
23
23
  /**
24
- * Ensure the topic contains the objectType/objectId segments before the attribute.
25
- * If already present, the topic is returned unchanged.
24
+ * Ensure the topic ends with a trailing slash for attribute concatenation.
26
25
  */
27
26
  private normalizeTopicWithObject;
28
27
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"uns-mqtt-proxy.d.ts","sourceRoot":"","sources":["../../src/uns-mqtt/uns-mqtt-proxy.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAa,MAAM,0BAA0B,CAAC;AAM1G,OAAO,QAAQ,MAAM,qBAAqB,CAAC;AAU3C,oBAAY,WAAW;IACrB,GAAG,QAAQ,CAAM,iCAAiC;IAClD,KAAK,UAAU,CAAE,8BAA8B;IAC/C,IAAI,SAAS;CACd;AAED,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,QAAQ;IAChD,OAAO,CAAC,UAAU,CAA8E;IAChG,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,eAAe,CAAmF;IAC1G,OAAO,CAAC,aAAa,CAAiB;IACtC,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,YAAY,CAAmB;gBAGrC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,aAAa,CAAC,EAAE,cAAc,EAC9B,eAAe,GAAE,OAAe,EAChC,gBAAgB,GAAE,OAAe;IA0BnC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAkC7B;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAmBhC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAmDxB;;;;;;;OAOG;YACW,2BAA2B;IASzC;;;;;OAKG;IACI,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAI3E;;;OAGG;IACI,mBAAmB,IAAI,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAY9D;;;;;OAKG;IACI,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAI5E;;;OAGG;IACI,oBAAoB,IAAI,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAa/D;;;OAGG;IACU,iCAAiC,IAAI,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAWlF;;;;;OAKG;IACI,kBAAkB,CAAC,WAAW,EAAE,YAAY,GAAG,IAAI,EAAE,IAAI,GAAE,WAA6B;IAiC/F;;;;;;OAMG;IACI,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpE;;;;;OAKG;IACI,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAI7D;;;;OAIG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAItD;;;;OAIG;IACI,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAI/C;;;;;;;OAOG;YACW,wBAAwB;IA+EtC;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAmBnC"}
1
+ {"version":3,"file":"uns-mqtt-proxy.d.ts","sourceRoot":"","sources":["../../src/uns-mqtt/uns-mqtt-proxy.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAa,MAAM,0BAA0B,CAAC;AAO1G,OAAO,QAAQ,MAAM,qBAAqB,CAAC;AAU3C,oBAAY,WAAW;IACrB,GAAG,QAAQ,CAAM,iCAAiC;IAClD,KAAK,UAAU,CAAE,8BAA8B;IAC/C,IAAI,SAAS;CACd;AAED,MAAM,CAAC,OAAO,OAAO,YAAa,SAAQ,QAAQ;IAChD,OAAO,CAAC,UAAU,CAA8E;IAChG,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,eAAe,CAAmF;IAC1G,OAAO,CAAC,aAAa,CAAiB;IACtC,SAAS,CAAC,kBAAkB,EAAE,MAAM,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,YAAY,CAAmB;gBAGrC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,aAAa,CAAC,EAAE,cAAc,EAC9B,eAAe,GAAE,OAAe,EAChC,gBAAgB,GAAE,OAAe;IA0BnC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAkC7B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAIhC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAmDxB;;;;;;;OAOG;YACW,2BAA2B;IASzC;;;;;OAKG;IACI,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAI3E;;;OAGG;IACI,mBAAmB,IAAI,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAY9D;;;;;OAKG;IACI,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI;IAI5E;;;OAGG;IACI,oBAAoB,IAAI,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAa/D;;;OAGG;IACU,iCAAiC,IAAI,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAWlF;;;;;OAKG;IACI,kBAAkB,CAAC,WAAW,EAAE,YAAY,GAAG,IAAI,EAAE,IAAI,GAAE,WAA6B;IAiC/F;;;;;;OAMG;IACI,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpE;;;;;OAKG;IACI,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAI7D;;;;OAIG;IACI,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAItD;;;;OAIG;IACI,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAI/C;;;;;;;OAOG;YACW,wBAAwB;IAgFtC;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAmBnC"}
@@ -56,12 +56,18 @@ export default class UnsMqttProxy extends UnsProxy {
56
56
  resolveObjectIdentity(msg) {
57
57
  const providedType = msg.objectType;
58
58
  const providedId = msg.objectId;
59
+ const providedAsset = msg.asset;
59
60
  const topicParts = msg.topic.split("/").filter((part) => part.length > 0);
60
61
  const hasObjectTail = topicParts.length >= 2;
61
62
  const parsedType = hasObjectTail ? topicParts[topicParts.length - 2] : undefined;
62
63
  const parsedId = hasObjectTail ? topicParts[topicParts.length - 1] : undefined;
64
+ const parsedAsset = hasObjectTail
65
+ ? (topicParts.length >= 3 ? topicParts[topicParts.length - 3] : undefined)
66
+ : (topicParts.length >= 1 ? topicParts[topicParts.length - 1] : undefined);
63
67
  const objectType = providedType ?? parsedType;
64
68
  const objectId = providedId ?? parsedId ?? "main";
69
+ const asset = providedAsset ?? parsedAsset;
70
+ // If values are provided, trust them; otherwise derive from topic.
65
71
  if (!providedType || !providedId) {
66
72
  if (parsedType && parsedId) {
67
73
  logger.warn(`${this.instanceNameWithSuffix} - objectType/objectId missing; derived from topic tail ${parsedType}/${parsedId}`);
@@ -70,34 +76,17 @@ export default class UnsMqttProxy extends UnsProxy {
70
76
  logger.warn(`${this.instanceNameWithSuffix} - objectType/objectId missing; defaulting objectId to 'main' for topic '${msg.topic}'. Expected topic to end with '<objectType>/<objectId>/'`);
71
77
  }
72
78
  }
73
- if (providedType && parsedType && providedType !== parsedType) {
74
- logger.warn(`${this.instanceNameWithSuffix} - Provided objectType '${providedType}' does not match topic tail '${parsedType}'`);
75
- }
76
- if (providedId && parsedId && providedId !== parsedId) {
77
- logger.warn(`${this.instanceNameWithSuffix} - Provided objectId '${providedId}' does not match topic tail '${parsedId}'`);
78
- }
79
+ // Asset is optional; no warning on mismatch to avoid noisy logs when base topics don't carry it.
79
80
  msg.objectType = objectType;
80
81
  msg.objectId = objectId;
81
- return { objectType, objectId };
82
+ msg.asset = asset;
83
+ return { objectType, objectId, asset };
82
84
  }
83
85
  /**
84
- * Ensure the topic contains the objectType/objectId segments before the attribute.
85
- * If already present, the topic is returned unchanged.
86
+ * Ensure the topic ends with a trailing slash for attribute concatenation.
86
87
  */
87
- normalizeTopicWithObject(topic, objectType, objectId) {
88
- if (!objectType || !objectId) {
89
- // Nothing to append; ensure trailing slash for attribute concatenation.
90
- return topic.endsWith("/") ? topic : `${topic}/`;
91
- }
92
- const normalizedBase = topic.endsWith("/") ? topic : `${topic}/`;
93
- const parts = normalizedBase.split("/").filter((p) => p.length > 0);
94
- const last = parts[parts.length - 1];
95
- const secondLast = parts[parts.length - 2];
96
- const alreadyHasObject = secondLast === objectType && last === objectId;
97
- if (alreadyHasObject) {
98
- return `${parts.join("/")}/`;
99
- }
100
- return `${normalizedBase}${objectType}/${objectId}/`;
88
+ normalizeTopicWithObject(topic) {
89
+ return topic.endsWith("/") ? topic : `${topic}/`;
101
90
  }
102
91
  /**
103
92
  * Starts a worker thread to process the throttled publish queue.
@@ -319,8 +308,8 @@ export default class UnsMqttProxy extends UnsProxy {
319
308
  dataGroup = msg.packet.message.table.dataGroup ?? "";
320
309
  if (attributeType == UnsAttributeType.Event)
321
310
  dataGroup = msg.packet.message.event.dataGroup ?? "";
322
- const { objectType, objectId } = this.resolveObjectIdentity(msg);
323
- const normalizedTopic = this.normalizeTopicWithObject(msg.topic, objectType, objectId);
311
+ const { objectType, objectId, asset } = this.resolveObjectIdentity(msg);
312
+ const normalizedTopic = this.normalizeTopicWithObject(msg.topic);
324
313
  msg.topic = normalizedTopic;
325
314
  this.registerUniqueTopic({
326
315
  timestamp: time,
@@ -331,22 +320,23 @@ export default class UnsMqttProxy extends UnsProxy {
331
320
  tags: msg.tags,
332
321
  attributeNeedsPersistence: msg.attributeNeedsPersistence,
333
322
  dataGroup,
323
+ asset,
334
324
  objectType,
335
325
  objectId
336
326
  });
337
- const fullTopic = `${msg.topic}${msg.attribute}`;
327
+ const publishTopic = `${msg.topic}${objectType ? `${objectType}/` : ""}${objectId ? `${objectId}/` : ""}${msg.attribute}`;
338
328
  const sequenceId = this.currentSequenceId.get(msg.topic) ?? 0;
339
329
  this.currentSequenceId.set(msg.topic, sequenceId + 1);
340
330
  msg.packet.sequenceId = sequenceId;
341
331
  if (msg.packet.message.data) {
342
332
  const newValue = msg.packet.message.data.value;
343
333
  const newUom = msg.packet.message.data.uom;
344
- const lastValueEntry = this.lastValues.get(fullTopic);
334
+ const lastValueEntry = this.lastValues.get(publishTopic);
345
335
  const currentTime = new Date(msg.packet.message.data.time);
346
336
  if (lastValueEntry) {
347
337
  const intervalBetweenMessages = currentTime.getTime() - lastValueEntry.timestamp.getTime();
348
338
  const lastValue = lastValueEntry.value;
349
- this.lastValues.set(fullTopic, { value: newValue, uom: newUom, timestamp: currentTime });
339
+ this.lastValues.set(publishTopic, { value: newValue, uom: newUom, timestamp: currentTime });
350
340
  // Compute the delta and manage cumulative resets
351
341
  if (valueIsCumulative == true && typeof newValue === "number" && typeof lastValue === "number") {
352
342
  // Skip if newValue is 0 (likely a glitch)
@@ -357,27 +347,27 @@ export default class UnsMqttProxy extends UnsProxy {
357
347
  msg.packet.message.data.value = delta < 0 ? newValue : delta;
358
348
  }
359
349
  msg.packet.interval = intervalBetweenMessages;
360
- await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));
350
+ await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));
361
351
  }
362
352
  else {
363
- this.lastValues.set(fullTopic, { value: newValue, uom: newUom, timestamp: currentTime });
364
- logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate interval on topic ${fullTopic}`);
353
+ this.lastValues.set(publishTopic, { value: newValue, uom: newUom, timestamp: currentTime });
354
+ logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate interval on topic ${publishTopic}`);
365
355
  if (valueIsCumulative === false) {
366
- await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));
356
+ await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));
367
357
  }
368
358
  else {
369
- logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate difference on value in data for topic ${fullTopic}`);
359
+ logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate difference on value in data for topic ${publishTopic}`);
370
360
  }
371
361
  }
372
362
  }
373
363
  else if (msg.packet.message.command) {
374
- await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));
364
+ await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));
375
365
  }
376
366
  else if (msg.packet.message.event) {
377
- await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));
367
+ await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));
378
368
  }
379
369
  else if (msg.packet.message.table) {
380
- await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));
370
+ await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));
381
371
  }
382
372
  }
383
373
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"uns-mqtt-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/uns-mqtt-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from \"fs\";\nimport { IClientPublishOptions } from \"mqtt\";\nimport * as path from \"path\";\nimport { Worker } from \"worker_threads\";\nimport { fileURLToPath } from \"url\";\nimport { basePath } from \"../base-path.js\";\nimport logger from \"../logger.js\";\nimport { IMqttMessage, IUnsPacket, IUnsParameters, UnsEvents, ValueType } from \"../uns/uns-interfaces.js\";\nimport type { UnsObjectId, UnsObjectType } from \"../uns/uns-object.js\";\nimport { MeasurementUnit } from \"../uns/uns-measurements.js\";\nimport { UnsPacket } from \"../uns/uns-packet.js\";\nimport { IMqttParameters, IMqttWorkerData } from \"./mqtt-interfaces.js\";\nimport { MqttTopicBuilder } from \"./mqtt-topic-builder.js\";\nimport UnsProxy from \"../uns/uns-proxy.js\";\nimport { UnsAttributeType } from \"../graphql/schema.js\";\n\nconst packageJsonPath = path.join(basePath, \"package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf8\"));\n\nconst moduleDirectory = path.dirname(fileURLToPath(import.meta.url));\nconst packageRoot = path.resolve(moduleDirectory, \"..\", \"..\");\nconst workerScriptPath = path.join(packageRoot, \"dist/uns-mqtt/mqtt-worker-init.js\");\n\nexport enum MessageMode {\n Raw = 'raw', // Send only the original message\n Delta = 'delta', // Send only the delta message\n Both = 'both' // Send both the original and delta messages\n}\n\nexport default class UnsMqttProxy extends UnsProxy {\n private lastValues: Map<string, { value: ValueType; uom: string; timestamp: Date }> = new Map();\n private worker: Worker;\n private pendingEnqueues: Map<string, { resolve: () => void; reject: (reason?: any) => void }> = new Map();\n private unsParameters: IUnsParameters;\n protected processStatusTopic: string;\n public instanceName: string;\n private currentSequenceId: Map<string, number> = new Map();\n private topicBuilder: MqttTopicBuilder;\n\n constructor(\n mqttHost: string,\n processName: string,\n instanceName: string,\n unsParameters?: IUnsParameters,\n publisherActive: boolean = false,\n subscriberActive: boolean = false\n ) {\n super();\n this.instanceName = instanceName;\n // Create the topic builder using packageJson values and the processName.\n this.topicBuilder = new MqttTopicBuilder(`uns-infra/${MqttTopicBuilder.sanitizeTopicPart(packageJson.name)}/${MqttTopicBuilder.sanitizeTopicPart(packageJson.version)}/${MqttTopicBuilder.sanitizeTopicPart(processName)}/`);\n\n // Generate the processStatusTopic using the builder.\n this.processStatusTopic = this.topicBuilder.getProcessStatusTopic();\n // Derive the instanceStatusTopic by appending the instance name.\n this.instanceStatusTopic = this.processStatusTopic + instanceName + \"/\";\n\n // Concatenate processName with instanceName for the worker identification.\n this.instanceNameWithSuffix = `${processName}-${instanceName}`;\n \n const mqttParameters: IMqttParameters = {\n mqttSubToTopics: unsParameters?.mqttSubToTopics ?? [],\n username: unsParameters?.username ?? \"\",\n password: unsParameters?.password ?? \"\",\n mqttSSL: unsParameters?.mqttSSL ?? false,\n statusTopic: this.instanceStatusTopic,\n };\n this.unsParameters = unsParameters ?? {};\n this.startQueueWorker(mqttHost, this.instanceNameWithSuffix, mqttParameters, publisherActive, subscriberActive);\n }\n\n /**\n * Resolve object identity from explicit fields or the tail of the topic path.\n * Falls back to parsing when not provided for backward compatibility.\n */\n private resolveObjectIdentity(msg: IMqttMessage): { objectType?: UnsObjectType; objectId?: UnsObjectId } {\n const providedType = msg.objectType;\n const providedId = msg.objectId;\n\n const topicParts = msg.topic.split(\"/\").filter((part) => part.length > 0);\n const hasObjectTail = topicParts.length >= 2;\n const parsedType = hasObjectTail ? topicParts[topicParts.length - 2] as UnsObjectType : undefined;\n const parsedId = hasObjectTail ? topicParts[topicParts.length - 1] as UnsObjectId : undefined;\n\n const objectType = providedType ?? parsedType;\n const objectId = providedId ?? parsedId ?? \"main\";\n\n if (!providedType || !providedId) {\n if (parsedType && parsedId) {\n logger.warn(`${this.instanceNameWithSuffix} - objectType/objectId missing; derived from topic tail ${parsedType}/${parsedId}`);\n } else {\n logger.warn(`${this.instanceNameWithSuffix} - objectType/objectId missing; defaulting objectId to 'main' for topic '${msg.topic}'. Expected topic to end with '<objectType>/<objectId>/'`);\n }\n }\n\n if (providedType && parsedType && providedType !== parsedType) {\n logger.warn(`${this.instanceNameWithSuffix} - Provided objectType '${providedType}' does not match topic tail '${parsedType}'`);\n }\n\n if (providedId && parsedId && providedId !== parsedId) {\n logger.warn(`${this.instanceNameWithSuffix} - Provided objectId '${providedId}' does not match topic tail '${parsedId}'`);\n }\n\n msg.objectType = objectType;\n msg.objectId = objectId;\n\n return { objectType, objectId };\n }\n\n /**\n * Ensure the topic contains the objectType/objectId segments before the attribute.\n * If already present, the topic is returned unchanged.\n */\n private normalizeTopicWithObject(topic: string, objectType?: UnsObjectType, objectId?: UnsObjectId): string {\n if (!objectType || !objectId) {\n // Nothing to append; ensure trailing slash for attribute concatenation.\n return topic.endsWith(\"/\") ? topic : `${topic}/`;\n }\n\n const normalizedBase = topic.endsWith(\"/\") ? topic : `${topic}/`;\n const parts = normalizedBase.split(\"/\").filter((p) => p.length > 0);\n const last = parts[parts.length - 1];\n const secondLast = parts[parts.length - 2];\n\n const alreadyHasObject = secondLast === objectType && last === objectId;\n if (alreadyHasObject) {\n return `${parts.join(\"/\")}/`;\n }\n\n return `${normalizedBase}${objectType}/${objectId}/`;\n }\n\n /**\n * Starts a worker thread to process the throttled publish queue.\n */\n private startQueueWorker(\n mqttHost: string,\n instanceNameWithSuffix: string,\n mqttParameters: IMqttParameters,\n publisherActive: boolean,\n subscriberActive: boolean\n ): void {\n const workerData: IMqttWorkerData = {\n publishThrottlingDelay: this.unsParameters.publishThrottlingDelay ?? 1,\n subscribeThrottlingDelay: this.unsParameters.subscribeThrottlingDelay ?? 1,\n persistToDisk: false,\n mqttHost: mqttHost,\n instanceNameWithSuffix: instanceNameWithSuffix,\n mqttParameters: mqttParameters,\n publisherActive,\n subscriberActive\n };\n\n this.worker = new Worker(workerScriptPath, { workerData });\n\n this.worker.on(\"message\", (msg) => {\n if (msg && msg.command === \"enqueueResult\" && msg.id) {\n const pending = this.pendingEnqueues.get(msg.id);\n if (pending) {\n if (msg.status === \"success\" && msg.topic && msg.message) {\n pending.resolve();\n } else {\n pending.reject(new Error(msg.error));\n }\n this.pendingEnqueues.delete(msg.id);\n }\n } else if (msg && msg.command === \"input\") {\n this.event.emit(\"input\", { topic: msg.topic, message: msg.message.toString(), packet: msg.packet });\n } else if (msg && (msg.command === \"handover_subscriber\" || msg.command === \"handover_publisher\")) {\n this.event.emit(\"mqttWorker\", { command: msg.command, batchSize: msg.batchSize, referenceHash: msg.referenceHash, instanceName: this.instanceName });\n } else if (msg && msg.command === \"mqttProxyStatus\") {\n this.event.emit(\"mqttProxyStatus\", { event: msg.event, value: msg.value, uom: msg.uom, statusTopic: msg.statusTopic });\n }\n });\n\n this.worker.on(\"error\", (err) => {\n logger.error(\"Error in worker:\", err);\n });\n\n this.worker.on(\"exit\", (code) => {\n if (code !== 0) {\n logger.error(`Worker exited with code ${code}`);\n }\n });\n }\n\n /**\n * Enqueues a message to the worker queue.\n *\n * @param topic - The topic to which the message belongs.\n * @param message - The message to be enqueued.\n * @param options - Optional publish options.\n * @returns A promise that resolves when the message is successfully enqueued.\n */\n private async enqueueMessageToWorkerQueue(topic: string, message: string, options?: IClientPublishOptions): Promise<void> {\n return new Promise((resolve, reject) => {\n // const id: string = String(this.currentSequenceId.get(topic) ?? 0);\n const id = `${Date.now()}-${Math.random()}`;\n this.pendingEnqueues.set(id, { resolve, reject });\n this.worker.postMessage({ command: \"enqueue\", id, topic, message, options });\n });\n }\n\n /**\n * Sets the publisher active state.\n *\n * @param batchSize - Optional batch size.\n * @param referenceHash - Optional reference hash.\n */\n public setPublisherActive(batchSize?: number, referenceHash?: string): void {\n this.worker.postMessage({ command: \"setPublisherActive\", batchSize, referenceHash });\n }\n\n /**\n * Sets the publisher to passive mode.\n * @returns A promise that resolves when the publisher is set to passive.\n */\n public setPublisherPassive(): Promise<UnsEvents[\"mqttWorker\"]> {\n this.worker.postMessage({ command: \"setPublisherPassive\"});\n return new Promise((resolve) => {\n this.event.on(\"mqttWorker\", (msg: UnsEvents[\"mqttWorker\"]) => {\n if (msg.command === \"handover_publisher\") {\n logger.info(`${this.instanceNameWithSuffix} - Publisher set to passive.`);\n resolve(msg);\n }\n });\n });\n }\n\n /**\n * Sets the subscriber active state.\n *\n * @param batchSize - Optional batch size.\n * @param referenceHash - Optional reference hash.\n */\n public setSubscriberActive(batchSize?: number, referenceHash?: string): void {\n this.worker.postMessage({ command: \"setSubscriberActive\", batchSize, referenceHash });\n }\n\n /**\n * Sets the subscriber to passive mode.\n * @returns A promise that resolves when the subscriber is set to passive.\n */\n public setSubscriberPassive(): Promise<UnsEvents[\"mqttWorker\"]> {\n this.worker.postMessage({ command: \"setSubscriberPassive\"});\n return new Promise((resolve) => {\n this.event.on(\"mqttWorker\", (msg: UnsEvents[\"mqttWorker\"]) => {\n if (msg.command === \"handover_subscriber\") {\n logger.info(`${this.instanceNameWithSuffix} - Publisher set to passive.`);\n resolve(msg);\n }\n });\n });\n }\n\n\n /**\n * Sets the subscriber to passive mode and allows the publisher to run\n * until the queue is empty (all messages are processed).\n */\n public async setSubscriberPassiveAndDrainQueue(): Promise<UnsEvents[\"mqttWorker\"]> {\n return new Promise(async (resolve) => {\n const mqttWorkerData = await this.setSubscriberPassive();\n while (this.pendingEnqueues.size > 0) {\n await new Promise((resolve) => setTimeout(resolve, 100)); // Poll every 100ms\n }\n logger.info(`${this.instanceNameWithSuffix} - Subscriber set to passive and queue drained.`);\n resolve(mqttWorkerData);\n });\n }\n\n /**\n * Processes and publishes MQTT messages based on the selected message mode.\n *\n * @param mqttMessage - The MQTT message object.\n * @param mode - The message mode (Raw, Delta, or Both).\n */\n public publishMqttMessage(mqttMessage: IMqttMessage | null, mode: MessageMode = MessageMode.Raw) {\n if (mqttMessage) {\n if (mqttMessage.packet) {\n const time = UnsPacket.formatToISO8601(new Date());\n switch (mode) {\n case MessageMode.Raw: {\n this.processAndEnqueueMessage(mqttMessage, time, false);\n break;\n }\n case MessageMode.Delta: {\n const deltaMessage = { ...mqttMessage };\n deltaMessage.attribute = `${mqttMessage.attribute}-delta`;\n deltaMessage.description = `${mqttMessage.description} (delta)`;\n this.processAndEnqueueMessage(deltaMessage, time, true);\n break;\n }\n case MessageMode.Both: {\n this.processAndEnqueueMessage(mqttMessage, time, false);\n const deltaMessageBoth = { ...mqttMessage };\n deltaMessageBoth.attribute = `${mqttMessage.attribute}-delta`;\n deltaMessageBoth.description = `${mqttMessage.description} (delta)`;\n this.processAndEnqueueMessage(deltaMessageBoth, time, true);\n break;\n }\n } \n } else {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing mqtt message: mqttMessage.packet must be defined.`);\n }\n } else {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing mqtt message: mqttMessage must be defined.`);\n }\n }\n\n /**\n * Publishes a message to a specified topic.\n *\n * @param topic - The MQTT topic.\n * @param message - The message to publish.\n * @returns A promise that resolves when enqueued.\n */\n public publishMessage(topic: string, message: string): Promise<void> {\n return this.enqueueMessageToWorkerQueue(topic, message);\n }\n\n /**\n * Parses an MQTT packet from a JSON string.\n *\n * @param mqttPacket - The MQTT packet string.\n * @returns A parsed IUnsPacket object or null.\n */\n public parseMqttPacket(mqttPacket: string): IUnsPacket | null {\n return UnsPacket.parseMqttPacket(mqttPacket, this.instanceNameWithSuffix);\n }\n\n /**\n * Subscribes asynchronously to one or more topics.\n *\n * @param topics - A topic or list of topics.\n */\n public subscribeAsync(topics: string | string[]): void {\n this.worker.postMessage({ command: \"subscribeAsync\", topics });\n }\n\n /**\n * Unsubscribes asynchronously from the given topics.\n *\n * @param topics - A list of topics.\n */\n public unsubscribeAsync(topics: string[]): void {\n this.worker.postMessage({ command: \"unsubscribeAsync\", topics });\n }\n\n /**\n * Processes and enqueues a message to the worker queue, including handling\n * sequencing, value differences, and tracking of unique topics.\n *\n * @param msg - The MQTT message to process.\n * @param time - The timestamp.\n * @param valueIsCumulative - Whether the value is cumulative.\n */\n private async processAndEnqueueMessage(msg: IMqttMessage, time: string, valueIsCumulative: boolean = false): Promise<void> {\n try {\n const attributeType =\n msg.packet.message.data ? UnsAttributeType.Data :\n msg.packet.message.event ? UnsAttributeType.Event :\n msg.packet.message.table ? UnsAttributeType.Table : null;\n \n let dataGroup = \"\";\n if (attributeType == UnsAttributeType.Data)\n dataGroup = msg.packet.message.data.dataGroup ?? \"\";\n if (attributeType == UnsAttributeType.Table)\n dataGroup = msg.packet.message.table.dataGroup ?? \"\";\n if (attributeType == UnsAttributeType.Event)\n dataGroup = msg.packet.message.event.dataGroup ?? \"\";\n\n const { objectType, objectId } = this.resolveObjectIdentity(msg);\n const normalizedTopic = this.normalizeTopicWithObject(msg.topic, objectType, objectId);\n msg.topic = normalizedTopic;\n\n this.registerUniqueTopic({\n timestamp: time,\n topic: msg.topic,\n attribute: msg.attribute,\n attributeType: attributeType,\n description: msg.description,\n tags: msg.tags,\n attributeNeedsPersistence: msg.attributeNeedsPersistence,\n dataGroup,\n objectType,\n objectId\n });\n\n const fullTopic = `${msg.topic}${msg.attribute}`;\n const sequenceId = this.currentSequenceId.get(msg.topic) ?? 0;\n this.currentSequenceId.set(msg.topic, sequenceId + 1);\n msg.packet.sequenceId = sequenceId;\n\n if (msg.packet.message.data) {\n const newValue = msg.packet.message.data.value;\n const newUom: MeasurementUnit = msg.packet.message.data.uom;\n const lastValueEntry = this.lastValues.get(fullTopic);\n const currentTime = new Date(msg.packet.message.data.time);\n\n if (lastValueEntry) {\n const intervalBetweenMessages = currentTime.getTime() - lastValueEntry.timestamp.getTime();\n const lastValue = lastValueEntry.value;\n this.lastValues.set(fullTopic, { value: newValue, uom: newUom, timestamp: currentTime });\n // Compute the delta and manage cumulative resets\n if (valueIsCumulative == true && typeof newValue === \"number\" && typeof lastValue === \"number\") {\n // Skip if newValue is 0 (likely a glitch)\n if (newValue === 0) {\n return; // Don't process or enqueue\n }\n const delta = newValue - lastValue;\n msg.packet.message.data.value = delta < 0 ? newValue : delta;\n }\n msg.packet.interval = intervalBetweenMessages;\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\n } else {\n this.lastValues.set(fullTopic, { value: newValue, uom: newUom, timestamp: currentTime });\n logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate interval on topic ${fullTopic}`);\n if (valueIsCumulative === false) {\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\n } else {\n logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate difference on value in data for topic ${fullTopic}`);\n }\n }\n } else if (msg.packet.message.command) {\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\n } else if (msg.packet.message.event) {\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\n } else if (msg.packet.message.table) {\n await this.enqueueMessageToWorkerQueue(fullTopic, JSON.stringify(msg.packet));\n }\n } catch (error: any) {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing message to topic ${msg.topic}${msg.attribute}: ${error.message}`);\n }\n }\n\n /**\n * Stops the UnsProxy instance and cleans up resources.\n */\n public async stop(): Promise<void> {\n super.stop();\n // Terminate the worker thread if it exists.\n if (this.worker) {\n try {\n const exitCode = await this.worker.terminate();\n logger.info(`${this.instanceNameWithSuffix} - Worker terminated with exit code ${exitCode}`);\n } catch (error: any) {\n logger.error(`${this.instanceNameWithSuffix} - Error terminating worker: ${error.message}`);\n }\n }\n \n // Optionally, handle any pending enqueues.\n for (const [id, pending] of this.pendingEnqueues) {\n pending.reject(new Error(\"UnsProxy has been stopped\"));\n this.pendingEnqueues.delete(id);\n }\n }\n\n}\n"]}
1
+ {"version":3,"file":"uns-mqtt-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/uns-mqtt-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from \"fs\";\nimport { IClientPublishOptions } from \"mqtt\";\nimport * as path from \"path\";\nimport { Worker } from \"worker_threads\";\nimport { fileURLToPath } from \"url\";\nimport { basePath } from \"../base-path.js\";\nimport logger from \"../logger.js\";\nimport { IMqttMessage, IUnsPacket, IUnsParameters, UnsEvents, ValueType } from \"../uns/uns-interfaces.js\";\nimport type { UnsObjectId, UnsObjectType } from \"../uns/uns-object.js\";\nimport type { UnsAsset } from \"../uns/uns-asset.js\";\nimport { MeasurementUnit } from \"../uns/uns-measurements.js\";\nimport { UnsPacket } from \"../uns/uns-packet.js\";\nimport { IMqttParameters, IMqttWorkerData } from \"./mqtt-interfaces.js\";\nimport { MqttTopicBuilder } from \"./mqtt-topic-builder.js\";\nimport UnsProxy from \"../uns/uns-proxy.js\";\nimport { UnsAttributeType } from \"../graphql/schema.js\";\n\nconst packageJsonPath = path.join(basePath, \"package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf8\"));\n\nconst moduleDirectory = path.dirname(fileURLToPath(import.meta.url));\nconst packageRoot = path.resolve(moduleDirectory, \"..\", \"..\");\nconst workerScriptPath = path.join(packageRoot, \"dist/uns-mqtt/mqtt-worker-init.js\");\n\nexport enum MessageMode {\n Raw = 'raw', // Send only the original message\n Delta = 'delta', // Send only the delta message\n Both = 'both' // Send both the original and delta messages\n}\n\nexport default class UnsMqttProxy extends UnsProxy {\n private lastValues: Map<string, { value: ValueType; uom: string; timestamp: Date }> = new Map();\n private worker: Worker;\n private pendingEnqueues: Map<string, { resolve: () => void; reject: (reason?: any) => void }> = new Map();\n private unsParameters: IUnsParameters;\n protected processStatusTopic: string;\n public instanceName: string;\n private currentSequenceId: Map<string, number> = new Map();\n private topicBuilder: MqttTopicBuilder;\n\n constructor(\n mqttHost: string,\n processName: string,\n instanceName: string,\n unsParameters?: IUnsParameters,\n publisherActive: boolean = false,\n subscriberActive: boolean = false\n ) {\n super();\n this.instanceName = instanceName;\n // Create the topic builder using packageJson values and the processName.\n this.topicBuilder = new MqttTopicBuilder(`uns-infra/${MqttTopicBuilder.sanitizeTopicPart(packageJson.name)}/${MqttTopicBuilder.sanitizeTopicPart(packageJson.version)}/${MqttTopicBuilder.sanitizeTopicPart(processName)}/`);\n\n // Generate the processStatusTopic using the builder.\n this.processStatusTopic = this.topicBuilder.getProcessStatusTopic();\n // Derive the instanceStatusTopic by appending the instance name.\n this.instanceStatusTopic = this.processStatusTopic + instanceName + \"/\";\n\n // Concatenate processName with instanceName for the worker identification.\n this.instanceNameWithSuffix = `${processName}-${instanceName}`;\n \n const mqttParameters: IMqttParameters = {\n mqttSubToTopics: unsParameters?.mqttSubToTopics ?? [],\n username: unsParameters?.username ?? \"\",\n password: unsParameters?.password ?? \"\",\n mqttSSL: unsParameters?.mqttSSL ?? false,\n statusTopic: this.instanceStatusTopic,\n };\n this.unsParameters = unsParameters ?? {};\n this.startQueueWorker(mqttHost, this.instanceNameWithSuffix, mqttParameters, publisherActive, subscriberActive);\n }\n\n /**\n * Resolve object identity from explicit fields or the tail of the topic path.\n * Falls back to parsing when not provided for backward compatibility.\n */\n private resolveObjectIdentity(msg: IMqttMessage): { objectType?: UnsObjectType; objectId?: UnsObjectId; asset?: UnsAsset } {\n const providedType = msg.objectType;\n const providedId = msg.objectId;\n const providedAsset = msg.asset;\n\n const topicParts = msg.topic.split(\"/\").filter((part) => part.length > 0);\n const hasObjectTail = topicParts.length >= 2;\n const parsedType = hasObjectTail ? topicParts[topicParts.length - 2] as UnsObjectType : undefined;\n const parsedId = hasObjectTail ? topicParts[topicParts.length - 1] as UnsObjectId : undefined;\n const parsedAsset = hasObjectTail\n ? (topicParts.length >= 3 ? topicParts[topicParts.length - 3] as UnsAsset : undefined)\n : (topicParts.length >= 1 ? topicParts[topicParts.length - 1] as UnsAsset : undefined);\n\n const objectType = providedType ?? parsedType;\n const objectId = providedId ?? parsedId ?? \"main\";\n const asset = providedAsset ?? parsedAsset;\n\n // If values are provided, trust them; otherwise derive from topic.\n if (!providedType || !providedId) {\n if (parsedType && parsedId) {\n logger.warn(`${this.instanceNameWithSuffix} - objectType/objectId missing; derived from topic tail ${parsedType}/${parsedId}`);\n } else {\n logger.warn(`${this.instanceNameWithSuffix} - objectType/objectId missing; defaulting objectId to 'main' for topic '${msg.topic}'. Expected topic to end with '<objectType>/<objectId>/'`);\n }\n }\n // Asset is optional; no warning on mismatch to avoid noisy logs when base topics don't carry it.\n\n msg.objectType = objectType;\n msg.objectId = objectId;\n msg.asset = asset;\n\n return { objectType, objectId, asset };\n }\n\n /**\n * Ensure the topic ends with a trailing slash for attribute concatenation.\n */\n private normalizeTopicWithObject(topic: string): string {\n return topic.endsWith(\"/\") ? topic : `${topic}/`;\n }\n\n /**\n * Starts a worker thread to process the throttled publish queue.\n */\n private startQueueWorker(\n mqttHost: string,\n instanceNameWithSuffix: string,\n mqttParameters: IMqttParameters,\n publisherActive: boolean,\n subscriberActive: boolean\n ): void {\n const workerData: IMqttWorkerData = {\n publishThrottlingDelay: this.unsParameters.publishThrottlingDelay ?? 1,\n subscribeThrottlingDelay: this.unsParameters.subscribeThrottlingDelay ?? 1,\n persistToDisk: false,\n mqttHost: mqttHost,\n instanceNameWithSuffix: instanceNameWithSuffix,\n mqttParameters: mqttParameters,\n publisherActive,\n subscriberActive\n };\n\n this.worker = new Worker(workerScriptPath, { workerData });\n\n this.worker.on(\"message\", (msg) => {\n if (msg && msg.command === \"enqueueResult\" && msg.id) {\n const pending = this.pendingEnqueues.get(msg.id);\n if (pending) {\n if (msg.status === \"success\" && msg.topic && msg.message) {\n pending.resolve();\n } else {\n pending.reject(new Error(msg.error));\n }\n this.pendingEnqueues.delete(msg.id);\n }\n } else if (msg && msg.command === \"input\") {\n this.event.emit(\"input\", { topic: msg.topic, message: msg.message.toString(), packet: msg.packet });\n } else if (msg && (msg.command === \"handover_subscriber\" || msg.command === \"handover_publisher\")) {\n this.event.emit(\"mqttWorker\", { command: msg.command, batchSize: msg.batchSize, referenceHash: msg.referenceHash, instanceName: this.instanceName });\n } else if (msg && msg.command === \"mqttProxyStatus\") {\n this.event.emit(\"mqttProxyStatus\", { event: msg.event, value: msg.value, uom: msg.uom, statusTopic: msg.statusTopic });\n }\n });\n\n this.worker.on(\"error\", (err) => {\n logger.error(\"Error in worker:\", err);\n });\n\n this.worker.on(\"exit\", (code) => {\n if (code !== 0) {\n logger.error(`Worker exited with code ${code}`);\n }\n });\n }\n\n /**\n * Enqueues a message to the worker queue.\n *\n * @param topic - The topic to which the message belongs.\n * @param message - The message to be enqueued.\n * @param options - Optional publish options.\n * @returns A promise that resolves when the message is successfully enqueued.\n */\n private async enqueueMessageToWorkerQueue(topic: string, message: string, options?: IClientPublishOptions): Promise<void> {\n return new Promise((resolve, reject) => {\n // const id: string = String(this.currentSequenceId.get(topic) ?? 0);\n const id = `${Date.now()}-${Math.random()}`;\n this.pendingEnqueues.set(id, { resolve, reject });\n this.worker.postMessage({ command: \"enqueue\", id, topic, message, options });\n });\n }\n\n /**\n * Sets the publisher active state.\n *\n * @param batchSize - Optional batch size.\n * @param referenceHash - Optional reference hash.\n */\n public setPublisherActive(batchSize?: number, referenceHash?: string): void {\n this.worker.postMessage({ command: \"setPublisherActive\", batchSize, referenceHash });\n }\n\n /**\n * Sets the publisher to passive mode.\n * @returns A promise that resolves when the publisher is set to passive.\n */\n public setPublisherPassive(): Promise<UnsEvents[\"mqttWorker\"]> {\n this.worker.postMessage({ command: \"setPublisherPassive\"});\n return new Promise((resolve) => {\n this.event.on(\"mqttWorker\", (msg: UnsEvents[\"mqttWorker\"]) => {\n if (msg.command === \"handover_publisher\") {\n logger.info(`${this.instanceNameWithSuffix} - Publisher set to passive.`);\n resolve(msg);\n }\n });\n });\n }\n\n /**\n * Sets the subscriber active state.\n *\n * @param batchSize - Optional batch size.\n * @param referenceHash - Optional reference hash.\n */\n public setSubscriberActive(batchSize?: number, referenceHash?: string): void {\n this.worker.postMessage({ command: \"setSubscriberActive\", batchSize, referenceHash });\n }\n\n /**\n * Sets the subscriber to passive mode.\n * @returns A promise that resolves when the subscriber is set to passive.\n */\n public setSubscriberPassive(): Promise<UnsEvents[\"mqttWorker\"]> {\n this.worker.postMessage({ command: \"setSubscriberPassive\"});\n return new Promise((resolve) => {\n this.event.on(\"mqttWorker\", (msg: UnsEvents[\"mqttWorker\"]) => {\n if (msg.command === \"handover_subscriber\") {\n logger.info(`${this.instanceNameWithSuffix} - Publisher set to passive.`);\n resolve(msg);\n }\n });\n });\n }\n\n\n /**\n * Sets the subscriber to passive mode and allows the publisher to run\n * until the queue is empty (all messages are processed).\n */\n public async setSubscriberPassiveAndDrainQueue(): Promise<UnsEvents[\"mqttWorker\"]> {\n return new Promise(async (resolve) => {\n const mqttWorkerData = await this.setSubscriberPassive();\n while (this.pendingEnqueues.size > 0) {\n await new Promise((resolve) => setTimeout(resolve, 100)); // Poll every 100ms\n }\n logger.info(`${this.instanceNameWithSuffix} - Subscriber set to passive and queue drained.`);\n resolve(mqttWorkerData);\n });\n }\n\n /**\n * Processes and publishes MQTT messages based on the selected message mode.\n *\n * @param mqttMessage - The MQTT message object.\n * @param mode - The message mode (Raw, Delta, or Both).\n */\n public publishMqttMessage(mqttMessage: IMqttMessage | null, mode: MessageMode = MessageMode.Raw) {\n if (mqttMessage) {\n if (mqttMessage.packet) {\n const time = UnsPacket.formatToISO8601(new Date());\n switch (mode) {\n case MessageMode.Raw: {\n this.processAndEnqueueMessage(mqttMessage, time, false);\n break;\n }\n case MessageMode.Delta: {\n const deltaMessage = { ...mqttMessage };\n deltaMessage.attribute = `${mqttMessage.attribute}-delta`;\n deltaMessage.description = `${mqttMessage.description} (delta)`;\n this.processAndEnqueueMessage(deltaMessage, time, true);\n break;\n }\n case MessageMode.Both: {\n this.processAndEnqueueMessage(mqttMessage, time, false);\n const deltaMessageBoth = { ...mqttMessage };\n deltaMessageBoth.attribute = `${mqttMessage.attribute}-delta`;\n deltaMessageBoth.description = `${mqttMessage.description} (delta)`;\n this.processAndEnqueueMessage(deltaMessageBoth, time, true);\n break;\n }\n } \n } else {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing mqtt message: mqttMessage.packet must be defined.`);\n }\n } else {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing mqtt message: mqttMessage must be defined.`);\n }\n }\n\n /**\n * Publishes a message to a specified topic.\n *\n * @param topic - The MQTT topic.\n * @param message - The message to publish.\n * @returns A promise that resolves when enqueued.\n */\n public publishMessage(topic: string, message: string): Promise<void> {\n return this.enqueueMessageToWorkerQueue(topic, message);\n }\n\n /**\n * Parses an MQTT packet from a JSON string.\n *\n * @param mqttPacket - The MQTT packet string.\n * @returns A parsed IUnsPacket object or null.\n */\n public parseMqttPacket(mqttPacket: string): IUnsPacket | null {\n return UnsPacket.parseMqttPacket(mqttPacket, this.instanceNameWithSuffix);\n }\n\n /**\n * Subscribes asynchronously to one or more topics.\n *\n * @param topics - A topic or list of topics.\n */\n public subscribeAsync(topics: string | string[]): void {\n this.worker.postMessage({ command: \"subscribeAsync\", topics });\n }\n\n /**\n * Unsubscribes asynchronously from the given topics.\n *\n * @param topics - A list of topics.\n */\n public unsubscribeAsync(topics: string[]): void {\n this.worker.postMessage({ command: \"unsubscribeAsync\", topics });\n }\n\n /**\n * Processes and enqueues a message to the worker queue, including handling\n * sequencing, value differences, and tracking of unique topics.\n *\n * @param msg - The MQTT message to process.\n * @param time - The timestamp.\n * @param valueIsCumulative - Whether the value is cumulative.\n */\n private async processAndEnqueueMessage(msg: IMqttMessage, time: string, valueIsCumulative: boolean = false): Promise<void> {\n try {\n const attributeType =\n msg.packet.message.data ? UnsAttributeType.Data :\n msg.packet.message.event ? UnsAttributeType.Event :\n msg.packet.message.table ? UnsAttributeType.Table : null;\n \n let dataGroup = \"\";\n if (attributeType == UnsAttributeType.Data)\n dataGroup = msg.packet.message.data.dataGroup ?? \"\";\n if (attributeType == UnsAttributeType.Table)\n dataGroup = msg.packet.message.table.dataGroup ?? \"\";\n if (attributeType == UnsAttributeType.Event)\n dataGroup = msg.packet.message.event.dataGroup ?? \"\";\n\n const { objectType, objectId, asset } = this.resolveObjectIdentity(msg);\n const normalizedTopic = this.normalizeTopicWithObject(msg.topic);\n msg.topic = normalizedTopic;\n\n this.registerUniqueTopic({\n timestamp: time,\n topic: msg.topic,\n attribute: msg.attribute,\n attributeType: attributeType,\n description: msg.description,\n tags: msg.tags,\n attributeNeedsPersistence: msg.attributeNeedsPersistence,\n dataGroup,\n asset,\n objectType,\n objectId\n });\n\n const publishTopic = `${msg.topic}${objectType ? `${objectType}/` : \"\"}${objectId ? `${objectId}/` : \"\"}${msg.attribute}`;\n const sequenceId = this.currentSequenceId.get(msg.topic) ?? 0;\n this.currentSequenceId.set(msg.topic, sequenceId + 1);\n msg.packet.sequenceId = sequenceId;\n\n if (msg.packet.message.data) {\n const newValue = msg.packet.message.data.value;\n const newUom: MeasurementUnit = msg.packet.message.data.uom;\n const lastValueEntry = this.lastValues.get(publishTopic);\n const currentTime = new Date(msg.packet.message.data.time);\n\n if (lastValueEntry) {\n const intervalBetweenMessages = currentTime.getTime() - lastValueEntry.timestamp.getTime();\n const lastValue = lastValueEntry.value;\n this.lastValues.set(publishTopic, { value: newValue, uom: newUom, timestamp: currentTime });\n // Compute the delta and manage cumulative resets\n if (valueIsCumulative == true && typeof newValue === \"number\" && typeof lastValue === \"number\") {\n // Skip if newValue is 0 (likely a glitch)\n if (newValue === 0) {\n return; // Don't process or enqueue\n }\n const delta = newValue - lastValue;\n msg.packet.message.data.value = delta < 0 ? newValue : delta;\n }\n msg.packet.interval = intervalBetweenMessages;\n await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));\n } else {\n this.lastValues.set(publishTopic, { value: newValue, uom: newUom, timestamp: currentTime });\n logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate interval on topic ${publishTopic}`);\n if (valueIsCumulative === false) {\n await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));\n } else {\n logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate difference on value in data for topic ${publishTopic}`);\n }\n }\n } else if (msg.packet.message.command) {\n await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));\n } else if (msg.packet.message.event) {\n await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));\n } else if (msg.packet.message.table) {\n await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));\n }\n } catch (error: any) {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing message to topic ${msg.topic}${msg.attribute}: ${error.message}`);\n }\n }\n\n /**\n * Stops the UnsProxy instance and cleans up resources.\n */\n public async stop(): Promise<void> {\n super.stop();\n // Terminate the worker thread if it exists.\n if (this.worker) {\n try {\n const exitCode = await this.worker.terminate();\n logger.info(`${this.instanceNameWithSuffix} - Worker terminated with exit code ${exitCode}`);\n } catch (error: any) {\n logger.error(`${this.instanceNameWithSuffix} - Error terminating worker: ${error.message}`);\n }\n }\n \n // Optionally, handle any pending enqueues.\n for (const [id, pending] of this.pendingEnqueues) {\n pending.reject(new Error(\"UnsProxy has been stopped\"));\n this.pendingEnqueues.delete(id);\n }\n }\n\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uns-kit/core",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Core utilities and runtime building blocks for UNS-based realtime transformers.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-config.d.ts","sourceRoot":"","sources":["../src/app-config.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-config.js","sourceRoot":"","sources":["../src/app-config.ts"],"names":[],"mappings":"","sourcesContent":["/* Auto-generated. Do not edit by hand. */\nexport type AppConfig = {\n uns: {\n graphql: string;\n rest: string;\n instanceMode?: \"wait\" | \"force\" | \"handover\";\n processName?: string | undefined;\n handover?: boolean;\n jwksWellKnownUrl?: string | undefined;\n kidWellKnownUrl?: string | undefined;\n env?: \"dev\" | \"staging\" | \"test\" | \"prod\";\n };\n input?: {\n host: string | ({\n /** Use the supplied host or IP address. */\n provider: \"inline\";\n /** Host or IP address that should be used directly. */\n value: string;\n } | {\n /** Resolve the host from an external mapping. */\n provider: \"external\";\n /** Identifier used when resolving the host from HostResolverOptions. */\n key: string;\n /** Allow the external host to be missing without throwing during resolution. */\n optional?: boolean | undefined;\n /** Fallback host when optional is true and the external entry is missing. */\n default?: string | undefined;\n } | {\n /** Resolve the host from local network interfaces. */\n provider: \"system\";\n /** Address family to return when scanning interfaces. */\n family?: \"IPv4\" | \"IPv6\";\n /** Specific interface to read (falls back to the first match when omitted). */\n interfaceName?: string | undefined;\n /** Allow the interface lookup to fail without throwing during resolution. */\n optional?: boolean | undefined;\n /** Fallback host/IP when optional is true and no interface matches. */\n default?: string | undefined;\n });\n username?: string | undefined;\n password?: (string | ({\n /** Load the secret from an environment variable. */\n provider: \"env\";\n /** Name of the environment variable to read. */\n key: string;\n /** Allow the variable to be absent without throwing during resolution. */\n optional?: boolean | undefined;\n /** Fallback value when optional is true and the variable is missing. */\n default?: string | undefined;\n } | {\n /** Load the secret from Infisical. */\n provider: \"infisical\";\n /** Secret folder path in Infisical, e.g. '/app/database'. */\n path: string;\n /** Secret key/name inside the given path. */\n key: string;\n /** Allow the secret to be absent without throwing during resolution. */\n optional?: boolean | undefined;\n /** Infisical environment override (defaults to current mode if omitted). */\n environment?: string | undefined;\n /** Optional Infisical project identifier when not using the default. */\n projectId?: string | undefined;\n /** Fallback value when the secret is missing and optional resolution is allowed. */\n default?: string | undefined;\n })) | undefined;\n clientId?: string | undefined;\n } | undefined;\n output?: {\n host: string | ({\n /** Use the supplied host or IP address. */\n provider: \"inline\";\n /** Host or IP address that should be used directly. */\n value: string;\n } | {\n /** Resolve the host from an external mapping. */\n provider: \"external\";\n /** Identifier used when resolving the host from HostResolverOptions. */\n key: string;\n /** Allow the external host to be missing without throwing during resolution. */\n optional?: boolean | undefined;\n /** Fallback host when optional is true and the external entry is missing. */\n default?: string | undefined;\n } | {\n /** Resolve the host from local network interfaces. */\n provider: \"system\";\n /** Address family to return when scanning interfaces. */\n family?: \"IPv4\" | \"IPv6\";\n /** Specific interface to read (falls back to the first match when omitted). */\n interfaceName?: string | undefined;\n /** Allow the interface lookup to fail without throwing during resolution. */\n optional?: boolean | undefined;\n /** Fallback host/IP when optional is true and no interface matches. */\n default?: string | undefined;\n });\n username?: string | undefined;\n password?: (string | ({\n /** Load the secret from an environment variable. */\n provider: \"env\";\n /** Name of the environment variable to read. */\n key: string;\n /** Allow the variable to be absent without throwing during resolution. */\n optional?: boolean | undefined;\n /** Fallback value when optional is true and the variable is missing. */\n default?: string | undefined;\n } | {\n /** Load the secret from Infisical. */\n provider: \"infisical\";\n /** Secret folder path in Infisical, e.g. '/app/database'. */\n path: string;\n /** Secret key/name inside the given path. */\n key: string;\n /** Allow the secret to be absent without throwing during resolution. */\n optional?: boolean | undefined;\n /** Infisical environment override (defaults to current mode if omitted). */\n environment?: string | undefined;\n /** Optional Infisical project identifier when not using the default. */\n projectId?: string | undefined;\n /** Fallback value when the secret is missing and optional resolution is allowed. */\n default?: string | undefined;\n })) | undefined;\n clientId?: string | undefined;\n } | undefined;\n infra: {\n host: string | ({\n /** Use the supplied host or IP address. */\n provider: \"inline\";\n /** Host or IP address that should be used directly. */\n value: string;\n } | {\n /** Resolve the host from an external mapping. */\n provider: \"external\";\n /** Identifier used when resolving the host from HostResolverOptions. */\n key: string;\n /** Allow the external host to be missing without throwing during resolution. */\n optional?: boolean | undefined;\n /** Fallback host when optional is true and the external entry is missing. */\n default?: string | undefined;\n } | {\n /** Resolve the host from local network interfaces. */\n provider: \"system\";\n /** Address family to return when scanning interfaces. */\n family?: \"IPv4\" | \"IPv6\";\n /** Specific interface to read (falls back to the first match when omitted). */\n interfaceName?: string | undefined;\n /** Allow the interface lookup to fail without throwing during resolution. */\n optional?: boolean | undefined;\n /** Fallback host/IP when optional is true and no interface matches. */\n default?: string | undefined;\n });\n username?: string | undefined;\n password?: (string | ({\n /** Load the secret from an environment variable. */\n provider: \"env\";\n /** Name of the environment variable to read. */\n key: string;\n /** Allow the variable to be absent without throwing during resolution. */\n optional?: boolean | undefined;\n /** Fallback value when optional is true and the variable is missing. */\n default?: string | undefined;\n } | {\n /** Load the secret from Infisical. */\n provider: \"infisical\";\n /** Secret folder path in Infisical, e.g. '/app/database'. */\n path: string;\n /** Secret key/name inside the given path. */\n key: string;\n /** Allow the secret to be absent without throwing during resolution. */\n optional?: boolean | undefined;\n /** Infisical environment override (defaults to current mode if omitted). */\n environment?: string | undefined;\n /** Optional Infisical project identifier when not using the default. */\n projectId?: string | undefined;\n /** Fallback value when the secret is missing and optional resolution is allowed. */\n default?: string | undefined;\n })) | undefined;\n clientId?: string | undefined;\n };\n devops?: {\n provider?: string | undefined;\n organization: string;\n project?: string | undefined;\n } | undefined;\n}\n"]}