{{
- capitalizeFirstLetter(referenceKey) + ': '
+ capitalizeFirstLetter(referenceKey) +
+ ' (' +
+ getReferences[referenceKey as 'first' | 'second'].type +
+ '): '
}}
-
+
- {{ '(' + value.type + ') ' }}{{ value.value }}
+ {{ '(' + keys.type + ') ' }}{{ keys.value }}
-
-
- Description:
-
- {{ value.type }}
- {{ value.value }}
+ {{ keys.type }}
+ {{ keys.value }}
@@ -48,10 +47,10 @@
:loading="getLoadingState[referenceKey as 'first' | 'second']"
:disabled="getDisabledState[referenceKey as 'first' | 'second']"
@click="
- jumpToReferencedElement(
- getReferencedAAS[referenceKey as 'first' | 'second'],
- getReference[referenceKey as 'first' | 'second'],
- getReferencedSubmodel[referenceKey as 'first' | 'second']
+ jumpToReference(
+ getReferences[referenceKey as 'first' | 'second'],
+ getAasDescriptor[referenceKey as 'first' | 'second'],
+ getSmRef[referenceKey as 'first' | 'second']
)
"
>Jump, // Value of the first Reference (Array of Reference Keys)
- secondReference: [] as Array, // Value of the second Reference (Array of Reference Keys)
+ firstReference: {} as any,
+ secondReference: {} as any,
+ // firstReferenceKeys: [] as Array, // Value of the first Reference (Array of Reference Keys)
+ // secondReferenceKeys: [] as Array, // Value of the second Reference (Array of Reference Keys)
+ // firstReferenceType: '' as string,
+ // secondReferenceType: '' as string,
firstLoading: false, // Loading State of the first Jump-Button (loading when checking if referenced element exists in one of the registered AAS)
secondLoading: false, // Loading State of the second Jump-Button (loading when checking if referenced element exists in one of the registered AAS)
firstDisabled: true, // Disabled State of the first Jump-Button (disabled when referenced element does not exist in one of the registered AAS)
secondDisabled: true, // Disabled State of the second Jump-Button (disabled when referenced element does not exist in one of the registered AAS)
- firstReferencedAAS: Object as any, // first AAS in which the referenced Element is included (if it exists)
- secondReferencedAAS: Object as any, // second AAS in which the referenced Element is included (if it exists)
- firstReferencedSubmodel: Object as any, // first Submodel in which the referenced Element is included (if it exists)
- secondReferencedSubmodel: Object as any, // second Submodel in which the referenced Element is included (if it exists)
+ firstAasDescriptor: Object as any, // first AAS in which the referenced Element is included (if it exists)
+ secondAasDescriptor: Object as any, // second AAS in which the referenced Element is included (if it exists)
+ firstSmRef: Object as any, // first Submodel in which the referenced Element is included (if it exists)
+ secondSmRef: Object as any, // second Submodel in which the referenced Element is included (if it exists)
};
},
computed: {
- // Get the selected Treeview Node (SubmodelElement) from the store
- SelectedNode() {
- return this.aasStore.getSelectedNode;
- },
-
// Get the referenceObject based on the referenceKey
- getReference() {
+ getReferences() {
return {
first: this.firstReference,
second: this.secondReference,
@@ -121,18 +119,18 @@
},
// Get the referencedAAS based on the referenceKey
- getReferencedAAS() {
+ getAasDescriptor() {
return {
- first: this.firstReferencedAAS,
- second: this.secondReferencedAAS,
+ first: this.firstAasDescriptor,
+ second: this.secondAasDescriptor,
};
},
// Get the referencedSubmodel based on the referenceKey
- getReferencedSubmodel() {
+ getSmRef() {
return {
- first: this.firstReferencedSubmodel,
- second: this.secondReferencedSubmodel,
+ first: this.firstSmRef,
+ second: this.secondSmRef,
};
},
@@ -154,21 +152,12 @@
},
watch: {
- // Watch for changes in the selected Node and reset input
- SelectedNode: {
- deep: true,
- handler() {
- this.firstReference = [];
- this.secondReference = [];
- },
- },
-
- // Watch for changes in the referenceElementObject
- referenceElementObject: {
+ // Watch for changes in the relationshipElementObject
+ relationshipElementObject: {
deep: true,
handler() {
- this.firstReference = this.relationshipElementObject.first.keys;
- this.secondReference = this.relationshipElementObject.second.keys;
+ this.firstReference = this.relationshipElementObject.first;
+ this.secondReference = this.relationshipElementObject.second;
this.validateReference('first');
this.validateReference('second');
},
@@ -176,31 +165,36 @@
},
mounted() {
- // console.log('RelationshipElement Mounted:', this.relationshipElementObject);
- this.firstReference = this.relationshipElementObject.first.keys;
- this.secondReference = this.relationshipElementObject.second.keys;
+ this.firstReference = this.relationshipElementObject.first;
+ this.secondReference = this.relationshipElementObject.second;
this.validateReference('first');
this.validateReference('second');
},
methods: {
// Function to check if the referenced Element exists
- validateReference(reference: string) {
- (this as any)[reference + 'Loading'] = true;
- this.checkReference((this as any)[reference + 'Reference'])
- .then(({ success, aas, submodel }) => {
- // console.log('checkReference: ', success, aas, submodel);
+ validateReference(referenceKey: string) {
+ (this as any)[referenceKey + 'Loading'] = true;
+
+ this.checkReference((this as any)[referenceKey + 'Reference'], this.selectedAAS)
+ .then(({ success, aasDescriptor, submodelRef }) => {
+ // console.log(
+ // 'validateReference (' + referenceKey + ') --> checkReference: ',
+ // success,
+ // aasDescriptor,
+ // submodelRef
+ // );
if (success) {
- (this as any)[reference + 'ReferencedAAS'] = aas;
- (this as any)[reference + 'ReferencedSubmodel'] = submodel;
- (this as any)[reference + 'Disabled'] = false;
+ (this as any)[referenceKey + 'AasDescriptor'] = aasDescriptor;
+ (this as any)[referenceKey + 'SmRef'] = submodelRef;
+ (this as any)[referenceKey + 'Disabled'] = false;
}
- (this as any)[reference + 'Loading'] = false;
+ (this as any)[referenceKey + 'Loading'] = false;
})
.catch((error) => {
// Handle any errors
console.error('Error:', error);
- (this as any)[reference + 'Loading'] = false;
+ (this as any)[referenceKey + 'Loading'] = false;
});
},
},
diff --git a/aas-web-ui/src/components/SubmodelList.vue b/aas-web-ui/src/components/SubmodelList.vue
index 7ec9c0c..3d66639 100644
--- a/aas-web-ui/src/components/SubmodelList.vue
+++ b/aas-web-ui/src/components/SubmodelList.vue
@@ -9,9 +9,9 @@
Submodel List
-
+
{{
- 'AAS: ' + nameToDisplay(SelectedAAS)
+ 'AAS: ' + nameToDisplay(selectedAAS)
}}
@@ -21,36 +21,42 @@
-
-
-
- SM
-
- {{
- submodel.idShort
- }}
-
-
+
+
+
+
+
+ SM
+
+ {{
+ submodel.idShort
+ }}
+
+
+
@@ -103,7 +109,7 @@
},
// get selected AAS from Store
- SelectedAAS() {
+ selectedAAS() {
return this.aasStore.getSelectedAAS;
},
@@ -139,11 +145,8 @@
watch: {
// initialize Submodel List when AAS gets selected or changes
- SelectedAAS: {
- deep: true,
- handler() {
- this.initSubmodelList();
- },
+ selectedAAS() {
+ this.initSubmodelList();
},
// Resets the Submodel List when the AAS Registry changes
@@ -166,72 +169,37 @@
},
methods: {
- initSubmodelList() {
- // console.log("initialize Submodel List: ", this.SelectedAAS);
+ async initSubmodelList() {
+ // console.log('Initialize SubmodelList', this.SelectedAAS, this.initialUpdate, this.initialNode);
// return if no endpoints are available
- if (!this.SelectedAAS || !this.SelectedAAS.endpoints || this.SelectedAAS.endpoints.length === 0) {
+ if (!this.selectedAAS || !this.selectedAAS.endpoints || this.selectedAAS.endpoints.length === 0) {
// this.navigationStore.dispatchSnackbar({ status: true, timeout: 4000, color: 'error', btnColor: 'buttonText', text: 'AAS with no (valid) Endpoint selected!' });
this.submodelData = [];
return;
}
- if (this.loading) return; // return if loading state is true -> prevents multiple requests
+ if (this.loading && !this.initialUpdate) return; // return if loading state is true -> prevents multiple requests
this.aasStore.dispatchLoadingState(true); // set loading state to true
- this.submodelData = []; // reset Submdoel List Data
- // retrieve AAS from endpoint
- const shellHref = this.extractEndpointHref(this.SelectedAAS, 'AAS-3.0');
- let path = shellHref;
- let context = 'retrieving AAS Data';
- let disableMessage = false;
- this.getRequest(path, context, disableMessage)
- .then(async (response: any) => {
- if (response.success) {
- // execute if the Request was successful
- try {
- let AAS = response.data;
- AAS.endpoints = this.SelectedAAS.endpoints;
- this.aasStore.dispatchSelectedAAS(AAS); // dispatch the selected AAS to the Store
- // request submodels from the retrieved AAS
- let submodelData = await this.requestSubmodels(AAS.submodels);
- if (this.initialUpdate && this.initialNode) {
- // set the isActive Property of the initial Node to true and dispatch it to the store
- submodelData.forEach((submodel: any) => {
- if (submodel.path === this.initialNode.path) {
- submodel.isActive = true;
- this.aasStore.dispatchNode(submodel);
- this.aasStore.dispatchRealTimeObject(submodel);
- }
- });
- this.initialUpdate = false;
- this.initialNode = {};
- this.submodelData = submodelData; // set the Submodel Data
- } else {
- this.submodelData = submodelData; // set the Submodel Data
- }
- } catch (error: any) {
- // console.error('Error while parsing the Submodel References: ', error);
- const errorMessage = error.message;
- const errorStack = error.stack;
- const errorLocation = errorStack ? errorStack.split('\n')[1] : '';
- this.navigationStore.dispatchSnackbar({
- status: true,
- timeout: 60000,
- color: 'error',
- btnColor: 'buttonText',
- baseError: 'Error while parsing the Submodel References!',
- extendedError: `Error: ${errorMessage}\nLocation: ${errorLocation.trim()}`,
- });
- } finally {
- this.aasStore.dispatchLoadingState(false);
+ if (this.selectedAAS.submodels) {
+ let submodelData = await this.requestSubmodels(this.selectedAAS.submodels);
+ // set the isActive prop of the initialNode if it exists and the initialUpdate flag is set
+ if (this.initialUpdate && this.initialNode) {
+ submodelData.forEach((submodel: any) => {
+ if (submodel.path === this.initialNode.path) {
+ submodel.isActive = true;
+ this.aasStore.dispatchNode(submodel);
+ this.aasStore.dispatchRealTimeObject(submodel);
}
- } else {
- // execute if the Request failed
- this.submodelData = [];
- this.aasStore.dispatchLoadingState(false);
- }
- })
- .catch(() => {
- this.aasStore.dispatchLoadingState(false);
- });
+ });
+ this.initialUpdate = false;
+ this.initialNode = {};
+ this.submodelData = submodelData;
+ } else {
+ this.submodelData = submodelData;
+ }
+ } else {
+ this.submodelData = [];
+ }
+ this.aasStore.dispatchLoadingState(false);
},
// Function to request all Submodels for the selected AAS
@@ -312,13 +280,13 @@
});
// Add path of the selected Node to the URL as Router Query
if (localSubmodel.isActive) {
- const shellHref = this.extractEndpointHref(this.SelectedAAS, 'AAS-3.0');
+ const aasEndpopint = this.extractEndpointHref(this.selectedAAS, 'AAS-3.0');
if (this.isMobile) {
// Change to SubmodelElementView on Mobile and add the path to the URL
this.router.push({
path: '/componentvisualization',
query: {
- aas: shellHref,
+ aas: aasEndpopint,
path: localSubmodel.path,
},
});
@@ -326,7 +294,7 @@
// just add the path to the URL
this.router.push({
query: {
- aas: shellHref,
+ aas: aasEndpopint,
path: localSubmodel.path,
},
});
@@ -345,9 +313,9 @@
// Function to initialize the Submodel List with the Route Parameters
initSubmodelListWithRouteParameters() {
- // check if the SelectedAAS is already set in the Store and initialize the Submodel List if so
- if (this.SelectedAAS && this.SelectedAAS.endpoints && this.SelectedAAS.endpoints.length > 0) {
- // console.log('init Tree from Route Params: ', this.SelectedAAS);
+ // check if the selectedAAS is already set in the Store and initialize the Submodel List if so
+ if (this.selectedAAS && this.selectedAAS.endpoints && this.selectedAAS.endpoints.length > 0) {
+ // console.log('init Tree from Route Params: ', this.selectedAAS);
this.initSubmodelList();
}
diff --git a/aas-web-ui/src/components/UIComponents/GenericDataVisu.vue b/aas-web-ui/src/components/UIComponents/GenericDataVisu.vue
index e3cedf9..685dee4 100644
--- a/aas-web-ui/src/components/UIComponents/GenericDataVisu.vue
+++ b/aas-web-ui/src/components/UIComponents/GenericDataVisu.vue
@@ -133,7 +133,7 @@
if (!this.submodelElementData) return;
// console.log('SubmodelElementData: ', this.submodelElementData)
- if (Object.keys(this.submodelElementData).length == 0) {
+ if (Object.keys(this.submodelElementData).length === 0) {
this.localSubmodelElementData = []; // Reset the SubmodelElement Data when no Node is selected
return;
}
diff --git a/aas-web-ui/src/components/UIComponents/VTreeview.vue b/aas-web-ui/src/components/UIComponents/VTreeview.vue
index 2449b00..b74dfd9 100644
--- a/aas-web-ui/src/components/UIComponents/VTreeview.vue
+++ b/aas-web-ui/src/components/UIComponents/VTreeview.vue
@@ -23,35 +23,35 @@
@click.stop="toggleChildren()">
-
mdi-folder-lock
-
+
mdi-folder-lock
-
mdi-folder-alert
-
+
+ mdi-folder-alert
+
-
{{ showChildren ? "mdi-folder-open" : "mdi-folder" }}
+
+ {{ showChildren ? 'mdi-folder-open' : 'mdi-folder' }}
+
-
mdi-file-alert
+
+ mdi-file-alert
+
-
mdi-file-multiple
+
+ mdi-file-multiple
+
-
mdi-file-alert
+
+ mdi-file-alert
+
mdi-list-box
-
mdi-file-alert
+
+ mdi-file-alert
+
mdi-format-list-group
@@ -160,13 +160,13 @@
localItem.isActive = !localItem.isActive;
// Add path of the selected Node to the URL as Router Query
if (localItem.isActive) {
- const shellHref = this.extractEndpointHref(this.SelectedAAS, 'AAS-3.0');
+ const aasEndpopint = this.extractEndpointHref(this.SelectedAAS, 'AAS-3.0');
if (this.isMobile) {
// Change to SubmodelElementView on Mobile and add the path to the URL
this.router.push({
path: '/submodelelementview',
query: {
- aas: shellHref,
+ aas: aasEndpopint,
path: localItem.path,
},
});
@@ -174,7 +174,7 @@
// just add the path to the URL
this.router.push({
query: {
- aas: shellHref,
+ aas: aasEndpopint,
path: localItem.path,
},
});
diff --git a/aas-web-ui/src/components/Widgets/Button.vue b/aas-web-ui/src/components/Widgets/Button.vue
index ac8ca24..1d36863 100644
--- a/aas-web-ui/src/components/Widgets/Button.vue
+++ b/aas-web-ui/src/components/Widgets/Button.vue
@@ -52,7 +52,7 @@
if (
!this.widgetSettings ||
!this.submodelElementData ||
- Object.keys(this.submodelElementData).length == 0
+ Object.keys(this.submodelElementData).length === 0
)
return;
let localSubmodelElementData = { ...this.submodelElementData };
diff --git a/aas-web-ui/src/components/Widgets/InputField.vue b/aas-web-ui/src/components/Widgets/InputField.vue
index a391031..17c99a5 100644
--- a/aas-web-ui/src/components/Widgets/InputField.vue
+++ b/aas-web-ui/src/components/Widgets/InputField.vue
@@ -83,7 +83,7 @@
if (
!this.widgetSettings ||
!this.submodelElementData ||
- Object.keys(this.submodelElementData).length == 0
+ Object.keys(this.submodelElementData).length === 0
)
return;
let localSubmodelElementData = { ...this.submodelElementData };
diff --git a/aas-web-ui/src/components/Widgets/Lamp.vue b/aas-web-ui/src/components/Widgets/Lamp.vue
index 7903556..8702085 100644
--- a/aas-web-ui/src/components/Widgets/Lamp.vue
+++ b/aas-web-ui/src/components/Widgets/Lamp.vue
@@ -63,7 +63,7 @@
if (
!this.widgetSettings ||
!this.submodelElementData ||
- Object.keys(this.submodelElementData).length == 0
+ Object.keys(this.submodelElementData).length === 0
)
return;
let localSubmodelElementData = { ...this.submodelElementData };
diff --git a/aas-web-ui/src/components/Widgets/LineChart.vue b/aas-web-ui/src/components/Widgets/LineChart.vue
index 6b25381..1c65160 100644
--- a/aas-web-ui/src/components/Widgets/LineChart.vue
+++ b/aas-web-ui/src/components/Widgets/LineChart.vue
@@ -162,7 +162,7 @@
// console.log('initializeSeries: ', this.chartData, this.timeVariable, this.yVariables);
// Prepare new series values
let newSeries = this.prepareSeriesValues(this.chartData, this.yVariables);
- console.log('newSeries: ', newSeries);
+ // console.log('newSeries: ', newSeries);
// prepare the tooltip for the y-axis
let tooltip_y = this.prepareYValueTooltip(this.chartData, this.yVariables);
// prepare the legend for the series
diff --git a/aas-web-ui/src/components/Widgets/Switch.vue b/aas-web-ui/src/components/Widgets/Switch.vue
index b738e22..fd9d6ff 100644
--- a/aas-web-ui/src/components/Widgets/Switch.vue
+++ b/aas-web-ui/src/components/Widgets/Switch.vue
@@ -55,7 +55,7 @@
if (
!this.widgetSettings ||
!this.submodelElementData ||
- Object.keys(this.submodelElementData).length == 0
+ Object.keys(this.submodelElementData).length === 0
)
return;
let localSubmodelElementData = { ...this.submodelElementData };
diff --git a/aas-web-ui/src/mixins/DashboardHandling.ts b/aas-web-ui/src/mixins/DashboardHandling.ts
index ade1365..7fdc87b 100644
--- a/aas-web-ui/src/mixins/DashboardHandling.ts
+++ b/aas-web-ui/src/mixins/DashboardHandling.ts
@@ -161,8 +161,8 @@ export default defineComponent({
// console.log(this.SelectedAAS)
return this.SelectedAAS;
} else {
- const shellHref = this.extractEndpointHref(this.SelectedAAS, 'AAS-3.0');
- const path = shellHref;
+ const aasEndpopint = this.extractEndpointHref(this.SelectedAAS, 'AAS-3.0');
+ const path = aasEndpopint;
const context = 'getting aas from endpoint';
const disableMessage = false;
const response = await this.getRequest(path, context, disableMessage);
diff --git a/aas-web-ui/src/mixins/SubmodelElementHandling.ts b/aas-web-ui/src/mixins/SubmodelElementHandling.ts
index 687bde3..d80ff68 100644
--- a/aas-web-ui/src/mixins/SubmodelElementHandling.ts
+++ b/aas-web-ui/src/mixins/SubmodelElementHandling.ts
@@ -24,22 +24,32 @@ export default defineComponent({
computed: {
// get AAS Discovery URL from Store
- aasDiscoveryURLMixin() {
+ aasDiscoveryUrl() {
return this.navigationStore.getAASDiscoveryURL;
},
// get AAS Registry URL from Store
- aasRegistryURLMixin() {
+ aasRegistryUrl() {
return this.navigationStore.getAASRegistryURL;
},
// Get the Submodel Repository URL from the Store
- submodelRepoURL() {
+ submodelRegistryUrl() {
+ return this.navigationStore.getSubmodelRepoURL;
+ },
+
+ // Get the Submodel Repository URL from the Store
+ aasRepoUrl() {
+ return this.navigationStore.getAASRepoURL;
+ },
+
+ // Get the Submodel Repository URL from the Store
+ submodelRepoUrl() {
return this.navigationStore.getSubmodelRepoURL;
},
// Get the Concept Description Repository URL from the Store
- conceptDescriptionRepoURL() {
+ conceptDescriptionRepoUrl() {
return this.navigationStore.getConceptDescriptionRepoURL;
},
@@ -376,156 +386,399 @@ export default defineComponent({
// Function to check if the referenced Element exists
async checkReference(
- referenceValue: Array
- ): Promise<{ success: boolean; aas?: object; submodel?: object }> {
- // console.log('Reference Value: ', referenceValue);
- // check if aasRegistryURL includes "/shell-descriptors" and add id if not (backward compatibility)
- if (!this.aasRegistryURLMixin.includes('/shell-descriptors')) {
- this.aasRegistryURLMixin += '/shell-descriptors';
- }
- const path = this.aasRegistryURLMixin;
- const context = 'retrieving AAS Data';
- const disableMessage = false;
- try {
- const response = await this.getRequest(path, context, disableMessage);
- // console.log('Response: ', response);
- if (response.success && response.data.result && response.data.result.length > 0) {
- const aasList = response.data.result;
- if (referenceValue[0].type == 'AssetAdministrationShell') {
- return await this.checkReferenceAAS(aasList, referenceValue);
- }
- if (referenceValue[0].type == 'Submodel') {
- return await this.checkReferenceSubmodel(aasList, referenceValue);
+ reference: any,
+ currentAasDescriptor?: any
+ ): Promise<{ success: boolean; aasDescriptor?: object; submodelRef?: object }> {
+ // console.log(
+ // 'checkReference (' + reference.type + '): ',
+ // 'reference',
+ // reference,
+ // 'currentAasDescriptor',
+ // currentAasDescriptor
+ // );
+ // TODO This check just works down to SM level. It is not working for checking the availability of a specific SME!
+ const failResponse = { success: false, aasDescriptor: {}, submodelRef: {} }; // Define once for reuse
+
+ if (reference.type === 'ExternalReference') {
+ this.navigationStore.dispatchSnackbar({
+ status: true,
+ timeout: 10000,
+ color: 'warning',
+ btnColor: 'buttonText',
+ text: 'Reference check for ExternalReference not implemented',
+ }); // Show Error Snackbar
+ return failResponse;
+ } else if (reference.type === 'ModelReference') {
+ // Check ModelReference
+ let aasDescriptor = {};
+ if (reference?.keys[0]?.type === 'AssetAdministrationShell') {
+ aasDescriptor = await this.checkAasReference(reference).then(({ aasDescriptor }) => {
+ return aasDescriptor;
+ });
+ } else if (Object.keys(currentAasDescriptor).length > 0) {
+ aasDescriptor = currentAasDescriptor;
+ }
+
+ if (Object.keys(aasDescriptor).length > 0) {
+ const aasDescriptorList = [aasDescriptor];
+
+ if (reference?.keys[0]?.type === 'AssetAdministrationShell') {
+ if (reference?.keys[1]?.type === 'Submodel') {
+ return await this.checkSmReference(reference, aasDescriptorList, aasDescriptor);
+ }
+ return await this.checkAasReference(reference, aasDescriptorList);
+ } else if (reference?.keys[0]?.type === 'Submodel') {
+ const checkResponse = await this.checkSmReference(reference, aasDescriptorList, aasDescriptor);
+ if (checkResponse?.success === false) {
+ // Check Reference to exist in other AAS
+ let aasRegistryUrl = this.aasRegistryUrl;
+ if (!aasRegistryUrl.includes('/shell-descriptors')) {
+ aasRegistryUrl += '/shell-descriptors';
+ }
+ const aasRegistryPath = aasRegistryUrl;
+ const aasRegistryContext = 'retrieving AAS Descriptors';
+ const disableMessage = false;
+ try {
+ const aasRegistryResponse = await this.getRequest(
+ aasRegistryPath,
+ aasRegistryContext,
+ disableMessage
+ );
+ if (
+ aasRegistryResponse.success &&
+ aasRegistryResponse.data.result &&
+ aasRegistryResponse.data.result.length > 0
+ ) {
+ const aasDescriptorList = aasRegistryResponse.data.result;
+
+ const aasEndpoints = aasDescriptorList.map((aasDescriptor: any) => {
+ return this.extractEndpointHref(aasDescriptor, 'AAS-3.0');
+ });
+
+ const aasList = await Promise.all(
+ aasEndpoints.map((aasEndpoint: string) => {
+ return this.fetchAas(aasEndpoint);
+ })
+ );
+
+ const submodelId = reference?.keys[0]?.value;
+
+ const aas = aasList.find((aas: any) => {
+ const smRefs = aas.submodels;
+
+ if (smRefs) {
+ const smIds = smRefs.map((smRef: any) => {
+ return smRef?.keys[0]?.value;
+ });
+
+ if (smIds) {
+ const smId = smIds.find((smId: string) => {
+ return smId === submodelId;
+ });
+
+ if (smId) {
+ return true;
+ }
+ }
+ }
+ });
+
+ if (aas) {
+ return await this.checkSmReference(reference, aasDescriptorList, aas);
+ }
+
+ return failResponse;
+
+ // return await this.checkSmReference(
+ // reference,
+ // aasDescriptorList,
+ // currentAasDescriptor
+ // );
+ }
+ return failResponse;
+ } catch {
+ // handle error
+ return failResponse;
+ }
+ }
+ return checkResponse;
+ } else {
+ return failResponse;
}
}
- return { success: false, aas: {}, submodel: {} };
- } catch {
- // handle error
- return { success: false, aas: {}, submodel: {} };
+
+ return failResponse;
+ } else {
+ return failResponse;
}
},
- // Function to check if the referenced AAS exists
- async checkReferenceAAS(
- aasList: Array,
- referenceValue: Array
- ): Promise<{ success: boolean; aas?: object; submodel?: object }> {
- try {
- aasList.forEach((aas: any) => {
- if (aas.id == referenceValue[0].value) {
- // console.log('AAS found. AAS: ', { success: true, aas: aas, submodel: {} });
- throw { success: true, aas: aas, submodel: {} };
- }
+ // Function to check if AAS of Reference exists
+ async checkAasReference(
+ aasReference: any,
+ aasDescriptorList?: Array
+ ): Promise<{ success: boolean; aasDescriptor: object; submodelDescriptor: object }> {
+ // console.log('checkAasReference()', 'aasReference', aasReference, 'aasDescriptorList', aasDescriptorList);
+ const failResponse = { success: false, aasDescriptor: {}, submodelDescriptor: {} }; // Define once for reuse
+
+ if (aasReference?.keys[0]?.type !== 'AssetAdministrationShell') return failResponse;
+
+ if (!Array.isArray(aasDescriptorList) || aasDescriptorList.length === 0) {
+ aasDescriptorList = await this.fetchAasDescriptorList();
+ }
+
+ if (aasDescriptorList && Array.isArray(aasDescriptorList) && aasDescriptorList.length > 0) {
+ const aasDescriptor = aasDescriptorList.find((aasDescriptor: any) => {
+ return aasDescriptor.id == aasReference?.keys[0]?.value;
});
- } catch (result: any) {
- if (result.success) {
- return result;
- } else {
- throw result; // re-throw if it's an actual error
- }
+
+ return {
+ success: aasDescriptor ? true : false,
+ aasDescriptor: aasDescriptor ? aasDescriptor : {},
+ submodelDescriptor: {},
+ };
}
- return { success: false, aas: {}, submodel: {} };
+
+ return failResponse;
},
- // Function to check if the referenced Submodel (+ SubmodelElement) exists
- async checkReferenceSubmodel(
- aasList: Array,
- referenceValue: Array
- ): Promise<{ success: boolean; aas?: object; submodel?: object }> {
- const promises = aasList.map(async (aas: any) => {
- const shellHref = this.extractEndpointHref(aas, 'AAS-3.0');
- const path = shellHref + '/submodel-refs';
- const context = 'retrieving Submodel References';
- const disableMessage = false;
+ // Function to check if the referenced Submodel (+ SubmodelElement) exists (in aasDescriptor)
+ async checkSmReference(
+ smReference: any,
+ aasDescriptorList: Array,
+ currentAasDescriptor?: any
+ ): Promise<{ success: boolean; aasDescriptor?: object; submodelRef?: object }> {
+ // console.log(
+ // 'checkSmReference (' + smReference.type + '): ',
+ // 'smReference',
+ // smReference,
+ // 'aasDescriptorList (#' + (Array.isArray(aasDescriptorList) ? aasDescriptorList.length : 0) + ')',
+ // aasDescriptorList,
+ // 'currentAasDescriptor',
+ // currentAasDescriptor
+ // );
+
+ const failResponse = { success: false, aasDescriptor: {}, submodelRef: {} }; // Define once for reuse
+
+ // Todo checkSmReference for ExternalReference
+ if (smReference.type === 'ExternalReference') {
+ this.navigationStore.dispatchSnackbar({
+ status: true,
+ timeout: 10000,
+ color: 'warning',
+ btnColor: 'buttonText',
+ text: 'Reference check for ExternalReference not implemented',
+ }); // Show Error Snackbar
+ return failResponse;
+ } else if (smReference.type === 'ModelReference') {
+ // Check ModelReference
+ let aasDescriptor = {};
- const response = await this.getRequest(path, context, disableMessage);
- if (response.success) {
- const submodelList = response.data.result;
- const foundSubmodel = submodelList.find(
- (submodel: any) => submodel.keys[0].value == referenceValue[0].value
- );
- if (foundSubmodel) {
- return { success: true, aas: aas, submodel: foundSubmodel };
- }
+ if (smReference?.keys[0]?.type === 'AssetAdministrationShell') {
+ aasDescriptor = await this.checkAasReference(smReference).then(({ aasDescriptor }) => {
+ return aasDescriptor;
+ });
+ } else if (Object.keys(currentAasDescriptor).length > 0) {
+ aasDescriptor = currentAasDescriptor;
}
- return null; // null signifies that this particular iteration didn't find what it was looking for
- });
- const results = await Promise.all(promises);
- const foundResult = results.find((result) => result !== null);
+ if (
+ smReference?.keys[0]?.type === 'AssetAdministrationShell' &&
+ smReference?.keys[1]?.type === 'Submodel'
+ ) {
+ const promises = aasDescriptorList.map(async (aasDescriptor: any) => {
+ const aasEndpoint = this.extractEndpointHref(aasDescriptor, 'AAS-3.0');
+ const aasRepoPath = aasEndpoint + '/submodel-refs';
+ const aasRepoContext = 'retrieving Submodel References';
+ const disableMessage = false;
+
+ const aasRepoResponse = await this.getRequest(aasRepoPath, aasRepoContext, disableMessage);
+ if (aasRepoResponse.success) {
+ const submodelRefList = aasRepoResponse.data.result;
+ let foundSubmodelRef = {};
+ foundSubmodelRef = submodelRefList.find(
+ (submodelRef: any) => submodelRef.keys[0].value == smReference.keys[1].value
+ );
+ // }
+ if (foundSubmodelRef && Object.keys(foundSubmodelRef).length > 0) {
+ return {
+ success: true,
+ aasDescriptor: aasDescriptor,
+ submodelRef: foundSubmodelRef,
+ };
+ }
+ }
+ return null; // null signifies that this particular iteration didn't find what it was looking for
+ });
+
+ const results = await Promise.all(promises);
+ const result = results.find((result) => result !== null);
+
+ if (result) return result; // One of the ieterations was successful
+ return { success: false, aasDescriptor: {}, submodelRef: {} }; // None of the iterations were successful
+ } else if (Object.keys(aasDescriptor).length > 0 && smReference?.keys[0]?.type === 'Submodel') {
+ const aasEndpoint = this.extractEndpointHref(aasDescriptor, 'AAS-3.0');
+ const aasRepoPath = aasEndpoint + '/submodel-refs';
+ const aasRepoContext = 'retrieving Submodel References';
+ const disableMessage = false;
+
+ const aasRepoResponse = await this.getRequest(aasRepoPath, aasRepoContext, disableMessage);
+ if (aasRepoResponse.success) {
+ const submodelRefList = aasRepoResponse.data.result;
+ const foundSubmodelRef = submodelRefList.find(
+ (submodelRef: any) => submodelRef.keys[0].value === smReference.keys[0].value
+ );
+ if (foundSubmodelRef && Object.keys(foundSubmodelRef).length > 0) {
+ return {
+ success: true,
+ aasDescriptor: aasDescriptor,
+ submodelRef: foundSubmodelRef,
+ };
+ }
+ }
+ }
- if (foundResult) {
- return foundResult; // One of the iterations was successful
+ return { success: false, aasDescriptor: aasDescriptor, submodelRef: {} };
} else {
- return { success: false, aas: {}, submodel: {} }; // None of the iterations were successful
+ return failResponse;
}
},
// Function to jump to a referenced Element
- jumpToReferencedElement(referencedAAS: any, referenceValue: Array, referencedSubmodel?: any) {
- // console.log('jumpToReferencedElement. AAS: ', referencedAAS, 'Submodel: ', referencedSubmodel);
- const shellHref = this.extractEndpointHref(referencedAAS, 'AAS-3.0');
- const endpoint = shellHref;
- if (referencedSubmodel && Object.keys(referencedSubmodel).length > 0) {
+ jumpToReference(reference: any, aasDescriptor?: any, smRef?: any) {
+ // console.log('jumpToReference', 'reference', reference, 'aasDescriptor', aasDescriptor, 'smRef', smRef);
+ if (smRef && Object.keys(smRef).length > 0) {
// if the referenced Element is a Submodel or SubmodelElement
- this.jumpToSubmodelElement(referencedSubmodel, referenceValue, referencedAAS, endpoint);
- } else {
+ // console.log(
+ // 'jumpToReference --> jumpToSubmodelElement',
+ // 'reference',
+ // reference,
+ // 'aasDescriptor',
+ // aasDescriptor,
+ // 'smRef',
+ // smRef
+ // );
+ this.jumpToSubmodelElement(reference, aasDescriptor, smRef);
+ } else if (aasDescriptor && Object.keys(aasDescriptor).length > 0) {
// if the referenced Element is an AAS
- this.jumpToAAS(referencedAAS, endpoint);
+ // console.log('jumpToReference --> jumpToAasByAasDescriptor', 'aasDescriptor', aasDescriptor);
+ this.jumpToAasByAasDescriptor(aasDescriptor);
}
},
- jumpToSubmodelElement(
- referencedSubmodel: any,
- referenceValue: Array,
- referencedAAS: any,
- endpoint: string
- ) {
- let path =
- this.submodelRepoURL + '/' + this.URLEncode(referencedSubmodel.keys[0].value).replace(/%3D/g, '');
- if (referenceValue.length > 1) {
- // this is the layer directly under the Submodel
- path += '/submodel-elements/' + referenceValue[1].value;
+ jumpToSubmodelElement(reference: any, aasDescriptor: any, smRef: any) {
+ // console.log(
+ // 'jumpToSubmodelElement()',
+ // 'reference',
+ // reference,
+ // 'aasDescriptor',
+ // aasDescriptor,
+ // 'smRef',
+ // smRef
+ // );
+
+ const aasEndpoint = this.extractEndpointHref(aasDescriptor, 'AAS-3.0');
+ const smId = smRef?.keys[0]?.value;
+
+ // This is the Submodel layer
+ let smRepoUrl = this.submodelRepoUrl;
+ smRepoUrl += '/' + this.URLEncode(smId).replace(/%3D/g, '');
+
+ // This is the layer directly under the Submodel
+ if (
+ Array.isArray(reference?.keys) &&
+ reference?.keys.length > 1 &&
+ reference?.keys[0]?.type === 'Submodel'
+ ) {
+ smRepoUrl += '/submodel-elements/' + reference.keys[1].value;
+ } else if (
+ Array.isArray(reference?.keys) &&
+ reference?.keys.length > 2 &&
+ reference?.keys[1]?.type === 'Submodel'
+ ) {
+ smRepoUrl += '/submodel-elements/' + reference.keys[2].value;
}
+
let promise; // Promise to wait for the SubmodelElementList to be requested (if it exists)
- if (referenceValue.length > 2) {
+ if (
+ Array.isArray(reference?.keys) &&
+ ((reference?.keys.length > 2 && reference?.keys[0]?.type === 'Submodel') ||
+ (reference?.keys.length > 3 && reference?.keys[1]?.type === 'Submodel'))
+ ) {
// this is the layer under either a SubmodelElementCollection or SubmodelElementList
- promise = new Promise((resolve, reject) => {
- referenceValue.forEach((SubmodelElement: any, index: number) => {
- if (index > 1) {
+ promise = new Promise((resolve) => {
+ reference.keys.forEach(async (smeKey: any, index: number) => {
+ if (
+ Array.isArray(reference?.keys) &&
+ ((reference?.keys.length > 2 && reference?.keys[0]?.type === 'Submodel' && index > 1) ||
+ (reference?.keys.length > 3 && reference?.keys[1]?.type === 'Submodel' && index > 2))
+ ) {
// check if the type of the SubmodelElement with index - 1 is a SubmodelElementList
- if (referenceValue[index - 1].type == 'SubmodelElementList') {
- // console.log('SubmodelElementList: ', this.referenceValue[index - 1])
+ if (reference.keys[index - 1].type == 'SubmodelElementList') {
// check in which position of the list the element is (list needs to be requested to get the position)
- const listPath = path;
- const context = 'retrieving SubmodelElementList';
+ const smRepoPath = smRepoUrl;
+ const smRepoContext = 'retrieving SML';
const disableMessage = false;
- this.getRequest(listPath, context, disableMessage)
- .then((response: any) => {
- if (response.success) {
- // execute if the Request was successful
- const list = response.data;
- list.value.forEach((element: any, i: number) => {
- if (this.checkIdShort(element, SubmodelElement.value, false, true)) {
- path += encodeURIComponent('[') + i + encodeURIComponent(']');
- }
- });
- resolve();
+ try {
+ const smRepoResponse = await this.getRequest(
+ smRepoPath,
+ smRepoContext,
+ disableMessage
+ );
+ if (
+ smRepoResponse?.success &&
+ smRepoResponse?.data &&
+ Object.keys(smRepoResponse?.data).length > 0
+ ) {
+ const sml = smRepoResponse.data;
+ const index = sml.value.findIndex((sme: any) =>
+ this.checkIdShort(sme, smeKey.value, false, true)
+ );
+ if (index !== -1) {
+ smRepoUrl += encodeURIComponent('[') + index + encodeURIComponent(']');
}
- })
- .catch((error: any) => {
- // console.error('Error with getRequest:', error);
- reject(error);
- });
+ }
+ resolve();
+ } catch {
+ resolve();
+ }
+ } else if (reference.keys[index - 1].type == 'SubmodelElementCollection') {
+ // check in which position of the list the element is (list needs to be requested to get the position)
+ const smRepoPath = smRepoUrl;
+ const smRepoContext = 'retrieving SMC';
+ const disableMessage = false;
+ try {
+ const smRepoResponse = await this.getRequest(
+ smRepoPath,
+ smRepoContext,
+ disableMessage
+ );
+ if (
+ smRepoResponse?.success &&
+ smRepoResponse?.data &&
+ Object.keys(smRepoResponse?.data).length > 0
+ ) {
+ const smc = smRepoResponse.data;
+ const sme = smc.value.find((sme: any) =>
+ this.checkIdShort(sme, smeKey.value, false, true)
+ );
+ if (sme && Object.keys(sme).length > 0) {
+ smRepoUrl += '.' + smeKey.value;
+ }
+ }
+ resolve();
+ } catch {
+ resolve();
+ }
} else {
- path += '.' + SubmodelElement.value;
+ smRepoUrl += '.' + smeKey.value;
}
}
});
if (
- referenceValue.every(
+ reference.keys.every(
(SubmodelElement: any, index: number) =>
- index <= 1 || referenceValue[index - 1].type != 'SubmodelElementList'
+ index <= 1 || reference.keys[index - 1].type != 'SubmodelElementList'
)
) {
resolve(); // Resolve immediately if none of the elements are SubmodelElementList
@@ -536,35 +789,33 @@ export default defineComponent({
}
promise
- .then(() => {
+ .then(async () => {
+ // console.log('jumpToSubmodelElement()', 'aasEndPoint', aasEndpoint, 'smRepoUrl', smRepoUrl);
// check if mobile device
if (this.navigationStore.getIsMobile) {
- this.router.push({ name: 'SubmodelList', query: { aas: endpoint, path: path } });
+ this.router.push({ name: 'SubmodelList', query: { aas: aasEndpoint, path: smRepoUrl } });
} else {
// set the AAS Endpoint and SubmodelElement path in the aas and path query parameters using the router
- this.router.push({ query: { aas: endpoint, path: path } });
+ this.router.push({ query: { aas: aasEndpoint, path: smRepoUrl } });
}
// dispatch the AAS set by the ReferenceElement to the store
- this.aasStore.dispatchSelectedAAS(referencedAAS);
- this.navigationStore.dispatchTriggerAASSelected();
+ await this.fetchAndDispatchAas(aasEndpoint);
this.navigationStore.dispatchTriggerAASListScroll();
// Request the referenced SubmodelElement
- const elementPath = path;
+ const elementPath = smRepoUrl;
const context = 'retrieving SubmodelElement';
const disableMessage = true;
this.getRequest(elementPath, context, disableMessage).then((response: any) => {
if (response.success) {
- // execute if the Request was successful
- response.data.timestamp = this.formatDate(new Date()); // add timestamp to the SubmodelElement Data
- response.data.path = path; // add the path to the SubmodelElement Data
- response.data.isActive = true; // add the isActive Property to the SubmodelElement Data
- // console.log('SubmodelElement Data: ', response.data)
- // dispatch the SubmodelElementPath set by the URL to the store
- this.aasStore.dispatchNode(response.data); // set the updatedNode in the AASStore
+ const node = response.data;
+ node.timestamp = this.formatDate(new Date()); // add timestamp to the SubmodelElement Data
+ node.path = smRepoUrl; // add the path to the SubmodelElement Data
+ node.isActive = true; // add the isActive Property to the SubmodelElement Data
+ this.aasStore.dispatchNode(node); // set the updatedNode in the AASStore
this.aasStore.dispatchInitTreeByReferenceElement(true); // set the initTreeByReferenceElement in the AASStore to true to init + expand the Treeview on the referenced Element
} else {
// execute if the Request failed
- if (Object.keys(response.data).length == 0) {
+ if (response?.data && Object.keys(response?.data).length === 0) {
// don't copy the static SubmodelElement Data if no Node is selected or Node is invalid
this.navigationStore.dispatchSnackbar({
status: true,
@@ -584,64 +835,552 @@ export default defineComponent({
});
},
- jumpToAAS(aas: any, endpoint: string) {
- // check if mobile device
+ ////////////////////////////////////////////////// AAS Stuff //////////////////////////////////////////////////
+
+ // Fetch List of all available AAS Descriptors
+ async fetchAasDescriptorList(): Promise> {
+ // console.log('fetchAasDescriptorList()');
+
+ const failResponse = [] as Array;
+
+ let aasRegistryUrl = this.aasRegistryUrl;
+ if (aasRegistryUrl.trim() === '') return failResponse;
+ if (!aasRegistryUrl.includes('/shell-descriptors')) {
+ aasRegistryUrl += '/shell-descriptors';
+ }
+
+ const aasRegistryPath = aasRegistryUrl;
+ const aasRegistryContext = 'retrieving all AAS Descriptors';
+ const disableMessage = false;
+ try {
+ const aasRegistryResponse = await this.getRequest(aasRegistryPath, aasRegistryContext, disableMessage);
+ if (
+ aasRegistryResponse.success &&
+ aasRegistryResponse.data.result &&
+ aasRegistryResponse.data.result.length > 0
+ ) {
+ return aasRegistryResponse.data.result;
+ }
+ } catch {
+ // handle error
+ return failResponse;
+ }
+
+ return failResponse;
+ },
+
+ // Fetch List of all available AAS
+ async fetchAasList(): Promise> {
+ // console.log('fetchAasList()');
+
+ const failResponse = [] as Array;
+
+ let aasRepoUrl = this.aasRepoUrl;
+ if (aasRepoUrl.trim() === '') return failResponse;
+ if (!aasRepoUrl.includes('/shells')) {
+ aasRepoUrl += '/shells';
+ }
+
+ const aasRepoPath = aasRepoUrl;
+ const aasRepoContext = 'retrieving all AAS';
+ const disableMessage = false;
+ try {
+ const aasRepoResponse = await this.getRequest(aasRepoPath, aasRepoContext, disableMessage);
+ if (aasRepoResponse.success && aasRepoResponse.data.result && aasRepoResponse.data.result.length > 0) {
+ return aasRepoResponse.data.result;
+ }
+ } catch {
+ // handle error
+ return failResponse;
+ }
+ return failResponse;
+ },
+
+ // Fetch AAS Descriptor by AAS ID with AAS Registry
+ async fetchAasDescriptorById(aasId: string): Promise {
+ // console.log('fetchAasDescriptorById()', aasId);
+
+ const failResponse = {} as any;
+
+ let aasRegistryUrl = this.aasRegistryUrl;
+ if (aasRegistryUrl.trim() === '') return failResponse;
+ if (!aasRegistryUrl.includes('/shell-descriptors')) {
+ aasRegistryUrl += '/shell-descriptors';
+ }
+
+ const aasRegistryPath = aasRegistryUrl + '/' + this.URLEncode(aasId);
+ const aasRegistryContext = 'retrieving AAS Descriptor';
+ const disableMessage = false;
+ try {
+ const aasRegistryResponse = await this.getRequest(aasRegistryPath, aasRegistryContext, disableMessage);
+ if (
+ aasRegistryResponse?.success &&
+ aasRegistryResponse?.data &&
+ Object.keys(aasRegistryResponse?.data).length > 0
+ ) {
+ return aasRegistryResponse.data;
+ }
+ } catch {
+ // handle error
+ return failResponse;
+ }
+ return failResponse;
+ },
+
+ // Fetch AAS from AAS Repo (with the help of the AAS Registry)
+ async fetchAasById(aasId: string): Promise {
+ // console.log('fetchAasById()', aasId);
+ const failResponse = {} as any;
+
+ if (aasId.trim() === '') return failResponse;
+
+ const aasDescriptor = await this.fetchAasDescriptorById(aasId);
+
+ if (aasDescriptor && Object.keys(aasDescriptor).length > 0) {
+ const aasEndpoint = this.extractEndpointHref(aasDescriptor, 'AAS-3.0');
+ return this.fetchAas(aasEndpoint);
+ }
+
+ return failResponse;
+ },
+
+ // Fetch AAS from (AAS Repo) Endpoint
+ async fetchAas(aasEndpoint: string): Promise {
+ // console.log('fetchAas()', aasEndpoint);
+ const failResponse = {} as any;
+
+ if (aasEndpoint.trim() === '') return failResponse;
+
+ const aasRepoPath = aasEndpoint;
+ const aasRepoContext = 'retrieving AAS Data';
+ const disableMessage = true;
+ try {
+ const aasRepoResponse = await this.getRequest(aasRepoPath, aasRepoContext, disableMessage);
+ if (
+ aasRepoResponse?.success &&
+ aasRepoResponse?.data &&
+ Object.keys(aasRepoResponse?.data).length > 0
+ ) {
+ const aas = aasRepoResponse.data;
+ // console.log('fetchAas()', aasEndpoint, 'aas', aas);
+
+ // Add endpoint to AAS
+ aas.endpoints = [{ protocolInformation: { href: aasEndpoint }, interface: 'AAS-3.0' }];
+
+ return aas;
+ }
+ } catch {
+ return failResponse;
+ }
+
+ return failResponse;
+ },
+
+ // Fetch and Dispatch AAS from (AAS Repo) Endpoint
+ async fetchAndDispatchAas(aasEndpoint: string) {
+ // console.log('fetchAndDispatchAas()', aasEndpoint);
+ if (aasEndpoint.trim() === '') return;
+
+ const aas = await this.fetchAas(aasEndpoint);
+ // console.log('fetchAndDispatchAas()', aasEndpoint, 'aas', aas);
+
+ this.aasStore.dispatchSelectedAAS(aas);
+ },
+
+ // Checks weather an AAS is available
+ // Checks availability in AAS Repo
+ // Checks availability in AAS Registry and AAS Repo if AAS Registry is available
+ async aasIsAvailableById(aasId: string): Promise {
+ // console.log('aasIsAvailableById()', aasId);
+ const failResponse = false;
+
+ if (aasId.trim() === '') return failResponse;
+
+ const aasDescriptorList = await this.fetchAasDescriptorList();
+ const aasList = await this.fetchAasList();
+
+ if (aasList && Array.isArray(aasList) && aasList.length > 0) {
+ // Check availability of AAS in AAS Repo
+ const aasFound = aasList.find((aas: any) => {
+ return aas.id == aasId;
+ });
+
+ if (aasFound && Object.keys(aasFound).length > 0) {
+ if (aasDescriptorList && Array.isArray(aasDescriptorList) && aasDescriptorList.length > 0) {
+ // Check availability of AAS in AAS Registry
+ const aasDescriptorFound = aasDescriptorList.find((aasDescriptor: any) => {
+ return aasDescriptor.id == aasId;
+ });
+
+ if (aasDescriptorFound && Object.keys(aasDescriptorFound).length > 0) {
+ return true; // AAS found in AAS Registry and AAS Repo
+ }
+
+ return failResponse;
+ }
+ return true; // AAS only found in AAS Repo (AAS Registry not available)
+ }
+ }
+
+ return failResponse;
+ },
+
+ // Checks weather AAS is available in AAS Repo
+ async aasIsAvailable(aasEndpoint: string): Promise {
+ // console.log('aasIsAvailable()', aasEndpoint);
+ const failResponse = false;
+
+ if (aasEndpoint.trim() === '') return failResponse;
+
+ const aas = await this.fetchAas(aasEndpoint);
+ // console.log('aasIsAvailable()', aasEndpoint, 'aas', aas);
+
+ if (aas && Object.keys(aas).length > 0) return true;
+
+ return failResponse;
+ },
+
+ // Checks weather referenced AAS is available
+ async aasReferenceIsAvailable(aasReference: any): Promise {
+ // console.log('aasIsAvailable()', aasEndpoint);
+ const failResponse = false;
+
+ if (
+ !aasReference ||
+ Object.keys(aasReference).length === 0 ||
+ !aasReference?.keys ||
+ !Array.isArray(aasReference?.keys) ||
+ aasReference?.keys.length === 0 ||
+ !aasReference?.keys[0]?.type ||
+ aasReference?.keys[0]?.type !== 'AssetAdministrationShell' ||
+ !aasReference?.keys[0]?.value ||
+ aasReference?.keys[0]?.value.trim() === ''
+ ) {
+ return failResponse;
+ }
+
+ const aasId = aasReference?.keys[0]?.value.trim();
+
+ return this.aasIsAvailableById(aasId);
+ },
+
+ // Jumps to AAS by AAS Descriptor
+ async jumpToAasByAasDescriptor(aasDescriptor: any) {
+ // console.log('jumpToAasByAasDescriptor()', aasDescriptor);
+ const aasEndpoint = this.extractEndpointHref(aasDescriptor, 'AAS-3.0');
+ // console.log('jumpToAasByAasDescriptor() --> jumpToAasBy()', aasEndpoint);
+ this.jumpToAas(aasEndpoint);
+ },
+
+ // Jumps to AAS by AAS ID
+ async jumpToAasById(aasId: string) {
+ if (!this.aasIsAvailableById(aasId)) return;
+
+ const aas = await this.fetchAasById(aasId);
+ const aasEndpoint = this.extractEndpointHref(aas, 'AAS-3.0');
+
+ this.jumpToAas(aasEndpoint);
+ },
+
+ // Jumps to AAS by AAS Endpoint
+ async jumpToAas(aasEndpoint: string) {
+ // console.log('jumpToAasBy()', aasEndpoint);
+ if (aasEndpoint.trim() === '') return;
+
if (this.navigationStore.getIsMobile) {
- this.router.push({ name: 'SubmodelList', query: { aas: endpoint } });
+ this.router.push({ name: 'SubmodelList', query: { aas: aasEndpoint } });
} else {
- // set the AAS Endpoint in the aas query parameter using the router
- this.router.push({ query: { aas: endpoint } });
+ this.router.push({ query: { aas: aasEndpoint } });
}
- // dispatch the AAS set by the ReferenceElement to the store
- // console.log('AAS:', aas, 'Endpoint:', endpoint);
- this.aasStore.dispatchSelectedAAS(aas);
- this.navigationStore.dispatchTriggerAASSelected();
+ await this.fetchAndDispatchAas(aasEndpoint);
this.navigationStore.dispatchTriggerAASListScroll();
- this.aasStore.dispatchNode({});
},
+ ////////////////////////////////////////////////// SM Stuff //////////////////////////////////////////////////
+
+ // Fetch List of all available SM Descriptors
+ async fetchSmDescriptorList(): Promise> {
+ // console.log('fetchSmDescriptorList()');
+
+ const failResponse = [] as Array;
+
+ let smRegistryUrl = this.submodelRegistryUrl;
+ if (smRegistryUrl.trim() === '') return failResponse;
+ if (!smRegistryUrl.includes('/submodel-descriptors')) {
+ smRegistryUrl += '/submodel-descriptors';
+ }
+
+ const smRegistryPath = smRegistryUrl;
+ const smRegistryContext = 'retrieving all SM Descriptors';
+ const disableMessage = false;
+ try {
+ const smRegistryResponse = await this.getRequest(smRegistryPath, smRegistryContext, disableMessage);
+ if (
+ smRegistryResponse.success &&
+ smRegistryResponse.data.result &&
+ smRegistryResponse.data.result.length > 0
+ ) {
+ return smRegistryResponse.data.result;
+ }
+ } catch {
+ // handle error
+ return failResponse;
+ }
+ return failResponse;
+ },
+
+ // Fetch List of all available SM
+ async fetchSmList(): Promise> {
+ // console.log('fetchAasList()');
+
+ const failResponse = [] as Array;
+
+ let smRepoUrl = this.submodelRepoUrl;
+ if (smRepoUrl.trim() === '') return failResponse;
+ if (!smRepoUrl.includes('/shells')) {
+ smRepoUrl += '/shells';
+ }
+
+ const smRepoPath = smRepoUrl;
+ const smRepoContext = 'retrieving all SMs';
+ const disableMessage = false;
+ try {
+ const smRepoResponse = await this.getRequest(smRepoPath, smRepoContext, disableMessage);
+ if (smRepoResponse.success && smRepoResponse.data.result && smRepoResponse.data.result.length > 0) {
+ return smRepoResponse.data.result;
+ }
+ } catch {
+ // handle error
+ return failResponse;
+ }
+ return failResponse;
+ },
+
+ // Fetch SM Descriptor by SM ID with SM Registry
+ async fetchSmDescriptorById(smId: string): Promise {
+ // console.log('fetchSmDescriptorById()', smId);
+
+ const failResponse = {} as any;
+
+ let smRegistryUrl = this.submodelRegistryUrl;
+ if (smRegistryUrl.trim() === '') return failResponse;
+ if (!smRegistryUrl.includes('/shell-descriptors')) {
+ smRegistryUrl += '/shell-descriptors';
+ }
+
+ const smRegistryPath = smRegistryUrl + '/' + this.URLEncode(smId);
+ const smRegistryContext = 'retrieving SM Descriptor';
+ const disableMessage = false;
+ try {
+ const smRegistryResponse = await this.getRequest(smRegistryPath, smRegistryContext, disableMessage);
+ if (
+ smRegistryResponse?.success &&
+ smRegistryResponse?.data &&
+ Object.keys(smRegistryResponse?.data).length > 0
+ ) {
+ return smRegistryResponse.data;
+ }
+ } catch {
+ // handle error
+ return failResponse;
+ }
+ return failResponse;
+ },
+
+ // Fetch SM from SM Repo (with the help of the SM Registry)
+ async fetchSmById(smId: string): Promise {
+ // console.log('fetchAasById()', aasId);
+ const failResponse = {} as any;
+
+ if (smId.trim() === '') return failResponse;
+
+ const smDescriptor = await this.fetchSmDescriptorById(smId);
+
+ if (smDescriptor && Object.keys(smDescriptor).length > 0) {
+ const smEndpoint = this.extractEndpointHref(smDescriptor, 'SUBMODEL-3.0');
+ return this.fetchSm(smEndpoint);
+ }
+
+ return failResponse;
+ },
+
+ // Fetch SM from (SM Repo) Endpoint
+ async fetchSm(smEndpoint: string): Promise {
+ // console.log('fetchSm()', aasEndpoint);
+ const failResponse = {} as any;
+
+ if (smEndpoint.trim() === '') return failResponse;
+
+ const smRepoPath = smEndpoint;
+ const smRepoContext = 'retrieving SM Data';
+ const disableMessage = true;
+ try {
+ const smRepoResponse = await this.getRequest(smRepoPath, smRepoContext, disableMessage);
+ if (smRepoResponse?.success && smRepoResponse?.data && Object.keys(smRepoResponse?.data).length > 0) {
+ const sm = smRepoResponse.data;
+ // console.log('fetchSm()', smEndpoint, 'sm', sm);
+
+ // Add endpoint to AAS
+ sm.endpoints = [{ protocolInformation: { href: smEndpoint }, interface: 'SUBMODEL-3.0' }];
+
+ return sm;
+ }
+ } catch {
+ return failResponse;
+ }
+
+ return failResponse;
+ },
+
+ // Checks weather a SM is available
+ // Checks availability in SM Repo
+ // Checks availability in SM Registry and SM Repo if SM Registry is available
+ async smIsAvailableById(smId: string): Promise {
+ // console.log('smIsAvailableById()', smId);
+ const failResponse = false;
+
+ if (smId.trim() === '') return failResponse;
+
+ const smDescriptorList = await this.fetchSmDescriptorList();
+ const smList = await this.fetchSmList();
+
+ if (smList && Array.isArray(smList) && smList.length > 0) {
+ // Check availability of SM in SM Repo
+ const smFound = smList.find((sm: any) => {
+ return sm.id == smId;
+ });
+
+ if (smFound && Object.keys(smFound).length > 0) {
+ if (smDescriptorList && Array.isArray(smDescriptorList) && smDescriptorList.length > 0) {
+ // Check availability of SM in SM Registry
+ const smDescriptorFound = smDescriptorList.find((smDescriptor: any) => {
+ return smDescriptor.id == smId;
+ });
+
+ if (smDescriptorFound && Object.keys(smDescriptorFound).length > 0) {
+ return true; // SM found in SM Registry and SM Repo
+ }
+
+ return failResponse;
+ }
+ return true; // SM only found in SM Repo (SM Registry not available)
+ }
+ }
+
+ return failResponse;
+ },
+
+ // Checks weather SM is available in SM Repo
+ async smIsAvailable(smEndpoint: string): Promise {
+ // console.log('aasIsAvailable()', smEndpoint);
+ const failResponse = false;
+
+ if (smEndpoint.trim() === '') return failResponse;
+
+ const sm = await this.fetchSm(smEndpoint);
+ // console.log('smIsAvailable()', smEndpoint, 'sm', sm);
+
+ if (sm && Object.keys(sm).length > 0) return true;
+
+ return failResponse;
+ },
+
+ // Checks weather referenced SM is available
+ async smReferenceIsAvailable(smReference: any): Promise {
+ // console.log('aasIsAvailable()', aasEndpoint);
+ const failResponse = false;
+
+ if (
+ !smReference ||
+ Object.keys(smReference).length === 0 ||
+ !smReference?.keys ||
+ !Array.isArray(smReference?.keys) ||
+ smReference?.keys.length === 0 ||
+ !smReference?.keys[0]?.type
+ ) {
+ return failResponse;
+ }
+
+ if (
+ smReference?.keys[0]?.type === 'AssetAdministrationShell' &&
+ (!smReference?.keys[1]?.type ||
+ smReference?.keys[1]?.type !== 'Submodel' ||
+ !smReference?.keys[1]?.value ||
+ smReference?.keys[1]?.value.trim() === '')
+ ) {
+ return failResponse; //
+ }
+
+ if (
+ smReference?.keys[0]?.type === 'Submodel' &&
+ (!smReference?.keys[0]?.value || smReference?.keys[0]?.value.trim() === '')
+ ) {
+ return failResponse; //
+ }
+
+ let smId = '';
+ if (
+ smReference?.keys[0]?.type === 'AssetAdministrationShell' &&
+ smReference?.keys[1]?.type !== 'Submodel'
+ ) {
+ smId = smReference?.keys[1]?.value;
+ } else if (smReference?.keys[0]?.type === 'Submodel') {
+ smId = smReference?.keys[0]?.value;
+ }
+
+ if (smId.trim() !== '') {
+ return this.smIsAvailableById(smId);
+ }
+ return failResponse;
+ },
+
+ ////////////////////////////////////////////////// OTHER STUFF //////////////////////////////////////////////////
+
// Function to check if the assetId can be found in the AAS Discovery Service (and if it exists in the AAS Registry)
- async checkAssetId(assetId: string): Promise<{ success: boolean; aas?: object; submodel?: object }> {
- const failResponse = { success: false, aas: {}, submodel: {} }; // Define once for reuse
- // check if aasDiscoveryURL includes "/lookup/shells" and add id if not (backward compatibility)
- if (!this.aasDiscoveryURLMixin.includes('/lookup/shells')) {
- this.aasDiscoveryURLMixin += '/lookup/shells';
+ async checkAssetId(globalAssetId: string): Promise<{ success: boolean; aasDescriptor?: object }> {
+ // console.log('checkAssetId', 'globalAssetId', globalAssetId);
+ const failResponse = { success: false, aasDescriptor: {} }; // Define once for reuse
+ // check if aasDiscoveryUrl includes "/lookup/shells" and add id if not (backward compatibility)
+ let aasDiscoveryUrl = this.aasDiscoveryUrl;
+ if (!aasDiscoveryUrl.includes('/lookup/shells')) {
+ aasDiscoveryUrl += '/lookup/shells';
}
// construct the assetId Object
- const assetIdObject = JSON.stringify({ name: 'globalAssetId', value: assetId });
- const path = `${this.aasDiscoveryURLMixin}?assetIds=${this.URLEncode(assetIdObject)}`; // Use template literal and encodeURIComponent
- const context = 'retrieving AASID by AssetID';
+ const assetIdObject = JSON.stringify({ name: 'globalAssetId', value: globalAssetId });
+ const aasDiscoveryPath = `${aasDiscoveryUrl}?assetIds=${this.URLEncode(assetIdObject)}`; // Use template literal and encodeURIComponent
+ const aasDiscoveryContext = 'retrieving AAS ID by AssetID';
const disableMessage = true;
try {
- const discoveryResponse = await this.getRequest(path, context, disableMessage);
- // console.log('Discovery Response:', discoveryResponse);
- if (discoveryResponse.success && discoveryResponse.data.result?.length > 0) {
- const aasIds = discoveryResponse.data.result;
- // take the first aasId from the list and check if it exists in the AAS Registry
+ const aasDiscoveryResponse = await this.getRequest(
+ aasDiscoveryPath,
+ aasDiscoveryContext,
+ disableMessage
+ );
+ // console.log('discoveryContext', discoveryPath, 'discoveryResponse', discoveryResponse);
+ if (aasDiscoveryResponse?.success && aasDiscoveryResponse?.data?.result?.length > 0) {
+ const aasIds = aasDiscoveryResponse.data.result;
+
+ // Take the first aasId from the list and check if it exists in the AAS Registry
const aasId = aasIds[0];
- // console.log('AAS ID:', aasId);
- // check if aasRegistryURL includes "/shell-descriptors" and add id if not (backward compatibility)
- if (!this.aasRegistryURLMixin.includes('/shell-descriptors')) {
- this.aasRegistryURLMixin += '/shell-descriptors';
+ let aasRegistryUrl = this.aasRegistryUrl;
+ if (!aasRegistryUrl.includes('/shell-descriptors')) {
+ aasRegistryUrl += '/shell-descriptors';
}
- const registryPath = `${this.aasRegistryURLMixin}/${this.URLEncode(aasId)}`;
- const registryContext = 'retrieving AAS Data';
- try {
- const aasRegistryResponse = await this.getRequest(
- registryPath,
- registryContext,
- disableMessage
- );
- if (aasRegistryResponse.success) {
- const aas = aasRegistryResponse.data;
- // console.log('AAS:', aas);
- return { success: true, aas: aas, submodel: {} };
- }
- return failResponse;
- } catch {
- return failResponse;
+ const aasRegistryPath = `${aasRegistryUrl}/${this.URLEncode(aasId).replace(/%3D/g, '')}`;
+ const aasRegistryContext = 'retrieving AAS Descriptor';
+
+ const aasRegistryResponse = await this.getRequest(
+ aasRegistryPath,
+ aasRegistryContext,
+ disableMessage
+ );
+ if (aasRegistryResponse?.success && Object.keys(aasRegistryResponse?.data).length > 0) {
+ // console.log('registryContext', registryPath, 'registryResponse', registryResponse);
+ const aasDescriptor = aasRegistryResponse.data;
+ return { success: true, aasDescriptor: aasDescriptor };
}
}
+
return failResponse;
} catch {
return failResponse;
@@ -650,10 +1389,7 @@ export default defineComponent({
// Get all ConceptDescriptions for the SubmodelElement from the ConceptDescription Repository
async getConceptDescriptions(SelectedNode: any) {
- let conceptDescriptionRepoURL = '';
- if (this.conceptDescriptionRepoURL && this.conceptDescriptionRepoURL != '') {
- conceptDescriptionRepoURL = this.conceptDescriptionRepoURL;
- } else {
+ if (!this.conceptDescriptionRepoUrl || this.conceptDescriptionRepoUrl === '') {
return Promise.resolve([]); // Return an empty object wrapped in a resolved promise
}
@@ -683,7 +1419,7 @@ export default defineComponent({
);
const cdPromises = semanticIdsUniqueToFetch.map((semanticId: string) => {
- const path = conceptDescriptionRepoURL + '/' + this.URLEncode(semanticId);
+ const path = this.conceptDescriptionRepoUrl + '/' + this.URLEncode(semanticId);
const context = 'retrieving ConceptDescriptions';
const disableMessage = true;
@@ -838,14 +1574,14 @@ export default defineComponent({
},
// Name to be displayed
- nameToDisplay(sme: any, defaultNameToDisplay = '') {
- if (sme.displayName) {
- const displayNameEn = sme.displayName.find((displayName: any) => {
+ nameToDisplay(referable: any, defaultNameToDisplay = '') {
+ if (referable && referable?.displayName) {
+ const displayNameEn = referable.displayName.find((displayName: any) => {
return displayName.language === 'en' && displayName.text !== '';
});
if (displayNameEn && displayNameEn.text) return displayNameEn.text;
}
- return !defaultNameToDisplay && sme.idShort ? sme.idShort : defaultNameToDisplay;
+ return !defaultNameToDisplay && referable?.idShort ? referable.idShort : defaultNameToDisplay;
},
descriptionToDisplay(referable: any) {
@@ -930,13 +1666,13 @@ export default defineComponent({
},
smNotFound(response: any, submodelId: string, path: string, text: string): any {
-
// Check if response contains a "messages" array with a "403" or "401" code
const messages = response.data?.messages || [];
- const authorizationError = messages.some((message: any) => message.code === "403" || message.code === "401");
+ const authorizationError = messages.some(
+ (message: any) => message.code === '403' || message.code === '401'
+ );
if (authorizationError) {
-
const submodel = {
id: submodelId,
idShort: 'Submodel Not Authorized!',
@@ -953,7 +1689,6 @@ export default defineComponent({
return submodel;
}
-
if (text.trim().length > 0) {
this.navigationStore.dispatchSnackbar({
status: true,
diff --git a/aas-web-ui/src/router.ts b/aas-web-ui/src/router.ts
index 19aeff4..bb65ed2 100644
--- a/aas-web-ui/src/router.ts
+++ b/aas-web-ui/src/router.ts
@@ -6,6 +6,7 @@ import ComponentVisualization from '@/components/ComponentVisualization.vue';
import Dashboard from '@/components/Dashboard/Dashboard.vue';
import DashboardGroup from '@/components/Dashboard/DashboardGroup.vue';
import MainWindow from '@/components/MainWindow.vue';
+import Page404 from '@/components/Page404.vue';
import SubmodelList from '@/components/SubmodelList.vue';
const routes = [
@@ -15,6 +16,7 @@ const routes = [
{ path: '/componentvisualization', name: 'ComponentVisualization', component: ComponentVisualization },
{ path: '/aasviewer', name: 'AASViewer', component: AASViewer },
{ path: '/about', name: 'About', component: About },
+ { path: '/404', name: 'NotFound404', component: Page404 },
{ path: '/dashboard', name: 'Dashboard', component: Dashboard },
{ path: '/dashboard-group', name: 'DashboardGroup', component: DashboardGroup },
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: MainWindow },
diff --git a/aas-web-ui/src/store/AASDataStore.ts b/aas-web-ui/src/store/AASDataStore.ts
index 8fa13e4..c341ded 100644
--- a/aas-web-ui/src/store/AASDataStore.ts
+++ b/aas-web-ui/src/store/AASDataStore.ts
@@ -21,7 +21,7 @@ export const useAASStore = defineStore({
actions: {
dispatchSelectedAAS(aasData: object) {
this.aasObject = aasData;
- this.selectedNode = {};
+ this.selectedNode = {}; // Clear node
},
dispatchLoadingState(loadingState: boolean) {
this.loadingState = loadingState;
diff --git a/aas-web-ui/src/store/EnvironmentStore.ts b/aas-web-ui/src/store/EnvironmentStore.ts
index 4f5200b..c2c9dde 100644
--- a/aas-web-ui/src/store/EnvironmentStore.ts
+++ b/aas-web-ui/src/store/EnvironmentStore.ts
@@ -20,6 +20,8 @@ export const useEnvStore = defineStore({
keycloakRealm: '',
keycloakClientId: '',
endpointConfigAvailable: true,
+ singleAas: false,
+ singleAasRedirect: '',
}),
getters: {
getEnvLogoLightPath: (state) => state.logoLightPath,
@@ -39,6 +41,8 @@ export const useEnvStore = defineStore({
getKeycloakRealm: (state) => state.keycloakRealm,
getKeycloakClientId: (state) => state.keycloakClientId,
getEndpointConfigAvailable: (state) => state.endpointConfigAvailable,
+ getSingleAas: (state) => state.singleAas,
+ getSingleAasRedirect: (state) => state.singleAasRedirect,
},
actions: {
async fetchConfig() {
@@ -63,6 +67,17 @@ export const useEnvStore = defineStore({
this.keycloakClientId = config.keycloakClientId;
this.endpointConfigAvailable =
config.endpointConfigAvailable === true || config.endpointConfigAvailable === 'true' ? true : false;
+ this.singleAas = config.singleAas === true || config.singleAas === 'true' ? true : false;
+ if (this.singleAas && config.singleAasRedirect) {
+ // https://gist.github.com/dperini/729294
+ const expression =
+ /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i;
+ const regex = new RegExp(expression);
+ if (config.singleAasRedirect.match(regex)) {
+ // If valid URL
+ this.singleAasRedirect = config.singleAasRedirect;
+ }
+ }
} catch (error) {
console.error('Error fetching config.json: ', error);
}
diff --git a/aas-web-ui/src/store/NavigationStore.ts b/aas-web-ui/src/store/NavigationStore.ts
index a9ce91d..824057b 100644
--- a/aas-web-ui/src/store/NavigationStore.ts
+++ b/aas-web-ui/src/store/NavigationStore.ts
@@ -56,7 +56,6 @@ export const useNavigationStore = defineStore({
plugins: [] as PluginType[],
triggerAASListReload: false as boolean,
triggerAASListScroll: false as boolean,
- triggerAASSelected: false as boolean,
}),
getters: {
@@ -75,7 +74,6 @@ export const useNavigationStore = defineStore({
getPlugins: (state) => state.plugins,
getTriggerAASListReload: (state) => state.triggerAASListReload,
getTriggerAASListScroll: (state) => state.triggerAASListScroll,
- getTriggerAASSelected: (state) => state.triggerAASSelected,
},
actions: {
@@ -130,8 +128,5 @@ export const useNavigationStore = defineStore({
dispatchTriggerAASListScroll() {
this.triggerAASListScroll = !this.triggerAASListScroll;
},
- dispatchTriggerAASSelected() {
- this.triggerAASSelected = !this.triggerAASSelected;
- },
},
});