コード例 #1
0
        private static void AddRelationshipsBetweenInterfaces()
        {
            foreach (Tuple <DtdlInterface, string, string> dtdlInterfaceTuple in _interfaceList)
            {
                // find the interface to add a relationship to
                foreach (Tuple <DtdlInterface, string, string> dtdlInterfaceTupleRelationship in _interfaceList)
                {
                    if (dtdlInterfaceTuple.Item3 == dtdlInterfaceTupleRelationship.Item2)
                    {
                        DtdlContents dtdlRelationship = new DtdlContents
                        {
                            Type   = "Relationship",
                            Name   = "Parent",
                            Target = "dtmi:" + dtdlInterfaceTupleRelationship.Item1.DisplayName + ";1",
                        };

                        if (!dtdlInterfaceTuple.Item1.Contents.Contains(dtdlRelationship))
                        {
                            dtdlInterfaceTuple.Item1.Contents.Add(dtdlRelationship);
                        }
                        break;
                    }
                }
            }
        }
コード例 #2
0
        // OPC UA defines variables, views and objects, as well as associated variabletypes, datatypes, referencetypes and objecttypes
        // In addition, OPC UA defines methods and properties
        public static void Generate(UANodeSet nodeSet)
        {
            // clear previously generated DTDL
            _map.Clear();
            _interfaceList.Clear();
            _contentsList.Clear();
            _nodeList.Clear();
            _nodesetNamespaceURI = nodeSet.NamespaceUris[0];

            CreateSchemaMap();

            // create DTDL interfaces and their contents
            foreach (UANode uaNode in nodeSet.Items)
            {
                UAVariable variable = uaNode as UAVariable;
                if (variable != null)
                {
                    if (uaNode.BrowseName.ToString() == "InputArguments")
                    {
                        continue;
                    }

                    // check if this node is part of the model
                    bool isPartOfModel = false;
                    foreach (Reference reference in variable.References)
                    {
                        if (reference.ReferenceType == "HasModellingRule")
                        {
                            isPartOfModel = true;
                            break;
                        }
                    }
                    if (isPartOfModel)
                    {
                        // ignore this node
                        continue;
                    }

                    DtdlContents dtdlTelemetry = new DtdlContents
                    {
                        Type   = "Telemetry",
                        Name   = Regex.Replace(uaNode.BrowseName.ToString().Trim(), "[^A-Za-z]+", ""),
                        Schema = GetDtdlDataType(variable.DataType)
                    };

                    Tuple <DtdlContents, string> newTuple = new Tuple <DtdlContents, string>(dtdlTelemetry, variable.ParentNodeId);
                    if (!_contentsList.Contains(newTuple))
                    {
                        _contentsList.Add(newTuple);
                    }

                    Tuple <string, string, string> newNodeTuple;
                    if (variable.BrowseName.Length > 0)
                    {
                        newNodeTuple = new Tuple <string, string, string>(variable.BrowseName, GetDtdlDataType(variable.DataType.ToString()), variable.ParentNodeId ?? "");
                    }
                    else
                    {
                        newNodeTuple = new Tuple <string, string, string>(variable.NodeId.ToString(), GetDtdlDataType(variable.DataType.ToString()), variable.ParentNodeId ?? "");
                    }

                    string key = nodeSet.NamespaceUris[0] + "#" + variable.NodeId.ToString().Substring(variable.NodeId.ToString().IndexOf(';') + 1);
                    if (!_nodeList.ContainsKey(key))
                    {
                        _nodeList.Add(key, newNodeTuple);
                    }

                    continue;
                }

                UAMethod method = uaNode as UAMethod;
                if (method != null)
                {
                    // check if this node is part of the model
                    bool isPartOfModel = false;
                    foreach (Reference reference in method.References)
                    {
                        if (reference.ReferenceType == "HasModellingRule")
                        {
                            isPartOfModel = true;
                            break;
                        }
                    }
                    if (isPartOfModel)
                    {
                        // ignore this node
                        continue;
                    }

                    DtdlContents dtdlCommand = new DtdlContents
                    {
                        Type = "Command",
                        Name = Regex.Replace(uaNode.BrowseName.ToString().Trim(), "[^A-Za-z]+", "")
                    };

                    Tuple <DtdlContents, string> newTuple = new Tuple <DtdlContents, string>(dtdlCommand, method.ParentNodeId);
                    if (!_contentsList.Contains(newTuple))
                    {
                        _contentsList.Add(newTuple);
                    }

                    Tuple <string, string, string> newNodeTuple;
                    if (method.BrowseName.Length > 0)
                    {
                        newNodeTuple = new Tuple <string, string, string>(method.BrowseName, "command", method.ParentNodeId ?? "");
                    }
                    else
                    {
                        newNodeTuple = new Tuple <string, string, string>(method.NodeId.ToString(), "command", method.ParentNodeId ?? "");
                    }

                    string key = nodeSet.NamespaceUris[0] + "#" + method.NodeId.ToString().Substring(method.NodeId.ToString().IndexOf(';') + 1);
                    if (!_nodeList.ContainsKey(key))
                    {
                        _nodeList.Add(key, newNodeTuple);
                    }

                    continue;
                }

                UAObject uaObject = uaNode as UAObject;
                if (uaObject != null)
                {
                    // check if this node is part of the model
                    bool isPartOfModel = false;
                    foreach (Reference reference in uaObject.References)
                    {
                        if (reference.ReferenceType == "HasModellingRule")
                        {
                            isPartOfModel = true;
                            break;
                        }
                    }
                    if (isPartOfModel)
                    {
                        // ignore this node
                        continue;
                    }

                    DtdlInterface dtdlInterface = new DtdlInterface
                    {
                        Id          = "dtmi:" + Regex.Replace(uaNode.BrowseName.ToString().Trim(), "[^A-Za-z]+", "") + ";1",
                        Type        = "Interface",
                        DisplayName = Regex.Replace(uaNode.BrowseName.ToString().Trim(), "[^A-Za-z]+", ""),
                        Contents    = new List <DtdlContents>()
                    };

                    Tuple <DtdlInterface, string, string> newTuple = new Tuple <DtdlInterface, string, string>(dtdlInterface, uaObject.NodeId, uaObject.ParentNodeId);
                    if (!_interfaceList.Contains(newTuple))
                    {
                        _interfaceList.Add(newTuple);
                    }

                    Tuple <string, string, string> newNodeTuple;
                    if (uaObject.BrowseName.Length > 0)
                    {
                        newNodeTuple = new Tuple <string, string, string>(uaObject.BrowseName, "object", uaObject.ParentNodeId ?? "");
                    }
                    else
                    {
                        newNodeTuple = new Tuple <string, string, string>(uaObject.NodeId.ToString(), "object", uaObject.ParentNodeId ?? "");
                    }

                    string key = nodeSet.NamespaceUris[0] + "#" + uaObject.NodeId.ToString().Substring(uaObject.NodeId.ToString().IndexOf(';') + 1);
                    if (!_nodeList.ContainsKey(key))
                    {
                        _nodeList.Add(key, newNodeTuple);
                    }

                    continue;
                }

                UAView view = uaNode as UAView;
                if (view != null)
                {
                    // we don't map views since DTDL has no such concept
                    continue;
                }

                UAVariableType variableType = uaNode as UAVariableType;
                if (variableType != null)
                {
                    // we don't map UA variable types, only instances. DTDL only has a limited set of built-in types.
                    continue;
                }

                UADataType dataType = uaNode as UADataType;
                if (dataType != null)
                {
                    // we don't map UA data types, only instances. DTDL only has a limited set of built-in types.
                    continue;
                }

                UAReferenceType referenceType = uaNode as UAReferenceType;
                if (referenceType != null)
                {
                    // we don't map UA reference types, only instances. DTDL only has a limited set of built-in types.
                    continue;
                }

                UAObjectType objectType = uaNode as UAObjectType;
                if (objectType != null)
                {
                    // we don't map UA object (custom) types, only instances. DTDL only has a limited set of built-in types.
                    continue;
                }

                throw new ArgumentException("Unknown UA node detected!");
            }

            AddComponentsToInterfaces();
            AddRelationshipsBetweenInterfaces();

            // generate JSON files
            foreach (Tuple <DtdlInterface, string, string> dtdlInterfaceTuple in _interfaceList)
            {
                string generatedDTDL = JsonConvert.SerializeObject(dtdlInterfaceTuple.Item1, Formatting.Indented);
                string dtdlPath      = Path.Combine(Directory.GetCurrentDirectory(), "JSON", Path.GetFileNameWithoutExtension(dtdlInterfaceTuple.Item1.DisplayName) + ".dtdl.json");
                System.IO.File.WriteAllText(dtdlPath, generatedDTDL);
            }
        }
コード例 #3
0
        /// <summary>
        /// Generates a DTDL JSON file from an OWL-based RDF file.
        /// </summary>
        /// <param name="rdfFile">RDF input file</param>
        /// <param name="dtdlFile">DTDL output file</param>
        private static void GenerateDTDL(FileInfo rdfFile, FileInfo dtdlFile)
        {
            try
            {
                Console.WriteLine("Reading file...");

                FileLoader.Load(_ontologyGraph, rdfFile.FullName);

                // Start looping through for each owl:Class
                foreach (OntologyClass owlClass in _ontologyGraph.OwlClasses)
                {
                    // Generate a DTMI for the owl:Class
                    string Id = GenerateDTMI(owlClass);

                    if (!String.IsNullOrEmpty(Id))
                    {
                        Console.WriteLine($"{owlClass.Resource.ToString()} -> {Id}");

                        // Create Interface
                        DtdlInterface dtdlInterface = new DtdlInterface
                        {
                            Id          = Id,
                            Type        = "Interface",
                            DisplayName = GetInterfaceDisplayName(owlClass),
                            Comment     = GetInterfaceComment(owlClass),
                            Description = "",
                            Contents    = new List <DtdlContents>()
                        };

                        // Use DTDL 'extends' for super classes
                        IEnumerable <OntologyClass> foundSuperClasses = owlClass.DirectSuperClasses;

                        if (foundSuperClasses.Any())
                        {
                            List <string> extendsList = new List <string>();

                            int extendsMax = 0;

                            foreach (var superClass in foundSuperClasses)
                            {
                                // DTDL v2 allows for a maximum of 2 extends. We ignore the other super classes
                                if (extendsMax < 2)
                                {
                                    string superClassId = GenerateDTMI(superClass);

                                    if (superClassId != null)
                                    {
                                        extendsList.Add(superClassId);

                                        extendsMax++;
                                    }
                                }
                            }

                            dtdlInterface.Extends = extendsList;
                        }

                        List <OntologyProperty> properties;

                        // Get list of properties which have this class as a domain
                        properties = owlClass.IsDomainOf.ToList();

                        foreach (var property in properties)
                        {
                            // An owl:ObjectProperty is used to create a DTDL relationship.
                            if (property.Types.First().ToString() == "http://www.w3.org/2002/07/owl#ObjectProperty")
                            {
                                Console.WriteLine($"  Found relationship: {property}");

                                // If IRI, parse out relationship name from IRI
                                if (property.ToString().Contains("#"))
                                {
                                    int index = property.ToString().LastIndexOf("#");
                                    property.AddLabel(property.ToString().Substring(index + 1));
                                }
                                else if (property.ToString().Contains("/"))
                                {
                                    int index = property.ToString().LastIndexOf("/");
                                    property.AddLabel(property.ToString().Substring(index + 1));
                                }

                                // Create relationship
                                DtdlContents dtdlRelationship = new DtdlContents
                                {
                                    Name        = Trim(property.ToString()),
                                    Type        = "Relationship",
                                    DisplayName = GetRelationshipDisplayName(property),
                                    Comment     = GetComment(property)
                                };

                                // DTDL only supports a single target Id.
                                var range = property.Ranges.FirstOrDefault();

                                if (range == null)
                                {
                                    // If no range is found, we omit the DTDL target property.
                                    // This allows any Interface to be the target.
                                    Console.WriteLine("    No target found.");
                                }
                                else
                                {
                                    Console.WriteLine($"    Found target: {range}");

                                    // Convert range to DTMI and add to DTDL relationship target.
                                    string target = GenerateDTMI(range);
                                    dtdlRelationship.Target = target;
                                }

                                // Add relationship to the Interface
                                dtdlInterface.Contents.Add(dtdlRelationship);
                            }

                            // An owl:DatatypeProperty is used to create a DTDL property.
                            if (property.Types.First().ToString() == "http://www.w3.org/2002/07/owl#DatatypeProperty")
                            {
                                Console.WriteLine($"  Found property: {property}");

                                // Create property
                                DtdlContents dtdlProperty = new DtdlContents
                                {
                                    Name     = Trim(property.ToString()),
                                    Type     = "Property",
                                    Schema   = _map[property.Ranges.FirstOrDefault().ToString()],
                                    Comment  = GetComment(property),
                                    Writable = true
                                };

                                // Add the Property to the Interface
                                dtdlInterface.Contents.Add(dtdlProperty);
                            }

                            // An owl:AnnotationProperty is used to create a DTDL property.
                            if (property.Types.First().ToString() == "http://www.w3.org/2002/07/owl#AnnotationProperty")
                            {
                                Console.WriteLine($"  Found property: {property}");

                                // Create property
                                DtdlContents dtdlProperty = new DtdlContents
                                {
                                    Name = Trim(property.ToString()),
                                    Type = "Property",
                                    // TODO: Lookup actual data type and create complex DTDL schema or map to DTDL semantic type
                                    Schema   = "float",
                                    Comment  = GetComment(property),
                                    Writable = true
                                };

                                // Add the Property to the Interface
                                dtdlInterface.Contents.Add(dtdlProperty);
                            }
                        }

                        // Add the DTDL context to the Interface
                        dtdlInterface.Context = _context;

                        // Add interface to the list of interfaces
                        _interfaceList.Add(dtdlInterface);
                    }
                }

                if (_interfaceList.Count == 0)
                {
                    throw new Exception("No OWL:Classes found.");
                }

                // Serialize to JSON
                var json = JsonConvert.SerializeObject(_interfaceList);

                // Save to file
                System.IO.File.WriteAllText(dtdlFile.ToString(), json);
                Console.WriteLine($"DTDL written to: {dtdlFile}");

                // Run DTDL validation
                Console.WriteLine("Validating DTDL...");

                ModelParser modelParser = new ModelParser();

                List <string> modelJson = new List <string>();

                modelJson.Add(json);

                IReadOnlyDictionary <Dtmi, DTEntityInfo> parseTask = modelParser.ParseAsync(modelJson).GetAwaiter().GetResult();
            }
            catch (ParsingException pe)
            {
                Console.WriteLine($"*** Error parsing models");

                int errCount = 1;

                foreach (ParsingError err in pe.Errors)
                {
                    Console.WriteLine($"Error {errCount}:");
                    Console.WriteLine($"{err.Message}");
                    Console.WriteLine($"Primary ID: {err.PrimaryID}");
                    Console.WriteLine($"Secondary ID: {err.SecondaryID}");
                    Console.WriteLine($"Property: {err.Property}\n");
                    errCount++;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"{e.Message}");
            }

            Console.WriteLine($"Finished!");
        }