public UnresolvedReference(ConceptDescription dependant, ConceptMember referenceMember) { Dependant = dependant; Member = referenceMember; ReferencedStub = (IConceptInfo)Member.GetValue(Dependant.Concept); ReferencedKey = ReferencedStub?.GetKey(); }
/// <summary> /// Resolves concepts that were waiting for this concept to be resolved. /// </summary> private void MarkResolvedConcept(ConceptDescription resolved) { _logger.Trace(() => "New concept with resolved references: " + resolved.Key); _resolvedConcepts.Add(resolved.Concept); _resolvedConceptsByKey.Add(resolved.Key, resolved.Concept); foreach (var index in _dslModelIndexes) { index.Add(resolved.Concept); } List <UnresolvedReference> unresolvedReferences; if (_unresolvedConceptsByReference.TryGetValue(resolved.Key, out unresolvedReferences)) { foreach (var unresolved in unresolvedReferences) { if (unresolved.Dependant.UnresolvedDependencies <= 0) { throw new FrameworkException($"Internal error while resolving references of '{unresolved.Dependant.Concept.GetUserDescription()}'." + $" The concept has {unresolved.Dependant.UnresolvedDependencies} unresolved dependencies," + $" but it is marked as unresolved dependency to '{unresolved.ReferencedStub.GetUserDescription()}'."); } unresolved.Member.SetMemberValue(unresolved.Dependant.Concept, resolved.Concept); if (--unresolved.Dependant.UnresolvedDependencies == 0) { MarkResolvedConcept(unresolved.Dependant); } } _unresolvedConceptsByReference.Remove(resolved.Key); } }
private static ConceptDescription createConceptDescription(UANode node, string name) { //ConceptDescription // -> AASIdentifiable // -> Identification // -> Administration // -> DataSpecification // -> DataSpecificationIEC61360 ConceptDescription desc = new ConceptDescription(); Administration admin = new Administration(); Identification iden = new Identification(); desc.embeddedDataSpecification.dataSpecificationContent.dataSpecificationIEC61360.shortName = new LangStringSetIEC61360("EN?", makePretty(name)); foreach (Reference _ref in node.References) { if (_ref.ReferenceType != "HasTypeDefinition") { UANode val = findNode(_ref.Value); if (getTypeDefinition(val) == "1:IAASIdentifiableType") { foreach (Reference _refref in val.References) { if (_refref.ReferenceType != "HasTypeDefinition") { UANode var = findNode(_refref.Value); if (getTypeDefinition(var) == "1:AASIdentifierType") { iden = createIdentification(var); } if (getTypeDefinition(var) == "1:AASAdministrativeInformationType") { admin = createAdmninistration(var); } } } } if (getTypeDefinition(val) == "1:AASDataSpecificationType") { foreach (Reference _refref in val.References) { if (_refref.ReferenceType == "HasComponent") { setIECSpec(findNode(_ref.Value), desc); } } } } } desc.identification = iden; desc.administration = admin; return(desc); }
/// <summary> /// Since DSL parser and macro evaluators return stub references, this function replaces each reference with actual instance of the referenced concept. /// Note: This method could handle circular dependencies between the concepts, but for simplicity of the implementation this is currently not supported. /// </summary> private void ReplaceReferencesWithFullConcepts(ConceptDescription conceptDesc) { var references = ConceptMembers.Get(conceptDesc.Concept).Where(member => member.IsConceptInfo) .Select(member => new UnresolvedReference(conceptDesc, member)); foreach (var reference in references) { ReplaceReferenceWithFullConceptOrMarkUnresolved(reference); } if (conceptDesc.UnresolvedDependencies == 0) { MarkResolvedConcept(conceptDesc); } }
/// <summary> /// Updates concept references to reference existing instances from DslModel matched by the concept key. /// Returns new unique concepts that did not previously exist in DslModel /// (note that some of the returned concepts might not have their references resolved yet). /// </summary> public List <IConceptInfo> AddNewConceptsAndReplaceReferences(IEnumerable <IConceptInfo> newConcepts) { _addConceptsStopwatch.Start(); var newUniqueConcepts = new List <IConceptInfo>(); foreach (var concept in newConcepts) { string conceptKey = concept.GetKey(); if (!_givenConceptsByKey.TryGetValue(conceptKey, out ConceptDescription existingConcept)) { var conceptDesc = new ConceptDescription(concept, conceptKey); _givenConceptsByKey.Add(conceptDesc.Key, conceptDesc); ReplaceReferencesWithFullConcepts(conceptDesc); newUniqueConcepts.Add(conceptDesc.Concept); } else { ValidateNewConceptSameAsExisting(concept, existingConcept.Concept); } } _addConceptsStopwatch.Stop(); return(newUniqueConcepts); }
private static void ConvertToAssetAdministrationShell(AssetAdministrationShellEnvironment_V2_0 environment) { foreach (var envAsset in environment.EnvironmentAssets) { Asset asset = new Asset { Administration = envAsset.Administration, Category = envAsset.Category, Description = envAsset.Description, Identification = envAsset.Identification, IdShort = envAsset.IdShort, Kind = envAsset.Kind, AssetIdentificationModel = envAsset.AssetIdentificationModelReference?.ToReference_V2_0 <ISubmodel>() }; environment.Assets.Add(asset); } foreach (var envConceptDescription in environment.EnvironmentConceptDescriptions) { ConceptDescription conceptDescription = new ConceptDescription() { Administration = envConceptDescription.Administration, Category = envConceptDescription.Category, Description = envConceptDescription.Description, Identification = envConceptDescription.Identification, IdShort = envConceptDescription.IdShort, IsCaseOf = envConceptDescription.IsCaseOf?.ConvertAll(c => c.ToReference_V2_0()), EmbeddedDataSpecifications = (envConceptDescription.EmbeddedDataSpecification?.DataSpecificationContent?.DataSpecificationIEC61360 != null) ? new List <DataSpecificationIEC61360>() : null }; if (conceptDescription.EmbeddedDataSpecifications != null) { DataSpecificationIEC61360 dataSpecification = envConceptDescription .EmbeddedDataSpecification .DataSpecificationContent .DataSpecificationIEC61360 .ToDataSpecificationIEC61360(); (conceptDescription.EmbeddedDataSpecifications as List <DataSpecificationIEC61360>).Add(dataSpecification); } environment.ConceptDescriptions.Add(conceptDescription); } foreach (var envSubmodel in environment.EnvironmentSubmodels) { Submodel submodel = new Submodel() { Administration = envSubmodel.Administration, Category = envSubmodel.Category, Description = envSubmodel.Description, Identification = envSubmodel.Identification, IdShort = envSubmodel.IdShort, Kind = envSubmodel.Kind, Parent = string.IsNullOrEmpty(envSubmodel.Parent) ? null : new Reference( new Key(KeyElements.AssetAdministrationShell, KeyType.IRI, envSubmodel.Parent, true)), SemanticId = envSubmodel.SemanticId?.ToReference_V2_0(), ConceptDescription = null, }; List <ISubmodelElement> smElements = envSubmodel.SubmodelElements.ConvertAll(c => c.submodelElement?.ToSubmodelElement(environment.ConceptDescriptions)); foreach (var smElement in smElements) { submodel.SubmodelElements.Add(smElement); } environment.Submodels.Add(submodel); } foreach (var envAssetAdministrationShell in environment.EnvironmentAssetAdministationShells) { AssetAdministrationShell assetAdministrationShell = new AssetAdministrationShell() { Administration = envAssetAdministrationShell.Administration, Category = envAssetAdministrationShell.Category, DerivedFrom = envAssetAdministrationShell.DerivedFrom?.ToReference_V2_0 <IAssetAdministrationShell>(), Description = envAssetAdministrationShell.Description, Identification = envAssetAdministrationShell.Identification, IdShort = envAssetAdministrationShell.IdShort }; IAsset asset = environment.Assets.Find(a => a.Identification.Id == envAssetAdministrationShell.AssetReference?.Keys?.FirstOrDefault()?.Value); assetAdministrationShell.Asset = asset; foreach (var envSubmodelRef in envAssetAdministrationShell.SubmodelReferences) { ISubmodel submodel = environment.Submodels.Find(s => s.Identification.Id == envSubmodelRef.Keys?.FirstOrDefault()?.Value); if (submodel != null) { assetAdministrationShell.Submodels.Add(submodel); } } environment.AssetAdministrationShells.Add(assetAdministrationShell); } }
public override ISubmodelElement ReadJson(JsonReader reader, Type objectType, ISubmodelElement existingValue, bool hasExistingValue, JsonSerializer serializer) { JObject jObject; try { jObject = JObject.Load(reader); } catch (Exception) { return(null); } ModelType modelTypeToken = jObject.SelectToken("modelType")?.ToObject <ModelType>(serializer); DataType valueTypeToken = jObject.SelectToken("valueType")?.ToObject <DataType>(serializer); JToken embeddedDataSpecificationsToken = jObject.SelectToken("embeddedDataSpecifications"); JToken conceptDescriptionToken = jObject.SelectToken("conceptDescription"); SubmodelElement submodelElement; List <IEmbeddedDataSpecification> embeddedDataSpecifications = null; ConceptDescription conceptDescription = null; var embeddedDataSpecificationsTokenChildToken = embeddedDataSpecificationsToken?.Children(); if (embeddedDataSpecificationsTokenChildToken != null) { embeddedDataSpecifications = new List <IEmbeddedDataSpecification>(); foreach (var dataSpecificationToken in embeddedDataSpecificationsTokenChildToken) { var dataSpecReference = dataSpecificationToken.SelectToken("hasDataSpecification")?.ToObject <Reference>(serializer); if (dataSpecReference != null && DataElementInformationTypes.TryGetValue(dataSpecReference.First.Value, out Type type)) { var content = dataSpecificationToken?.ToObject(type, serializer); if (content != null) { embeddedDataSpecifications.Add((IEmbeddedDataSpecification)content); } } } jObject.Remove("embeddedDataSpecifications"); } if (conceptDescriptionToken != null) { var dataSpecifications = conceptDescriptionToken.SelectToken("embeddedDataSpecifications")?.Children(); if (dataSpecifications != null) { conceptDescription = new ConceptDescription(); foreach (var dataSpecificationToken in dataSpecifications) { var dataSpecReference = dataSpecificationToken.SelectToken("hasDataSpecification")?.ToObject <Reference>(serializer); if (dataSpecReference != null && DataElementInformationTypes.TryGetValue(dataSpecReference.First.Value, out Type type)) { var content = dataSpecificationToken.ToObject(type, serializer); if (content != null) { (conceptDescription.EmbeddedDataSpecifications as List <IEmbeddedDataSpecification>).Add((IEmbeddedDataSpecification)content); } } } } serializer.Populate(conceptDescriptionToken.CreateReader(), conceptDescription); } if (modelTypeToken != null) { submodelElement = SubmodelElementFactory.CreateSubmodelElement(modelTypeToken, valueTypeToken); submodelElement.EmbeddedDataSpecifications = embeddedDataSpecifications; submodelElement.ConceptDescription = conceptDescription; } else { logger.Error("ModelType missing: " + jObject.ToString()); return(null); } if (submodelElement == null) { logger.Error("DataElement is null: " + jObject.ToString()); return(null); } serializer.Populate(jObject.CreateReader(), submodelElement); return(submodelElement); }
private static void setIECSpec(UANode node, ConceptDescription desc) { //DataSpecificationIEC61360 // -> many, many parameters foreach (Reference _ref in node.References) { if (_ref.ReferenceType != "HasTypeDefinition") { foreach (Reference _refref in findNode(_ref.Value).References) { if (_refref.ReferenceType != "HasTypeDefinition") { if (_refref.ReferenceType == "HasProperty") { UAVariable var = (UAVariable)findNode(_refref.Value); if (var.BrowseName == "1:DataType") { desc.embeddedDataSpecification .dataSpecificationContent .dataSpecificationIEC61360 .dataType = var.Value.InnerText; } if (var.BrowseName == "1:Symbol") { desc.embeddedDataSpecification .dataSpecificationContent .dataSpecificationIEC61360 .symbol = var.Value.InnerText; } if (var.BrowseName == "1:Unit") { desc.embeddedDataSpecification .dataSpecificationContent .dataSpecificationIEC61360 .unit = var.Value.InnerText; } if (var.BrowseName == "1:ValueFormat") { desc.embeddedDataSpecification .dataSpecificationContent .dataSpecificationIEC61360 .valueFormat = var.Value.InnerText; } if (var.BrowseName == "1:IdShort ") { desc.idShort = var.Value.InnerText; } if (var.BrowseName == "1:Category ") { desc.category = var.Value.InnerText; } } else if (_refref.ReferenceType == "HasComponent") { UANode obj = findNode(_refref.Value); if (obj.BrowseName == "1:Definition") { desc.embeddedDataSpecification .dataSpecificationContent .dataSpecificationIEC61360 .definition .langString = getDescription(obj); } if (obj.BrowseName == "1:PreferredName") { desc.embeddedDataSpecification .dataSpecificationContent .dataSpecificationIEC61360 .preferredName .langString = getDescription(obj); } } } } } } desc.SetAdminstration("2.0", "1"); desc.SetIdentification( "URI", "http://admin-shell.io/DataSpecificationTemplates/DataSpecificationIEC61360/2/0"); }
public override IAssetAdministrationShell GenerateAssetAdministrationShell() { AssetAdministrationShell aas = new AssetAdministrationShell(); aas.IdShort = "HelloAAS"; aas.Identification = new Identifier("http://basys40.de/shells/HelloAAS/" + Guid.NewGuid().ToString(), KeyType.IRI); aas.Description = new LangStringSet() { new LangString("en-US", "This is an exemplary Asset Administration Shell for starters") }; aas.Asset = new Asset() { Description = new LangStringSet() { new LangString("en-US", "This is an exemplary Asset reference from the Asset Administration Shell") }, IdShort = "HelloAsset", Identification = new Identifier("http://basys40.de/assets/HelloAsset/" + Guid.NewGuid().ToString(), KeyType.IRI), Kind = AssetKind.Instance, SemanticId = new Reference(new GlobalKey(KeyElements.Asset, KeyType.IRI, "urn:basys:org.eclipse.basyx:assets:HelloAsset:1.0.0")) }; Submodel helloSubmodel = new Submodel { Description = new LangStringSet() { new LangString("en-US", "This is an exemplary Submodel") }, IdShort = "HelloSubmodel", Identification = new Identifier("http://basys40.de/submodels/HelloSubmodel/" + Guid.NewGuid().ToString(), KeyType.IRI), Kind = ModelingKind.Instance, SemanticId = new Reference(new GlobalKey(KeyElements.Submodel, KeyType.IRI, "urn:basys:org.eclipse.basyx:submodels:HelloSubmodel:1.0.0")) }; helloSubmodel.SubmodelElements = new ElementContainer <ISubmodelElement>(); helloSubmodel.SubmodelElements.Add(new Property <string>() { Description = new LangStringSet() { new LangString("en-US", "This is an exemplary property") }, IdShort = "HelloProperty", Kind = ModelingKind.Instance, Value = "TestValue", SemanticId = new Reference(new GlobalKey(KeyElements.Property, KeyType.IRI, "urn:basys:org.eclipse.basyx:dataElements:HelloProperty:1.0.0")) }); helloSubmodel.SubmodelElements.Add(new File() { Description = new LangStringSet() { new LangString("en-US", "This is an exemplary file attached to the Asset Administration Shell") }, IdShort = "HelloFile", Kind = ModelingKind.Instance, MimeType = "application/pdf", Value = "/HelloAssetAdministrationShell.pdf" }); var helloOperation_ConceptDescription = new ConceptDescription() { Identification = new Identifier("urn:basys:org.eclipse.basyx:dataSpecifications:EndpointSpecification:1.0.0", KeyType.IRI), EmbeddedDataSpecifications = new List <IEmbeddedDataSpecification>() { new EndpointSpecification( new EndpointSpecificationContent() { Endpoints = new List <IEndpoint>() { new OpcUaEndpoint("opc.tcp://127.0.0.1:4840/Objects/1:HelloAAS/1:SERVICE/1:TestOperation") } }) } }; helloSubmodel.SubmodelElements.Add(new Operation() { Description = new LangStringSet() { new LangString("en-US", "This is an exemplary operation returning the input argument with 'Hello' as prefix") }, IdShort = "HelloOperation", InputVariables = new OperationVariableSet() { new Property <string>() { IdShort = "Text" } }, OutputVariables = new OperationVariableSet() { new Property <string>() { IdShort = "ReturnValue" } }, ConceptDescription = helloOperation_ConceptDescription }); helloSubmodel.SubmodelElements.Add(new Event() { Description = new LangStringSet() { new LangString("en-US", "This is an exemplary event with only one property as event payload") }, IdShort = "HelloEvent", Kind = ModelingKind.Template, DataElements = new ElementContainer <ISubmodelElement>() { new Property <string>() { IdShort = "HelloEvent_Property", Kind = ModelingKind.Template } } }); aas.Submodels = new ElementContainer <ISubmodel>(); aas.Submodels.Add(helloSubmodel); var assetIdentificationSubmodel = new Submodel(); assetIdentificationSubmodel.IdShort = "AssetIdentification"; assetIdentificationSubmodel.Identification = new Identifier(Guid.NewGuid().ToString(), KeyType.Custom); assetIdentificationSubmodel.Kind = ModelingKind.Instance; assetIdentificationSubmodel.Parent = new Reference <IAssetAdministrationShell>(aas); var productTypeProp = new Property <string>() { IdShort = "ProductType", Kind = ModelingKind.Instance, SemanticId = new Reference( new GlobalKey( KeyElements.Property, KeyType.IRDI, "0173-1#02-AAO057#002")), Value = "HelloAsset_ProductType" }; ConceptDescription orderNumberCD = new ConceptDescription() { Identification = new Identifier("0173-1#02-AAO689#001", KeyType.IRDI), EmbeddedDataSpecifications = new List <IEmbeddedDataSpecification>() { new DataSpecificationIEC61360(new DataSpecificationIEC61360Content() { PreferredName = new LangStringSet { new LangString("EN", "identifying order number") }, Definition = new LangStringSet { new LangString("EN", "unique classifying number that enables to name an object and to order it from a supplier or manufacturer") }, DataType = DataTypeIEC61360.STRING }) } }; var orderNumber = new Property <string>() { IdShort = "OrderNumber", Kind = ModelingKind.Instance, SemanticId = new Reference( new GlobalKey( KeyElements.Property, KeyType.IRDI, "0173-1#02-AAO689#001")), Value = "HelloAsset_OrderNumber", ConceptDescription = orderNumberCD }; var serialNumber = new Property <string>() { IdShort = "SerialNumber", Kind = ModelingKind.Instance, Value = "HelloAsset_SerialNumber" }; assetIdentificationSubmodel.SubmodelElements.Add(productTypeProp); assetIdentificationSubmodel.SubmodelElements.Add(orderNumber); assetIdentificationSubmodel.SubmodelElements.Add(serialNumber); (aas.Asset as Asset).AssetIdentificationModel = new Reference <ISubmodel>(assetIdentificationSubmodel); aas.Submodels.Add(assetIdentificationSubmodel); return(aas); }