From dd97e989a8381146f6e4d9e4dcbe1f4aa2b1a7be Mon Sep 17 00:00:00 2001 From: danielpeintner Date: Thu, 21 Mar 2024 11:57:37 +0100 Subject: [PATCH 1/5] docs: update readmes to point to new location --- packages/td-tools/README.md | 2 + packages/td-tools/src/util/README.md | 103 +-------------------------- 2 files changed, 3 insertions(+), 102 deletions(-) diff --git a/packages/td-tools/README.md b/packages/td-tools/README.md index f0a0f6936..10f38758c 100644 --- a/packages/td-tools/README.md +++ b/packages/td-tools/README.md @@ -6,6 +6,8 @@ Current Maintainer(s): [@danielpeintner](https://github.com/danielpeintner) [@re In the following example it is shown how td-tools of node-wot can be used. +Note: Some additional tooling (e.g., AAS AID, TD to AsyncAPI Converter) can be found in its own repository (see https://github.com/eclipse-thingweb/td-tools). + ### Prerequisites - `npm install @node-wot/td-tools` diff --git a/packages/td-tools/src/util/README.md b/packages/td-tools/src/util/README.md index 9330cd706..78cd5a2e9 100644 --- a/packages/td-tools/src/util/README.md +++ b/packages/td-tools/src/util/README.md @@ -2,105 +2,4 @@ ## Asset Interface Description -The [IDTA Asset Interface Description (AID) working group](https://github.com/admin-shell-io/submodel-templates/tree/main/development/Asset%20Interface%20Description/1/0) defines a submodel that can be used to describe the asset's service interface or asset's related service interfaces. The current AID working assumptions reuse existing definitions from [WoT Thing Descriptions](https://www.w3.org/TR/wot-thing-description11/) and hence it is possible to consume AAS with AID definitions with node-wot (e.g., read/subscribe live data of the asset and/or associated service). - -### Sample Applications - -#### Prerequisites - -- `npm install @node-wot/td-tools` -- `npm install @node-wot/core` -- `npm install @node-wot/binding-http` - -#### AAS/AID to WoT TD - -The file `counterHTTP.json` describes the counter sample in AAS/AID format for http binding. The `AssetInterfaceDescriptionUtil` utility class allows to transform the AID format to a valid WoT TD format which in the end can be properly consumed by node-wot. - -The example `aid-to-td.js` tries to transform an AID submodel (from an AAS file) into a regular WoT TD. -Note: Besides converting the AID submodel it is also possible to convert a full AAS file (see `transformTD2AAS(...)`). - -```js -// aid-to-td.js -const fs = require("fs/promises"); // to read JSON file in AID format - -Servient = require("@node-wot/core").Servient; -HttpClientFactory = require("@node-wot/binding-http").HttpClientFactory; - -// AID Util -AssetInterfaceDescriptionUtil = require("@node-wot/td-tools").AssetInterfaceDescriptionUtil; - -// create Servient and add HTTP binding -let servient = new Servient(); -servient.addClientFactory(new HttpClientFactory(null)); - -let assetInterfaceDescriptionUtil = new AssetInterfaceDescriptionUtil(); - -async function example() { - try { - const aas = await fs.readFile("counterHTTP.json", { - encoding: "utf8", - }); - // pick AID submodel - const aid = JSON.stringify(JSON.parse(aas).submodels[0]); - - // transform AID to WoT TD - const tdAID = assetInterfaceDescriptionUtil.transformSM2TD(aid, `{"title": "counter"}`); - // Note: transformSM2TD() may have up to 3 input parameters - // * aid (required): AID submodel in JSON format - // * template (optional): Initial TD template - // * submodelRegex (optional): Submodel filter based on regular expression - // e.g., filtering HTTP only by calling transformAAS2TD(aas, `{}`, "HTTP") - - // do work as usual - const WoT = await servient.start(); - const thing = await WoT.consume(JSON.parse(tdAID)); - - // read property count - const read1 = await thing.readProperty("count"); - console.log("count value is: ", await read1.value()); - } catch (err) { - console.log(err); - } -} - -// launch example -example(); -``` - -#### WoT TD to AAS/AID - -The example `td-to-aid.js` tries to load the online counter TD and converts it to an AID submodel in JSON format. -Note: Besides converting it into an AID submodel it is also possible to convert it into a full AAS form (see `transformTD2AAS(...)`). - -```js -// td-to-aid.js -AssetInterfaceDescriptionUtil = require("@node-wot/td-tools").AssetInterfaceDescriptionUtil; - -let assetInterfaceDescriptionUtil = new AssetInterfaceDescriptionUtil(); - -async function example() { - try { - const response = await fetch("http://plugfest.thingweb.io:8083/counter"); - const counterTD = await response.json(); - - const sm = assetInterfaceDescriptionUtil.transformTD2SM(JSON.stringify(counterTD), ["http", "coap"]); - - // print JSON format of AID submodel - console.log(sm); - } catch (err) { - console.log(err); - } -} - -// launch example -example(); -``` - -#### Run the sample scripts - -`node aid-to-td.js` -... will show the counter value retrieved from http://plugfest.thingweb.io:8083/counter/properties/count -Note: make sure that the file `counterHTTP.json` is in the same folder as the script. - -`node td-to-aid.js` -... will show the online counter in AAS/AID JSON format (compliant with AAS V3.0 and can be imported by AASX Package Explorer). +Note: The AID tooling has been moved to its own repository (see https://github.com/eclipse-thingweb/td-tools/tree/main/node/aas-aid). From 24de8eae90d1c0196e3409f9e03b3cd0e29a1123 Mon Sep 17 00:00:00 2001 From: danielpeintner Date: Thu, 21 Mar 2024 12:03:14 +0100 Subject: [PATCH 2/5] refactor: remove AID tooling code and tests --- .../src/util/asset-interface-description.ts | 1593 ------- packages/td-tools/test/util/AIDSchema.json | 3727 ----------------- packages/td-tools/test/util/counterHTTP.json | 824 ---- .../td-tools/test/util/inverterModbus.json | 291 -- 4 files changed, 6435 deletions(-) delete mode 100644 packages/td-tools/src/util/asset-interface-description.ts delete mode 100644 packages/td-tools/test/util/AIDSchema.json delete mode 100644 packages/td-tools/test/util/counterHTTP.json delete mode 100644 packages/td-tools/test/util/inverterModbus.json diff --git a/packages/td-tools/src/util/asset-interface-description.ts b/packages/td-tools/src/util/asset-interface-description.ts deleted file mode 100644 index 2aeb5c768..000000000 --- a/packages/td-tools/src/util/asset-interface-description.ts +++ /dev/null @@ -1,1593 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and - * Document License (2015-05-13) which is available at - * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document. - * - * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513 - ********************************************************************************/ - -import Thing from "../thing-description"; -import * as TD from "../thing-description"; -import { SecurityScheme } from "wot-thing-description-types"; -import * as TDParser from "../td-parser"; - -import debug from "debug"; -import { ThingDescription } from "wot-typescript-definitions"; -import { FormElementBase, PropertyElement } from "wot-thing-model-types"; -import isAbsoluteUrl = require("is-absolute-url"); -import URLToolkit = require("url-toolkit"); -const namespace = "node-wot:td-tools:asset-interface-description-util"; -const logDebug = debug(`${namespace}:debug`); -const logInfo = debug(`${namespace}:info`); -const logError = debug(`${namespace}:error`); - -/** - * Utilities around Asset Interface Description - * https://github.com/admin-shell-io/submodel-templates/tree/main/development/Asset%20Interface%20Description/1/0 - * - * e.g, transform AAS (or AID submodel) to TD or vicerversa transform TD to AAS (or AID submodel) - * - */ - -export class AssetInterfaceDescriptionUtil { - /** - * Transform AAS in JSON format to a WoT ThingDescription (TD) - * - * @param aas input AAS in JSON format - * @param template TD template with basic desired TD template - * @param submodelRegex allows to filter submodel elements based on regex expression (e.g, "HTTP*") or full text based on idShort (e.g., "InterfaceHTTP") - * @returns transformed TD - */ - public transformAAS2TD(aas: string, template?: string, submodelRegex?: string): string { - const smInformation = this.getSubmodelInformation(aas, submodelRegex); - return this._transform(smInformation, template); - } - - /** - * Transform AID submodel definition in JSON format to a WoT ThingDescription (TD) - * - * @param aid input AID submodel in JSON format - * @param template TD template with basic desired TD template - * @param submodelRegex allows to filter submodel elements based on regex expression (e.g, "HTTP*") or full text based on idShort (e.g., "InterfaceHTTP") - * @returns transformed TD - */ - public transformSM2TD(aid: string, template?: string, submodelRegex?: string): string { - const submodel = JSON.parse(aid); - - const smInformation: SubmodelInformation = { - actions: new Map>(), - events: new Map>(), - properties: new Map>(), - endpointMetadataArray: [], - thing: new Map>(), - }; - - this.processSubmodel(smInformation, submodel, submodelRegex); - - return this._transform(smInformation, template); - } - - /** - * Transform WoT ThingDescription (TD) to AAS in JSON format - * - * @param td input TD - * @param protocols protocol prefixes of interest (e.g., ["http", "coap"]) or optional if all - * @returns transformed AAS in JSON format - */ - public transformTD2AAS(td: string, protocols?: string[]): string { - const submodel = this.transformTD2SM(td, protocols); - const submodelObj = JSON.parse(submodel); - const submodelId = submodelObj.id; - - // configuration - const aasName = "SampleAAS"; - const aasId = "https://example.com/ids/aas/7474_9002_6022_1115"; - - const aas = { - assetAdministrationShells: [ - { - idShort: this.sanitizeIdShort(aasName), - id: aasId, - assetInformation: { - assetKind: "Type", - }, - submodels: [ - { - type: "ModelReference", - keys: [ - { - type: "Submodel", - value: submodelId, - }, - ], - }, - ], - modelType: "AssetAdministrationShell", - }, - ], - submodels: [submodelObj], - conceptDescriptions: [], - }; - - return JSON.stringify(aas); - } - - /** - * Transform WoT ThingDescription (TD) to AID submodel definition in JSON format - * - * @param td input TD - * @param protocols protocol prefixes of interest (e.g., ["http", "coap"]) or optional if all - * @returns transformed AID submodel definition in JSON format - */ - public transformTD2SM(tdAsString: string, protocols?: string[]): string { - const td: ThingDescription = TDParser.parseTD(tdAsString); - - const aidID = td.id ?? "ID" + Math.random(); - - logInfo("TD " + td.title + " parsed..."); - - // collect all possible prefixes - if (protocols === undefined || protocols.length === 0) { - protocols = this.getProtocolPrefixes(td); - } - - const submdelElements = []; - for (const protocol of protocols) { - // use protocol binding prefix like "http" for name - const submodelElementIdShort = this.sanitizeIdShort( - protocol === undefined ? "Interface" : "Interface" + protocol.toUpperCase() - ); - - const supplementalSemanticIds = [this.createSemanticId("https://www.w3.org/2019/wot/td")]; - if (protocol !== undefined) { - const protocolLC = protocol.toLocaleLowerCase(); - let supplementalSemanticIdProtocolValue; - if (protocolLC.includes("modbus")) { - supplementalSemanticIdProtocolValue = "http://www.w3.org/2011/modbus"; - } else if (protocolLC.includes("mqtt")) { - supplementalSemanticIdProtocolValue = "http://www.w3.org/2011/mqtt"; - } else if (protocolLC.includes("http")) { - supplementalSemanticIdProtocolValue = "http://www.w3.org/2011/http"; - } - if (supplementalSemanticIdProtocolValue !== undefined) { - supplementalSemanticIds.push(this.createSemanticId(supplementalSemanticIdProtocolValue)); - } - } - - const values = [ - { - idShort: "title", - valueType: "xs:string", - value: td.title, - modelType: "Property", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/td#title"), - }, - this.createEndpointMetadata(td, protocol, aidID, submodelElementIdShort), // EndpointMetadata like base, security and securityDefinitions - this.createInteractionMetadata(td, protocol), // InteractionMetadata like properties, actions and events - // Note: "ExternalDescriptor" should contain file values --> not applicable to TD - /* { - idShort: "ExternalDescriptor", - semanticId: this.createSemanticId( - "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/ExternalDescriptor" - ), - // embeddedDataSpecifications ? - value: [], - modelType: "SubmodelElementCollection", - }, */ - ]; - if (td.created != null) { - values.push({ - idShort: "created", - valueType: "xs:dateTime", - value: td.created, - modelType: "Property", - semanticId: this.createSemanticId("http://purl.org/dc/terms/created"), - }); - } - if (td.modified != null) { - values.push({ - idShort: "modified", - valueType: "xs:dateTime", - value: td.modified, - modelType: "Property", - semanticId: this.createSemanticId("http://purl.org/dc/terms/modified"), - }); - } - if (td.support != null) { - values.push({ - idShort: "support", - valueType: "xs:anyURI", - value: td.support, - modelType: "Property", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/td#supportContact"), - }); - } - - const submdelElement = { - idShort: submodelElementIdShort, - semanticId: this.createSemanticId( - "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface" - ), - supplementalSemanticIds, - // embeddedDataSpecifications needed? - value: values, - modelType: "SubmodelElementCollection", - }; - - submdelElements.push(submdelElement); - } - - const aidObject = { - idShort: "AssetInterfacesDescription", - id: aidID, - kind: "Instance", - semanticId: this.createSemanticId("https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Submodel"), - description: [ - // TODO does this need to be an array or can it simply be a value - { - language: "en", - text: td.title, // TODO should be description, where does title go to? later on in submodel? - }, - ], - submodelElements: submdelElements, - modelType: "Submodel", - }; - - return JSON.stringify(aidObject); - } - - /** @deprecated use transformAAS2TD method instead */ - public transformToTD(aid: string, template?: string, submodelRegex?: string): string { - return this.transformAAS2TD(aid, template, submodelRegex); - } - - /* - * PRIVATE IMPLEMENTATION METHODS ARE FOLLOWING - * - */ - - private createSemanticId(value: string): object { - return { - type: "ExternalReference", - keys: [ - { - type: "GlobalReference", - value, - }, - ], - }; - } - - private replaceCharAt(str: string, index: number, char: string) { - if (index > str.length - 1) return str; - return str.substring(0, index) + char + str.substring(index + 1); - } - - private sanitizeIdShort(value: string): string { - // idShort of Referables shall only feature letters, digits, underscore ("_"); - // starting mandatory with a letter, i.e. [a-zA-Z][a-zA-Z0-9]*. - // - // see https://github.com/eclipse-thingweb/node-wot/issues/1145 - // and https://github.com/admin-shell-io/aas-specs/issues/295 - if (value != null) { - for (let i = 0; i < value.length; i++) { - const char = value.charCodeAt(i); - if (i !== 0 && char === " ".charCodeAt(0)) { - // underscore -> fine as is - } else if (char >= "0".charCodeAt(0) && char <= "9".charCodeAt(0)) { - // digit -> fine as is - } else if (char >= "A".charCodeAt(0) && char <= "Z".charCodeAt(0)) { - // small letter -> fine as is - } else if (char >= "a".charCodeAt(0) && char <= "z".charCodeAt(0)) { - // capital letter -> fine as is - } else { - // replace with underscore "_" - value = this.replaceCharAt(value, i, "_"); - } - } - } - return value; - } - - private getSimpleValueTypeXsd(value: unknown): string { - // see https://www.w3.org/TR/xmlschema-2/#built-in-datatypes - if (typeof value === "boolean") { - return "xs:boolean"; - } else if (typeof value === "number") { - const number = Number(value); - // TODO XSD can be even more fine-grained - if (Number.isInteger(number)) { - // int is ·derived· from long by setting the value of ·maxInclusive· to be 2147483647 and ·minInclusive· to be -2147483648 - if (number <= 2147483647 && number >= -2147483648) { - return "xs:int"; - } else { - return "xs:integer"; - } - } else { - return "xs:double"; - } - } else { - return "xs:string"; - } - } - - private getProtocolPrefixes(td: ThingDescription): string[] { - const protocols: string[] = []; - - if (td.properties) { - for (const propertyKey in td.properties) { - const property = td.properties[propertyKey]; - this.updateProtocolPrefixes(property.forms, protocols); - } - } - if (td.actions) { - for (const actionKey in td.actions) { - const action = td.actions[actionKey]; - this.updateProtocolPrefixes(action.forms, protocols); - } - } - if (td.events) { - for (const eventKey in td.events) { - const event = td.events[eventKey]; - this.updateProtocolPrefixes(event.forms, protocols); - } - } - - return protocols; - } - - private updateProtocolPrefixes(forms: [FormElementBase, ...FormElementBase[]], protocols: string[]): void { - if (forms != null) { - for (const interactionForm of forms) { - if (interactionForm.href != null) { - const positionColon = interactionForm.href.indexOf(":"); - if (positionColon > 0) { - const prefix = interactionForm.href.substring(0, positionColon); - if (!protocols.includes(prefix)) { - protocols.push(prefix); - } - } - } - } - } - } - - private getBaseFromEndpointMetadata(endpointMetadata?: Record): string { - if (endpointMetadata?.value instanceof Array) { - for (const v of endpointMetadata.value) { - if (v.idShort === "base") { - // e.g., "value": "modbus+tcp://192.168.1.187:502" - return v.value; - } - } - } - return "undefined"; // TODO what is th right value if information cannot be found - } - - private getContentTypeFromEndpointMetadata(endpointMetadata?: Record): string { - if (endpointMetadata?.value instanceof Array) { - for (const v of endpointMetadata.value) { - if (v.idShort === "contentType") { - // e.g., "value": "application/octet-stream;byteSeq=BIG_ENDIAN" - return v.value; - } - } - } - return ""; // TODO what is the right value if information cannot be found - } - - private getModbusMostSignificantByteFromEndpointMetadata( - endpointMetadata?: Record - ): string | undefined { - if (endpointMetadata?.value instanceof Array) { - for (const v of endpointMetadata.value) { - if (v.idShort === "modv_mostSignificantByte") { - return v.value; - } - } - } - return undefined; - } - - private getModbusMostSignificantWordFromEndpointMetadata( - endpointMetadata?: Record - ): string | undefined { - if (endpointMetadata?.value instanceof Array) { - for (const v of endpointMetadata.value) { - if (v.idShort === "modv_mostSignificantWord") { - return v.value; - } - } - } - return undefined; - } - - private updateRootMetadata(thing: Thing, endpointMetadata?: Record) { - const securityDefinitions: { - [k: string]: SecurityScheme; - } = {}; - const security: string[] = []; - - if (endpointMetadata?.value instanceof Array) { - for (const v of endpointMetadata.value) { - if (v.idShort === "base") { - thing.base = v.value; - } else if (v.idShort === "securityDefinitions") { - if (v.value instanceof Array) { - for (const securityDefinitionsValues of v.value) { - if (securityDefinitionsValues.idShort != null) { - // key - if (securityDefinitionsValues.value instanceof Array) { - for (const securityDefinitionsValue of securityDefinitionsValues.value) { - if (securityDefinitionsValue.idShort === "scheme") { - if (securityDefinitionsValue.value != null) { - const ss: SecurityScheme = { scheme: securityDefinitionsValue.value }; - securityDefinitions[securityDefinitionsValues.idShort] = ss; - } - } - } - } - } - } - } - } else if (v.idShort === "security") { - if (v.value instanceof Array) { - for (const securityValue of v.value) { - if (securityValue.value != null && securityValue.value.keys instanceof Array) { - // e.g., - // { - // "type": "SubmodelElementCollection", - // "value": "nosec_sc" - // } - const key = securityValue.value.keys[securityValue.value.keys.length - 1]; // last path - if (key.value != null) { - security.push(key.value); - } - } - } - } - } - } - } - - thing.securityDefinitions = securityDefinitions; - thing.security = security as string | [string, ...string[]]; - } - - private createInteractionForm(vi: AASInteraction, addSecurity: boolean): TD.Form { - const form: TD.Form = { - href: this.getBaseFromEndpointMetadata(vi.endpointMetadata), - contentType: this.getContentTypeFromEndpointMetadata(vi.endpointMetadata), - }; - - // special treatment for global definitions - // besides contentType there is the AID possibility for mostSignificantByte and mostSignificantWord (Modbus) - const mostSignificantByte = this.getModbusMostSignificantByteFromEndpointMetadata(vi.endpointMetadata); - if (mostSignificantByte != null) { - form["modv:mostSignificantByte"] = mostSignificantByte === "true" || mostSignificantByte === "1"; - } - const mostSignificantWord = this.getModbusMostSignificantWordFromEndpointMetadata(vi.endpointMetadata); - if (mostSignificantWord != null) { - form["modv:mostSignificantWord"] = mostSignificantWord === "true" || mostSignificantWord === "1"; - } - - if (addSecurity) { - // XXX need to add security at form level at all ? - logError("security at form level not added/present"); - /* - const securitySchemes = this.getSecurityDefinitionsFromEndpointMetadata(vi.endpointMetadata); - if (securitySchemes === undefined) { - form.security = [0 + "_sc"]; - } else { - if (vi.secNamesForEndpoint) { - form.security = vi.secNamesForEndpoint as [string, ...string[]]; - } - } - */ - } - if (vi.interaction.value instanceof Array) { - for (const iv of vi.interaction.value) { - if (iv.idShort === "forms") { - if (iv.value instanceof Array) { - for (const v of iv.value) { - // Binding - if (v.idShort === "href") { - if (v.value != null) { - const hrefValue: string = v.value; - if (isAbsoluteUrl(hrefValue)) { - form.href = hrefValue; - } else if (form.href && form.href.length > 0) { - form.href = URLToolkit.buildAbsoluteURL(form.href, hrefValue); - } else { - // silently ignore error case - // (no proper base and relative local href) - form.href = hrefValue; - } - } - } else if (typeof v.idShort === "string" && v.idShort.length > 0) { - // pick *any* value (and possibly override, e.g. contentType) - if (v.value != null) { - // Note: AID does not allow idShort to contain values with colon (i.e., ":") --> "_" used instead - // --> THIS MAY LEAD TO PROBLEMS BUT THAT'S HOW IT IS SPECIFIED - const tdTerm = (v.idShort as string).replace("_", ":"); - form[tdTerm] = v.value; - // use valueType to convert the string value - // TODO Should we add/support all value's (e.g., dataMapping might be empty array) ? - if ( - v.valueType != null && - v.valueType.dataObjectType != null && - v.valueType.dataObjectType.name != null && - typeof v.valueType.dataObjectType.name === "string" - ) { - // XSD schemaTypes, https://www.w3.org/TR/xmlschema-2/#built-in-datatypes - switch (v.valueType.dataObjectType.name) { - case "boolean": - form[tdTerm] = form[v.value] === "true"; - break; - case "float": - case "double": - case "decimal": - case "integer": - case "nonPositiveInteger": - case "negativeInteger": - case "long": - case "int": - case "short": - case "byte": - case "nonNegativeInteger": - case "unsignedLong": - case "unsignedInt": - case "unsignedShort": - case "unsignedByte": - case "positiveInteger": - form[tdTerm] = Number(form[v.value]); - break; - // TODO handle more XSD types ? - } - } - } - } - } - } - } - } - } - return form; - } - - private processSubmodel( - smInformation: SubmodelInformation, - submodel: Record, - submodelRegex?: string - ): void { - if ( - submodel instanceof Object && - submodel.idShort != null && - submodel.idShort === "AssetInterfacesDescription" - ) { - if (submodel.submodelElements instanceof Array) { - for (const submodelElement of submodel.submodelElements) { - if (submodelElement instanceof Object) { - logDebug("SubmodelElement.idShort: " + submodelElement.idShort); - if (typeof submodelRegex === "string" && submodelRegex.length > 0) { - const regex = new RegExp(submodelRegex); - if (!regex.test(submodelElement.idShort)) { - logInfo("submodel not of interest"); - continue; - } - } - - this.processSubmodelElement(smInformation, submodelElement); - } - } - } - } - } - - private processSubmodelElement(smInformation: SubmodelInformation, submodelElement: Record): void { - // EndpointMetadata vs. InteractionMetadata - if (submodelElement.value instanceof Array) { - // Note: iterate twice over to collect first EndpointMetadata - let endpointMetadata: Record = {}; - for (const smValue of submodelElement.value) { - if (smValue instanceof Object) { - if (smValue.idShort === "EndpointMetadata") { - logInfo("EndpointMetadata"); - // e.g., idShort: base , contentType, securityDefinitions, alternativeEndpointDescriptor? - endpointMetadata = smValue; - smInformation.endpointMetadataArray.push(endpointMetadata); - } else if (smValue.idShort === "InteractionMetadata") { - // handled later - } else if (smValue.idShort === "externalDescriptor") { - // needed? - } else { - smInformation.thing.set(smValue.idShort, smValue.value); - } - } - } - // the 2nd time look for InteractionMetadata that *need* EndpointMetadata - for (const smValue of submodelElement.value) { - if (smValue instanceof Object) { - if (smValue.idShort === "InteractionMetadata") { - logInfo("InteractionMetadata"); - if (smValue.value instanceof Array) { - for (const interactionValue of smValue.value) { - if (interactionValue.idShort === "properties") { - if (interactionValue.value instanceof Array) { - for (const iValue of interactionValue.value) { - logInfo("Property: " + iValue.idShort); - if (!smInformation.properties.has(iValue.idShort)) { - smInformation.properties.set(iValue.idShort, []); - } - const propInter: AASInteraction = { - endpointMetadata, - interaction: iValue, - }; - smInformation.properties.get(iValue.idShort)?.push(propInter); - } - } - } else if (interactionValue.idShort === "actions") { - if (interactionValue.value instanceof Array) { - for (const iValue of interactionValue.value) { - logInfo("Action: " + iValue.idShort); - if (!smInformation.actions.has(iValue.idShort)) { - smInformation.actions.set(iValue.idShort, []); - } - const actInter: AASInteraction = { - endpointMetadata, - interaction: iValue, - }; - smInformation.actions.get(iValue.idShort)?.push(actInter); - } - } - } else if (interactionValue.idShort === "events") { - if (interactionValue.value instanceof Array) { - for (const iValue of interactionValue.value) { - logInfo("Event: " + iValue.idShort); - if (!smInformation.events.has(iValue.idShort)) { - smInformation.events.set(iValue.idShort, []); - } - const evInter: AASInteraction = { - endpointMetadata, - interaction: iValue, - }; - smInformation.events.get(iValue.idShort)?.push(evInter); - } - } - } - } - } - } - } - } - } - } - - private getSubmodelInformation(aas: string, submodelRegex?: string): SubmodelInformation { - const aidModel = JSON.parse(aas); - - const smInformation: SubmodelInformation = { - actions: new Map>(), - events: new Map>(), - properties: new Map>(), - endpointMetadataArray: [], - thing: new Map>(), - }; - - if (aidModel instanceof Object && aidModel.submodels != null) { - if (aidModel.submodels instanceof Array) { - for (const submodel of aidModel.submodels) { - this.processSubmodel(smInformation, submodel, submodelRegex); - } - } - } - - return smInformation; - } - - private _transform(smInformation: SubmodelInformation, template?: string): string { - const thing: Thing = template != null ? JSON.parse(template) : {}; - - // walk over thing information and set them - for (const [key, value] of smInformation.thing) { - if (typeof value === "string") { - thing[key] = value; - } else { - // TODO what to do with non-string values? - } - } - - // required TD fields - if (thing["@context"] == null) { - thing["@context"] = "https://www.w3.org/2022/wot/td/v1.1"; - } - if (!thing.title) { - thing.title = "?TODO?"; // generate one? - } - - // Security in AID is defined for each submodel - // add "securityDefinitions" globally and add them on form level if necessary - // TODO: possible collisions for "security" names *could* be handled by cnt - if (thing.securityDefinitions == null) { - thing.securityDefinitions = {}; - } - // let cnt = 1; - const secNamesForEndpointMetadata = new Map, string[]>(); - for (const endpointMetadata of smInformation.endpointMetadataArray) { - const secNames: Array = []; - // update base, securityDefinitions, security, ... - this.updateRootMetadata(thing, endpointMetadata); - // iterate over securitySchemes - // eslint-disable-next-line unused-imports/no-unused-vars - for (const [key, value] of Object.entries(thing.securityDefinitions)) { - // TODO we could change the name to avoid name collisions. Shall we do so? - secNames.push(key); - } - secNamesForEndpointMetadata.set(endpointMetadata, secNames); - } - - // add interactions - // 1. properties - logDebug("########### PROPERTIES (" + smInformation.properties.size + ")"); - if (smInformation.properties.size > 0) { - thing.properties = {}; - - for (const [key, value] of smInformation.properties.entries()) { - logInfo("Property" + key + " = " + value); - - thing.properties[key] = {}; - thing.properties[key].forms = []; - - for (const vi of value) { - for (const keyInteraction in vi.interaction) { - if (keyInteraction === "description") { - const aasDescription = vi.interaction[keyInteraction]; - // convert - // - // [{ - // "language": "en", - // "text": "Current counter value" - // }, - // { - // "language": "de", - // "text": "Derzeitiger Zählerwert" - // }] - // - // to - // - // {"en": "Current counter value", "de": "Derzeitiger Zählerwert"} - const tdDescription: Record = {}; - if (aasDescription instanceof Array) { - for (const aasDescriptionEntry of aasDescription) { - if (aasDescriptionEntry.language != null && aasDescriptionEntry.text != null) { - const language: string = aasDescriptionEntry.language; - const text: string = aasDescriptionEntry.text; - tdDescription[language] = text; - } - } - } - thing.properties[key].descriptions = tdDescription; - } else if (keyInteraction === "value") { - if (vi.interaction.value instanceof Array) { - for (const interactionValue of vi.interaction.value) - if (interactionValue.idShort === "type") { - if (interactionValue.value === "float") { - thing.properties[key].type = "number"; - } else { - thing.properties[key].type = interactionValue.value; - } - } else if (interactionValue.idShort === "range") { - if (interactionValue.min != null) { - thing.properties[key].min = interactionValue.min; - } - if (interactionValue.max != null) { - thing.properties[key].max = interactionValue.max; - } - } else if (interactionValue.idShort === "observable") { - thing.properties[key].observable = interactionValue.value === "true"; - } else if (interactionValue.idShort === "readOnly") { - thing.properties[key].readOnly = interactionValue.value === "true"; - } else if (interactionValue.idShort === "writeOnly") { - thing.properties[key].writeOnly = interactionValue.value === "true"; - } else if (interactionValue.idShort === "min_max") { - // special treatment - if (thing.properties[key].type == null) { - thing.properties[key].type = "number"; - } - if (interactionValue.min != null) { - thing.properties[key].minimum = Number(interactionValue.min); - } - if (interactionValue.max != null) { - thing.properties[key].maximum = Number(interactionValue.max); - } - } else if (interactionValue.idShort === "itemsRange") { - // special treatment - if (thing.properties[key].type == null) { - thing.properties[key].type = "array"; - } - if (interactionValue.min != null) { - thing.properties[key].minItems = Number(interactionValue.min); - } - if (interactionValue.max != null) { - thing.properties[key].maxItems = Number(interactionValue.max); - } - } else if (interactionValue.idShort === "lengthRange") { - // special treatment - if (thing.properties[key].type == null) { - thing.properties[key].type = "string"; - } - if (interactionValue.min != null) { - thing.properties[key].minLength = Number(interactionValue.min); - } - if (interactionValue.max != null) { - thing.properties[key].maxLength = Number(interactionValue.max); - } - } else if (interactionValue.idShort === "forms") { - // will be handled below - } else { - // handle other terms specifically? - const key2 = interactionValue.idShort; - thing.properties[key][key2] = interactionValue.value; - } - } - } - } - - if (vi.endpointMetadata) { - vi.secNamesForEndpoint = secNamesForEndpointMetadata.get(vi.endpointMetadata); - } - const form = this.createInteractionForm(vi, smInformation.endpointMetadataArray.length > 1); - thing.properties[key].forms.push(form); - } - } - } - - // 2. actions - logDebug("########### ACTIONS (" + smInformation.actions.size + ")"); - if (smInformation.actions.size > 0) { - thing.actions = {}; - - for (const [key, value] of smInformation.actions.entries()) { - logInfo("Action" + key + " = " + value); - - thing.actions[key] = {}; - thing.actions[key].forms = []; - - for (const vi of value) { - if (vi.endpointMetadata) { - vi.secNamesForEndpoint = secNamesForEndpointMetadata.get(vi.endpointMetadata); - } - const form = this.createInteractionForm(vi, smInformation.endpointMetadataArray.length > 1); - thing.properties[key].forms.push(form); - } - } - } - - // 3. events - logDebug("########### EVENTS (" + smInformation.events.size + ")"); - if (smInformation.events.size > 0) { - thing.events = {}; - - for (const [key, value] of smInformation.events.entries()) { - logInfo("Event " + key + " = " + value); - - thing.events[key] = {}; - thing.events[key].forms = []; - - for (const vi of value) { - if (vi.endpointMetadata) { - vi.secNamesForEndpoint = secNamesForEndpointMetadata.get(vi.endpointMetadata); - } - const form = this.createInteractionForm(vi, smInformation.endpointMetadataArray.length > 1); - thing.properties[key].forms.push(form); - } - } - } - - return JSON.stringify(thing); - } - - private createEndpointMetadata( - td: ThingDescription, - protocol: string, - submodelIdShort: string, - submodelElementIdShort: string - ): Record { - const values: Array = []; - - // base (AID requires base) - let base = td.base ?? "NO_BASE"; - if (td.base == null && td.properties) { - // do best effort if base is not specified by looking at property forms - for (const propertyKey in td.properties) { - const property: PropertyElement = td.properties[propertyKey]; - // check whether form exists for a given protocol (prefix) - const formElementPicked = this.getFormForProtocol(property, protocol); - if (formElementPicked?.href !== undefined) { - const urlParts = URLToolkit.parseURL(formElementPicked.href); - if (urlParts != null) { - // keep scheme and netLoc only - urlParts.path = urlParts.params = urlParts.query = urlParts.fragment = ""; - base = URLToolkit.buildURLFromParts(urlParts); - continue; // abort to loop over remaining properties - } - } - } - } - values.push({ - idShort: "base", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/td#baseURI"), - valueType: "xs:anyURI", - value: base, - modelType: "Property", - }); - - // TODO wrong place.. not allowed in TD spec? - /* - { - idShort: "contentType", - valueType: "xs:string", - value: "application/json", // TODO - modelType: "Property", - }, - */ - - // security - const securityValues: Array = []; - if (td.security != null) { - for (const secKey of td.security) { - securityValues.push({ - value: { - type: "ModelReference", - keys: [ - { - type: "Submodel", - value: submodelIdShort, - }, - { - type: "SubmodelElementCollection", - value: submodelElementIdShort, - }, - { - type: "SubmodelElementCollection", - value: "EndpointMetadata", - }, - { - type: "SubmodelElementCollection", - value: "securityDefinitions", - }, - { - type: "SubmodelElementCollection", - value: secKey, - }, - ], - }, - modelType: "ReferenceElement", - }); - } - } - values.push({ - idShort: "security", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/td#hasSecurityConfiguration"), - typeValueListElement: "ReferenceElement", - value: securityValues, - modelType: "SubmodelElementList", - }); - - // securityDefinitions - const securityDefinitionsValues: Array = []; - for (const secKey in td.securityDefinitions) { - const secValue: SecurityScheme = td.securityDefinitions[secKey]; - const values = []; - // scheme always - values.push({ - idShort: "scheme", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#SecurityScheme"), - valueType: "xs:string", - value: secValue.scheme, - modelType: "Property", - }); - // other security information - if (secValue.proxy != null) { - values.push({ - idShort: "proxy", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#proxy"), - valueType: "xs:string", - value: secValue.proxy, - modelType: "Property", - }); - } - if (secValue.name != null) { - values.push({ - idShort: "name", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#name"), - valueType: "xs:string", - value: secValue.name, - modelType: "Property", - }); - } - if (secValue.in != null) { - values.push({ - idShort: "in", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#in"), - valueType: "xs:string", - value: secValue.in, - modelType: "Property", - }); - } - if (secValue.qop != null) { - values.push({ - idShort: "qop", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#qop"), - valueType: "xs:string", - value: secValue.qop, - modelType: "Property", - }); - } - if (secValue.authorization != null) { - values.push({ - idShort: "authorization", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#authorization"), - valueType: "xs:string", - value: secValue.authorization, - modelType: "Property", - }); - } - if (secValue.alg != null) { - values.push({ - idShort: "alg", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#alg"), - valueType: "xs:string", - value: secValue.alg, - modelType: "Property", - }); - } - if (secValue.format != null) { - values.push({ - idShort: "format", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#format"), - valueType: "xs:string", - value: secValue.format, - modelType: "Property", - }); - } - if (secValue.identity != null) { - values.push({ - idShort: "identity", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#identity"), - valueType: "xs:string", - value: secValue.identity, - modelType: "Property", - }); - } - if (secValue.token != null) { - values.push({ - idShort: "token", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#token"), - valueType: "xs:string", - value: secValue.token, - modelType: "Property", - }); - } - if (secValue.refresh != null) { - values.push({ - idShort: "refresh", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#refresh"), - valueType: "xs:string", - value: secValue.refresh, - modelType: "Property", - }); - } - if (secValue.scopes != null) { - values.push({ - idShort: "scopes", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#scopes"), - valueType: "xs:string", - value: secValue.scopes, - modelType: "Property", - }); - } - if (secValue.flow != null) { - values.push({ - idShort: "flow", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/security#flow"), - valueType: "xs:string", - value: secValue.flow, - modelType: "Property", - }); - } - - securityDefinitionsValues.push({ - idShort: secKey, - value: values, - modelType: "SubmodelElementCollection", - }); - } - values.push({ - idShort: "securityDefinitions", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/td#definesSecurityScheme"), - value: securityDefinitionsValues, - modelType: "SubmodelElementCollection", - }); - - const endpointMetadata: Record = { - idShort: "EndpointMetadata", - semanticId: this.createSemanticId( - "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/EndpointMetadata" - ), - // embeddedDataSpecifications ? - value: values, - modelType: "SubmodelElementCollection", - }; - - return endpointMetadata; - } - - private getFormForProtocol(property: PropertyElement, protocol: string): FormElementBase | undefined { - let formElementPicked: FormElementBase | undefined; - // check whether protocol prefix exists for a form - if (property.forms) { - for (const formElementProperty of property.forms) { - if (formElementProperty.href != null && formElementProperty.href.startsWith(protocol)) { - formElementPicked = formElementProperty; - // found matching form --> abort loop - break; - } - } - } - return formElementPicked; - } - - private hasOp(form: FormElementBase, op: string): boolean { - if (form.op != null) { - if (typeof form.op === "string" && form.op === op) { - return true; - } else if (Array.isArray(form.op) && form.op.includes(op)) { - return true; - } - } - return false; - } - - private addRequiredAidTermsForForm(form: FormElementBase, protocol: string): void { - if (form == null || protocol == null) { - return; - } - if (protocol.startsWith("http")) { - // HTTP: href, htv_methodName - // default for htv:methodName depending on op, see https://w3c.github.io/wot-binding-templates/bindings/protocols/http/index.html#http-default-vocabulary-terms - const htvKey = "htv:methodName"; - if (form[htvKey] == null) { - if ( - this.hasOp(form, "readproperty") || - this.hasOp(form, "readallproperties") || - this.hasOp(form, "readmultipleproperties") - ) { - form[htvKey] = "GET"; - } else if ( - this.hasOp(form, "writeproperty") || - this.hasOp(form, "writeallproperties") || - this.hasOp(form, "writemultipleproperties") - ) { - form[htvKey] = "PUT"; - } else if (this.hasOp(form, "invokeaction")) { - form[htvKey] = "POST"; - } - } - } else if (protocol.startsWith("modbus")) { - // Modbus: href, modv_function - // default for modv:function depending on op, see https://w3c.github.io/wot-binding-templates/bindings/protocols/modbus/index.html#default-mappings - const mbKey = "modv:function"; - if (form[mbKey] == null) { - if (this.hasOp(form, "writeproperty") || this.hasOp(form, "invokeaction")) { - form[mbKey] = "writeSingleCoil"; - } else if (this.hasOp(form, "readallproperties") || this.hasOp(form, "readmultipleproperties")) { - form[mbKey] = "readHoldingRegisters"; - } else if (this.hasOp(form, "writeallproperties") || this.hasOp(form, "writemultipleproperties")) { - form[mbKey] = "writeMultipleHoldingRegisters"; - } - } - } else if (protocol.startsWith("mqtt")) { - // MQTT: href, mqv_controlPacket - // default for mqv:controlPacket depending on op, see https://w3c.github.io/wot-binding-templates/bindings/protocols/mqtt/index.html#default-mappings - const mqvKey = "mqv:controlPacket"; - if (form[mqvKey] == null) { - if ( - this.hasOp(form, "readproperty") || - this.hasOp(form, "observeproperty") || - this.hasOp(form, "readallproperties") || - this.hasOp(form, "readmultipleproperties") || - this.hasOp(form, "subscribeevent") - ) { - form[mqvKey] = "subscribe"; - } else if ( - this.hasOp(form, "writeproperty") || - this.hasOp(form, "writeallproperties") || - this.hasOp(form, "writemultipleproperties") || - this.hasOp(form, "invokeaction") - ) { - form[mqvKey] = "publish"; - } else if (this.hasOp(form, "unobserveproperty") || this.hasOp(form, "unsubscribeevent")) { - form[mqvKey] = "unsubscribe"; - } - } - } - } - - private createInteractionMetadata(td: ThingDescription, protocol: string): Record { - const properties: Array = []; - const actions: Array = []; - const events: Array = []; - - if (protocol) { - // Properties - if (td.properties) { - for (const propertyKey in td.properties) { - const property: PropertyElement = td.properties[propertyKey]; - - // check whether form exists for a given protocol (prefix) - const formElementPicked = this.getFormForProtocol(property, protocol); - if (formElementPicked === undefined) { - // do not add this property, since there will be no href of interest - continue; - } - - const propertyValues: Array = []; - // type - if (property.type != null) { - propertyValues.push({ - idShort: "type", - semanticId: this.createSemanticId("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), - valueType: "xs:string", - value: property.type, - modelType: "Property", - }); - // special AID treatment - if (property.minimum != null || property.maximum != null) { - const minMax: { [k: string]: unknown } = { - idShort: "min_max", - semanticId: this.createSemanticId( - "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/minMaxRange" - ), - supplementalSemanticIds: [], - valueType: "integer".localeCompare(property.type) === 0 ? "xs:integer" : "xs:double", - modelType: "Range", - }; - if (property.minimum != null) { - minMax.min = property.minimum.toString(); - (minMax.supplementalSemanticIds as Array).push( - this.createSemanticId("https://www.w3.org/2019/wot/json-schema#minimum") - ); - } - if (property.maximum != null) { - minMax.max = property.maximum.toString(); - (minMax.supplementalSemanticIds as Array).push( - this.createSemanticId("https://www.w3.org/2019/wot/json-schema#maximum") - ); - } - propertyValues.push(minMax); - } - if (property.minItems != null || property.maxItems != null) { - const itemsRange: { [k: string]: unknown } = { - idShort: "itemsRange", - semanticId: this.createSemanticId( - "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/itemsRange" - ), - supplementalSemanticIds: [], - valueType: "xs:integer", - modelType: "Range", - }; - if (property.minItems != null) { - itemsRange.min = property.minItems.toString(); - (itemsRange.supplementalSemanticIds as Array).push( - this.createSemanticId("https://www.w3.org/2019/wot/json-schema#minItems") - ); - } - if (property.maxItems != null) { - itemsRange.max = property.maxItems.toString(); - (itemsRange.supplementalSemanticIds as Array).push( - this.createSemanticId("https://www.w3.org/2019/wot/json-schema#maxItems") - ); - } - propertyValues.push(itemsRange); - } - if (property.minLength != null || property.maxLength != null) { - const lengthRange: { [k: string]: unknown } = { - idShort: "lengthRange", - semanticId: this.createSemanticId( - "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/lengthRange" - ), - supplementalSemanticIds: [], - valueType: "xs:integer", - modelType: "Range", - }; - if (property.minLength != null) { - lengthRange.min = property.minLength.toString(); - (lengthRange.supplementalSemanticIds as Array).push( - this.createSemanticId("https://www.w3.org/2019/wot/json-schema#minLength") - ); - } - if (property.maxLength != null) { - lengthRange.max = property.maxLength.toString(); - (lengthRange.supplementalSemanticIds as Array).push( - this.createSemanticId("https://www.w3.org/2019/wot/json-schema#maxLength") - ); - } - propertyValues.push(lengthRange); - } - } - // title - if (property.title != null) { - propertyValues.push({ - idShort: "title", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/td#title"), - valueType: "xs:string", - value: property.title, - modelType: "Property", - }); - } - // description - if (property.description != null) { - // AID deals with description in level above - } - // observable (if it deviates from the default == false only) - if (property.observable != null && property.observable === true) { - propertyValues.push({ - idShort: "observable", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/td#isObservable"), - valueType: "xs:boolean", - value: `${property.observable}`, // in AID represented as string - modelType: "Property", - }); - } - // contentMediaType - if (property.contentMediaType != null) { - propertyValues.push({ - idShort: "contentMediaType", - semanticId: this.createSemanticId( - "https://www.w3.org/2019/wot/json-schema#contentMediaType" - ), - valueType: "xs:string", - value: property.contentMediaType, - modelType: "Property", - }); - } - // TODO enum - // const - if (property.const != null) { - propertyValues.push({ - idShort: "const", - valueType: "xs:string", - value: property.const, - modelType: "Property", - }); - } - // default - if (property.default != null) { - propertyValues.push({ - idShort: "default", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/json-schema#default"), - valueType: this.getSimpleValueTypeXsd(property.default), - value: property.default, - modelType: "Property", - }); - } - // unit - if (property.unit != null) { - propertyValues.push({ - idShort: "unit", - valueType: "xs:string", - value: property.unit, - modelType: "Property", - }); - } - // TODO items - - // readOnly and writeOnly marked as EXTERNAL in AID spec - // range and others? Simply add them as is? - - // forms - if (formElementPicked != null) { - const propertyForm: Array = []; - - // TODO AID for now supports just *one* href/form - // --> pick the first one that matches protocol (other means in future?) - - // AID has required terms that need to be present always for a given interface - this.addRequiredAidTermsForForm(formElementPicked, protocol); - - // walk over string values like: "href", "contentType", "htv:methodName", ... - for (let formTerm in formElementPicked) { - let formValue = formElementPicked[formTerm]; - - // Note: node-wot uses absolute URIs *almost* everywhere but we want to use "base" in AID - // --> try to create relative href's as much as possible - if ( - formTerm === "href" && - td.base != null && - td.base.length > 0 && - typeof formValue === "string" && - formValue.startsWith(td.base) - ) { - formValue = formValue.substring(td.base.length); - } - - let semanticId; - if (formTerm === "href") { - semanticId = "https://www.w3.org/2019/wot/hypermedia#hasTarget"; - } else if (formTerm === "contentType") { - semanticId = "https://www.w3.org/2019/wot/hypermedia#forContentType"; - } else if (formTerm === "htv:methodName") { - semanticId = "https://www.w3.org/2011/http#methodName"; - } else if (formTerm === "htv:headers") { - semanticId = "https://www.w3.org/2011/http#headers"; - } else if (formTerm === "htv:fieldName") { - semanticId = "https://www.w3.org/2011/http#fieldName"; - } else if (formTerm === "htv:fieldValue") { - semanticId = "https://www.w3.org/2011/http#fieldValue"; - } else if (formTerm === "modv:function") { - semanticId = "https://www.w3.org/2019/wot/modbus#hasFunction"; - } else if (formTerm === "modv:entity") { - semanticId = "https://www.w3.org/2019/wot/modbus#hasEntity"; - } else if (formTerm === "modv:zeroBasedAddressing") { - semanticId = "https://www.w3.org/2019/wot/modbus#hasZeroBasedAddressingFlag"; - } else if (formTerm === "modv:timeout") { - semanticId = "https://www.w3.org/2019/wot/modbus#hasTimeout"; - } else if (formTerm === "modv:pollingTime") { - semanticId = "https://www.w3.org/2019/wot/modbus#hasPollingTime"; - } else if (formTerm === "modv:type") { - semanticId = "https://www.w3.org/2019/wot/modbus#hasPayloadDataType"; - } else if (formTerm === "modv:mostSignificantByte") { - semanticId = "https://www.w3.org/2019/wot/modbus#hasMostSignificantByte"; - } else if (formTerm === "modv:mostSignificantWord") { - semanticId = "https://www.w3.org/2019/wot/modbus#hasMostSignificantWord"; - } else if (formTerm === "mqv:retain") { - semanticId = "https://www.w3.org/2019/wot/mqtt#hasRetainFlag"; - } else if (formTerm === "mqv:controlPacket") { - semanticId = "https://www.w3.org/2019/wot/mqtt#ControlPacket"; - } else if (formTerm === "mqv:qos") { - semanticId = "https://www.w3.org/2019/wot/mqtt#hasQoSFlag"; - } - - // Note: AID does not allow idShort to contain values with colon (i.e., ":") --> "_" used instead - // TODO are there more characters we need to deal with? - formTerm = formTerm.replace(":", "_"); - - if ( - typeof formValue === "string" || - typeof formValue === "number" || - typeof formValue === "boolean" - ) { - // AID schema restricts terms in form to a finite set of *allowed* terms - // e.g., "op" is not allowed - // at the momement all of them have "semanticId" -> use this as check - if (semanticId !== undefined) { - propertyForm.push({ - idShort: formTerm, - semanticId: this.createSemanticId(semanticId), - valueType: this.getSimpleValueTypeXsd(formValue), - value: formValue.toString(), - modelType: "Property", - }); - } else { - // unknown AID term - /* propertyForm.push({ - idShort: formTerm, - valueType: this.getSimpleValueTypeXsd(formValue), - value: formValue.toString(), - modelType: "Property", - }); */ - } - } - - // TODO terms that are not simple types like op arrays? - } - - propertyValues.push({ - idShort: "forms", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/td#hasForm"), - value: propertyForm, - modelType: "SubmodelElementCollection", - }); - } - - let description; - if (property.descriptions) { - description = []; - for (const langKey in property.descriptions) { - const langValue = property.descriptions[langKey]; - description.push({ - language: langKey, - text: langValue, - }); - } - } else if (property.description != null) { - // fallback - description = []; - description.push({ - language: "en", // TODO where to get language identifier - text: property.description, - }); - } - - properties.push({ - idShort: propertyKey, - description, - semanticId: this.createSemanticId( - "https://admin-shell.io/idta/AssetInterfaceDescription/1/0/PropertyDefinition" - ), - supplementalSemanticIds: [this.createSemanticId("https://www.w3.org/2019/wot/td#name")], - value: propertyValues, - modelType: "SubmodelElementCollection", - }); - } - } - // Actions - if (td.actions) { - // TODO actions - TBD by AID - } - - // Events - if (td.events) { - // TODO events - TBD by AID - } - } - - const values: Array = []; - // Properties - values.push({ - idShort: "properties", - semanticId: this.createSemanticId("https://www.w3.org/2019/wot/td#PropertyAffordance"), - value: properties, - modelType: "SubmodelElementCollection", - }); - // Actions - values.push({ - idShort: "actions", - value: actions, - modelType: "SubmodelElementCollection", - }); - // Events - values.push({ - idShort: "events", - value: events, - modelType: "SubmodelElementCollection", - }); - - const interactionMetadata: Record = { - idShort: "InteractionMetadata", - semanticId: this.createSemanticId( - "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/InteractionMetadata" - ), - supplementalSemanticIds: [this.createSemanticId("https://www.w3.org/2019/wot/td#InteractionAffordance")], - // embeddedDataSpecifications ? - value: values, - modelType: "SubmodelElementCollection", - }; - - return interactionMetadata; - } -} - -interface AASInteraction { - endpointMetadata?: Record; - secNamesForEndpoint?: Array; - interaction: Record; -} - -interface SubmodelInformation { - properties: Map>; - actions: Map>; - events: Map>; - - thing: Map>; - - endpointMetadataArray: Array>; -} diff --git a/packages/td-tools/test/util/AIDSchema.json b/packages/td-tools/test/util/AIDSchema.json deleted file mode 100644 index a87e3a061..000000000 --- a/packages/td-tools/test/util/AIDSchema.json +++ /dev/null @@ -1,3727 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "allOf": [ - { - "$ref": "#/definitions/Identifiable" - }, - { - "$ref": "#/definitions/HasKind" - }, - { - "$ref": "#/definitions/HasSemantics" - }, - { - "$ref": "#/definitions/Qualifiable" - }, - { - "$ref": "#/definitions/HasDataSpecification" - } - ], - "properties": { - "idShort": { - "type": "string", - "enum": ["AssetInterfacesDescription"] - }, - "submodelElements": { - "type": "array", - "minItems": 1, - "maxItems": 3, - "uniqueItems": true, - "items": { - "anyOf": [ - { - "$ref": "#/definitions/InterfaceHTTP" - }, - { - "$ref": "#/definitions/InterfaceMQTT" - }, - { - "$ref": "#/definitions/InterfaceMODBUS" - } - ] - } - }, - "modelType": { - "const": "Submodel" - } - }, - "definitions": { - "AasSubmodelElements": { - "type": "string", - "enum": [ - "AnnotatedRelationshipElement", - "BasicEventElement", - "Blob", - "Capability", - "DataElement", - "Entity", - "EventElement", - "File", - "MultiLanguageProperty", - "Operation", - "Property", - "Range", - "ReferenceElement", - "RelationshipElement", - "SubmodelElement", - "SubmodelElementCollection", - "SubmodelElementList" - ] - }, - "AbstractLangString": { - "type": "object", - "properties": { - "language": { - "type": "string", - "pattern": "^(([a-zA-Z]{2,3}(-[a-zA-Z]{3}(-[a-zA-Z]{3}){2})?|[a-zA-Z]{4}|[a-zA-Z]{5,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-(([a-zA-Z0-9]){5,8}|[0-9]([a-zA-Z0-9]){3}))*(-[0-9A-WY-Za-wy-z](-([a-zA-Z0-9]){2,8})+)*(-[xX](-([a-zA-Z0-9]){1,8})+)?|[xX](-([a-zA-Z0-9]){1,8})+|((en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang)))$" - }, - "text": { - "type": "string", - "minLength": 1, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - } - }, - "required": ["language", "text"] - }, - "AdministrativeInformation": { - "allOf": [ - { - "$ref": "#/definitions/HasDataSpecification" - }, - { - "properties": { - "version": { - "type": "string", - "allOf": [ - { - "minLength": 1, - "maxLength": 4 - }, - { - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - { - "pattern": "^(0|[1-9][0-9]*)$" - } - ] - }, - "revision": { - "type": "string", - "allOf": [ - { - "minLength": 1, - "maxLength": 4 - }, - { - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - { - "pattern": "^(0|[1-9][0-9]*)$" - } - ] - }, - "creator": { - "$ref": "#/definitions/Reference" - }, - "templateId": { - "type": "string", - "minLength": 1, - "maxLength": 2000, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - } - } - } - ] - }, - "DataElement": { - "$ref": "#/definitions/SubmodelElement" - }, - "DataElement_choice": { - "oneOf": [ - { - "$ref": "#/definitions/File" - }, - { - "$ref": "#/definitions/Property" - }, - { - "$ref": "#/definitions/Range" - }, - { - "$ref": "#/definitions/ReferenceElement" - } - ] - }, - "DataSpecificationContent": { - "type": "object", - "properties": { - "modelType": { - "$ref": "#/definitions/ModelType" - } - }, - "required": ["modelType"] - }, - "DataSpecificationContent_choice": { - "oneOf": [ - { - "$ref": "#/definitions/DataSpecificationIec61360" - } - ] - }, - "DataSpecificationIec61360": { - "allOf": [ - { - "$ref": "#/definitions/DataSpecificationContent" - }, - { - "properties": { - "preferredName": { - "type": "array", - "items": { - "$ref": "#/definitions/LangStringPreferredNameTypeIec61360" - }, - "minItems": 1 - }, - "shortName": { - "type": "array", - "items": { - "$ref": "#/definitions/LangStringShortNameTypeIec61360" - }, - "minItems": 1 - }, - "unit": { - "type": "string", - "minLength": 1, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - "unitId": { - "$ref": "#/definitions/Reference" - }, - "sourceOfDefinition": { - "type": "string", - "minLength": 1, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - "symbol": { - "type": "string", - "minLength": 1, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - "dataType": { - "$ref": "#/definitions/DataTypeIec61360" - }, - "definition": { - "type": "array", - "items": { - "$ref": "#/definitions/LangStringDefinitionTypeIec61360" - }, - "minItems": 1 - }, - "valueFormat": { - "type": "string", - "minLength": 1, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - "valueList": { - "$ref": "#/definitions/ValueList" - }, - "value": { - "type": "string", - "minLength": 1, - "maxLength": 2000, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - "levelType": { - "$ref": "#/definitions/LevelType" - }, - "modelType": { - "const": "DataSpecificationIec61360" - } - }, - "required": ["preferredName"] - } - ] - }, - "DataTypeDefXsd": { - "type": "string", - "enum": [ - "xs:anyURI", - "xs:base64Binary", - "xs:boolean", - "xs:byte", - "xs:date", - "xs:dateTime", - "xs:decimal", - "xs:double", - "xs:duration", - "xs:float", - "xs:gDay", - "xs:gMonth", - "xs:gMonthDay", - "xs:gYear", - "xs:gYearMonth", - "xs:hexBinary", - "xs:int", - "xs:integer", - "xs:long", - "xs:negativeInteger", - "xs:nonNegativeInteger", - "xs:nonPositiveInteger", - "xs:positiveInteger", - "xs:short", - "xs:string", - "xs:time", - "xs:unsignedByte", - "xs:unsignedInt", - "xs:unsignedLong", - "xs:unsignedShort" - ] - }, - "DataTypeIec61360": { - "type": "string", - "enum": [ - "BLOB", - "BOOLEAN", - "DATE", - "FILE", - "HTML", - "INTEGER_COUNT", - "INTEGER_CURRENCY", - "INTEGER_MEASURE", - "IRDI", - "IRI", - "RATIONAL", - "RATIONAL_MEASURE", - "REAL_COUNT", - "REAL_CURRENCY", - "REAL_MEASURE", - "STRING", - "STRING_TRANSLATABLE", - "TIME", - "TIMESTAMP" - ] - }, - "EmbeddedDataSpecification": { - "type": "object", - "properties": { - "dataSpecification": { - "$ref": "#/definitions/Reference" - }, - "dataSpecificationContent": { - "$ref": "#/definitions/DataSpecificationContent_choice" - } - }, - "required": ["dataSpecification", "dataSpecificationContent"] - }, - "Extension": { - "allOf": [ - { - "$ref": "#/definitions/HasSemantics" - }, - { - "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 128, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "value": { - "type": "string" - }, - "refersTo": { - "type": "array", - "items": { - "$ref": "#/definitions/Reference" - }, - "minItems": 1 - } - }, - "required": ["name"] - } - ] - }, - "File": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "value": { - "type": "string", - "allOf": [ - { - "minLength": 1, - "maxLength": 2000 - }, - { - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - { - "pattern": "^file:(//((localhost|(\\[((([0-9A-Fa-f]{1,4}:){6}([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|::([0-9A-Fa-f]{1,4}:){5}([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|([0-9A-Fa-f]{1,4})?::([0-9A-Fa-f]{1,4}:){4}([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})?::([0-9A-Fa-f]{1,4}:){3}([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}:){2}[0-9A-Fa-f]{1,4})?::([0-9A-Fa-f]{1,4}:){2}([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}:){3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}:){4}[0-9A-Fa-f]{1,4})?::([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}:){5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(([0-9A-Fa-f]{1,4}:){6}[0-9A-Fa-f]{1,4})?::)|[vV][0-9A-Fa-f]+\\.([a-zA-Z0-9\\-._~]|[!$&'()*+,;=]|:)+)\\]|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|([a-zA-Z0-9\\-._~]|%[0-9A-Fa-f][0-9A-Fa-f]|[!$&'()*+,;=])*)))?/((([a-zA-Z0-9\\-._~]|%[0-9A-Fa-f][0-9A-Fa-f]|[!$&'()*+,;=]|[:@]))+(/(([a-zA-Z0-9\\-._~]|%[0-9A-Fa-f][0-9A-Fa-f]|[!$&'()*+,;=]|[:@]))*)*)?|/((([a-zA-Z0-9\\-._~]|%[0-9A-Fa-f][0-9A-Fa-f]|[!$&'()*+,;=]|[:@]))+(/(([a-zA-Z0-9\\-._~]|%[0-9A-Fa-f][0-9A-Fa-f]|[!$&'()*+,;=]|[:@]))*)*)?)$" - } - ] - }, - "contentType": { - "type": "string", - "allOf": [ - { - "minLength": 1, - "maxLength": 100 - }, - { - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - { - "pattern": "^([!#$%&'*+\\-.^_`|~0-9a-zA-Z])+/([!#$%&'*+\\-.^_`|~0-9a-zA-Z])+([ \\t]*;[ \\t]*([!#$%&'*+\\-.^_`|~0-9a-zA-Z])+=(([!#$%&'*+\\-.^_`|~0-9a-zA-Z])+|\"(([\\t !#-\\[\\]-~]|[€-ÿ])|\\\\([\\t !-~]|[€-ÿ]))*\"))*$" - } - ] - }, - "modelType": { - "const": "File" - } - }, - "required": ["contentType"] - } - ] - }, - "HasDataSpecification": { - "type": "object", - "properties": { - "embeddedDataSpecifications": { - "type": "array", - "items": { - "$ref": "#/definitions/EmbeddedDataSpecification" - }, - "minItems": 0 - } - } - }, - "HasExtensions": { - "type": "object", - "properties": { - "extensions": { - "type": "array", - "items": { - "$ref": "#/definitions/Extension" - }, - "minItems": 1 - } - } - }, - "HasKind": { - "type": "object", - "properties": { - "kind": { - "$ref": "#/definitions/ModellingKind" - } - } - }, - "HasSemantics": { - "type": "object", - "properties": { - "semanticId": { - "$ref": "#/definitions/Reference" - }, - "supplementalSemanticIds": { - "type": "array", - "items": { - "$ref": "#/definitions/Reference" - }, - "minItems": 1 - } - } - }, - "Identifiable": { - "allOf": [ - { - "$ref": "#/definitions/Referable" - }, - { - "properties": { - "administration": { - "$ref": "#/definitions/AdministrativeInformation" - }, - "id": { - "type": "string", - "minLength": 1, - "maxLength": 2000, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - } - }, - "required": ["id"] - } - ] - }, - "Key": { - "type": "object", - "properties": { - "type": { - "$ref": "#/definitions/KeyTypes" - }, - "value": { - "type": "string", - "minLength": 1, - "maxLength": 2000, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - } - }, - "required": ["type", "value"] - }, - "KeyTypes": { - "type": "string", - "enum": [ - "AnnotatedRelationshipElement", - "AssetAdministrationShell", - "BasicEventElement", - "Blob", - "Capability", - "ConceptDescription", - "DataElement", - "Entity", - "EventElement", - "File", - "FragmentReference", - "GlobalReference", - "Identifiable", - "MultiLanguageProperty", - "Operation", - "Property", - "Range", - "Referable", - "ReferenceElement", - "RelationshipElement", - "Submodel", - "SubmodelElement", - "SubmodelElementCollection", - "SubmodelElementList" - ] - }, - "LangStringDefinitionTypeIec61360": { - "allOf": [ - { - "$ref": "#/definitions/AbstractLangString" - }, - { - "properties": { - "text": { - "maxLength": 1023 - } - } - } - ] - }, - "LangStringNameType": { - "allOf": [ - { - "$ref": "#/definitions/AbstractLangString" - }, - { - "properties": { - "text": { - "maxLength": 128 - } - } - } - ] - }, - "LangStringPreferredNameTypeIec61360": { - "allOf": [ - { - "$ref": "#/definitions/AbstractLangString" - }, - { - "properties": { - "text": { - "maxLength": 255 - } - } - } - ] - }, - "LangStringShortNameTypeIec61360": { - "allOf": [ - { - "$ref": "#/definitions/AbstractLangString" - }, - { - "properties": { - "text": { - "maxLength": 18 - } - } - } - ] - }, - "LangStringTextType": { - "allOf": [ - { - "$ref": "#/definitions/AbstractLangString" - }, - { - "properties": { - "text": { - "maxLength": 1023 - } - } - } - ] - }, - "LevelType": { - "type": "object", - "properties": { - "min": { - "type": "boolean" - }, - "nom": { - "type": "boolean" - }, - "typ": { - "type": "boolean" - }, - "max": { - "type": "boolean" - } - }, - "required": ["min", "nom", "typ", "max"] - }, - "ModelType": { - "type": "string", - "enum": [ - "AnnotatedRelationshipElement", - "AssetAdministrationShell", - "BasicEventElement", - "Blob", - "Capability", - "ConceptDescription", - "DataSpecificationIec61360", - "Entity", - "File", - "MultiLanguageProperty", - "Operation", - "Property", - "Range", - "ReferenceElement", - "RelationshipElement", - "Submodel", - "SubmodelElementCollection", - "SubmodelElementList" - ] - }, - "ModellingKind": { - "type": "string", - "enum": ["Instance", "Template"] - }, - "MultiLanguageProperty": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/LangStringTextType" - }, - "minItems": 1 - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "MultiLanguageProperty" - } - } - } - ] - }, - "Property": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "Qualifiable": { - "type": "object", - "properties": { - "qualifiers": { - "type": "array", - "items": { - "$ref": "#/definitions/Qualifier" - }, - "minItems": 1 - }, - "modelType": { - "$ref": "#/definitions/ModelType" - } - }, - "required": ["modelType"] - }, - "Qualifier": { - "allOf": [ - { - "$ref": "#/definitions/HasSemantics" - }, - { - "properties": { - "kind": { - "$ref": "#/definitions/QualifierKind" - }, - "type": { - "type": "string", - "minLength": 1, - "maxLength": 128, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - } - }, - "required": ["type", "valueType"] - } - ] - }, - "QualifierKind": { - "type": "string", - "enum": ["ConceptQualifier", "TemplateQualifier", "ValueQualifier"] - }, - "Range": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "min": { - "type": "string" - }, - "max": { - "type": "string" - }, - "modelType": { - "const": "Range" - } - }, - "required": ["valueType"] - } - ] - }, - "Referable": { - "allOf": [ - { - "$ref": "#/definitions/HasExtensions" - }, - { - "properties": { - "category": { - "type": "string", - "minLength": 1, - "maxLength": 128, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - "idShort": { - "type": "string", - "allOf": [ - { - "minLength": 1, - "maxLength": 128 - }, - { - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - { - "pattern": "^[a-zA-Z][a-zA-Z0-9_]*$" - } - ] - }, - "displayName": { - "type": "array", - "items": { - "$ref": "#/definitions/LangStringNameType" - }, - "minItems": 1 - }, - "description": { - "type": "array", - "items": { - "$ref": "#/definitions/LangStringTextType" - }, - "minItems": 1 - }, - "modelType": { - "$ref": "#/definitions/ModelType" - } - }, - "required": ["modelType"] - } - ] - }, - "Reference": { - "type": "object", - "properties": { - "type": { - "$ref": "#/definitions/ReferenceTypes" - }, - "referredSemanticId": { - "$ref": "#/definitions/Reference" - }, - "keys": { - "type": "array", - "items": { - "$ref": "#/definitions/Key" - }, - "minItems": 1 - } - }, - "required": ["type", "keys"] - }, - "ReferenceElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "value": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "ReferenceElement" - } - } - } - ] - }, - "ReferenceTypes": { - "type": "string", - "enum": ["ExternalReference", "ModelReference"] - }, - "Resource": { - "type": "object", - "properties": { - "path": { - "type": "string", - "allOf": [ - { - "minLength": 1, - "maxLength": 2000 - }, - { - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - { - "pattern": "^file:(//((localhost|(\\[((([0-9A-Fa-f]{1,4}:){6}([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|::([0-9A-Fa-f]{1,4}:){5}([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|([0-9A-Fa-f]{1,4})?::([0-9A-Fa-f]{1,4}:){4}([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})?::([0-9A-Fa-f]{1,4}:){3}([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}:){2}[0-9A-Fa-f]{1,4})?::([0-9A-Fa-f]{1,4}:){2}([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}:){3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}:){4}[0-9A-Fa-f]{1,4})?::([0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))|(([0-9A-Fa-f]{1,4}:){5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(([0-9A-Fa-f]{1,4}:){6}[0-9A-Fa-f]{1,4})?::)|[vV][0-9A-Fa-f]+\\.([a-zA-Z0-9\\-._~]|[!$&'()*+,;=]|:)+)\\]|([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])|([a-zA-Z0-9\\-._~]|%[0-9A-Fa-f][0-9A-Fa-f]|[!$&'()*+,;=])*)))?/((([a-zA-Z0-9\\-._~]|%[0-9A-Fa-f][0-9A-Fa-f]|[!$&'()*+,;=]|[:@]))+(/(([a-zA-Z0-9\\-._~]|%[0-9A-Fa-f][0-9A-Fa-f]|[!$&'()*+,;=]|[:@]))*)*)?|/((([a-zA-Z0-9\\-._~]|%[0-9A-Fa-f][0-9A-Fa-f]|[!$&'()*+,;=]|[:@]))+(/(([a-zA-Z0-9\\-._~]|%[0-9A-Fa-f][0-9A-Fa-f]|[!$&'()*+,;=]|[:@]))*)*)?)$" - } - ] - }, - "contentType": { - "type": "string", - "allOf": [ - { - "minLength": 1, - "maxLength": 100 - }, - { - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - { - "pattern": "^([!#$%&'*+\\-.^_`|~0-9a-zA-Z])+/([!#$%&'*+\\-.^_`|~0-9a-zA-Z])+([ \\t]*;[ \\t]*([!#$%&'*+\\-.^_`|~0-9a-zA-Z])+=(([!#$%&'*+\\-.^_`|~0-9a-zA-Z])+|\"(([\\t !#-\\[\\]-~]|[€-ÿ])|\\\\([\\t !-~]|[€-ÿ]))*\"))*$" - } - ] - } - }, - "required": ["path"] - }, - "Submodel": { - "allOf": [ - { - "$ref": "#/definitions/Identifiable" - }, - { - "$ref": "#/definitions/HasKind" - }, - { - "$ref": "#/definitions/HasSemantics" - }, - { - "$ref": "#/definitions/Qualifiable" - }, - { - "$ref": "#/definitions/HasDataSpecification" - }, - { - "properties": { - "submodelElements": { - "type": "array", - "items": { - "$ref": "#/definitions/SubmodelElement_choice" - }, - "minItems": 1 - }, - "modelType": { - "const": "Submodel" - } - } - } - ] - }, - "SubmodelElement": { - "allOf": [ - { - "$ref": "#/definitions/Referable" - }, - { - "$ref": "#/definitions/HasSemantics" - }, - { - "$ref": "#/definitions/Qualifiable" - }, - { - "$ref": "#/definitions/HasDataSpecification" - } - ] - }, - "SubmodelElementCollection": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/SubmodelElement_choice" - }, - "minItems": 1 - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "SubmodelElementList": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "orderRelevant": { - "type": "boolean" - }, - "semanticIdListElement": { - "$ref": "#/definitions/Reference" - }, - "typeValueListElement": { - "$ref": "#/definitions/AasSubmodelElements" - }, - "valueTypeListElement": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/SubmodelElement_choice" - }, - "minItems": 1 - }, - "modelType": { - "const": "SubmodelElementList" - } - }, - "required": ["typeValueListElement"] - } - ] - }, - "SubmodelElement_choice": { - "oneOf": [ - { - "$ref": "#/definitions/File" - }, - { - "$ref": "#/definitions/Property" - }, - { - "$ref": "#/definitions/Range" - }, - { - "$ref": "#/definitions/ReferenceElement" - }, - { - "$ref": "#/definitions/SubmodelElementCollection" - }, - { - "$ref": "#/definitions/SubmodelElementList" - } - ] - }, - "ValueList": { - "type": "object", - "properties": { - "valueReferencePairs": { - "type": "array", - "items": { - "$ref": "#/definitions/ValueReferencePair" - }, - "minItems": 1 - } - }, - "required": ["valueReferencePairs"] - }, - "ValueReferencePair": { - "type": "object", - "properties": { - "value": { - "type": "string", - "minLength": 1, - "maxLength": 2000, - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - "valueId": { - "$ref": "#/definitions/Reference" - } - }, - "required": ["value", "valueId"] - }, - "InterfaceHTTP": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "title": "Interface HTTP submodelElement collection", - "description": "In this collection, EndpointMetadta and InteractionMetadata should be mandatory and other elements should be optional", - "type": "array", - "uniqueItems": true, - "unevaluatedItems": false, - "maxItems": 7, - "items": { - "anyOf": [ - { "$ref": "#/definitions/titleElement" }, - { "$ref": "#/definitions/createdElement" }, - { "$ref": "#/definitions/modifiedElement" }, - { "$ref": "#/definitions/supportElement" }, - { "$ref": "#/definitions/ExternalDescriptorContainer" }, - { "$ref": "#/definitions/HTTPEndpointMetadata" }, - { "$ref": "#/definitions/HTTPInteractionMetadata" } - ] - }, - "if": { - "not": { - "contains": { - "$ref": "#/definitions/ExternalDescriptorContainer" - } - } - }, - "then": { - "contains": { - "anyOf": [ - { "$ref": "#/definitions/HTTPEndpointMetadata" }, - { "$ref": "#/definitions/HTTPInteractionMetadata" } - ] - }, - "minContains": 2, - "maxContains": 2 - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "InterfaceMODBUS": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "title": "Interface modbus submodelElement collection", - "description": "In this collection, EndpointMetadta and InteractionMetadata should be mandatory and other elements should be optional", - "type": "array", - "uniqueItems": true, - "unevaluatedItems": false, - "maxItems": 7, - "items": { - "anyOf": [ - { "$ref": "#/definitions/titleElement" }, - { "$ref": "#/definitions/createdElement" }, - { "$ref": "#/definitions/modifiedElement" }, - { "$ref": "#/definitions/supportElement" }, - { "$ref": "#/definitions/ExternalDescriptorContainer" }, - { "$ref": "#/definitions/MODBUSEndpointMetadata" }, - { "$ref": "#/definitions/MODBUSInteractionMetadata" } - ] - }, - "if": { - "not": { - "contains": { - "$ref": "#/definitions/ExternalDescriptorContainer" - } - } - }, - "then": { - "contains": { - "anyOf": [ - { "$ref": "#/definitions/MODBUSEndpointMetadata" }, - { "$ref": "#/definitions/MODBUSInteractionMetadata" } - ] - }, - "minContains": 2, - "maxContains": 2 - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "InterfaceMQTT": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "title": "Interface MQTT submodelElement collection", - "description": "In this collection, EndpointMetadta and InteractionMetadata should be mandatory and other elements should be optional", - "type": "array", - "uniqueItems": true, - "unevaluatedItems": false, - "maxItems": 7, - "items": { - "anyOf": [ - { "$ref": "#/definitions/titleElement" }, - { "$ref": "#/definitions/createdElement" }, - { "$ref": "#/definitions/modifiedElement" }, - { "$ref": "#/definitions/supportElement" }, - { "$ref": "#/definitions/ExternalDescriptorContainer" }, - { "$ref": "#/definitions/MQTTEndpointMetadata" }, - { "$ref": "#/definitions/MQTTInteractionMetadata" } - ] - }, - "if": { - "not": { - "contains": { - "$ref": "#/definitions/ExternalDescriptorContainer" - } - } - }, - "then": { - "contains": { - "anyOf": [ - { "$ref": "#/definitions/MQTTEndpointMetadata" }, - { "$ref": "#/definitions/MQTTInteractionMetadata" } - ] - }, - "minContains": 2, - "maxContains": 2 - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "titleElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["title"] - }, - - "valueType": { - "type": "string", - "enum": ["xs:string"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType", "idShort"] - } - ] - }, - "createdElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["created"] - }, - - "valueType": { - "type": "string", - "enum": ["xs:dateTime", "xs:date"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType", "idShort"] - } - ] - }, - "modifiedElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["modified"] - }, - - "valueType": { - "type": "string", - "enum": ["xs:dateTime", "xs:date"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType", "idShort"] - } - ] - }, - "supportElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["support"] - }, - - "valueType": { - "type": "string", - "enum": ["xs:anyURI"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType", "idShort"] - } - ] - }, - "HTTPEndpointMetadata": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["EndpointMetadata"] - }, - "value": { - "uniqueItems": true, - "unevaluatedItems": false, - "maxItems": 4, - "type": "array", - "items": { - "anyOf": [ - { "$ref": "#/definitions/securityDefinitionsElement" }, - { "$ref": "#/definitions/contentTypeElement" }, - { "$ref": "#/definitions/HTTPbaseElement" }, - { "$ref": "#/definitions/securityElement" } - ] - }, - "contains": { - "oneOf": [ - { "$ref": "#/definitions/securityDefinitionsElement" }, - { "$ref": "#/definitions/HTTPbaseElement" }, - { "$ref": "#/definitions/securityElement" } - ] - }, - "minContains": 3, - "maxContains": 3 - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "MODBUSEndpointMetadata": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["EndpointMetadata"] - }, - "value": { - "uniqueItems": true, - "unevaluatedItems": false, - "maxItems": 6, - "type": "array", - "items": { - "anyOf": [ - { "$ref": "#/definitions/securityDefinitionsElement" }, - { "$ref": "#/definitions/contentTypeElement" }, - { "$ref": "#/definitions/MODBUSbaseElement" }, - { "$ref": "#/definitions/securityElement" }, - { "$ref": "#/definitions/modbusMostSignificantByteElement" }, - { "$ref": "#/definitions/modbusMostSignificantWordElement" } - ] - }, - "contains": { - "oneOf": [ - { "$ref": "#/definitions/securityDefinitionsElement" }, - { "$ref": "#/definitions/MODBUSbaseElement" }, - { "$ref": "#/definitions/securityElement" } - ] - }, - "minContains": 3, - "maxContains": 3 - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "MQTTEndpointMetadata": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["EndpointMetadata"] - }, - "value": { - "uniqueItems": true, - "unevaluatedItems": false, - "maxItems": 4, - "type": "array", - "items": { - "anyOf": [ - { "$ref": "#/definitions/securityDefinitionsElement" }, - { "$ref": "#/definitions/contentTypeElement" }, - { "$ref": "#/definitions/MQTTbaseElement" }, - { "$ref": "#/definitions/securityElement" } - ] - }, - "contains": { - "oneOf": [ - { "$ref": "#/definitions/securityDefinitionsElement" }, - { "$ref": "#/definitions/MQTTbaseElement" }, - { "$ref": "#/definitions/securityElement" } - ] - }, - "minContains": 3, - "maxContains": 3 - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "HTTPInteractionMetadata": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["InteractionMetadata"] - }, - "value": { - "type": "array", - "uniqueItems": true, - "unevaluatedItems": false, - "maxItems": 3, - "items": { - "anyOf": [ - { - "$ref": "#/definitions/HTTPInteractionMetadataPropertiesElement" - }, - { "$ref": "#/definitions/InteractionMetadataActionsElement" }, - { "$ref": "#/definitions/InteractionMetadataEventsElement" } - ] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "MODBUSInteractionMetadata": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["InteractionMetadata"] - }, - "value": { - "type": "array", - "uniqueItems": true, - "unevaluatedItems": false, - "maxItems": 3, - "items": { - "anyOf": [ - { - "$ref": "#/definitions/ModbusInteractionMetadataPropertiesElement" - }, - { "$ref": "#/definitions/InteractionMetadataActionsElement" }, - { "$ref": "#/definitions/InteractionMetadataEventsElement" } - ] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "MQTTInteractionMetadata": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["InteractionMetadata"] - }, - "value": { - "type": "array", - "uniqueItems": true, - "unevaluatedItems": false, - "maxItems": 3, - "items": { - "anyOf": [ - { - "$ref": "#/definitions/MQTTInteractionMetadataPropertiesElement" - }, - { "$ref": "#/definitions/InteractionMetadataActionsElement" }, - { "$ref": "#/definitions/InteractionMetadataEventsElement" } - ] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "HTTPInteractionMetadataPropertiesElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["properties"] - }, - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/HTTPPropertyOfPropertiesElement" - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "ModbusInteractionMetadataPropertiesElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["properties"] - }, - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/ModbusPropertyOfPropertiesElement" - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "MQTTInteractionMetadataPropertiesElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["properties"] - }, - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/MQTTPropertyOfPropertiesElement" - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "InteractionMetadataActionsElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["actions"] - }, - "value": { - "type": "array", - "uniqueItems": true, - "unevaluatedItems": false, - "maxItems": 3, - "items": { - "oneOf": [{}] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "InteractionMetadataEventsElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["events"] - }, - "value": { - "type": "array", - "uniqueItems": true, - "unevaluatedItems": false, - "maxItems": 3, - "items": { - "oneOf": [{}] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "HTTPPropertyOfPropertiesElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "value": { - "type": "array", - "uniqueItems": true, - "items": { - "anyOf": [ - { "$ref": "#/definitions/keyElement" }, - { "$ref": "#/definitions/typeElement" }, - { "$ref": "#/definitions/observableElement" }, - { "$ref": "#/definitions/constElement" }, - { "$ref": "#/definitions/defaultElement" }, - { "$ref": "#/definitions/unitElement" }, - { "$ref": "#/definitions/min_maxElement" }, - { "$ref": "#/definitions/lengthRangeElement" }, - { "$ref": "#/definitions/itemsRangeElement" }, - { "$ref": "#/definitions/valueSemanticsElement" }, - { "$ref": "#/definitions/httpFormsElement" }, - { "$ref": "#/definitions/titleElement" }, - { "$ref": "#/definitions/itemsElement" }, - { "$ref": "#/definitions/InternalPropertiesForObjectElement" } - ] - }, - "contains": { - "$ref": "#/definitions/httpFormsElement" - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "ModbusPropertyOfPropertiesElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "value": { - "type": "array", - "items": { - "anyOf": [ - { "$ref": "#/definitions/keyElement" }, - { "$ref": "#/definitions/typeElement" }, - { "$ref": "#/definitions/observableElement" }, - { "$ref": "#/definitions/constElement" }, - { "$ref": "#/definitions/defaultElement" }, - { "$ref": "#/definitions/unitElement" }, - { "$ref": "#/definitions/min_maxElement" }, - { "$ref": "#/definitions/lengthRangeElement" }, - { "$ref": "#/definitions/itemsRangeElement" }, - { "$ref": "#/definitions/valueSemanticsElement" }, - { "$ref": "#/definitions/modbusFormsElement" }, - { "$ref": "#/definitions/titleElement" }, - { "$ref": "#/definitions/itemsElement" }, - { "$ref": "#/definitions/InternalPropertiesForObjectElement" } - ] - }, - "contains": { - "$ref": "#/definitions/modbusFormsElement" - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "MQTTPropertyOfPropertiesElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "value": { - "type": "array", - "items": { - "anyOf": [ - { "$ref": "#/definitions/keyElement" }, - { "$ref": "#/definitions/typeElement" }, - { "$ref": "#/definitions/observableElement" }, - { "$ref": "#/definitions/constElement" }, - { "$ref": "#/definitions/defaultElement" }, - { "$ref": "#/definitions/unitElement" }, - { "$ref": "#/definitions/min_maxElement" }, - { "$ref": "#/definitions/lengthRangeElement" }, - { "$ref": "#/definitions/itemsRangeElement" }, - { "$ref": "#/definitions/valueSemanticsElement" }, - { "$ref": "#/definitions/mqttFormsElement" }, - { "$ref": "#/definitions/titleElement" }, - { "$ref": "#/definitions/itemsElement" }, - { "$ref": "#/definitions/InternalPropertiesForObjectElement" } - ] - }, - "contains": { - "$ref": "#/definitions/mqttFormsElement" - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "ExternalDescriptorContainer": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["ExternalDescriptor"] - }, - "value": { - "type": "array", - "uniqueItems": true, - "unevaluatedItems": false, - "minItems": 1, - "items": { - "$ref": "#/definitions/ExternalDescriptorElement" - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "ExternalDescriptorElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "type": "string", - "allOf": [ - { - "minLength": 1, - "maxLength": 2000 - }, - { - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - } - ] - }, - "contentType": { - "type": "string", - "allOf": [ - { - "minLength": 1, - "maxLength": 100 - }, - { - "pattern": "^([\\t\\n\\r -퟿-�]|\\ud800[\\udc00-\\udfff]|[\\ud801-\\udbfe][\\udc00-\\udfff]|\\udbff[\\udc00-\\udfff])*$" - }, - { - "pattern": "^([!#$%&'*+\\-.^_`|~0-9a-zA-Z])+/([!#$%&'*+\\-.^_`|~0-9a-zA-Z])+([ \\t]*;[ \\t]*([!#$%&'*+\\-.^_`|~0-9a-zA-Z])+=(([!#$%&'*+\\-.^_`|~0-9a-zA-Z])+|\"(([\\t !#-\\[\\]-~]|[€-ÿ])|\\\\([\\t !-~]|[€-ÿ]))*\"))*$" - } - ] - }, - "modelType": { - "const": "File" - } - }, - "required": ["contentType"] - } - ] - }, - "HTTPbaseElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["base"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:anyURI"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "MODBUSbaseElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["base"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:anyURI"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "MQTTbaseElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["base"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:anyURI"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "contentTypeElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["contentType"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:string"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "securityElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["security"] - }, - "orderRelevant": { - "type": "boolean" - }, - "semanticIdListElement": { - "$ref": "#/definitions/Reference" - }, - "typeValueListElement": { - "$ref": "#/definitions/AasSubmodelElements" - }, - "valueTypeListElement": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "value": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/securityReferenceName" - } - }, - "modelType": { - "const": "SubmodelElementList" - } - }, - "required": ["typeValueListElement"] - } - ] - }, - "securityDefinitionsElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["securityDefinitions"] - }, - "value": { - "type": "array", - "minItems": 1, - "items": { - "anyOf": [ - { "$ref": "#/definitions/basicSecurityDefinitions" }, - { "$ref": "#/definitions/bearerSecurityDefinitions" }, - { "$ref": "#/definitions/digestSecurityDefinitions" }, - { "$ref": "#/definitions/apikeySecurityDefinitions" }, - { "$ref": "#/definitions/autoSecurityDefinitions" }, - { "$ref": "#/definitions/oauth2SecurityDefinitions" }, - { "$ref": "#/definitions/comboSecurityDefinitions" }, - { "$ref": "#/definitions/pskSecurityDefinitions" }, - { "$ref": "#/definitions/nosecSecurityDefinitions" } - ] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "securityReferenceName": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "value": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "ReferenceElement" - } - } - } - ] - }, - "securityName": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - - "valueType": { - "type": "string", - "enum": ["xs:string"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "nosecSecurityDefinitions": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "type": "array", - "minItems": 1, - "items": { - "allOf": [{ "$ref": "#/definitions/schemeSecurityElement" }] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "basicSecurityDefinitions": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "type": "array", - "minItems": 1, - "minContains": 1, - "items": { - "anyOf": [ - { "$ref": "#/definitions/nameSecurityElement" }, - { "$ref": "#/definitions/inSecurityElement" }, - { "$ref": "#/definitions/proxySecurityElement" }, - { "$ref": "#/definitions/schemeSecurityElement" } - ] - }, - "contains": { - "allOf": [{ "$ref": "#/definitions/schemeSecurityElement" }] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "bearerSecurityDefinitions": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "type": "array", - "minItems": 1, - "minContains": 1, - "items": { - "anyOf": [ - { "$ref": "#/definitions/authorizationSecurityElement" }, - { "$ref": "#/definitions/nameSecurityElement" }, - { "$ref": "#/definitions/algSecurityElement" }, - { "$ref": "#/definitions/formatSecurityElement" }, - { "$ref": "#/definitions/inSecurityElement" }, - { "$ref": "#/definitions/proxySecurityElement" }, - { "$ref": "#/definitions/schemeSecurityElement" } - ] - }, - "contains": { - "allOf": [{ "$ref": "#/definitions/schemeSecurityElement" }] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "digestSecurityDefinitions": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "type": "array", - "minItems": 1, - "minContains": 1, - "items": { - "anyOf": [ - { "$ref": "#/definitions/nameSecurityElement" }, - { "$ref": "#/definitions/inSecurityElement" }, - { "$ref": "#/definitions/qopSecurityElement" }, - { "$ref": "#/definitions/proxySecurityElement" }, - { "$ref": "#/definitions/schemeSecurityElement" } - ] - }, - "contains": { - "allOf": [{ "$ref": "#/definitions/schemeSecurityElement" }] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "apikeySecurityDefinitions": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "type": "array", - "minItems": 1, - "minContains": 1, - "items": { - "anyOf": [ - { "$ref": "#/definitions/nameSecurityElement" }, - { "$ref": "#/definitions/inSecurityElement" }, - { "$ref": "#/definitions/proxySecurityElement" }, - { "$ref": "#/definitions/schemeSecurityElement" } - ] - }, - "contains": { - "allOf": [{ "$ref": "#/definitions/schemeSecurityElement" }] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "autoSecurityDefinitions": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "type": "array", - "minItems": 1, - "minContains": 1, - "items": { - "anyOf": [ - { "$ref": "#/definitions/proxySecurityElement" }, - { "$ref": "#/definitions/schemeSecurityElement" } - ] - }, - "contains": { - "allOf": [{ "$ref": "#/definitions/schemeSecurityElement" }] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "pskSecurityDefinitions": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "type": "array", - "minItems": 1, - "minContains": 1, - "items": { - "anyOf": [ - { "$ref": "#/definitions/identitySecurityElement" }, - { "$ref": "#/definitions/proxySecurityElement" }, - { "$ref": "#/definitions/schemeSecurityElement" } - ] - }, - "contains": { - "allOf": [{ "$ref": "#/definitions/schemeSecurityElement" }] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "oauth2SecurityDefinitions": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "type": "array", - "minItems": 1, - - "items": { - "anyOf": [ - { "$ref": "#/definitions/authorizationSecurityElement" }, - { "$ref": "#/definitions/tokenSecurityElement" }, - { "$ref": "#/definitions/refreshSecurityElement" }, - { "$ref": "#/definitions/flowSecurityElement" }, - { "$ref": "#/definitions/proxySecurityElement" }, - { "$ref": "#/definitions/schemeSecurityElement" }, - { "$ref": "#/definitions/scopesSecurityElement" } - ] - }, - "contains": { - "anyOf": [ - { "$ref": "#/definitions/flowSecurityElement" }, - { "$ref": "#/definitions/schemeSecurityElement" } - ] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "comboSecurityDefinitions": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string" - }, - "value": { - "type": "array", - "minItems": 1, - "items": { - "oneOf": [ - { "$ref": "#/definitions/allOfsecurityElement" }, - { "$ref": "#/definitions/oneOfsecurityElement" }, - { "$ref": "#/definitions/proxySecurityElement" }, - { "$ref": "#/definitions/schemeSecurityElement" } - ] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "schemeSecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["scheme"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:string"] - }, - "value": { - "type": "string", - "enum": ["nosec", "digest", "basic", "apikey", "psk", "bearer", "auto", "combo", "oauth2"] - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "proxySecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["proxy"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:anyURI"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "nameSecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["name"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:string"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "inSecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["in"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:string"] - }, - "value": { - "type": "string", - "enum": ["header", "query", "body", "cookie", "auto"] - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "identitySecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["identity"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:string"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "qopSecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["qop"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:string"] - }, - "value": { - "type": "string", - "enum": ["auth", "auth-int"] - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "authorizationSecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["authorization"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:anyURI"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "algSecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["alg"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:string"] - }, - "value": { - "type": "string", - "enum": ["ES256", "ES512-256"] - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "formatSecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["format"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:string"] - }, - "value": { - "type": "string", - "enum": ["jwt", "cwt", "jwe", "jws"] - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "tokenSecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["token"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:anyURI"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "refreshSecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["refresh"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:anyURI"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "scopesSecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["scopes"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:string"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "flowSecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["flow"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd", - "enum": ["xs:string"] - }, - "value": { - "type": "string", - "enum": ["code", "client"] - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "allOfsecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["allOf"] - }, - "orderRelevant": { - "type": "boolean" - }, - "semanticIdListElement": { - "$ref": "#/definitions/Reference" - }, - "typeValueListElement": { - "$ref": "#/definitions/AasSubmodelElements" - }, - "valueTypeListElement": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/securityName" - }, - "minItems": 1 - }, - "modelType": { - "const": "SubmodelElementList" - } - }, - "required": ["typeValueListElement"] - } - ] - }, - "oneOfsecurityElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["oneOf"] - }, - "orderRelevant": { - "type": "boolean" - }, - "semanticIdListElement": { - "$ref": "#/definitions/Reference" - }, - "typeValueListElement": { - "$ref": "#/definitions/AasSubmodelElements" - }, - "valueTypeListElement": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/securityName" - }, - "minItems": 1 - }, - "modelType": { - "const": "SubmodelElementList" - } - }, - "required": ["typeValueListElement"] - } - ] - }, - "keyElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["key"] - }, - - "valueType": { - "type": "string", - "enum": ["xs:string"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "typeElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["type"] - }, - - "valueType": { - "type": "string", - "enum": ["xs:string"] - }, - "value": { - "type": "string", - "enum": ["float", "integer", "object", "array", "number", "string"] - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "observableElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["observable"] - }, - - "valueType": { - "type": "string", - "enum": ["xs:boolean"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "constElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["const"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "defaultElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["default"] - }, - - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "unitElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["unit"] - }, - - "valueType": { - "type": "string" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "min_maxElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["min_max"] - }, - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "min": { - "type": "string" - }, - "max": { - "type": "string" - }, - "modelType": { - "const": "Range" - } - }, - "required": ["valueType"] - } - ] - }, - "lengthRangeElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["lengthRange"] - }, - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "min": { - "type": "string" - }, - "max": { - "type": "string" - }, - "modelType": { - "const": "Range" - } - }, - "required": ["valueType"] - } - ] - }, - "itemsRangeElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["itemsRange"] - }, - "valueType": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "min": { - "type": "string" - }, - "max": { - "type": "string" - }, - "modelType": { - "const": "Range" - } - }, - "required": ["valueType"] - } - ] - }, - "valueSemanticsElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["valueSemantics"] - }, - "value": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "ReferenceElement" - } - } - } - ] - }, - "itemsElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["items"] - }, - "value": { - "type": "array", - "items": {} - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "InternalPropertiesForObjectElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["properties"] - }, - "value": { - "type": "array", - "items": {} - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "hrefElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["href"] - }, - - "valueType": { - "type": "string", - "enum": ["xs:anyURI", "xs:string"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "htvMethodNameElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["htv_methodName"] - }, - - "valueType": { - "type": "string" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "htvHeadersElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["htv_headers"] - }, - "orderRelevant": { - "type": "boolean" - }, - "semanticIdListElement": { - "$ref": "#/definitions/Reference" - }, - "typeValueListElement": { - "$ref": "#/definitions/AasSubmodelElements" - }, - "valueTypeListElement": { - "$ref": "#/definitions/DataTypeDefXsd" - }, - "value": { - "type": "array", - "minItems": 1, - "items": {} - }, - "modelType": { - "const": "SubmodelElementList" - } - }, - "required": ["typeValueListElement"] - } - ] - }, - "mqvRetainElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["mqv_retain"] - }, - - "valueType": { - "type": "string" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "mqvControlPacketElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["mqv_controlPacket"] - }, - - "valueType": { - "type": "string" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "mqvQOSElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["mqv_qos"] - }, - - "valueType": { - "type": "string" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "modbusFunctionElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["modv_function"] - }, - - "valueType": { - "type": "string", - "enum": ["xs:string"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "modbusElements": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["modv_function"] - }, - - "valueType": { - "type": "string", - "enum": ["xs:string"] - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "modbusEntityElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["modv_entity"] - }, - - "valueType": { - "type": "string" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "modbusZeroBasedAddressingElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["modv_zeroBasedAddressing"] - }, - - "valueType": { - "type": "string" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "modbusPollingTimeElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["modv_pollingTime"] - }, - - "valueType": { - "type": "string" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "modbustimeoutElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["modv_timeout"] - }, - - "valueType": { - "type": "string" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "modbusTypeElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["modv_type"] - }, - - "valueType": { - "type": "string" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "modbusMostSignificantByteElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["modv_mostSignificantByte"] - }, - - "valueType": { - "type": "string" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "modbusMostSignificantWordElement": { - "allOf": [ - { - "$ref": "#/definitions/DataElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["modv_mostSignificantWord"] - }, - "valueType": { - "type": "string" - }, - "value": { - "type": "string" - }, - "valueId": { - "$ref": "#/definitions/Reference" - }, - "modelType": { - "const": "Property" - } - }, - "required": ["valueType"] - } - ] - }, - "httpFormsElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["forms"] - }, - "value": { - "type": "array", - "items": { - "anyOf": [ - { "$ref": "#/definitions/contentTypeElement" }, - { "$ref": "#/definitions/hrefElement" }, - { "$ref": "#/definitions/securityElement" }, - { "$ref": "#/definitions/htvMethodNameElement" }, - { "$ref": "#/definitions/htvHeadersElement" } - ] - }, - "contains": { - "$ref": "#/definitions/hrefElement" - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "mqttFormsElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["forms"] - }, - "value": { - "type": "array", - "items": { - "anyOf": [ - { "$ref": "#/definitions/contentTypeElement" }, - { "$ref": "#/definitions/hrefElement" }, - { "$ref": "#/definitions/securityElement" }, - { "$ref": "#/definitions/mqvQOSElement" }, - { "$ref": "#/definitions/mqvRetainElement" }, - { "$ref": "#/definitions/mqvControlPacketElement" } - ] - }, - "contains": { - "anyOf": [ - { "$ref": "#/definitions/hrefElement" }, - { "$ref": "#/definitions/mqvControlPacketElement" } - ] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - }, - "modbusFormsElement": { - "allOf": [ - { - "$ref": "#/definitions/SubmodelElement" - }, - { - "properties": { - "idShort": { - "type": "string", - "enum": ["forms"] - }, - "value": { - "uniqueItems": true, - "unevaluatedItems": false, - "maxItems": 11, - "type": "array", - "items": { - "anyOf": [ - { "$ref": "#/definitions/contentTypeElement" }, - { "$ref": "#/definitions/hrefElement" }, - { "$ref": "#/definitions/securityElement" }, - { "$ref": "#/definitions/modbusEntityElement" }, - { "$ref": "#/definitions/modbusFunctionElement" }, - { "$ref": "#/definitions/modbusPollingTimeElement" }, - { "$ref": "#/definitions/modbusTypeElement" }, - { "$ref": "#/definitions/modbusZeroBasedAddressingElement" }, - { "$ref": "#/definitions/modbustimeoutElement" }, - { "$ref": "#/definitions/modbusMostSignificantByteElement" }, - { "$ref": "#/definitions/modbusMostSignificantWordElement" } - ] - }, - "contains": { - "anyOf": [ - { "$ref": "#/definitions/hrefElement" }, - { "$ref": "#/definitions/modbusFunctionElement" } - ] - } - }, - "modelType": { - "const": "SubmodelElementCollection" - } - } - } - ] - } - } -} diff --git a/packages/td-tools/test/util/counterHTTP.json b/packages/td-tools/test/util/counterHTTP.json deleted file mode 100644 index 8748bef79..000000000 --- a/packages/td-tools/test/util/counterHTTP.json +++ /dev/null @@ -1,824 +0,0 @@ -{ - "assetAdministrationShells": [ - { - "idShort": "SampleAAS", - "id": "https://example.com/ids/aas/7474_9002_6022_1115", - "assetInformation": { - "assetKind": "Type", - "globalAssetId": "https://example.com/ids/asset/3071_4170_8032_4893", - "specificAssetIds": [], - "assetType": "" - }, - "submodels": [ - { - "type": "ModelReference", - "keys": [ - { - "type": "Submodel", - "value": "https://example.com/ids/sm/4333_9041_7022_4184" - } - ] - } - ], - "modelType": "AssetAdministrationShell" - } - ], - "submodels": [ - { - "idShort": "AssetInterfacesDescription", - "description": [ - { "language": "en", "text": "Counter example Thing" }, - { "language": "de", "text": "Zähler Beispiel Ding" }, - { "language": "it", "text": "Contatore di esempio" } - ], - "id": "https://example.com/ids/sm/4333_9041_7022_4184", - "kind": "Instance", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Submodel" - } - ] - }, - "submodelElements": [ - { - "idShort": "InterfaceHTTP", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface" - } - ] - }, - "supplementalSemanticIds": [ - { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "http://www.w3.org/2011/http" - } - ] - } - ], - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "title", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#title" - } - ] - }, - "valueType": "xs:string", - "value": "Counter", - "modelType": "Property" - }, - { - "idShort": "support", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#support" - } - ] - }, - "valueType": "xs:anyURI", - "value": "https://github.com/eclipse-thingweb/node-wot/", - "modelType": "Property" - }, - { - "idShort": "EndpointMetadata", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/EndpointMetadata" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "base", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#base" - } - ] - }, - "embeddedDataSpecifications": [], - "valueType": "xs:anyURI", - "value": "http://plugfest.thingweb.io:8083", - "modelType": "Property" - }, - { - "idShort": "contentType", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/hypermedia#forContentType" - } - ] - }, - "embeddedDataSpecifications": [], - "valueType": "xs:string", - "value": "application/json", - "modelType": "Property" - }, - { - "idShort": "security", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#hasSecurityConfiguration" - } - ] - }, - "typeValueListElement": "ReferenceElement", - "value": [ - { - "value": { - "type": "ModelReference", - "keys": [ - { - "type": "Submodel", - "value": "https://example.com/ids/sm/4333_9041_7022_4184" - }, - { - "type": "SubmodelElementCollection", - "value": "InterfaceHTTP" - }, - { - "type": "SubmodelElementCollection", - "value": "EndpointMetadata" - }, - { - "type": "SubmodelElementCollection", - "value": "securityDefinitions" - }, - { - "type": "SubmodelElementCollection", - "value": "nosec_sc" - } - ] - }, - "modelType": "ReferenceElement" - } - ], - "modelType": "SubmodelElementList" - }, - { - "idShort": "securityDefinitions", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#definesSecurityScheme" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "nosec_sc", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/security#NoSecurityScheme" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "scheme", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#definesSecurityScheme" - } - ] - }, - "valueType": "xs:string", - "value": "nosec", - "modelType": "Property" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - }, - { - "idShort": "InteractionMetadata", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/InteractionMetadata" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "properties", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#PropertyAffordance" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "count", - "description": [ - { "language": "en", "text": "Current counter value" }, - { - "language": "de", - "text": "Derzeitiger Z\u00E4hlerwert" - }, - { - "language": "it", - "text": "Valore attuale del contatore" - } - ], - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://admin-shell.io/idta/AssetInterfaceDescription/1/0/PropertyDefinition" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "type", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/1999/02/22-rdf-syntax-ns#type" - } - ] - }, - "valueType": "xs:string", - "value": "integer", - "modelType": "Property" - }, - { - "idShort": "min_max", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/minMaxRange" - } - ] - }, - "supplementalSemanticIds": [ - { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/json-schema#minimum" - }, - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/json-schema#maximum" - } - ] - } - ], - "valueType": "xs:integer", - "min": "1", - "max": "100", - "modelType": "Range" - }, - { - "idShort": "title", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#title" - } - ] - }, - "valueType": "xs:string", - "value": "Count", - "modelType": "Property" - }, - { - "idShort": "observable", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#isObservable" - } - ] - }, - "valueType": "xs:boolean", - "value": "true", - "modelType": "Property" - }, - { - "idShort": "forms", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#hasForm" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "htv_methodName", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2011/http#methodName" - } - ] - }, - "embeddedDataSpecifications": [], - "valueType": "xs:string", - "value": "GET", - "modelType": "Property" - }, - { - "idShort": "href", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/hypermedia#hasTarget" - } - ] - }, - "embeddedDataSpecifications": [], - "valueType": "xs:string", - "value": "/counter/properties/count", - "modelType": "Property" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - }, - { - "idShort": "countAsImage", - "description": [ - { - "language": "en", - "text": "Current counter value as SVG image" - }, - { - "language": "de", - "text": "Aktueller Z\u00E4hlerwert als SVG-Bild" - }, - { - "language": "it", - "text": "Valore attuale del contatore come immagine SVG" - } - ], - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://admin-shell.io/idta/AssetInterfaceDescription/1/0/PropertyDefinition" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "observable", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#isObservable" - } - ] - }, - "valueType": "xs:boolean", - "value": "false", - "modelType": "Property" - }, - { - "idShort": "forms", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#hasForm" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "htv_methodName", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2011/http#methodName" - } - ] - }, - "embeddedDataSpecifications": [], - "valueType": "xs:string", - "value": "GET", - "modelType": "Property" - }, - { - "idShort": "href", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/hypermedia#hasTarget" - } - ] - }, - "embeddedDataSpecifications": [], - "valueType": "xs:string", - "value": "/counter/properties/countAsImage", - "modelType": "Property" - }, - { - "idShort": "contentType", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/hypermedia#forContentType" - } - ] - }, - "embeddedDataSpecifications": [], - "valueType": "xs:string", - "value": "image/svg\u002Bxml", - "modelType": "Property" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - }, - { - "idShort": "redDotImage", - "description": [ - { "language": "en", "text": "Red dot image as PNG" }, - { "language": "de", "text": "Rotes Punktbild als PNG" }, - { - "language": "it", - "text": "Immagine punto rosso come PNG" - } - ], - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://admin-shell.io/idta/AssetInterfaceDescription/1/0/PropertyDefinition" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "observable", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#isObservable" - } - ] - }, - "valueType": "xs:boolean", - "value": "false", - "modelType": "Property" - }, - { - "idShort": "forms", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#hasForm" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "htv_methodName", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2011/http#methodName" - } - ] - }, - "embeddedDataSpecifications": [], - "valueType": "xs:string", - "value": "GET", - "modelType": "Property" - }, - { - "idShort": "href", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/hypermedia#hasTarget" - } - ] - }, - "embeddedDataSpecifications": [], - "valueType": "xs:string", - "value": "/counter/properties/redDotImage", - "modelType": "Property" - }, - { - "idShort": "contentType", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/hypermedia#forContentType" - } - ] - }, - "embeddedDataSpecifications": [], - "valueType": "xs:string", - "value": "image/png;base64", - "modelType": "Property" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - }, - { - "idShort": "lastChange", - "description": [ - { - "language": "en", - "text": "Last change of counter value" - }, - { "language": "de", "text": "Letzte \u00C4nderung" }, - { - "language": "it", - "text": "Ultima modifica del valore" - } - ], - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://admin-shell.io/idta/AssetInterfaceDescription/1/0/PropertyDefinition" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "type", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/1999/02/22-rdf-syntax-ns#type" - } - ] - }, - "valueType": "xs:string", - "value": "string", - "modelType": "Property" - }, - { - "idShort": "title", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#title" - } - ] - }, - "valueType": "xs:string", - "value": "Last change", - "modelType": "Property" - }, - { - "idShort": "observable", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#isObservable" - } - ] - }, - "valueType": "xs:boolean", - "value": "true", - "modelType": "Property" - }, - { - "idShort": "forms", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#hasForm" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "htv_methodName", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2011/http#methodName" - } - ] - }, - "embeddedDataSpecifications": [], - "valueType": "xs:string", - "value": "GET", - "modelType": "Property" - }, - { - "idShort": "href", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/hypermedia#hasTarget" - } - ] - }, - "embeddedDataSpecifications": [], - "valueType": "xs:string", - "value": "/counter/properties/lastChange", - "modelType": "Property" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - }, - { - "idShort": "actions", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#ActionAffordance" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [], - "modelType": "SubmodelElementCollection" - }, - { - "idShort": "events", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#EventAffordance" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - }, - { - "idShort": "ExternalDescriptor", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/ExternalDescriptor" - } - ] - }, - "embeddedDataSpecifications": [], - "value": [ - { - "idShort": "ThingDescription", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/externalDescriptorName" - } - ] - }, - "embeddedDataSpecifications": [], - "value": "/aasx/files/counter-http-simple.td.jsonld", - "contentType": "application/json", - "modelType": "File" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "Submodel" - } - ], - "conceptDescriptions": [] -} diff --git a/packages/td-tools/test/util/inverterModbus.json b/packages/td-tools/test/util/inverterModbus.json deleted file mode 100644 index 8d40b3363..000000000 --- a/packages/td-tools/test/util/inverterModbus.json +++ /dev/null @@ -1,291 +0,0 @@ -{ - "assetAdministrationShells": [ - { - "idShort": "SampleAAS", - "id": "https://example.com/ids/aas/7474_9002_6022_1115", - "assetInformation": { "assetKind": "Type" }, - "submodels": [ - { - "type": "ModelReference", - "keys": [ - { - "type": "Submodel", - "value": "uri:dev:inverter" - } - ] - } - ], - "modelType": "AssetAdministrationShell" - } - ], - "submodels": [ - { - "idShort": "AssetInterfacesDescription", - "id": "uri:dev:inverter", - "kind": "Instance", - "description": [ - { - "language": "en", - "text": "Inverter GEN44" - } - ], - "submodelElements": [ - { - "idShort": "InterfaceMODBUS_TCP", - "value": [ - { - "idShort": "title", - "valueType": "xs:string", - "value": "Inverter GEN44", - "modelType": "Property" - }, - { - "idShort": "created", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "http://purl.org/dc/terms/created" - } - ] - }, - "valueType": "xs:dateTime", - "value": "2020-12-09T16:09:53+00:00", - "modelType": "Property" - }, - { - "idShort": "modified", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "http://purl.org/dc/terms/modified" - } - ] - }, - "valueType": "xs:dateTime", - "value": "2023-01-09T18:09:12+01:01", - "modelType": "Property" - }, - { - "idShort": "support", - "semanticId": { - "type": "ExternalReference", - "keys": [ - { - "type": "GlobalReference", - "value": "https://www.w3.org/2019/wot/td#supportContact" - } - ] - }, - "valueType": "xs:anyURI", - "value": "mailto:idta@submodel.de", - "modelType": "Property" - }, - { - "idShort": "EndpointMetadata", - "value": [ - { - "idShort": "base", - "valueType": "xs:anyURI", - "value": "modbus+tcp://192.168.178.146:502/", - "modelType": "Property" - }, - { - "idShort": "contentType", - "valueType": "xs:string", - "value": "text/plain", - "modelType": "Property" - }, - { - "idShort": "modv_mostSignificantByte", - "valueType": "xs:boolean", - "value": "true", - "modelType": "Property" - }, - { - "idShort": "security", - "typeValueListElement": "ReferenceElement", - "value": [ - { - "value": { - "type": "ModelReference", - "keys": [ - { - "type": "Submodel", - "value": "uri:dev:inverter" - }, - { - "type": "SubmodelElementCollection", - "value": "InterfaceMODBUS_TCP" - }, - { - "type": "SubmodelElementCollection", - "value": "EndpointMetadata" - }, - { - "type": "SubmodelElementCollection", - "value": "securityDefinitions" - }, - { - "type": "SubmodelElementCollection", - "value": "nosec_sc" - } - ] - }, - "modelType": "ReferenceElement" - } - ], - "modelType": "SubmodelElementList" - }, - { - "idShort": "securityDefinitions", - "value": [ - { - "idShort": "nosec_sc", - "value": [ - { - "idShort": "scheme", - "valueType": "xs:string", - "value": "nosec", - "modelType": "Property" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - }, - { - "idShort": "InteractionMetadata", - "value": [ - { - "idShort": "properties", - "value": [ - { - "idShort": "device_name", - "value": [ - { - "idShort": "type", - "valueType": "xs:string", - "value": "string", - "modelType": "Property" - }, - { - "idShort": "title", - "valueType": "xs:string", - "value": "Device name", - "modelType": "Property" - }, - { - "idShort": "forms", - "value": [ - { - "idShort": "href", - "valueType": "xs:string", - "value": "modbus+tcp://192.168.178.146:502/1/40020?quantity=16", - "modelType": "Property" - }, - { - "idShort": "modv_function", - "valueType": "xs:string", - "value": "readHoldingRegisters", - "modelType": "Property" - }, - { - "idShort": "modv_type", - "valueType": "xs:string", - "value": "string", - "modelType": "Property" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - }, - { - "idShort": "soc", - "value": [ - { - "idShort": "type", - "valueType": "xs:string", - "value": "integer", - "modelType": "Property" - }, - { - "idShort": "title", - "valueType": "xs:string", - "value": "Battery SoC scaled in %", - "modelType": "Property" - }, - { - "idShort": "min_max", - "valueType": "xs:integer", - "min": "0", - "max": "100", - "modelType": "Range" - }, - { - "idShort": "forms", - "value": [ - { - "idShort": "href", - "valueType": "xs:string", - "value": "/40361?quantity=1", - "modelType": "Property" - }, - { - "idShort": "modv_function", - "valueType": "xs:string", - "value": "readHoldingRegisters", - "modelType": "Property" - }, - { - "idShort": "modv_type", - "valueType": "xs:string", - "value": "uint16be", - "modelType": "Property" - }, - { - "idShort": "contentType", - "valueType": "xs:string", - "value": "application/octet-stream", - "modelType": "Property" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - }, - { - "idShort": "actions", - "value": [], - "modelType": "SubmodelElementCollection" - }, - { - "idShort": "events", - "value": [], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "SubmodelElementCollection" - } - ], - "modelType": "Submodel" - } - ], - "conceptDescriptions": [] -} From c691a38a983a3b968b0a2d23dfdcb4a040667e1d Mon Sep 17 00:00:00 2001 From: danielpeintner Date: Thu, 21 Mar 2024 12:08:13 +0100 Subject: [PATCH 3/5] refactor: remove AID --- packages/td-tools/src/td-tools.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/td-tools/src/td-tools.ts b/packages/td-tools/src/td-tools.ts index dbfc2207d..43a367c6d 100644 --- a/packages/td-tools/src/td-tools.ts +++ b/packages/td-tools/src/td-tools.ts @@ -20,7 +20,6 @@ export * from "./thing-description"; export * from "./td-parser"; export * from "./td-helpers"; export * from "./thing-model-helpers"; -export * from "./util/asset-interface-description"; type DeepPartial = T extends Record ? { [P in keyof T]?: T[P] extends Array ? Array> : DeepPartial; From bb1a816e37ea19fe3526a79d6deaa609605b7cfb Mon Sep 17 00:00:00 2001 From: danielpeintner Date: Thu, 21 Mar 2024 12:14:34 +0100 Subject: [PATCH 4/5] refactor: remove AID browser example --- examples/browser/aid-tools.html | 77 --------------------------------- examples/browser/aid-tools.js | 42 ------------------ 2 files changed, 119 deletions(-) delete mode 100644 examples/browser/aid-tools.html delete mode 100644 examples/browser/aid-tools.js diff --git a/examples/browser/aid-tools.html b/examples/browser/aid-tools.html deleted file mode 100644 index 11263112c..000000000 --- a/examples/browser/aid-tools.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - TD-Tools node-wot tryout - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-

AID Transformation to TD via node-wot Tools

- - - - -
-
-
-
- -
-
- - - - diff --git a/examples/browser/aid-tools.js b/examples/browser/aid-tools.js deleted file mode 100644 index 3696a925f..000000000 --- a/examples/browser/aid-tools.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * In the browser, node-wot only works in client mode with limited support. - * - * After adding the following - * - * you can access all node-wot functionality / supported packages through the "Wot" global object. - * Examples: - * var assetInterfaceDescriptionUtil = new Wot.Tools.AssetInterfaceDescriptionUtil(); - * var servient = new Wot.Core.Servient(); - * var client = new Wot.Http.HttpClient(); - * - **/ - -async function transform_to_td() { - let fileElement = document.getElementById("fileInput"); - - // check if user has selected a file - if (fileElement.files.length === 0) { - alert("Please choose a file"); - return; - } - - var fileReader = new FileReader(); - fileReader.onload = function (fileLoadedEvent) { - var aidFromFileLoaded = fileLoadedEvent.target.result; - const template = { title: "AID-Conversion" }; - let tdAID = assetInterfaceDescriptionUtil.transformAAS2TD(aidFromFileLoaded, JSON.stringify(template)); - // let's pretty print the result - tdAID = JSON.stringify(JSON.parse(tdAID), null, 2); - // Note - document.getElementById("tdJSON").value = tdAID; - editorJSON.setValue(tdAID); - }; - fileReader.readAsText(fileElement.files[0], "UTF-8"); -} - -var assetInterfaceDescriptionUtil = new Wot.Tools.AssetInterfaceDescriptionUtil(); - -document.getElementById("transform").onclick = () => { - transform_to_td(); -}; From 0ff34faab53cfbcf42d1a0fc0ff65d7b7bea3e15 Mon Sep 17 00:00:00 2001 From: danielpeintner Date: Thu, 21 Mar 2024 12:17:31 +0100 Subject: [PATCH 5/5] chore: remove AID test case --- .../test/AssetInterfaceDescriptionTest.ts | 1267 ----------------- 1 file changed, 1267 deletions(-) delete mode 100644 packages/td-tools/test/AssetInterfaceDescriptionTest.ts diff --git a/packages/td-tools/test/AssetInterfaceDescriptionTest.ts b/packages/td-tools/test/AssetInterfaceDescriptionTest.ts deleted file mode 100644 index 18c23fcb3..000000000 --- a/packages/td-tools/test/AssetInterfaceDescriptionTest.ts +++ /dev/null @@ -1,1267 +0,0 @@ -/******************************************************************************** - * Copyright (c) 2022 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v. 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0, or the W3C Software Notice and - * Document License (2015-05-13) which is available at - * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document. - * - * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513 - ********************************************************************************/ - -import { suite, test } from "@testdeck/mocha"; -import { expect } from "chai"; - -import { AssetInterfaceDescriptionUtil } from "../src/util/asset-interface-description"; -import { promises as fs } from "fs"; -import { ThingDescription } from "wot-typescript-definitions"; - -import Ajv, { ValidateFunction, ErrorObject } from "ajv"; -import * as AIDSchema from "../test/util/AIDSchema.json"; - -const aidSchema = AIDSchema; -const ajv = new Ajv({ strict: false }); - -@suite("tests to verify the Asset Interface Description Utils") -class AssetInterfaceDescriptionUtilTest { - private assetInterfaceDescriptionUtil = new AssetInterfaceDescriptionUtil(); - - aidValidator = ajv.compile(aidSchema) as ValidateFunction; - - // Note: Should this be a functionality of the AID tool OR for the time beeing just a test/control - validateAID(aidSubmodel: object): { valid: boolean; errors?: string } { - const isValid = this.aidValidator(aidSubmodel); - let errors; - if (!isValid) { - errors = this.aidValidator.errors?.map((o: ErrorObject) => o.message).join("\n"); - } - return { - valid: isValid, - errors, - }; - } - - @test async "should correctly transform counterHTTP into a TD"() { - const modelAID = (await fs.readFile("test/util/counterHTTP.json")).toString(); - - const modelAIDobj = JSON.parse(modelAID); - expect(modelAIDobj).to.have.property("submodels").to.be.an("array").to.have.lengthOf(1); - const isValid = this.validateAID(modelAIDobj.submodels[0]); - expect(isValid.valid, isValid.errors).to.equal(true); - - const td = this.assetInterfaceDescriptionUtil.transformAAS2TD(modelAID, `{"title": "bla"}`); - - const tdObj = JSON.parse(td); - expect(tdObj).to.have.property("@context").that.equals("https://www.w3.org/2022/wot/td/v1.1"); - expect(tdObj).to.have.property("title").that.equals("Counter"); // should come form AAS - expect(tdObj).to.have.property("support").that.equals("https://github.com/eclipse-thingweb/node-wot/"); - - expect(tdObj).to.have.property("securityDefinitions").to.be.an("object"); - - expect(tdObj).to.have.property("security").to.be.an("array").to.have.lengthOf(1); - expect(tdObj.securityDefinitions[tdObj.security[0]]).to.have.property("scheme").that.equals("nosec"); - - // check count property - expect(tdObj).to.have.property("properties").to.have.property("count"); - expect(tdObj).to.have.property("properties").to.have.property("count").to.have.property("descriptions").to.eql({ - en: "Current counter value", - de: "Derzeitiger Zählerwert", - it: "Valore attuale del contatore", - }); - expect(tdObj) - .to.have.property("properties") - .to.have.property("count") - .to.have.property("type") - .that.equals("integer"); - expect(tdObj) - .to.have.property("properties") - .to.have.property("count") - .to.have.property("title") - .that.equals("Count"); - expect(tdObj) - .to.have.property("properties") - .to.have.property("count") - .to.have.property("observable") - .that.equals(true); - expect(tdObj) - .to.have.property("properties") - .to.have.property("count") - .to.have.property("forms") - .to.be.an("array") - .to.have.lengthOf(1); - expect(tdObj.properties.count.forms[0]) - .to.have.property("href") - .to.eql("http://plugfest.thingweb.io:8083/counter" + "/properties/count"); - expect(tdObj.properties.count.forms[0]).to.have.property("htv:methodName").to.eql("GET"); - expect(tdObj.properties.count.forms[0]).to.have.property("contentType").to.eql("application/json"); - expect(tdObj.properties.count.forms[0]).not.to.have.property("security"); - - // check countAsImage property - expect(tdObj).to.have.property("properties").to.have.property("countAsImage"); - expect(tdObj) - .to.have.property("properties") - .to.have.property("countAsImage") - .to.have.property("observable") - .that.equals(false); - expect(tdObj) - .to.have.property("properties") - .to.have.property("countAsImage") - .to.have.property("forms") - .to.be.an("array") - .to.have.lengthOf(1); - expect(tdObj.properties.countAsImage.forms[0]) - .to.have.property("href") - .to.eql("http://plugfest.thingweb.io:8083/counter" + "/properties/countAsImage"); - expect(tdObj.properties.countAsImage.forms[0]).to.have.property("htv:methodName").to.eql("GET"); - expect(tdObj.properties.countAsImage.forms[0]).to.have.property("contentType").to.eql("image/svg+xml"); - expect(tdObj.properties.countAsImage.forms[0]).not.to.have.property("security"); - - // check redDotImage property - expect(tdObj).to.have.property("properties").to.have.property("redDotImage"); - expect(tdObj) - .to.have.property("properties") - .to.have.property("redDotImage") - .to.have.property("observable") - .that.equals(false); - expect(tdObj) - .to.have.property("properties") - .to.have.property("redDotImage") - .to.have.property("forms") - .to.be.an("array") - .to.have.lengthOf(1); - expect(tdObj.properties.redDotImage.forms[0]) - .to.have.property("href") - .to.eql("http://plugfest.thingweb.io:8083/counter" + "/properties/redDotImage"); - expect(tdObj.properties.redDotImage.forms[0]).to.have.property("htv:methodName").to.eql("GET"); - expect(tdObj.properties.redDotImage.forms[0]).to.have.property("contentType").to.eql("image/png;base64"); - expect(tdObj.properties.redDotImage.forms[0]).not.to.have.property("security"); - - // check count property - expect(tdObj).to.have.property("properties").to.have.property("lastChange"); - expect(tdObj) - .to.have.property("properties") - .to.have.property("lastChange") - .to.have.property("type") - .that.equals("string"); - expect(tdObj) - .to.have.property("properties") - .to.have.property("lastChange") - .to.have.property("title") - .that.equals("Last change"); - expect(tdObj) - .to.have.property("properties") - .to.have.property("lastChange") - .to.have.property("observable") - .that.equals(true); - expect(tdObj) - .to.have.property("properties") - .to.have.property("lastChange") - .to.have.property("forms") - .to.be.an("array") - .to.have.lengthOf(1); - expect(tdObj.properties.lastChange.forms[0]) - .to.have.property("href") - .to.eql("http://plugfest.thingweb.io:8083/counter" + "/properties/lastChange"); - expect(tdObj.properties.lastChange.forms[0]).to.have.property("htv:methodName").to.eql("GET"); - expect(tdObj.properties.lastChange.forms[0]).to.have.property("contentType").to.eql("application/json"); - expect(tdObj.properties.lastChange.forms[0]).not.to.have.property("security"); - - // TODO actions and events for counter thing (TBD by AAS) - - // check RegEx capability with fully qualified submodel - const td2 = this.assetInterfaceDescriptionUtil.transformAAS2TD( - modelAID, - `{"title": "counter"}`, - "InterfaceHTTP" - ); - const td2Obj = JSON.parse(td2); - expect(tdObj).to.deep.equal(td2Obj); - - // check RegEx capability with search pattern for submodel - const td3 = this.assetInterfaceDescriptionUtil.transformAAS2TD(modelAID, `{"title": "counter"}`, "HTTP*"); - const td3Obj = JSON.parse(td3); - expect(tdObj).to.deep.equal(td3Obj); - - // check RegEx capability with fully unknown submodel - const td4 = this.assetInterfaceDescriptionUtil.transformAAS2TD(modelAID, `{"title": "counter"}`, "OPC*"); - const td4Obj = JSON.parse(td4); - expect(td4Obj).to.not.have.property("properties"); - } - - @test async "should correctly transform inverterModbus into a TD"() { - const modelAID = (await fs.readFile("test/util/inverterModbus.json")).toString(); - - const modelAIDobj = JSON.parse(modelAID); - expect(modelAIDobj).to.have.property("submodels").to.be.an("array").to.have.lengthOf(1); - const isValid = this.validateAID(modelAIDobj.submodels[0]); - expect(isValid.valid, isValid.errors).to.equal(true); - - const td = this.assetInterfaceDescriptionUtil.transformAAS2TD(modelAID, `{"title": "bla"}`); - - const tdObj = JSON.parse(td); - expect(tdObj).to.have.property("@context").that.equals("https://www.w3.org/2022/wot/td/v1.1"); - expect(tdObj).to.have.property("title").that.equals("Inverter GEN44"); // should come form AAS - expect(tdObj).to.have.property("created").that.equals("2020-12-09T16:09:53+00:00"); - expect(tdObj).to.have.property("modified").that.equals("2023-01-09T18:09:12+01:01"); - expect(tdObj).to.have.property("support").that.equals("mailto:idta@submodel.de"); - - expect(tdObj).to.have.property("securityDefinitions").to.be.an("object"); - - expect(tdObj).to.have.property("security").to.be.an("array").to.have.lengthOf(1); - expect(tdObj.securityDefinitions[tdObj.security[0]]).to.have.property("scheme").that.equals("nosec"); - - // check property device_name - expect(tdObj).to.have.property("properties").to.have.property("device_name"); - expect(tdObj) - .to.have.property("properties") - .to.have.property("device_name") - .to.have.property("type") - .that.equals("string"); - expect(tdObj) - .to.have.property("properties") - .to.have.property("device_name") - .to.have.property("title") - .that.equals("Device name"); - expect(tdObj) - .to.have.property("properties") - .to.have.property("device_name") - .to.have.property("forms") - .to.be.an("array") - .to.have.lengthOf(1); - // expect(tdObj.properties.device_name.forms[0]).to.have.property("op").to.eql("readproperty"); // AID does not know "op" - expect(tdObj.properties.device_name.forms[0]) - .to.have.property("href") - .to.eql("modbus+tcp://192.168.178.146:502/1/40020?quantity=16"); - expect(tdObj.properties.device_name.forms[0]).to.have.property("modv:function").to.eql("readHoldingRegisters"); - expect(tdObj.properties.device_name.forms[0]).to.have.property("modv:type").to.eql("string"); - expect(tdObj.properties.device_name.forms[0]).to.have.property("contentType").to.eql("text/plain"); - expect(tdObj.properties.device_name.forms[0]).not.to.have.property("security"); - - // check property soc - expect(tdObj).to.have.property("properties").to.have.property("soc"); - expect(tdObj) - .to.have.property("properties") - .to.have.property("soc") - .to.have.property("type") - .that.equals("integer"); - expect(tdObj).to.have.property("properties").to.have.property("soc").to.have.property("minimum").that.equals(0); - expect(tdObj) - .to.have.property("properties") - .to.have.property("soc") - .to.have.property("maximum") - .that.equals(100); - expect(tdObj) - .to.have.property("properties") - .to.have.property("soc") - .to.have.property("title") - .that.equals("Battery SoC scaled in %"); - expect(tdObj) - .to.have.property("properties") - .to.have.property("soc") - .to.have.property("forms") - .to.be.an("array") - .to.have.lengthOf(1); - // expect(tdObj.properties.soc.forms[0]).to.have.property("op").to.eql("readproperty"); // AID does not know "op" - expect(tdObj.properties.soc.forms[0]) - .to.have.property("href") - .to.eql("modbus+tcp://192.168.178.146:502/40361?quantity=1"); - expect(tdObj.properties.soc.forms[0]).to.have.property("modv:function").to.eql("readHoldingRegisters"); - expect(tdObj.properties.soc.forms[0]).to.have.property("modv:type").to.eql("uint16be"); - expect(tdObj.properties.soc.forms[0]).to.have.property("contentType").to.eql("application/octet-stream"); - expect(tdObj.properties.device_name.forms[0]).not.to.have.property("security"); - } - - @test async "should correctly roundtrip inverterModbus from/to AID"() { - const aasInput = (await fs.readFile("test/util/inverterModbus.json")).toString(); - const td = this.assetInterfaceDescriptionUtil.transformAAS2TD(aasInput); - - const aidOutput = this.assetInterfaceDescriptionUtil.transformTD2SM(td); - - const smObj = JSON.parse(aidOutput); - const isValid = this.validateAID(smObj); - expect(isValid.valid, isValid.errors).to.equal(true); - expect(smObj).to.have.property("idShort").that.equals("AssetInterfacesDescription"); - expect(smObj).to.have.property("submodelElements").to.be.an("array").to.have.lengthOf.greaterThan(0); - const smInterface = smObj.submodelElements[0]; - expect(smInterface).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - let hasThingTitle = false; - let hasEndpointMetadata = false; - for (const smValue of smInterface.value) { - if (smValue.idShort === "title") { - hasThingTitle = true; - expect(smValue).to.have.property("value").to.equal("Inverter GEN44"); - } else if (smValue.idShort === "EndpointMetadata") { - hasEndpointMetadata = true; - const endpointMetadata = smValue; - expect(endpointMetadata).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - let hasBase = false; - let hasSecurity = false; - let hasSecurityDefinitions = false; - for (const endpointMetadataValue of endpointMetadata.value) { - if (endpointMetadataValue.idShort === "base") { - hasBase = true; - expect(endpointMetadataValue.value).to.equal("modbus+tcp://192.168.178.146:502/"); - } else if (endpointMetadataValue.idShort === "security") { - hasSecurity = true; - expect(endpointMetadataValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - expect(endpointMetadataValue.value[0]).to.have.property("value"); - const modelReferenceValue = endpointMetadataValue.value[0].value; - expect(modelReferenceValue).to.have.property("type").to.equal("ModelReference"); - expect(modelReferenceValue).to.have.property("keys").to.be.an("array").to.have.lengthOf(5); - expect(modelReferenceValue.keys[4]).to.have.property("value").to.equal("nosec_sc"); - } else if (endpointMetadataValue.idShort === "securityDefinitions") { - hasSecurityDefinitions = true; - expect(endpointMetadataValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasBasicSC = false; - for (const securityDefinitionValue of endpointMetadataValue.value) { - if (securityDefinitionValue.idShort === "nosec_sc") { - hasBasicSC = true; - expect(securityDefinitionValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasBasic = false; - for (const sec of securityDefinitionValue.value) { - if (sec.idShort === "scheme") { - hasBasic = true; - expect(sec.value).to.equal("nosec"); - } - } - expect(hasBasic).to.equal(true); - } - } - expect(hasBasicSC).to.equal(true); - } - } - expect(hasBase).to.equal(true); - expect(hasSecurity).to.equal(true); - expect(hasSecurityDefinitions).to.equal(true); - } - } - expect(hasThingTitle, "No thing title").to.equal(true); - expect(hasEndpointMetadata, "No EndpointMetadata").to.equal(true); - - // InteractionMetadata with properties etc - let hasInteractionMetadata = false; - for (const smValue of smInterface.value) { - if (smValue.idShort === "InteractionMetadata") { - hasInteractionMetadata = true; - expect(smValue).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - let hasProperties = false; - for (const interactionValues of smValue.value) { - if (interactionValues.idShort === "properties") { - hasProperties = true; - expect(interactionValues) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasPropertyDeviceName = false; - let hasPropertySOC = false; - for (const propertyValue of interactionValues.value) { - if (propertyValue.idShort === "device_name") { - hasPropertyDeviceName = true; - expect(propertyValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasType = false; - let hasTitle = false; - let hasObservable = false; - let hasForms = false; - for (const propProperty of propertyValue.value) { - if (propProperty.idShort === "type") { - hasType = true; - expect(propProperty.value).to.equal("string"); - } else if (propProperty.idShort === "title") { - hasTitle = true; - expect(propProperty.value).to.equal("Device name"); - } else if (propProperty.idShort === "observable") { - hasObservable = true; - } else if (propProperty.idShort === "forms") { - hasForms = true; - expect(propProperty) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasHref = false; - let hasOp = false; - let hasContentType = false; - let hasModbusFunction = false; - let hasModbusType = false; - let hasModbusMostSignificantByte = false; - for (const formEntry of propProperty.value) { - if (formEntry.idShort === "href") { - hasHref = true; - expect(formEntry.value).to.equal("1/40020?quantity=16"); - } else if (formEntry.idShort === "op") { - hasOp = true; - // Note: AID does not know "op" - // expect(formEntry.value).to.equal("readproperty"); - } else if (formEntry.idShort === "contentType") { - hasContentType = true; - // Note: It uses the global contentType (locally it was not set in the AID) - expect(formEntry.value).to.equal("text/plain"); - // expect(formEntry.value).to.equal("application/octet-stream"); - } else if (formEntry.idShort === "modv_function") { - // vs. "modv:function" - hasModbusFunction = true; - expect(formEntry.value).to.equal("readHoldingRegisters"); - } else if (formEntry.idShort === "modv_type") { - // vs. "modv:type" - hasModbusType = true; - expect(formEntry.value).to.equal("string"); - } else if (formEntry.idShort === "modv_mostSignificantByte") { - // vs. "modv:mostSignificantByte" - hasModbusMostSignificantByte = true; - expect(formEntry.value).to.equal("true"); - } - } - expect(hasHref).to.equal(true); - expect(hasOp).to.equal(false); - expect(hasContentType).to.equal(true); - expect(hasModbusFunction).to.equal(true); - expect(hasModbusType).to.equal(true); - expect(hasModbusMostSignificantByte).to.equal(true); // global - } - } - expect(hasType).to.equal(true); - expect(hasTitle).to.equal(true); - expect(hasObservable).to.equal(false); // it is default only - expect(hasForms).to.equal(true); - } else if (propertyValue.idShort === "soc") { - hasPropertySOC = true; - expect(propertyValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasType = false; - let hasTitle = false; - let hasMinMax = false; - let hasForms = false; - for (const propProperty of propertyValue.value) { - if (propProperty.idShort === "type") { - hasType = true; - expect(propProperty.value).to.equal("integer"); - } else if (propProperty.idShort === "title") { - hasTitle = true; - expect(propProperty.value).to.equal("Battery SoC scaled in %"); - } else if (propProperty.idShort === "min_max") { - hasMinMax = true; - expect(propProperty.min).to.equal("0"); - expect(propProperty.max).to.equal("100"); - expect(propProperty.valueType).to.equal("xs:integer"); - expect(propProperty.modelType).to.equal("Range"); - } else if (propProperty.idShort === "forms") { - hasForms = true; - expect(propProperty) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasHref = false; - let hasOp = false; - let hasContentType = false; - let hasModbusFunction = false; - let hasModbusType = false; - for (const formEntry of propProperty.value) { - if (formEntry.idShort === "href") { - hasHref = true; - expect(formEntry.value).to.equal("40361?quantity=1"); // use base - } else if (formEntry.idShort === "op") { - hasOp = true; - // Note: AID does not know "op" - // expect(formEntry.value).to.equal("readproperty"); - } else if (formEntry.idShort === "contentType") { - hasContentType = true; - expect(formEntry.value).to.equal("application/octet-stream"); - } else if (formEntry.idShort === "modv_function") { - // vs. "modv:function" - hasModbusFunction = true; - expect(formEntry.value).to.equal("readHoldingRegisters"); - } else if (formEntry.idShort === "modv_type") { - // vs. "modv:type" - hasModbusType = true; - expect(formEntry.value).to.equal("uint16be"); - } - } - expect(hasHref).to.equal(true); - expect(hasOp).to.equal(false); - expect(hasContentType).to.equal(true); - expect(hasModbusFunction).to.equal(true); - expect(hasModbusType).to.equal(true); - } - } - expect(hasType).to.equal(true); - expect(hasTitle).to.equal(true); - expect(hasMinMax).to.equal(true); - expect(hasForms).to.equal(true); - } - } - expect(hasPropertyDeviceName).to.equal(true); - expect(hasPropertySOC).to.equal(true); - } - } - expect(hasProperties).to.equal(true); - } - } - expect(hasInteractionMetadata, "No InteractionMetadata").to.equal(true); - } - - td1Base = "https://www.example.com/"; - td1: ThingDescription = { - "@context": "https://www.w3.org/2022/wot/td/v1.1", - title: "testTD", - id: "urn:uuid:0804d572-cce8-422a-bb7c-4412fcd56f03", - created: "2021-12-09T16:09:53+00:00", - modified: "2024-01-09T18:09:12+01:01", - support: "mailto:user@foo.com", - securityDefinitions: { - basic_sc: { - scheme: "basic", - in: "header", - }, - }, - security: "basic_sc", - base: this.td1Base, - properties: { - status: { - type: "string", - observable: true, - descriptions: { - en: "Statistic", - de: "Statistik", - }, - forms: [ - { - href: "stat", - contentType: "application/json", - op: ["readproperty"], - }, - ], - }, - temperature: { - description: "Temperature value of the weather station", - type: "number", - minimum: -32.5, - maximum: 55.2, - unit: "degreeCelsius", - forms: [ - { - href: "temp", - }, - ], - }, - }, - }; - - @test async "should correctly transform sample TD1 into AID submodel"() { - const sm = this.assetInterfaceDescriptionUtil.transformTD2SM(JSON.stringify(this.td1), ["https"]); - - const smObj = JSON.parse(sm); - const isValid = this.validateAID(smObj); - expect(isValid.valid, isValid.errors).to.equal(true); - expect(smObj).to.have.property("idShort").that.equals("AssetInterfacesDescription"); - expect(smObj).to.have.property("id"); - expect(smObj).to.have.property("semanticId"); - expect(smObj).to.have.property("submodelElements").to.be.an("array").to.have.lengthOf.greaterThan(0); - const smInterface = smObj.submodelElements[0]; - expect(smInterface).to.have.property("idShort"); - expect(smInterface).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - expect(smInterface) - .to.have.property("semanticId") - .to.be.an("object") - .with.property("keys") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0) - .to.have.deep.members([ - { - type: "GlobalReference", - value: "https://admin-shell.io/idta/AssetInterfacesDescription/1/0/Interface", - }, - ]); - expect(smInterface) - .to.have.property("supplementalSemanticIds") - .to.be.an("array") - .to.have.lengthOf.greaterThan(1); // default WoT-TD and http - let hasThingTitle = false; - let hasThingCreated = false; - let hasThingModified = false; - let hasThingSupport = false; - let hasEndpointMetadata = false; - for (const smValue of smInterface.value) { - if (smValue.idShort === "title") { - hasThingTitle = true; - expect(smValue).to.have.property("value").to.equal("testTD"); - } else if (smValue.idShort === "created") { - hasThingCreated = true; - expect(smValue).to.have.property("value").to.equal("2021-12-09T16:09:53+00:00"); - } else if (smValue.idShort === "modified") { - hasThingModified = true; - expect(smValue).to.have.property("value").to.equal("2024-01-09T18:09:12+01:01"); - } else if (smValue.idShort === "support") { - hasThingSupport = true; - expect(smValue).to.have.property("value").to.equal("mailto:user@foo.com"); - } else if (smValue.idShort === "EndpointMetadata") { - hasEndpointMetadata = true; - const endpointMetadata = smValue; - expect(endpointMetadata).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - let hasBase = false; - let hasContentType = false; - let hasSecurity = false; - let hasSecurityDefinitions = false; - for (const endpointMetadataValue of endpointMetadata.value) { - if (endpointMetadataValue.idShort === "base") { - hasBase = true; - expect(endpointMetadataValue.value).to.equal(this.td1Base); - } else if (endpointMetadataValue.idShort === "contentType") { - hasContentType = true; - } else if (endpointMetadataValue.idShort === "security") { - hasSecurity = true; - expect(endpointMetadataValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - expect(endpointMetadataValue.value[0]).to.have.property("value"); - const modelReferenceValue = endpointMetadataValue.value[0].value; - expect(modelReferenceValue).to.have.property("type").to.equal("ModelReference"); - expect(modelReferenceValue).to.have.property("keys").to.be.an("array").to.have.lengthOf(5); - expect(modelReferenceValue.keys[0]).to.have.property("type").to.equal("Submodel"); - expect(modelReferenceValue.keys[0]).to.have.property("value").to.equal(smObj.id); - expect(modelReferenceValue.keys[1]) - .to.have.property("type") - .to.equal("SubmodelElementCollection"); - expect(modelReferenceValue.keys[1]).to.have.property("value").to.equal(smInterface.idShort); - expect(modelReferenceValue.keys[2]) - .to.have.property("type") - .to.equal("SubmodelElementCollection"); - expect(modelReferenceValue.keys[2]).to.have.property("value").to.equal("EndpointMetadata"); - expect(modelReferenceValue.keys[3]) - .to.have.property("type") - .to.equal("SubmodelElementCollection"); - expect(modelReferenceValue.keys[3]).to.have.property("value").to.equal("securityDefinitions"); - expect(modelReferenceValue.keys[4]) - .to.have.property("type") - .to.equal("SubmodelElementCollection"); - expect(modelReferenceValue.keys[4]).to.have.property("value").to.equal("basic_sc"); - } else if (endpointMetadataValue.idShort === "securityDefinitions") { - hasSecurityDefinitions = true; - expect(endpointMetadataValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasBasicSC = false; - for (const securityDefinitionValue of endpointMetadataValue.value) { - if (securityDefinitionValue.idShort === "basic_sc") { - hasBasicSC = true; - expect(securityDefinitionValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasBasic = false; - let hasIn = false; - for (const sec of securityDefinitionValue.value) { - if (sec.idShort === "scheme") { - hasBasic = true; - expect(sec.value).to.equal("basic"); - } else if (sec.idShort === "in") { - hasIn = true; - expect(sec.value).to.equal("header"); - } - } - expect(hasBasic).to.equal(true); - expect(hasIn).to.equal(true); - } - } - expect(hasBasicSC).to.equal(true); - } - } - expect(hasBase).to.equal(true); - expect(hasContentType).to.equal(false); - expect(hasSecurity).to.equal(true); - expect(hasSecurityDefinitions).to.equal(true); - } - } - expect(hasThingTitle, "No thing title").to.equal(true); - expect(hasThingCreated, "No thing created").to.equal(true); - expect(hasThingModified, "No thing modified").to.equal(true); - expect(hasThingSupport, "No thing support").to.equal(true); - expect(hasEndpointMetadata, "No EndpointMetadata").to.equal(true); - - // InteractionMetadata with properties etc - let hasInteractionMetadata = false; - for (const smValue of smInterface.value) { - if (smValue.idShort === "InteractionMetadata") { - hasInteractionMetadata = true; - expect(smValue).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - let hasProperties = false; - for (const interactionValues of smValue.value) { - if (interactionValues.idShort === "properties") { - hasProperties = true; - expect(interactionValues) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasPropertyStatus = false; - let hasPropertyTemperature = false; - for (const propertyValue of interactionValues.value) { - if (propertyValue.idShort === "status") { - hasPropertyStatus = true; - expect(propertyValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasType = false; - let hasTitle = false; - let hasObservable = false; - let hasForms = false; - let hasPropertyStatusDescription = false; - for (const propProperty of propertyValue.value) { - if (propProperty.idShort === "type") { - hasType = true; - expect(propProperty.value).to.equal("string"); - } else if (propProperty.idShort === "title") { - hasTitle = true; - } else if (propProperty.idShort === "observable") { - hasObservable = true; - expect(propProperty.value).to.equal("true"); - } else if (propProperty.idShort === "forms") { - hasForms = true; - expect(propProperty) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - expect(propProperty) - .to.have.property("semanticId") - .to.be.an("object") - .with.property("keys") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0) - .to.have.deep.members([ - { - type: "GlobalReference", - value: "https://www.w3.org/2019/wot/td#hasForm", - }, - ]); - let hasHref = false; - let hasContentType = false; - let hasHtvMethodName = false; - for (const formEntry of propProperty.value) { - if (formEntry.idShort === "href") { - hasHref = true; - expect(formEntry.value).to.be.oneOf([ - "stat", - "https://www.example.com/stat", - ]); - } else if (formEntry.idShort === "contentType") { - hasContentType = true; - expect(formEntry.value).to.equal("application/json"); - } else if (formEntry.idShort === "htv_methodName") { - hasHtvMethodName = true; - expect(formEntry.value).to.equal("GET"); - } - } - expect(hasHref).to.equal(true); - expect(hasContentType).to.equal(true); - expect(hasHtvMethodName).to.equal(true); - } - } - if (propertyValue.description != null) { - hasPropertyStatusDescription = true; - expect(propertyValue) - .to.have.property("description") - .to.eql([ - { - language: "en", - text: "Statistic", - }, - { - language: "de", - text: "Statistik", - }, - ]); - } - expect(hasType).to.equal(true); - expect(hasTitle).to.equal(false); - expect(hasObservable).to.equal(true); - expect(hasForms).to.equal(true); - expect(hasPropertyStatusDescription).to.equal(true); - } else if (propertyValue.idShort === "temperature") { - hasPropertyTemperature = true; - expect(propertyValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasType = false; - let hasDescription = false; - let hasUnit = false; - let hasForms = false; - for (const propProperty of propertyValue.value) { - if (propProperty.idShort === "type") { - hasType = true; - expect(propProperty.value).to.equal("number"); - } else if (propProperty.idShort === "description") { - hasDescription = true; - // Note: AID has description on upper level - } else if (propProperty.idShort === "unit") { - hasUnit = true; - expect(propProperty.value).to.equal("degreeCelsius"); - } else if (propProperty.idShort === "forms") { - hasForms = true; - } - } - expect(hasType).to.equal(true); - expect(hasDescription).to.equal(false); - expect(hasUnit).to.equal(true); - expect(hasForms).to.equal(true); - } - } - expect(hasPropertyStatus).to.equal(true); - expect(hasPropertyTemperature).to.equal(true); - } - } - expect(hasProperties).to.equal(true); - } - } - expect(hasInteractionMetadata, "No InteractionMetadata").to.equal(true); - - // Test to use all possible prefixes -> in this case it is only https - // Note: id is autogenerated (if not present) -> needs to be exluded/removed/set in TD - const sm2 = this.assetInterfaceDescriptionUtil.transformTD2SM(JSON.stringify(this.td1)); - const sm2Obj = JSON.parse(sm2); - expect(smObj).to.eql(sm2Obj); - } - - @test - async "should transform sample TD1 into JSON submodel without any properties due to unknown protocol prefix"() { - const sm = this.assetInterfaceDescriptionUtil.transformTD2SM(JSON.stringify(this.td1), ["unknown"]); - - const smObj = JSON.parse(sm); - expect(smObj).to.have.property("idShort").that.equals("AssetInterfacesDescription"); - expect(smObj).to.have.property("submodelElements").to.be.an("array").to.have.lengthOf.greaterThan(0); - const smInterface = smObj.submodelElements[0]; - expect(smInterface).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - - // InteractionMetadata with *no* properties for this protocol - let hasInteractionMetadata = false; - for (const smValue of smInterface.value) { - if (smValue.idShort === "InteractionMetadata") { - hasInteractionMetadata = true; - expect(smValue).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - for (const interactionValues of smValue.value) { - if (interactionValues.idShort === "properties") { - expect(interactionValues).to.have.property("value").to.be.an("array").to.have.lengthOf(0); - } - } - } - } - expect(hasInteractionMetadata, "No InteractionMetadata").to.equal(true); - } - - @test async "should correctly transform sample TD1 into JSON AAS"() { - const sm = this.assetInterfaceDescriptionUtil.transformTD2AAS(JSON.stringify(this.td1), ["http"]); - - const aasObj = JSON.parse(sm); - expect(aasObj).to.have.property("assetAdministrationShells").to.be.an("array"); - expect(aasObj).to.have.property("submodels").to.be.an("array").to.have.lengthOf(1); - - // Note: proper AID submodel checks done in previous test-cases - } - - td2: ThingDescription = { - "@context": "https://www.w3.org/2022/wot/td/v1.1", - title: "ModbusTD", - securityDefinitions: { - nosec_sc: { - scheme: "nosec", - }, - }, - security: "nosec_sc", - properties: { - prop: { - forms: [ - { - href: "modbus+tcp://127.0.0.1:60000/1", - op: "readproperty", - "modv:function": "readCoil", - "modv:pollingTime": 1, - }, - ], - }, - }, - }; - - @test async "should correctly transform sample TD2 into AID submodel"() { - const sm = this.assetInterfaceDescriptionUtil.transformTD2SM(JSON.stringify(this.td2)); - - const smObj = JSON.parse(sm); - // console.log("###\n\n" + JSON.stringify(smObj) + "\n\n###"); - const isValid = this.validateAID(smObj); - expect(isValid.valid, isValid.errors).to.equal(true); - expect(smObj).to.have.property("idShort").that.equals("AssetInterfacesDescription"); - expect(smObj).to.have.property("semanticId"); - expect(smObj).to.have.property("submodelElements").to.be.an("array").to.have.lengthOf.greaterThan(0); - const smInterface = smObj.submodelElements[0]; - expect(smInterface).to.have.property("idShort").to.equal("InterfaceMODBUS_TCP"); // AID does not allow "+" in idShort, see InterfaceMODBUS+TCP - expect(smInterface).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - expect(smInterface) - .to.have.property("semanticId") - .to.be.an("object") - .with.property("keys") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - expect(smInterface) - .to.have.property("supplementalSemanticIds") - .to.be.an("array") - .to.have.lengthOf.greaterThan(1); // default WoT-TD and http - let hasThingTitle = false; - let hasEndpointMetadata = false; - for (const smValue of smInterface.value) { - if (smValue.idShort === "title") { - hasThingTitle = true; - expect(smValue).to.have.property("value").to.equal("ModbusTD"); - } else if (smValue.idShort === "EndpointMetadata") { - hasEndpointMetadata = true; - const endpointMetadata = smValue; - expect(endpointMetadata).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - let hasBase = false; - let hasContentType = false; - let hasSecurity = false; - let hasSecurityDefinitions = false; - for (const endpointMetadataValue of endpointMetadata.value) { - if (endpointMetadataValue.idShort === "base") { - hasBase = true; - expect(endpointMetadataValue.value).to.equal("modbus+tcp://127.0.0.1:60000"); - } else if (endpointMetadataValue.idShort === "contentType") { - hasContentType = true; - } else if (endpointMetadataValue.idShort === "security") { - hasSecurity = true; - expect(endpointMetadataValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - expect(endpointMetadataValue.value[0]).to.have.property("value"); - const modelReferenceValue = endpointMetadataValue.value[0].value; - expect(modelReferenceValue).to.have.property("type").to.equal("ModelReference"); - expect(modelReferenceValue).to.have.property("keys").to.be.an("array").to.have.lengthOf(5); - expect(modelReferenceValue.keys[4]).to.have.property("value").to.equal("nosec_sc"); - } else if (endpointMetadataValue.idShort === "securityDefinitions") { - hasSecurityDefinitions = true; - } - } - expect(hasBase).to.equal(true); // AID requires base to exist - expect(hasContentType).to.equal(false); - expect(hasSecurity).to.equal(true); - expect(hasSecurityDefinitions).to.equal(true); - } - } - expect(hasThingTitle, "No thing title").to.equal(true); - expect(hasEndpointMetadata, "No EndpointMetadata").to.equal(true); - - // InteractionMetadata with properties etc - let hasInteractionMetadata = false; - for (const smValue of smInterface.value) { - if (smValue.idShort === "InteractionMetadata") { - hasInteractionMetadata = true; - expect(smValue).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - let hasProperties = false; - for (const interactionValues of smValue.value) { - if (interactionValues.idShort === "properties") { - hasProperties = true; - expect(interactionValues) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasPropertyProp = false; - for (const propertyValue of interactionValues.value) { - if (propertyValue.idShort === "prop") { - hasPropertyProp = true; - expect(propertyValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasType = false; - let hasTitle = false; - let hasObservable = false; - let hasForms = false; - for (const propProperty of propertyValue.value) { - if (propProperty.idShort === "type") { - hasType = true; - } else if (propProperty.idShort === "title") { - hasTitle = true; - } else if (propProperty.idShort === "observable") { - hasObservable = true; - } else if (propProperty.idShort === "forms") { - hasForms = true; - expect(propProperty) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasHref = false; - let hasContentType = false; - let hasOp = false; - let hasModbusFunction = false; - let hasModbusAddress = false; - for (const formEntry of propProperty.value) { - if (formEntry.idShort === "href") { - hasHref = true; - expect(formEntry.value).to.equal("modbus+tcp://127.0.0.1:60000/1"); - } else if (formEntry.idShort === "contentType") { - hasContentType = true; - } else if (formEntry.idShort === "op") { - hasOp = true; - // Note: AID does not know "op" - // expect(formEntry.value).to.equal("readproperty"); - } else if (formEntry.idShort === "modv_function") { - hasModbusFunction = true; - expect(formEntry.value).to.equal("readCoil"); - } else if (formEntry.idShort === "modv_pollingTime") { - hasModbusAddress = true; - expect(formEntry.value).to.equal("1"); - expect(formEntry.valueType).to.equal("xs:int"); - } - } - expect(hasHref).to.equal(true); - expect(hasContentType).to.equal(false); - expect(hasOp).to.equal(false); - expect(hasModbusFunction).to.equal(true); - expect(hasModbusAddress).to.equal(true); - } - } - expect(hasType).to.equal(false); - expect(hasTitle).to.equal(false); - expect(hasObservable).to.equal(false); - expect(hasForms).to.equal(true); - } - } - expect(hasPropertyProp).to.equal(true); - } - } - expect(hasProperties).to.equal(true); - } - } - expect(hasInteractionMetadata, "No InteractionMetadata").to.equal(true); - } - - td3: ThingDescription = { - "@context": "https://www.w3.org/2022/wot/td/v1.1", - title: "ModbusTD", - securityDefinitions: { - nosec_sc: { - scheme: "nosec", - }, - }, - security: "nosec_sc", - base: "modbus+tcp://$$addr$$:502/$$unitid$$/", - properties: { - voltage: { - forms: [ - { - href: "40001?quantity=2", - contentType: "application/octet-stream", - op: ["readproperty"], - "modv:function": "readHoldingRegisters", - "modv:type": "xsd:float", - "modv:mostSignificantByte": true, - "modv:mostSignificantWord": true, - }, - ], - }, - }, - }; - - @test async "should correctly transform sample TD3 into AID submodel"() { - const sm = this.assetInterfaceDescriptionUtil.transformTD2SM(JSON.stringify(this.td3)); - - const smObj = JSON.parse(sm); - // console.log("###\n\n" + JSON.stringify(smObj) + "\n\n###"); - const isValid = this.validateAID(smObj); - expect(isValid.valid, isValid.errors).to.equal(true); - expect(smObj).to.have.property("idShort").that.equals("AssetInterfacesDescription"); - expect(smObj).to.have.property("semanticId"); - expect(smObj).to.have.property("submodelElements").to.be.an("array").to.have.lengthOf.greaterThan(0); - const smInterface = smObj.submodelElements[0]; - expect(smInterface).to.have.property("idShort").to.equal("InterfaceMODBUS_TCP"); // AID does not allow "+" in idShort, see InterfaceMODBUS+TCP - expect(smInterface).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - expect(smInterface) - .to.have.property("semanticId") - .to.be.an("object") - .with.property("keys") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - expect(smInterface) - .to.have.property("supplementalSemanticIds") - .to.be.an("array") - .to.have.lengthOf.greaterThan(1); // default WoT-TD and http - let hasThingTitle = false; - let hasEndpointMetadata = false; - for (const smValue of smInterface.value) { - if (smValue.idShort === "title") { - hasThingTitle = true; - expect(smValue).to.have.property("value").to.equal("ModbusTD"); - } else if (smValue.idShort === "EndpointMetadata") { - hasEndpointMetadata = true; - const endpointMetadata = smValue; - expect(endpointMetadata).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - let hasBase = false; - let hasContentType = false; - let hasSecurity = false; - let hasSecurityDefinitions = false; - for (const endpointMetadataValue of endpointMetadata.value) { - if (endpointMetadataValue.idShort === "base") { - hasBase = true; - expect(endpointMetadataValue.value).to.equal("modbus+tcp://$$addr$$:502/$$unitid$$/"); - } else if (endpointMetadataValue.idShort === "contentType") { - hasContentType = true; - } else if (endpointMetadataValue.idShort === "security") { - hasSecurity = true; - expect(endpointMetadataValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - expect(endpointMetadataValue.value[0]).to.have.property("value"); - const modelReferenceValue = endpointMetadataValue.value[0].value; - expect(modelReferenceValue).to.have.property("type").to.equal("ModelReference"); - expect(modelReferenceValue).to.have.property("keys").to.be.an("array").to.have.lengthOf(5); - expect(modelReferenceValue.keys[4]).to.have.property("value").to.equal("nosec_sc"); - } else if (endpointMetadataValue.idShort === "securityDefinitions") { - hasSecurityDefinitions = true; - } - } - expect(hasBase).to.equal(true); // AID requires base to exist - expect(hasContentType).to.equal(false); - expect(hasSecurity).to.equal(true); - expect(hasSecurityDefinitions).to.equal(true); - } - } - expect(hasThingTitle, "No thing title").to.equal(true); - expect(hasEndpointMetadata, "No EndpointMetadata").to.equal(true); - - // InteractionMetadata with properties etc - let hasInteractionMetadata = false; - for (const smValue of smInterface.value) { - if (smValue.idShort === "InteractionMetadata") { - hasInteractionMetadata = true; - expect(smValue).to.have.property("value").to.be.an("array").to.have.lengthOf.greaterThan(0); - let hasProperties = false; - for (const interactionValues of smValue.value) { - if (interactionValues.idShort === "properties") { - hasProperties = true; - expect(interactionValues) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasPropertyVoltage = false; - for (const propertyValue of interactionValues.value) { - if (propertyValue.idShort === "voltage") { - hasPropertyVoltage = true; - expect(propertyValue) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasType = false; - let hasTitle = false; - let hasObservable = false; - let hasForms = false; - for (const propProperty of propertyValue.value) { - if (propProperty.idShort === "type") { - hasType = true; - } else if (propProperty.idShort === "title") { - hasTitle = true; - } else if (propProperty.idShort === "observable") { - hasObservable = true; - } else if (propProperty.idShort === "forms") { - hasForms = true; - expect(propProperty) - .to.have.property("value") - .to.be.an("array") - .to.have.lengthOf.greaterThan(0); - let hasHref = false; - let hasContentType = false; - let hasOp = false; - let hasModbusFunction = false; - let hasModbusType = false; - let hasModbusMostSignificantByte = false; - let hasModbusMostSignificantWord = false; - for (const formEntry of propProperty.value) { - if (formEntry.idShort === "href") { - hasHref = true; - expect(formEntry.value).to.be.oneOf([ - "40001?quantity=2", - "modbus+tcp://$$addr$$:502/$$unitid$$/40001?quantity=2", - ]); // absolute or relative - } else if (formEntry.idShort === "contentType") { - hasContentType = true; - expect(formEntry.value).to.equal("application/octet-stream"); - } else if (formEntry.idShort === "op") { - hasOp = true; - // Note: AID does not know "op" - // expect(formEntry.value).to.equal("readproperty"); - } else if (formEntry.idShort === "modv_function") { - hasModbusFunction = true; - expect(formEntry.value).to.equal("readHoldingRegisters"); - } else if (formEntry.idShort === "modv_type") { - hasModbusType = true; - expect(formEntry.value).to.equal("xsd:float"); - expect(formEntry.valueType).to.equal("xs:string"); - } else if (formEntry.idShort === "modv_mostSignificantByte") { - hasModbusMostSignificantByte = true; - expect(formEntry.value).to.equal("true"); - expect(formEntry.valueType).to.equal("xs:boolean"); - } else if (formEntry.idShort === "modv_mostSignificantWord") { - hasModbusMostSignificantWord = true; - expect(formEntry.value).to.equal("true"); - expect(formEntry.valueType).to.equal("xs:boolean"); - } - } - expect(hasHref).to.equal(true); - expect(hasContentType).to.equal(true); - expect(hasOp).to.equal(false); - expect(hasModbusFunction).to.equal(true); - expect(hasModbusType).to.equal(true); - expect(hasModbusMostSignificantByte).to.equal(true); - expect(hasModbusMostSignificantWord).to.equal(true); - } - } - expect(hasType).to.equal(false); - expect(hasTitle).to.equal(false); - expect(hasObservable).to.equal(false); - expect(hasForms).to.equal(true); - } - } - expect(hasPropertyVoltage).to.equal(true); - } - } - expect(hasProperties).to.equal(true); - } - } - expect(hasInteractionMetadata, "No InteractionMetadata").to.equal(true); - } - - @test.skip async "should correctly transform counter TD into JSON AAS"() { - // built-in fetch requires Node.js 18+ - const response = await fetch("http://plugfest.thingweb.io:8083/counter"); - const counterTD = await response.json(); - - const sm = this.assetInterfaceDescriptionUtil.transformTD2AAS(JSON.stringify(counterTD), ["http"]); // "coap" - console.log("XXX AAS\n\n" + sm + "\n\nXXX"); - - const aasObj = JSON.parse(sm); - // TODO proper AID submodel checks - expect(aasObj).to.have.property("assetAdministrationShells").to.be.an("array"); - expect(aasObj).to.have.property("submodels").to.be.an("array").to.have.lengthOf(1); - const submodel = aasObj.submodels[0]; - console.log("YYY AID\n\n" + JSON.stringify(submodel) + "\n\nYYY"); - const isValid = this.validateAID(submodel); - expect(isValid.valid, isValid.errors).to.equal(true); - expect(submodel).to.have.property("submodelElements").to.be.an("array").to.have.lengthOf(1); - } -}