Draw the rest of the f-ing owl 🦉

This commit is contained in:
Daniel Kluge
2023-12-06 16:15:54 +01:00
parent 64279a6efa
commit 76ec6e4c9d
13 changed files with 1981 additions and 132 deletions
+428
View File
@@ -0,0 +1,428 @@
{
"idShort": "AssetInterfacesDescription",
"id": "www.example.com/ids/sm/7142_2140_7032_7989",
"kind": "Instance",
"submodelElements": [
{
"idShort": "MQTT",
"typeValueListElement": "SubmodelElement",
"value": [
{
"idShort": "DEL-00",
"semanticId": {
"type": "ExternalReference",
"keys": []
},
"embeddedDataSpecifications": [],
"value": [
{
"idShort": "EndpointMetadata",
"semanticId": {
"type": "ExternalReference",
"keys": []
},
"embeddedDataSpecifications": [],
"value": [
{
"idShort": "titles",
"value": [
{
"language": "en",
"text": "AID and AIMC Test"
}
],
"modelType": "MultiLanguageProperty"
},
{
"idShort": "base",
"semanticId": {
"type": "ExternalReference",
"keys": []
},
"embeddedDataSpecifications": [],
"valueType": "xs:string",
"value": "mqtt://127.0.0.1:1883",
"modelType": "Property"
},
{
"idShort": "mqv:version",
"semanticId": {
"type": "ExternalReference",
"keys": []
},
"embeddedDataSpecifications": [],
"valueType": "xs:string",
"value": "5.0",
"modelType": "Property"
},
{
"idShort": "contentType",
"semanticId": {
"type": "ExternalReference",
"keys": []
},
"embeddedDataSpecifications": [],
"valueType": "xs:string",
"value": "application/json",
"modelType": "Property"
},
{
"idShort": "securityDefinitions",
"semanticId": {
"type": "ExternalReference",
"keys": []
},
"embeddedDataSpecifications": [],
"value": [
{
"idShort": "basic",
"semanticId": {
"type": "ExternalReference",
"keys": []
},
"embeddedDataSpecifications": [],
"value": [
{
"idShort": "in",
"semanticId": {
"type": "ExternalReference",
"keys": []
},
"embeddedDataSpecifications": [],
"valueType": "xs:string",
"value": "header",
"modelType": "Property"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "SubmodelElementCollection"
},
{
"idShort": "AssetsReservedClientName",
"valueType": "xs:string",
"value": "thisandthat",
"modelType": "Property"
}
],
"modelType": "SubmodelElementCollection"
},
{
"idShort": "InterfaceMetadata",
"semanticId": {
"type": "ExternalReference",
"keys": []
},
"embeddedDataSpecifications": [],
"value": [
{
"idShort": "Properties",
"semanticId": {
"type": "ExternalReference",
"keys": []
},
"embeddedDataSpecifications": [],
"typeValueListElement": "SubmodelElementCollection",
"value": [
{
"idShort": "DEL-00",
"value": [
{
"idShort": "title",
"valueType": "xs:string",
"value": "TestingParameter01",
"modelType": "Property"
},
{
"idShort": "observable",
"valueType": "xs:boolean",
"value": "true",
"modelType": "Property"
},
{
"idShort": "type",
"valueType": "xs:string",
"value": "integer",
"modelType": "Property"
},
{
"idShort": "forms",
"typeValueListElement": "SubmodelElementCollection",
"value": [
{
"idShort": "",
"value": [
{
"idShort": "href",
"valueType": "xs:string",
"value": "/testtopic/testparam1",
"modelType": "Property"
},
{
"idShort": "contentType",
"valueType": "xs:string",
"value": "application/json",
"modelType": "Property"
},
{
"idShort": "op",
"valueType": "xs:string",
"value": "readProperty",
"modelType": "Property"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "SubmodelElementList"
}
],
"modelType": "SubmodelElementCollection"
},
{
"idShort": "DEL-01",
"value": [
{
"idShort": "title",
"valueType": "xs:string",
"value": "TestingParameter02",
"modelType": "Property"
},
{
"idShort": "observable",
"valueType": "xs:boolean",
"value": "false",
"modelType": "Property"
},
{
"idShort": "type",
"valueType": "xs:string",
"value": "boolean",
"modelType": "Property"
},
{
"idShort": "forms",
"typeValueListElement": "SubmodelElementCollection",
"value": [
{
"idShort": "",
"value": [
{
"idShort": "href",
"valueType": "xs:string",
"value": "mqtt://127.0.0.1:1883/testtopic/testparam2",
"modelType": "Property"
},
{
"idShort": "contentType",
"valueType": "xs:string",
"value": "application/json",
"modelType": "Property"
},
{
"idShort": "op",
"valueType": "xs:string",
"value": "readProperty",
"modelType": "Property"
}
],
"modelType": "SubmodelElementCollection"
},
{
"idShort": "",
"value": [
{
"idShort": "href",
"valueType": "xs:string",
"value": "mqtt://127.0.0.1:1883/testtopic/testparam2/write",
"modelType": "Property"
},
{
"idShort": "contentType",
"valueType": "xs:string",
"value": "application/json",
"modelType": "Property"
},
{
"idShort": "op",
"valueType": "xs:string",
"value": "writeProperty",
"modelType": "Property"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "SubmodelElementList"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "SubmodelElementList"
},
{
"idShort": "Actions",
"semanticId": {
"type": "ExternalReference",
"keys": []
},
"embeddedDataSpecifications": [],
"typeValueListElement": "SubmodelElementCollection",
"value": [
{
"idShort": "DEL-00",
"value": [
{
"idShort": "async",
"valueType": "xs:boolean",
"value": "false",
"modelType": "Property"
},
{
"idShort": "forms",
"typeValueListElement": "SubmodelElementCollection",
"value": [
{
"idShort": "",
"value": [
{
"idShort": "href",
"valueType": "xs:string",
"value": "/testtopic/testoperation1",
"modelType": "Property"
},
{
"idShort": "contentType",
"valueType": "xs:string",
"value": "application/json",
"modelType": "Property"
},
{
"idShort": "op",
"valueType": "xs:string",
"value": "invokeAction",
"modelType": "Property"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "SubmodelElementList"
}
],
"modelType": "SubmodelElementCollection"
},
{
"idShort": "DEL-01",
"value": [
{
"idShort": "async",
"valueType": "xs:boolean",
"value": "false",
"modelType": "Property"
},
{
"idShort": "forms",
"typeValueListElement": "SubmodelElementCollection",
"value": [
{
"idShort": "",
"value": [
{
"idShort": "href",
"valueType": "xs:string",
"value": "/testtopic/testoperation2",
"modelType": "Property"
},
{
"idShort": "contentType",
"valueType": "xs:string",
"value": "application/json",
"modelType": "Property"
},
{
"idShort": "op",
"valueType": "xs:string",
"value": "invokeAction",
"modelType": "Property"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "SubmodelElementList"
}
],
"modelType": "SubmodelElementCollection"
},
{
"idShort": "DEL-02",
"value": [
{
"idShort": "async",
"valueType": "xs:boolean",
"value": "false",
"modelType": "Property"
},
{
"idShort": "forms",
"typeValueListElement": "SubmodelElementCollection",
"value": [
{
"idShort": "",
"value": [
{
"idShort": "href",
"valueType": "xs:string",
"value": "/testtopic/testoperation3",
"modelType": "Property"
},
{
"idShort": "contentType",
"valueType": "xs:string",
"value": "application/json",
"modelType": "Property"
},
{
"idShort": "op",
"valueType": "xs:string",
"value": "invokeAction",
"modelType": "Property"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "SubmodelElementList"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "SubmodelElementList"
},
{
"idShort": "Events",
"semanticId": {
"type": "ExternalReference",
"keys": []
},
"embeddedDataSpecifications": [],
"typeValueListElement": "SubmodelElementCollection",
"value": [],
"modelType": "SubmodelElementList"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "SubmodelElementList"
}
],
"modelType": "Submodel"
}
@@ -0,0 +1,341 @@
{
"idShort": "AssetInterfacesMappingConfiguration",
"id": "https://example.com/ids/sm/4342_8060_7032_0872",
"kind": "Instance",
"submodelElements": [
{
"idShort": "MQTT",
"typeValueListElement": "SubmodelElementCollection",
"value": [
{
"idShort": "DEL-00",
"value": [
{
"idShort": "EndpointMetaDataReference",
"value": {
"type": "ModelReference",
"keys": [
{
"type": "Submodel",
"value": "www.example.com/ids/sm/7142_2140_7032_7989"
},
{
"type": "SubmodelElementList",
"value": "MQTT"
},
{
"type": "SubmodelElementCollection",
"value": "DEL-00"
},
{
"type": "SubmodelElementCollection",
"value": "EndpointMetadata"
}
]
},
"modelType": "ReferenceElement"
},
{
"idShort": "MappingConfiguration",
"typeValueListElement": "SubmodelElement",
"value": [
{
"idShort": "DEL-00",
"value": [
{
"idShort": "InterfaceMetaDataReference",
"value": {
"type": "ModelReference",
"keys": [
{
"type": "Submodel",
"value": "www.example.com/ids/sm/7142_2140_7032_7989"
},
{
"type": "SubmodelElementList",
"value": "MQTT"
},
{
"type": "SubmodelElementCollection",
"value": "DEL-00"
},
{
"type": "SubmodelElementCollection",
"value": "InterfaceMetadata"
}
]
},
"modelType": "ReferenceElement"
},
{
"idShort": "SourceSinkMappings",
"typeValueListElement": "SubmodelElement",
"value": [
{
"idShort": "DEL-00",
"first": {
"type": "ModelReference",
"keys": [
{
"type": "Submodel",
"value": "www.example.com/ids/sm/7142_2140_7032_7989"
},
{
"type": "SubmodelElementList",
"value": "MQTT"
},
{
"type": "SubmodelElementCollection",
"value": "DEL-00"
},
{
"type": "SubmodelElementCollection",
"value": "InterfaceMetadata"
},
{
"type": "SubmodelElementList",
"value": "Properties"
},
{
"type": "SubmodelElementCollection",
"value": "DEL-00"
}
]
},
"second": {
"type": "ModelReference",
"keys": [
{
"type": "Submodel",
"value": "https://example.com/ids/sm/8055_9060_7032_0793"
},
{
"type": "SubmodelElementCollection",
"value": "Params"
},
{
"type": "Property",
"value": "TestParam1"
}
]
},
"modelType": "RelationshipElement"
},
{
"idShort": "DEL-01",
"first": {
"type": "ModelReference",
"keys": [
{
"type": "Submodel",
"value": "www.example.com/ids/sm/7142_2140_7032_7989"
},
{
"type": "SubmodelElementList",
"value": "MQTT"
},
{
"type": "SubmodelElementCollection",
"value": "DEL-00"
},
{
"type": "SubmodelElementCollection",
"value": "InterfaceMetadata"
},
{
"type": "SubmodelElementList",
"value": "Properties"
},
{
"type": "SubmodelElementCollection",
"value": "DEL-01"
}
]
},
"second": {
"type": "ModelReference",
"keys": [
{
"type": "Submodel",
"value": "https://example.com/ids/sm/8055_9060_7032_0793"
},
{
"type": "SubmodelElementCollection",
"value": "Params"
},
{
"type": "Property",
"value": "TestParam2"
}
]
},
"modelType": "RelationshipElement"
},
{
"idShort": "DEL-02",
"first": {
"type": "ModelReference",
"keys": [
{
"type": "Submodel",
"value": "www.example.com/ids/sm/7142_2140_7032_7989"
},
{
"type": "SubmodelElementList",
"value": "MQTT"
},
{
"type": "SubmodelElementCollection",
"value": "DEL-00"
},
{
"type": "SubmodelElementCollection",
"value": "InterfaceMetadata"
},
{
"type": "SubmodelElementList",
"value": "Actions"
},
{
"type": "SubmodelElementCollection",
"value": "DEL-00"
}
]
},
"second": {
"type": "ModelReference",
"keys": [
{
"type": "Submodel",
"value": "https://example.com/ids/sm/8055_9060_7032_0793"
},
{
"type": "SubmodelElementCollection",
"value": "Operations"
},
{
"type": "Operation",
"value": "TestOperation1"
}
]
},
"modelType": "RelationshipElement"
},
{
"idShort": "DEL-03",
"first": {
"type": "ModelReference",
"keys": [
{
"type": "Submodel",
"value": "www.example.com/ids/sm/7142_2140_7032_7989"
},
{
"type": "SubmodelElementList",
"value": "MQTT"
},
{
"type": "SubmodelElementCollection",
"value": "DEL-00"
},
{
"type": "SubmodelElementCollection",
"value": "InterfaceMetadata"
},
{
"type": "SubmodelElementList",
"value": "Actions"
},
{
"type": "SubmodelElementCollection",
"value": "DEL-01"
}
]
},
"second": {
"type": "ModelReference",
"keys": [
{
"type": "Submodel",
"value": "https://example.com/ids/sm/8055_9060_7032_0793"
},
{
"type": "SubmodelElementCollection",
"value": "Operations"
},
{
"type": "Operation",
"value": "TestOperation2"
}
]
},
"modelType": "RelationshipElement"
},
{
"idShort": "DEL-04",
"first": {
"type": "ModelReference",
"keys": [
{
"type": "Submodel",
"value": "www.example.com/ids/sm/7142_2140_7032_7989"
},
{
"type": "SubmodelElementList",
"value": "MQTT"
},
{
"type": "SubmodelElementCollection",
"value": "DEL-00"
},
{
"type": "SubmodelElementCollection",
"value": "InterfaceMetadata"
},
{
"type": "SubmodelElementList",
"value": "Actions"
},
{
"type": "SubmodelElementCollection",
"value": "DEL-02"
}
]
},
"second": {
"type": "ModelReference",
"keys": [
{
"type": "Submodel",
"value": "https://example.com/ids/sm/8055_9060_7032_0793"
},
{
"type": "SubmodelElementCollection",
"value": "Operations"
},
{
"type": "Operation",
"value": "TestOperation3"
}
]
},
"modelType": "RelationshipElement"
}
],
"modelType": "SubmodelElementList"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "SubmodelElementList"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "SubmodelElementList"
}
],
"modelType": "Submodel"
}
+86
View File
@@ -0,0 +1,86 @@
{
"idShort": "OperationalData",
"id": "https://example.com/ids/sm/8055_9060_7032_0793",
"submodelElements": [
{
"idShort": "Params",
"value": [
{
"idShort": "TestParam1",
"valueType": "xs:string",
"modelType": "Property"
},
{
"idShort": "TestParam2",
"valueType": "xs:string",
"modelType": "Property"
}
],
"modelType": "SubmodelElementCollection"
},
{
"idShort": "Operations",
"value": [
{
"idShort": "TestOperation1",
"description": [
{
"language": "de",
"text": "Operation, sync mit keinem In/Out"
}
],
"modelType": "Operation"
},
{
"idShort": "TestOperation2",
"description": [
{
"language": "de",
"text": "Operation, sync mit einem Input"
}
],
"inputVariables": [
{
"value": {
"idShort": "TestInput",
"valueType": "xs:string",
"modelType": "Property"
}
}
],
"modelType": "Operation"
},
{
"idShort": "TestOperation3",
"description": [
{
"language": "de",
"text": "Operation, sync mit einem Input und einem Output"
}
],
"inputVariables": [
{
"value": {
"idShort": "TestInput",
"valueType": "xs:int",
"modelType": "Property"
}
}
],
"outputVariables": [
{
"value": {
"idShort": "TestOutput",
"valueType": "xs:float",
"modelType": "Property"
}
}
],
"modelType": "Operation"
}
],
"modelType": "SubmodelElementCollection"
}
],
"modelType": "Submodel"
}
+5 -5
View File
@@ -198,7 +198,7 @@ export default class HTTPInterfaceServer extends AbstractInterfaceServer<Config>
const prop = Traverser.getElementByIdPath(this.aas, sm, idShortPath); const prop = Traverser.getElementByIdPath(this.aas, sm, idShortPath);
if (prop === null || !AASCoreTypes.isProperty(prop)) return res.status(404).end(); if (prop === null || !AASCoreTypes.isProperty(prop)) return res.status(404).end();
const request: Types.RequestTypes.Request = req.method === "GET" ? { type: "READ", target: prop } : { type: "WRITE", target: prop, extraData: { value: req.body } }; const request: Types.RequestTypes.Request = req.method === "GET" ? { type: "readProperty", target: prop } : { type: "writeProperty", target: prop, extraData: { value: req.body } };
const value = this.onRequestCallback(request); const value = this.onRequestCallback(request);
@@ -215,7 +215,7 @@ export default class HTTPInterfaceServer extends AbstractInterfaceServer<Config>
// TODO // TODO
// Parameter? // Parameter?
const success = this.onRequestCallback({ type: "CALL", target: op, extraData: { args: req.body } }); const success = this.onRequestCallback({ type: "invokeAction", target: op, extraData: { args: req.body, async: false } });
return res.send(success ? 204 : 500).end(); return res.send(success ? 204 : 500).end();
} }
@@ -226,7 +226,7 @@ export default class HTTPInterfaceServer extends AbstractInterfaceServer<Config>
// TODO // TODO
// Invoke operation and get handle // Invoke operation and get handle
const request: Types.RequestTypes.Request = { type: "CALL-ASYNC", target: op, extraData: { args: req.body } }; const request: Types.RequestTypes.Request = { type: "invokeAction", target: op, extraData: { args: req.body, async: true } };
const handle = this.onRequestCallback(request); const handle = this.onRequestCallback(request);
@@ -241,7 +241,7 @@ export default class HTTPInterfaceServer extends AbstractInterfaceServer<Config>
case "operation-status": { case "operation-status": {
if (req.method !== "GET") return res.status(405).end(); if (req.method !== "GET") return res.status(405).end();
const state = this.onRequestCallback({ type: "GET-OP-STATE", target: handle }); const state = this.onRequestCallback({ type: "xAsyncActionState", target: handle });
if (state === undefined) return res.status(404).end(); if (state === undefined) return res.status(404).end();
@@ -253,7 +253,7 @@ export default class HTTPInterfaceServer extends AbstractInterfaceServer<Config>
case "operation-result": { case "operation-result": {
if (req.method !== "GET") return res.status(405).end(); if (req.method !== "GET") return res.status(405).end();
const result = this.onRequestCallback({ type: "GET-OP-RESULT", target: handle }); const result = this.onRequestCallback({ type: "xAsyncActionResult", target: handle });
if (result === null) return res.status(404).end(); if (result === null) return res.status(404).end();
return res.json({ return res.json({
+71 -35
View File
@@ -1,6 +1,7 @@
import * as mqtt from "mqtt"; import * as mqtt from "mqtt";
import { AbstractConnectionObject } from "aas-multimessagebroker"; import { AbstractConnectionObject } from "aas-multimessagebroker";
import type { AASCoreTypes } from "aas-multimessagebroker"; import { AASCoreTypes, Types } from "aas-multimessagebroker";
import { MMBEvent } from "aas-multimessagebroker/dist/types/requests";
/** /**
* This is an example module for the asset connection object. * This is an example module for the asset connection object.
@@ -70,7 +71,10 @@ export default class MQTTConnector extends AbstractConnectionObject<mqtt.IClient
this.messageStore[topic] = message.toString("utf-8"); this.messageStore[topic] = message.toString("utf-8");
// Notify observers // Notify observers
if (this.observerStore[topic] !== undefined) { if (this.observerStore[topic] !== undefined) {
this.observerStore[topic].forEach(cb => cb(message.toString("utf-8"))); this.observerStore[topic].forEach(sub => sub.cb({ type: "event", value: message.toString("utf-8"), target: sub.target}));
}
if (this.eventSubStore[topic] !== undefined) {
this.eventSubStore[topic].forEach(sub => sub.cb({ type: "event", value: message.toString("utf-8"), target: sub.target}));
} }
}); });
this.client.subscribe("#"); this.client.subscribe("#");
@@ -87,6 +91,10 @@ export default class MQTTConnector extends AbstractConnectionObject<mqtt.IClient
this.client = null; this.client = null;
} }
private assertConnected(): void {
if (!this.client || !this.client.connected) throw new Error("Not connected");
}
/** /**
* Read a property value from the asset. * Read a property value from the asset.
* *
@@ -98,16 +106,13 @@ export default class MQTTConnector extends AbstractConnectionObject<mqtt.IClient
* @override * @override
* @public * @public
*/ */
public readProperty(prop: AASCoreTypes.Property): any { public readProperty(_target: AASCoreTypes.Property, mapping: Types.RequestTypes.ConnectionConfiguration): any {
const cc = this.mapper.get(prop); const errorReturn = mapping.default ?? null;
if (cc === undefined) return null;
const errorReturn = cc.default ?? null;
if (!this.client || !this.client.connected) return errorReturn; if (!this.client || !this.client.connected) return errorReturn;
const value = this.messageStore[cc.forms.href.substring(1)]; const value = this.messageStore[mapping.forms[0].href.substring(1)];
if (value === undefined) return errorReturn; if (value === undefined) return errorReturn;
switch (cc.type) { switch (mapping.type) {
case "integer": case "integer":
return Number.parseInt(value); return Number.parseInt(value);
case "float": case "float":
@@ -129,11 +134,10 @@ export default class MQTTConnector extends AbstractConnectionObject<mqtt.IClient
* @override * @override
* @public * @public
*/ */
public writeProperty(prop: AASCoreTypes.Property, value: any): boolean { public writeProperty(_target: AASCoreTypes.Property, mapping: Types.RequestTypes.ConnectionConfiguration, value: any): boolean {
const cc = this.mapper.get(prop); if (!this.client || !this.client.connected) return false;
if (cc === undefined || !this.client || !this.client.connected) return false;
const topic = cc.forms.href.substring(1); const topic = mapping.forms[0].href.substring(1);
if (topic === undefined) return false; if (topic === undefined) return false;
this.client.publish(topic, value.toString()); this.client.publish(topic, value.toString());
@@ -149,17 +153,22 @@ export default class MQTTConnector extends AbstractConnectionObject<mqtt.IClient
* @override * @override
* @public * @public
*/ */
public observeProperty(prop: AASCoreTypes.Property, callback: (value: any) => void): boolean { public observeProperty(target: AASCoreTypes.Property, mapping: Types.RequestTypes.ConnectionConfiguration, cb: (value: Types.RequestTypes.MMBEvent) => void): boolean {
const cc = this.mapper.get(prop); if (!mapping.observable || !this.client || !this.client.connected) return false;
if (cc === undefined || !cc.observable || !this.client || !this.client.connected) return false;
const topic = cc.forms.href.substring(1); const topic = mapping.forms[0].href.substring(1);
if (this.observerStore[topic] === undefined) this.observerStore[topic] = [callback]; if (this.observerStore[topic] === undefined) this.observerStore[topic] = [{ target, cb }];
else this.observerStore[topic].push(callback); else this.observerStore[topic].push({ target, cb });
return true; return true;
} }
public unobserveProperty(target: AASCoreTypes.Property, mapping: Types.RequestTypes.ConnectionConfiguration): void {
const topic = mapping.forms[0].href.substring(1);
this.observerStore[topic];
//! TODO
}
/** /**
* Calls an action synchronously. * Calls an action synchronously.
* @param action Action * @param action Action
@@ -168,13 +177,22 @@ export default class MQTTConnector extends AbstractConnectionObject<mqtt.IClient
* @returns Return value of action. * @returns Return value of action.
* @override * @override
* @public * @public
* @alpha * @beta
*/ */
public callActionSync(action: AASCoreTypes.Operation, args: Record<string, any>): any { public callActionSync(_target: AASCoreTypes.Operation, mapping: Types.RequestTypes.ConnectionConfiguration, args: Record<string, any>): any {
// TODO this.assertConnected();
// Vorher mal ne ordentliche Mapping-Definition
throw new Error("Method not implemented."); const form: Types.AIDTypes.InterfaceFormMQTTAction = mapping.forms[0];
const topic = form.href.substring(1);
if (topic === undefined || !mapping.forms) throw new Error("Mapping invalid.");
const message = JSON.stringify(args);
this.execute(form.mqv_controlPacketValue ?? "PUBLISH", topic, message);
// There is currently no way to get the result of an action
// Not because we cannot wait but because we don't know where the result is sent!
return;
} }
/** /**
@@ -187,11 +205,17 @@ export default class MQTTConnector extends AbstractConnectionObject<mqtt.IClient
* @public * @public
* @alpha * @alpha
*/ */
public callActionAsync(action: AASCoreTypes.Operation, args: Record<string, any>): string | null { public callActionAsync(_target: AASCoreTypes.Operation, mapping: Types.RequestTypes.ConnectionConfiguration, args: Record<string, any>): string {
// TODO this.assertConnected();
// Vorher mal ne ordentliche Mapping-Definition
throw new Error("Method not implemented."); const form: Types.AIDTypes.InterfaceFormMQTTAction = mapping.forms[0];
const topic = form.href.substring(1);
if (topic === undefined || !mapping.forms) throw new Error("Mapping invalid.");
const message = JSON.stringify(args);
this.execute(form.mqv_controlPacketValue ?? "PUBLISH", topic, message);
return this.generateAsyncHandle();
} }
/** /**
@@ -203,11 +227,14 @@ export default class MQTTConnector extends AbstractConnectionObject<mqtt.IClient
* @public * @public
* @alpha * @alpha
*/ */
public subscribeEvent(event: AASCoreTypes.BasicEventElement, callback: (event: AASCoreTypes.BasicEventElement) => void): boolean { public subscribeEvent(target: AASCoreTypes.Class, mapping: Types.RequestTypes.ConnectionConfiguration, cb: (event: Types.RequestTypes.MMBEvent) => void): boolean {
// TODO if (!mapping.observable || !this.client || !this.client.connected) return false;
// Vorher mal ne ordentliche Mapping-Definition
throw new Error("Method not implemented."); const topic = mapping.forms[0].href.substring(1);
if (this.eventSubStore[topic] === undefined) this.eventSubStore[topic] = [{ target, cb }];
else this.eventSubStore[topic].push({ target, cb });
return true;
} }
/** /**
@@ -217,11 +244,20 @@ export default class MQTTConnector extends AbstractConnectionObject<mqtt.IClient
* @public * @public
* @alpha * @alpha
*/ */
public unsubscribeEvent(event: AASCoreTypes.BasicEventElement): void { public unsubscribeEvent(event: AASCoreTypes.Class, mapping: Types.RequestTypes.ConnectionConfiguration): void {
// TODO // TODO
// Vorher mal ne ordentliche Mapping-Definition // How do we know which event to unsubscribe from?
}
throw new Error("Method not implemented."); private execute(packetType: "PUBLISH" | "SUBSCRIBE" | "UNSUBSCRIBE", topic: string, message?: string) {
this.assertConnected();
if (this.client){
switch (packetType) {
case "PUBLISH": return this.client.publish(topic, message ?? "1");
case "SUBSCRIBE": return this.client.subscribe(topic);
case "UNSUBSCRIBE": return this.client.unsubscribe(topic);
}
}
} }
} }
+5 -4
View File
@@ -1,9 +1,10 @@
import type { types } from "@aas-core-works/aas-core3.0-typescript"; import type { types } from "@aas-core-works/aas-core3.0-typescript";
import type { ConnectionConfiguration, AIMCMap } from "./types/aimcConf"; import type { AIMCMap } from "./types/aimcConf";
import type { ConnectionConfiguration } from "./types/requests";
import type { InterfaceAction, InterfaceActionForm, InterfaceEvent, InterfaceEventForm, InterfaceProperty, InterfacePropertyForm } from "./types/aidConf";
import AIMCParser from "./parser/AIMCParser"; import AIMCParser from "./parser/AIMCParser";
import Traverser from "./helper/traverser"; import Traverser from "./helper/traverser";
import AIDParser from "./parser/AIDParser"; import AIDParser from "./parser/AIDParser";
import type { InterfaceAction, InterfaceActionForm, InterfaceEvent, InterfaceEventForm, InterfaceProperty, InterfacePropertyForm } from "./types/aidConf";
/** /**
* The AIMC Mapper. * The AIMC Mapper.
@@ -93,10 +94,10 @@ export default class AIMCMapper {
if (parsedPropConf === null) continue; if (parsedPropConf === null) continue;
this.map.set(second, { this.map.set(second, ({
...ep, ...ep,
...parsedPropConf ...parsedPropConf
}); } as any as ConnectionConfiguration));
} }
} }
} }
+12 -16
View File
@@ -1,8 +1,8 @@
import type { types } from "@aas-core-works/aas-core3.0-typescript"; import type { types } from "@aas-core-works/aas-core3.0-typescript";
import AIMCMapper from "./AIMCMapper"; import AIMCMapper from "./AIMCMapper";
import { v4 } from "uuid"; import { v4 } from "uuid";
import type { EndpointMetadata, FormOp, InterfaceActionForm, InterfaceEventForm, InterfacePropertyForm } from "./types/aidConf"; import type { EndpointMetadata } from "./types/aidConf";
import type { ConnectionConfiguration } from "./types/aimcConf"; import type { ConnectionConfiguration, MMBEvent } from "./types/requests";
type ConnectionType = "ON_DEMAND" | "PERMANENT"; type ConnectionType = "ON_DEMAND" | "PERMANENT";
@@ -51,12 +51,12 @@ export default abstract class AbstractConnectionObject<ConfigInterface> {
* A store for all observers and their callbacks. * A store for all observers and their callbacks.
* @sealed * @sealed
*/ */
protected readonly observerStore: Record<any, ((value: any) => void)[]> = {}; protected readonly observerStore: Record<any, { target: types.Property, cb:((event: MMBEvent) => void) }[]> = {};
/** /**
* A store for all event subscriptions and their callbacks. * A store for all event subscriptions and their callbacks.
* @sealed * @sealed
*/ */
protected readonly eventSubStore: Record<any, ((value: any) => void)[]> = {}; protected readonly eventSubStore: Record<any, { target: types.Class, cb:((event: MMBEvent) => void) }[]> = {};
/** /**
* A store for all async action handles and their results. * A store for all async action handles and their results.
* @sealed * @sealed
@@ -100,7 +100,7 @@ export default abstract class AbstractConnectionObject<ConfigInterface> {
* @public * @public
* @virtual * @virtual
*/ */
public abstract readProperty(mapping: ConnectionConfiguration): void; public abstract readProperty(target: types.Property, mapping: ConnectionConfiguration): void;
/** /**
* Write a property value to the asset. * Write a property value to the asset.
@@ -109,7 +109,7 @@ export default abstract class AbstractConnectionObject<ConfigInterface> {
* @public * @public
* @virtual * @virtual
*/ */
public abstract writeProperty(mapping: ConnectionConfiguration, value: any): void; public abstract writeProperty(target: types.Property, mapping: ConnectionConfiguration, value: any): void;
/** /**
* Observe a property value from the asset. * Observe a property value from the asset.
@@ -119,7 +119,7 @@ export default abstract class AbstractConnectionObject<ConfigInterface> {
* @public * @public
* @virtual * @virtual
*/ */
public abstract observeProperty(mapping: ConnectionConfiguration, callback: (value: any) => void): boolean; public abstract observeProperty(target: types.Property, mapping: ConnectionConfiguration, callback: (value: any) => void): boolean;
/** /**
* Unobserve a property value from the asset. * Unobserve a property value from the asset.
@@ -127,7 +127,7 @@ export default abstract class AbstractConnectionObject<ConfigInterface> {
* @public * @public
* @virtual * @virtual
*/ */
public abstract unobserveProperty(mapping: ConnectionConfiguration): void; public abstract unobserveProperty(target: types.Property, mapping: ConnectionConfiguration): void;
/** /**
* Call an action on the asset synchronously. * Call an action on the asset synchronously.
@@ -137,7 +137,7 @@ export default abstract class AbstractConnectionObject<ConfigInterface> {
* @public * @public
* @virtual * @virtual
*/ */
public abstract callActionSync(mapping: ConnectionConfiguration, args: Record<string, any>): any; public abstract callActionSync(target: types.Operation, mapping: ConnectionConfiguration, args: Record<string, any>): any;
/** /**
* Call an action on the asset asynchronously. * Call an action on the asset asynchronously.
@@ -147,7 +147,7 @@ export default abstract class AbstractConnectionObject<ConfigInterface> {
* @public * @public
* @virtual * @virtual
*/ */
public abstract callActionAsync(mapping: ConnectionConfiguration, args: Record<string, any>): string | null; public abstract callActionAsync(target: types.Operation, mapping: ConnectionConfiguration, args: Record<string, any>): string | null;
/** /**
* Read the state of an async action. * Read the state of an async action.
@@ -179,7 +179,7 @@ export default abstract class AbstractConnectionObject<ConfigInterface> {
* @public * @public
* @virtual * @virtual
*/ */
public abstract subscribeEvent(mapping: ConnectionConfiguration, callback: (event: types.BasicEventElement) => void): boolean; public abstract subscribeEvent(target: types.Class, mapping: ConnectionConfiguration, callback: (event: MMBEvent) => void): boolean;
/** /**
* Unsubscribe from an event. * Unsubscribe from an event.
@@ -187,7 +187,7 @@ export default abstract class AbstractConnectionObject<ConfigInterface> {
* @public * @public
* @virtual * @virtual
*/ */
public abstract unsubscribeEvent(mapping: ConnectionConfiguration): void; public abstract unsubscribeEvent(target: types.Class, mapping: ConnectionConfiguration): void;
/** /**
* Generate a handle for an async action. * Generate a handle for an async action.
@@ -199,8 +199,4 @@ export default abstract class AbstractConnectionObject<ConfigInterface> {
this.asyncActionStateStore[handle] = {finished: false, result: null}; this.asyncActionStateStore[handle] = {finished: false, result: null};
return handle; return handle;
} }
protected static findValidForms(mapping: ConnectionConfiguration, op: FormOp): (InterfacePropertyForm | InterfaceActionForm | InterfaceEventForm)[] {
return mapping.forms.filter((form: InterfacePropertyForm | InterfaceActionForm | InterfaceEventForm) => form.op === op);
}
} }
+17 -9
View File
@@ -4,8 +4,8 @@ import type { Request } from "./types/requests";
import type AbstractConnectionObject from "./abstractConnectionObject"; import type AbstractConnectionObject from "./abstractConnectionObject";
import AIMCMapper from "./AIMCMapper"; import AIMCMapper from "./AIMCMapper";
import AIDParser from "./parser/AIDParser"; import AIDParser from "./parser/AIDParser";
import type { EndpointMetadata, InterfaceActionForm, InterfaceEventForm, InterfacePropertyForm } from "./types/aidConf"; import type { EndpointMetadata, InterfaceActionForm, InterfaceEventForm, InterfaceForm, InterfacePropertyForm } from "./types/aidConf";
import type { ConnectionConfiguration } from "./types/aimcConf"; import type { ConnectionConfiguration } from "./types/requests";
type AASRegistration = { type AASRegistration = {
aas: types.Environment, aas: types.Environment,
@@ -192,16 +192,24 @@ export default class MultiMessageBroker {
} }
else { else {
const mapping = getMapping(request.target); const mapping = getMapping(request.target);
mapping.forms = mapping.forms.filter((form: InterfaceForm) => form.op.toLocaleLowerCase() === request.type.toLocaleLowerCase());
if (mapping.forms.length === 0) throw new ReferenceError(`No form found for ${(request.target as any).idShort} with operation ${request.type}`);
const connector = getConnector(mapping); const connector = getConnector(mapping);
switch (request.type) { switch (request.type) {
case "readProperty": return connector.readProperty(mapping); case "readProperty": return connector.readProperty(request.target, mapping);
case "writeProperty": return connector.writeProperty(mapping, request.extraData.value); case "writeProperty": return connector.writeProperty(request.target, mapping, request.extraData.value);
case "observeProperty": return connector.observeProperty(mapping, request.extraData.callback); case "observeProperty": return connector.observeProperty(request.target, mapping, request.extraData.callback);
case "unobserveProperty": return connector.unobserveProperty(mapping); case "unobserveProperty": return connector.unobserveProperty(request.target, mapping);
case "subscribeEvent": return connector.subscribeEvent(mapping, request.extraData.callback); case "subscribeEvent": {
case "unsubscribeEvent": return connector.unsubscribeEvent(mapping); return connector.subscribeEvent(request.target, mapping, request.extraData.callback);
case "invokeAction": return request.extraData.async ? connector.callActionAsync(mapping, request.extraData.args) : connector.callActionSync(mapping, request.extraData.args); }
case "unsubscribeEvent": {
return connector.unsubscribeEvent(request.target, mapping);
}
case "invokeAction": return request.extraData.async ? connector.callActionAsync(request.target, mapping, request.extraData.args) : connector.callActionSync(request.target, mapping, request.extraData.args);
} }
} }
} }
+9 -10
View File
@@ -2,7 +2,6 @@ import * as aasCore from "@aas-core-works/aas-core3.0-typescript";
import type { AssetInterfacesDescription, EndpointMetadata, InterfaceDescription, InterfaceMetadata, InterfaceAction, InterfaceEvent, InterfaceProperty, InterfacePropertyForm, InterfaceActionForm, InterfaceFormBase, InterfaceFormBaseHTTP, InterfaceEventForm } from "../types/aidConf"; import type { AssetInterfacesDescription, EndpointMetadata, InterfaceDescription, InterfaceMetadata, InterfaceAction, InterfaceEvent, InterfaceProperty, InterfacePropertyForm, InterfaceActionForm, InterfaceFormBase, InterfaceFormBaseHTTP, InterfaceEventForm } from "../types/aidConf";
import { AvailableEndpoint, endpointAvailable } from "../types/common"; import { AvailableEndpoint, endpointAvailable } from "../types/common";
import Traverser from "../helper/traverser"; import Traverser from "../helper/traverser";
import { Property } from "@aas-core-works/aas-core3.0-typescript/dist/types/types";
/** /**
* Class for static methods to parse the AssetInterfacesDescription Submodel * Class for static methods to parse the AssetInterfacesDescription Submodel
@@ -285,7 +284,7 @@ export default class AIDParser {
if (!endpoint) return true; if (!endpoint) return true;
return validOperations[endpoint][element].includes(operation); return validOperations[endpoint][element].includes(operation.toLocaleLowerCase());
} }
private static parseAdditionalFormProperties(form: aasCore.types.SubmodelElementCollection, currentlyParsed: any, endpointProtocol?: AvailableEndpoint): InterfacePropertyForm | InterfaceActionForm | InterfaceEventForm { private static parseAdditionalFormProperties(form: aasCore.types.SubmodelElementCollection, currentlyParsed: any, endpointProtocol?: AvailableEndpoint): InterfacePropertyForm | InterfaceActionForm | InterfaceEventForm {
@@ -297,21 +296,21 @@ export default class AIDParser {
// If method is set and it's a valid HTTP method we take it, else we use the default // If method is set and it's a valid HTTP method we take it, else we use the default
// setting for read/write // setting for read/write
const methodName = ["GET", "PUT", "POST", "DELETE", "PATCH"].includes(method.value?.toLocaleUpperCase() ?? "") ? method.value?.toLocaleUpperCase() : AIDParser.getDefaultMethod(currentlyParsed.op) ?? "GET"; const methodName = ["GET", "PUT", "POST", "DELETE", "PATCH"].includes(method.value?.toLocaleUpperCase() ?? "") ? method.value?.toLocaleUpperCase() : AIDParser.getDefaultMethod(currentlyParsed.op) ?? "GET";
currentlyParsed["htv:methodName"] = methodName; currentlyParsed.htv_methodName = methodName;
} }
const headers = Traverser.findElement(form, element => (element as any).idShort?.toLocaleLowerCase() === "htv:headers"); const headers = Traverser.findElement(form, element => (element as any).idShort?.toLocaleLowerCase() === "htv:headers");
if (headers !== null && aasCore.types.isSubmodelElementList(headers)) { if (headers !== null && aasCore.types.isSubmodelElementList(headers)) {
const parsedHeaders: { "htv:fieldName": string, "htv:fieldValue": string }[] = []; const parsedHeaders: { htv_fieldName: string, htv_fieldValue: string }[] = [];
for (const header of headers.overValueOrEmpty()) { for (const header of headers.overValueOrEmpty()) {
if (!aasCore.types.isSubmodelElementCollection(header) || !header.value) continue; if (!aasCore.types.isSubmodelElementCollection(header) || !header.value) continue;
const fieldName = Traverser.findElement(header, element => (element as any).idShort?.toLocaleLowerCase() === "htv:fieldname"); const fieldName = Traverser.findElement(header, element => (element as any).idShort?.toLocaleLowerCase() === "htv:fieldname");
const fieldValue = Traverser.findElement(header, element => (element as any).idShort?.toLocaleLowerCase() === "htv:fieldvalue"); const fieldValue = Traverser.findElement(header, element => (element as any).idShort?.toLocaleLowerCase() === "htv:fieldvalue");
if (fieldName === null || !aasCore.types.isProperty(fieldName) || !fieldName.value || fieldValue === null || !aasCore.types.isProperty(fieldValue) || !fieldValue.value) continue; if (fieldName === null || !aasCore.types.isProperty(fieldName) || !fieldName.value || fieldValue === null || !aasCore.types.isProperty(fieldValue) || !fieldValue.value) continue;
parsedHeaders.push({ "htv:fieldName": fieldName.value, "htv:fieldValue": fieldValue.value }); parsedHeaders.push({ htv_fieldName: fieldName.value, htv_fieldValue: fieldValue.value });
} }
currentlyParsed["htv:headers"] = parsedHeaders; currentlyParsed.htv_headers = parsedHeaders;
} }
break; break;
} }
@@ -322,12 +321,12 @@ export default class AIDParser {
// If controlPacket is set and it's a valid MQTT control packet we take it, else we use the default // If controlPacket is set and it's a valid MQTT control packet we take it, else we use the default
// setting for read/write // setting for read/write
const controlPacketValue = ["PUBLISH", "SUBSCRIBE", "UNSUBSCRIBE"].includes(controlPacket.value?.toLocaleUpperCase() ?? "") ? controlPacket.value?.toLocaleUpperCase() : AIDParser.getDefaultMethod(currentlyParsed.op); const controlPacketValue = ["PUBLISH", "SUBSCRIBE", "UNSUBSCRIBE"].includes(controlPacket.value?.toLocaleUpperCase() ?? "") ? controlPacket.value?.toLocaleUpperCase() : AIDParser.getDefaultMethod(currentlyParsed.op);
currentlyParsed["mqv:controlPacketValue"] = controlPacketValue; currentlyParsed.mqv_controlPacketValue = controlPacketValue;
} }
const options = Traverser.findElement(form, element => (element as any).idShort?.toLocaleLowerCase() === "mqv:options"); const options = Traverser.findElement(form, element => (element as any).idShort?.toLocaleLowerCase() === "mqv:options");
if (options !== null && aasCore.types.isSubmodelElementList(options)) { if (options !== null && aasCore.types.isSubmodelElementList(options)) {
const parsedOptions: ({ "mqv:optionName": string, "mqv:optionValue": number | boolean })[] = []; const parsedOptions: ({ mqv_optionName: string, mqv_optionValue: number | boolean })[] = [];
for (const option of options.overValueOrEmpty()) { for (const option of options.overValueOrEmpty()) {
if (!aasCore.types.isSubmodelElementCollection(option) || !option.value) continue; if (!aasCore.types.isSubmodelElementCollection(option) || !option.value) continue;
@@ -335,9 +334,9 @@ export default class AIDParser {
const optionValue = Traverser.findElement(option, element => (element as any).idShort?.toLocaleLowerCase() === "mqv:optionvalue"); const optionValue = Traverser.findElement(option, element => (element as any).idShort?.toLocaleLowerCase() === "mqv:optionvalue");
if (optionName === null || !aasCore.types.isProperty(optionName) || !optionName.value || optionValue === null || !aasCore.types.isProperty(optionValue) || !optionValue.value) continue; if (optionName === null || !aasCore.types.isProperty(optionName) || !optionName.value || optionValue === null || !aasCore.types.isProperty(optionValue) || !optionValue.value) continue;
const value = Number.isNaN(Number.parseInt(optionValue.value)) ? optionValue.value === "true" : Number.parseInt(optionValue.value); const value = Number.isNaN(Number.parseInt(optionValue.value)) ? optionValue.value === "true" : Number.parseInt(optionValue.value);
parsedOptions.push({ "mqv:optionName": optionName.value, "mqv:optionValue": value }); parsedOptions.push({ mqv_optionName: optionName.value, mqv_optionValue: value });
} }
currentlyParsed["mqv:options"] = parsedOptions; currentlyParsed.mqv_options = parsedOptions;
} }
break; break;
+34 -42
View File
@@ -48,25 +48,25 @@ It should be pretty easy to extend this.
So let's derive some of this from the WoT and see what we can achieve. So let's derive some of this from the WoT and see what we can achieve.
*/ */
export type FormOp = "readproperty" | export type FormOp = "readProperty" |
"writeproperty" | "writeProperty" |
"observeproperty" | "observeProperty" |
"unobserveproperty" | "unobserveProperty" |
"invokeaction" | "invokeAction" |
"subscribeevent" | "subscribeEvent" |
"unsubscribeevent"; "unsubscribeEvent";
// The following are defined in WoT but not useful in our case // The following are defined in WoT but not useful in our case
//"readallproperties" | //"readallproperties" |
//"writeallproperties" | //"writeallproperties" |
//"readmultipleproperties" | //"readmultipleproperties" |
//"writemultipleproperties"; //"writemultipleproperties";
type FormOpHTTPProp = "readproperty" | "writeproperty"; type FormOpHTTPProp = "readProperty" | "writeProperty";
type FormOpHTTPAction = "invokeaction"; type FormOpHTTPAction = "invokeAction";
type FormOpMQTTProp = "readproperty" | "writeproperty" | "observeproperty" | "unobserveproperty"; type FormOpMQTTProp = "readProperty" | "writeProperty" | "observeProperty" | "unobserveProperty";
type FormOpMQTTAction = "invokeaction"; type FormOpMQTTAction = "invokeAction";
type FormOpMQTTEvent = "subscribeevent" | "unsubscribeevent"; type FormOpMQTTEvent = "subscribeEvent" | "unsubscribeEvent";
export type InterfaceFormBase = { export type InterfaceFormBase = {
href: string; href: string;
@@ -75,50 +75,51 @@ export type InterfaceFormBase = {
} }
export type InterfaceFormBaseHTTP = InterfaceFormBase & { export type InterfaceFormBaseHTTP = InterfaceFormBase & {
"htv:methodName": "GET" | "PUT" | "POST" | "DELETE" | "PATCH"; htv_methodName?: "GET" | "PUT" | "POST" | "DELETE" | "PATCH";
"htv:headers": { htv_headers?: {
"htv:fieldName": string; htv_fieldName: string;
"htv:fieldValue": string; htv_fieldValue: string;
}[]; }[];
op: FormOpHTTPProp | FormOpHTTPAction; op: FormOpHTTPProp | FormOpHTTPAction;
} }
type IFormHTTPProp = InterfaceFormBaseHTTP & { export type InterfaceFormHTTPProp = InterfaceFormBaseHTTP & {
op: FormOpHTTPProp; op: FormOpHTTPProp;
} }
type IFormHTTPAction = InterfaceFormBaseHTTP & { export type InterfaceFormHTTPAction = InterfaceFormBaseHTTP & {
op: FormOpHTTPAction; op: FormOpHTTPAction;
} }
export type InterfaceFormBaseMQTT = InterfaceFormBase & { export type InterfaceFormBaseMQTT = InterfaceFormBase & {
"mqv:controlPacketValue": "PUBLISH" | "SUBSCRIBE" | "UNSUBSCRIBE"; mqv_controlPacketValue?: "PUBLISH" | "SUBSCRIBE" | "UNSUBSCRIBE";
"mqv:options": ({ mqv_options?: ({
"mqv:optionName": "qos"; mqv_optionName: "qos";
"mqv:optionValue": 0 | 1 | 2; mqv_optionValue: 0 | 1 | 2;
} | { } | {
"mqv:optionName": "retain" | "dup"; mqv_optionName: "retain" | "dup";
"mqv:optionValue": boolean; mqv_optionValue: boolean;
})[]; })[];
op: FormOpMQTTProp | FormOpMQTTAction | FormOpMQTTEvent; op: FormOpMQTTProp | FormOpMQTTAction | FormOpMQTTEvent;
} }
type IFormMQTTProp = InterfaceFormBaseMQTT & { export type InterfaceFormMQTTProp = InterfaceFormBaseMQTT & {
op: FormOpMQTTProp; op: FormOpMQTTProp;
} }
type IFormMQTTAction = InterfaceFormBaseMQTT & { export type InterfaceFormMQTTAction = InterfaceFormBaseMQTT & {
op: FormOpMQTTAction; op: FormOpMQTTAction;
} }
type IFormMQTTEvent = InterfaceFormBaseMQTT & { export type InterfaceFormMQTTEvent = InterfaceFormBaseMQTT & {
op: FormOpMQTTEvent; op: FormOpMQTTEvent;
} }
export type InterfacePropertyForm = IFormHTTPProp | IFormMQTTProp; export type InterfacePropertyForm = InterfaceFormHTTPProp | InterfaceFormMQTTProp;
export type InterfaceActionForm = IFormHTTPAction | IFormMQTTAction; export type InterfaceActionForm = InterfaceFormHTTPAction | InterfaceFormMQTTAction;
export type InterfaceEventForm = IFormMQTTEvent; export type InterfaceEventForm = InterfaceFormMQTTEvent;
export type InterfaceForm = InterfacePropertyForm | InterfaceActionForm | InterfaceEventForm;
export type InterfaceProperty = { export type InterfaceProperty = {
title?: string; title?: string;
@@ -139,20 +140,11 @@ export type InterfaceProperty = {
} }
/** @beta */ /** @beta */
export type InterfaceAction = InterfaceActionSync | InterfaceActionAsync; export type InterfaceAction = {
type InterfaceActionBase = {
title?: string; title?: string;
type: string; type?: string;
forms: InterfaceActionForm[]; forms: InterfaceActionForm[];
} async: boolean;
type InterfaceActionSync = InterfaceActionBase & {
async: false;
}
type InterfaceActionAsync = {
async: true;
} }
/** @beta */ /** @beta */
+2 -5
View File
@@ -1,6 +1,6 @@
import type { types } from "@aas-core-works/aas-core3.0-typescript"; import type { types } from "@aas-core-works/aas-core3.0-typescript";
import type { AvailableEndpoint } from "./common"; import type { AvailableEndpoint } from "./common";
import type { EndpointMetadata, InterfaceAction, InterfaceEvent, InterfaceProperty } from "./aidConf"; import type { ConnectionConfiguration } from "./requests";
export type AssetInterfacesMappingConfiguration = Record<AvailableEndpoint, MappingConfEntry[]>; export type AssetInterfacesMappingConfiguration = Record<AvailableEndpoint, MappingConfEntry[]>;
@@ -14,7 +14,4 @@ export type MappingConfiguration = {
SourceSinkMappings: types.RelationshipElement[]; SourceSinkMappings: types.RelationshipElement[];
} }
export type AIMCMap = Map<types.Class, ConnectionConfiguration>; export type AIMCMap = Map<types.Class, ConnectionConfiguration>;
type InterfaceElement = InterfaceProperty | InterfaceAction | InterfaceEvent;
export type ConnectionConfiguration = EndpointMetadata & InterfaceElement; // Wenn Transformationen implementiert werden, dann hier anpassen
+14 -5
View File
@@ -1,4 +1,5 @@
import type { types } from "@aas-core-works/aas-core3.0-typescript"; import type { types } from "@aas-core-works/aas-core3.0-typescript";
import type { EndpointMetadata, InterfaceForm } from "./aidConf";
/** /**
* Read Property Request * Read Property Request
@@ -36,7 +37,7 @@ type ObserveRequest = {
type: "observeProperty"; type: "observeProperty";
target: types.Property; target: types.Property;
extraData: { extraData: {
callback: (value: any) => void; callback: (event: MMBEvent) => void;
} }
} }
@@ -52,7 +53,7 @@ type UnobserveRequest = {
type: "unobserveProperty"; type: "unobserveProperty";
target: types.Property; target: types.Property;
extraData: { extraData: {
callback: (value: any) => void; callback: (event: MMBEvent) => void;
} }
} }
@@ -66,9 +67,9 @@ type UnobserveRequestCallback = (request: ObserveRequest) => boolean;
*/ */
type SubscribeRequest = { type SubscribeRequest = {
type: "subscribeEvent"; type: "subscribeEvent";
target: types.BasicEventElement; target: types.Class;
extraData: { extraData: {
callback: (value: any) => void; callback: (event: MMBEvent) => void;
} }
} }
@@ -82,7 +83,7 @@ type SubscribeRequestCallback = (request: SubscribeRequest) => boolean;
*/ */
type UnsubscribeRequest = { type UnsubscribeRequest = {
type: "unsubscribeEvent"; type: "unsubscribeEvent";
target: types.BasicEventElement; target: types.Class;
} }
/** /**
@@ -142,3 +143,11 @@ export type Request = GetRequest | WriteRequest | ObserveRequest | UnobserveRequ
* Combined Request Callback Type * Combined Request Callback Type
*/ */
export type OnRequestCallback = (request: Request) => any & GetRequestCallback & WriteRequestCallback & ObserveRequestCallback & UnobserveRequestCallback & CallRequestCallback & AsyncStateRequestCallback & AsyncResultRequestCallback & SubscribeRequestCallback & UnsubscribeRequestCallback; export type OnRequestCallback = (request: Request) => any & GetRequestCallback & WriteRequestCallback & ObserveRequestCallback & UnobserveRequestCallback & CallRequestCallback & AsyncStateRequestCallback & AsyncResultRequestCallback & SubscribeRequestCallback & UnsubscribeRequestCallback;
export type ConnectionConfiguration = EndpointMetadata & InterfaceForm; // Wenn Transformationen implementiert werden, dann hier anpassen
export type MMBEvent = {
type: "changed" | "event";
target: types.Class;
value: any;
}
+957 -1
View File
File diff suppressed because one or more lines are too long