-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add documentation on OPCUA to Semantic Web transformation
An overview and tutorial has been added which shows how to transform companion specifications and instance nodeset2.xml into semantic WEB, i.e. OWL, SHACL and NGSI-LD Signed-off-by: marcel <[email protected]>
- Loading branch information
1 parent
8f20d9a
commit 08d05f6
Showing
12 changed files
with
504 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Table of Contents | ||
|
||
1. [Overview & Setup](./overview.md) | ||
2. [Example & Tutorial](./simple-example.md) | ||
3. [Building Companion Specifications](./building-companion-specifications.md) | ||
3. [Mapping concept](./mapping-concept.md) | ||
5. [Tools](./tools.md) | ||
|
||
|
||
# References | ||
|
||
[1] W3C. (2017). SHACL (Shapes Constraint Language). W3C Recommendation. Available at: https://www.w3.org/TR/shacl/ | ||
|
||
[2] W3C. (2012). OWL 2 Web Ontology Language: Document Overview. W3C Recommendation. Available at: https://www.w3.org/TR/owl2-overview/ | ||
|
||
[3] W3C. (2020). JSON-LD 1.1: A JSON-based Serialization for Linked Data. W3C Recommendation. Available at: https://www.w3.org/TR/json-ld11/ | ||
|
||
[4] ETSI. (2019). NGSI-LD API: Linked Data-based API for context information management. ETSI GS CIM 009 V1.1.1. Available at: https://www.etsi.org/deliver/etsi_gs/CIM/001_099/009/01.08.01_60/gs_cim009v010801p.pdf | ||
|
||
[5] W3C. (2014). Turtle - Terse RDF Triple Language. W3C Recommendation. Available at: https://www.w3.org/TR/turtle/ | ||
|
||
[6] Berners-Lee, T., Hendler, J., & Lassila, O. (2001). The Semantic Web. Scientific American, 284(5), 34-43. | ||
|
||
[7] Protege, https://protege.stanford.edu/ |
86 changes: 86 additions & 0 deletions
86
semantic-model/opcua/docs/building-companion-specifications.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# Convert Companion Specifications | ||
|
||
Companion specifications and their dependencies must be converted to ensure that all dependencies are fulfilled. The specifications can be built for *local* testing with *local* dependencies or for *global* use with IRIs. The main difference is that for *local* testing, the dependencies are referencing the local filesystem and can only be used on the current *local* system whereas the *globallly* built specifications can be imported or used from everywhere with Internet access. | ||
|
||
In OWL, dependencies are managed by `owl:imports` triples. A *global* import contains an IRI like so: | ||
|
||
owl:imports <https://industryfusion.github.io/contexts/staging/ontology/v0.1/base.ttl> ; | ||
|
||
In contrast, a *local* import is referencing the local directories in a File URI, for instance: | ||
|
||
owl:imports </home/user/src/IndustryFusion/DigitalTwin/semantic-model/opcua/core.ttl> | ||
|
||
For convenience, a script is provided to create the "usual suspect" companion specifications (note nodeset version: `NODESET_VERSION=UA-1.05.03-2023-12-15`): | ||
|
||
bash ./translate_default_specs.bash | ||
|
||
creates the *local* version of the specifications. | ||
|
||
The *global* version of the specifications can be created as follows: | ||
|
||
bash ./translate_default_specs.bash remote | ||
|
||
|
||
## Convert Specific Companion Specifications | ||
|
||
Currently there is no autdetection of dependencies. Therefore, a conversion must add the depenencies manually. Every specification is dependend on the base ontology: | ||
|
||
<https://industryfusion.github.io/contexts/staging/ontology/v0.1/base.ttl> | ||
|
||
For instance, converting the core OPCUA specification looks as follows: | ||
|
||
|
||
NODESET_VERSION=UA-1.05.03-2023-12-15 | ||
CORE_NODESET=https://raw.githubusercontent.com/OPCFoundation/UA-Nodeset/${NODESET_VERSION}/Schema/Opc.Ua.NodeSet2.xml | ||
BASE_ONTOLOGY=https://industryfusion.github.io/contexts/staging/ontology/v0.1/base.ttl | ||
python3 nodeset2owl.py ${CORE_NODESET} -i ${BASE_ONTOLOGY} -p opcua -o core.ttl | ||
|
||
The `DI` specification is translated as follows: | ||
|
||
NODESET_VERSION=UA-1.05.03-2023-12-15 | ||
CORE_NODESET=https://raw.githubusercontent.com/OPCFoundation/UA-Nodeset/${NODESET_VERSION}/Schema/Opc.Ua.NodeSet2.xml | ||
BASE_ONTOLOGY=https://industryfusion.github.io/contexts/staging/ontology/v0.1/base.ttl | ||
CORE_ONTOLOGY=core.ttl | ||
python3 nodeset2owl.py ${DI_NODESET} -i ${BASE_ONTOLOGY} ${CORE_ONTOLOGY} -p devices -o devices.ttl | ||
|
||
And the `Machinery` specification is converted like so: | ||
|
||
NODESET_VERSION=UA-1.05.03-2023-12-15 | ||
CORE_NODESET=https://raw.githubusercontent.com/OPCFoundation/UA-Nodeset/${NODESET_VERSION}/Schema/Opc.Ua.NodeSet2.xml | ||
BASE_ONTOLOGY=https://industryfusion.github.io/contexts/staging/ontology/v0.1/base.ttl | ||
MACHINERY_NODESET=https://raw.githubusercontent.com/OPCFoundation/UA-Nodeset/${NODESET_VERSION}/Machinery/Opc.Ua.Machinery.NodeSet2.xml | ||
CORE_ONTOLOGY=core.ttl | ||
DEVICES_ONTOLOGY=devices.ttl | ||
python3 nodeset2owl.py ${MACHINERY_NODESET} -i ${BASE_ONTOLOGY} ${CORE_ONTOLOGY} ${DEVICES_ONTOLOGY} -p machinery -o machinery.ttl | ||
|
||
In general, to determine the dependencies, the `<Models>` section of the target Nodeset must be analyzed. In the Pumps specification it looks e.g. like this | ||
|
||
``` | ||
<Models> | ||
<Model ModelUri="http://opcfoundation.org/UA/Pumps/" Version="1.0.0" PublicationDate="2021-04-19T00:00:00Z"> | ||
<RequiredModel ModelUri="http://opcfoundation.org/UA/" Version="1.04.7" PublicationDate="2020-07-15T00:00:00Z" /> | ||
<RequiredModel ModelUri="http://opcfoundation.org/UA/DI/" Version="1.02.2" PublicationDate="2020-06-02T00:00:00Z" /> | ||
<RequiredModel ModelUri="http://opcfoundation.org/UA/Machinery/" Version="1.0.0" PublicationDate="2020-09-25T00:00:00Z" /> | ||
</Model> | ||
</Models> | ||
``` | ||
and this suggest that the nodeset is (besides the base specification) dependends on `core.ttl`, `devices.ttl` and `machinery.ttl`. The conversation would then look like: | ||
|
||
``` | ||
NODESET_VERSION=UA-1.05.03-2023-12-15 | ||
PUMPS_NODESET=https://raw.githubusercontent.com/OPCFoundation/UA-Nodeset/${NODESET_VERSION}/Pumps/Opc.Ua.Pumps.NodeSet2.xml | ||
BASE_ONTOLOGY=https://industryfusion.github.io/contexts/staging/ontology/v0.1/base.ttl | ||
python3 nodeset2owl.py ${PUMPS_NODESET} -i ${BASE_ONTOLOGY} core.ttl devices.ttl machinery.ttl -p pumps -o pumps.ttl | ||
``` | ||
|
||
## Extract SHACL and JSON-LD from instances | ||
|
||
|
||
|
||
## Global Specifications | ||
|
||
IndustrsFusion Foundation is offering a set of `usual` suspects here: | ||
|
||
https://industryfusion.github.io/contexts/staging/opcua/v0.1/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<!-- | ||
--> | ||
|
||
<UANodeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" LastModified="2024-07-15T00:00:00Z" xmlns="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd"> | ||
<Models> | ||
<Model ModelUri="http://my.test/" XmlSchemaUri="http://opcfoundation.org/UA/2008/02/Types.xsd" Version="1.05.03" PublicationDate="2024-07-29T00:00:00Z" ModelVersion="1.5.3" /> | ||
</Models> | ||
<NamespaceUris> | ||
<Uri>http://my.test/</Uri> | ||
</NamespaceUris> | ||
<Aliases> | ||
<Alias Alias="Boolean">i=1</Alias> | ||
<Alias Alias="SByte">i=2</Alias> | ||
<Alias Alias="Byte">i=3</Alias> | ||
<Alias Alias="Int16">i=4</Alias> | ||
<Alias Alias="UInt16">i=5</Alias> | ||
<Alias Alias="Int32">i=6</Alias> | ||
<Alias Alias="UInt32">i=7</Alias> | ||
<Alias Alias="Int64">i=8</Alias> | ||
<Alias Alias="UInt64">i=9</Alias> | ||
<Alias Alias="Float">i=10</Alias> | ||
<Alias Alias="Double">i=11</Alias> | ||
<Alias Alias="DateTime">i=13</Alias> | ||
<Alias Alias="String">i=12</Alias> | ||
<Alias Alias="ByteString">i=15</Alias> | ||
<Alias Alias="Guid">i=14</Alias> | ||
<Alias Alias="XmlElement">i=16</Alias> | ||
<Alias Alias="NodeId">i=17</Alias> | ||
<Alias Alias="ExpandedNodeId">i=18</Alias> | ||
<Alias Alias="QualifiedName">i=20</Alias> | ||
<Alias Alias="LocalizedText">i=21</Alias> | ||
<Alias Alias="StatusCode">i=19</Alias> | ||
<Alias Alias="Structure">i=22</Alias> | ||
<Alias Alias="Number">i=26</Alias> | ||
<Alias Alias="Integer">i=27</Alias> | ||
<Alias Alias="UInteger">i=28</Alias> | ||
<Alias Alias="HasComponent">i=47</Alias> | ||
<Alias Alias="HasProperty">i=46</Alias> | ||
<Alias Alias="Organizes">i=35</Alias> | ||
<Alias Alias="HasEventSource">i=36</Alias> | ||
<Alias Alias="HasNotifier">i=48</Alias> | ||
<Alias Alias="HasSubtype">i=45</Alias> | ||
<Alias Alias="HasTypeDefinition">i=40</Alias> | ||
<Alias Alias="HasModellingRule">i=37</Alias> | ||
<Alias Alias="HasEncoding">i=38</Alias> | ||
<Alias Alias="HasDescription">i=39</Alias> | ||
<Alias Alias="HasCause">i=53</Alias> | ||
<Alias Alias="ToState">i=52</Alias> | ||
<Alias Alias="FromState">i=51</Alias> | ||
<Alias Alias="HasEffect">i=54</Alias> | ||
<Alias Alias="HasTrueSubState">i=9004</Alias> | ||
<Alias Alias="HasFalseSubState">i=9005</Alias> | ||
<Alias Alias="HasDictionaryEntry">i=17597</Alias> | ||
<Alias Alias="HasCondition">i=9006</Alias> | ||
<Alias Alias="HasGuard">i=15112</Alias> | ||
<Alias Alias="HasAddIn">i=17604</Alias> | ||
<Alias Alias="HasInterface">i=17603</Alias> | ||
</Aliases> | ||
|
||
<UAReferenceType NodeId="ns=1;i=100" BrowseName="X" IsAbstract="true" Symmetric="false"> | ||
<DisplayName>X Reference</DisplayName> | ||
<References> | ||
<Reference ReferenceType="HasSubtype" IsForward="false">i=32</Reference> | ||
</References> | ||
</UAReferenceType> | ||
<UAReferenceType NodeId="ns=1;i=101" BrowseName="Y" IsAbstract="true" Symmetric="false"> | ||
<DisplayName>Y Reference</DisplayName> | ||
<References> | ||
<Reference ReferenceType="HasSubtype" IsForward="false">i=32</Reference> | ||
</References> | ||
</UAReferenceType> | ||
<UAObjectType NodeId="ns=1;i=1001" BrowseName="1:AlphaType"> | ||
<DisplayName>AlphaType</DisplayName> | ||
<Description>A custom object type Alpha</Description> | ||
<References> | ||
<Reference ReferenceType="HasSubtype" IsForward="false">i=58</Reference> | ||
<Reference ReferenceType="ns=1;i=101" IsForward="true">ns=1;i=2001</Reference> | ||
<Reference ReferenceType="ns=1;i=100" IsForward="true">ns=1;i=1003</Reference> | ||
<Reference ReferenceType="HasComponent">ns=1;i=1003</Reference> | ||
</References> | ||
</UAObjectType> | ||
<UAObjectType NodeId="ns=1;i=1002" BrowseName="1:BType"> | ||
<DisplayName>B Type</DisplayName> | ||
<Description>A custom object type B</Description> | ||
<References> | ||
<Reference ReferenceType="HasSubtype" IsForward="false">i=58</Reference> | ||
</References> | ||
</UAObjectType> | ||
<UAObject NodeId="ns=1;i=1003" BrowseName="1:B"> | ||
<DisplayName>Object B</DisplayName> | ||
<References> | ||
<Reference ReferenceType="HasTypeDefinition" IsForward="true">ns=1;i=1002</Reference> | ||
<Reference ReferenceType="HasComponent">ns=1;i=1004</Reference> | ||
</References> | ||
</UAObject> | ||
<UAVariable NodeId="ns=1;i=1004" BrowseName="MyVariable" DataType="Boolean"> | ||
<DisplayName>Variable of B-object</DisplayName> | ||
<References> | ||
<Reference ReferenceType="HasTypeDefinition" IsForward="true">i=63</Reference> | ||
</References> | ||
</UAVariable> | ||
<UAObjectType NodeId="ns=1;i=1005" BrowseName="1:BSubType"> | ||
<DisplayName>B Sub Type</DisplayName> | ||
<Description>A custom subobject of type B</Description> | ||
<References> | ||
<Reference ReferenceType="HasSubtype" IsForward="false">ns=1;i=1002</Reference> | ||
</References> | ||
</UAObjectType> | ||
|
||
|
||
<UAVariable NodeId="ns=1;i=2001" BrowseName="1:C" DataType="i=11"> | ||
<DisplayName>Variable of AlphaType</DisplayName> | ||
<References> | ||
<Reference ReferenceType="HasTypeDefinition" IsForward="true">i=63</Reference> | ||
<Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=1001</Reference> | ||
</References> | ||
</UAVariable> | ||
<UAVariable NodeId="ns=1;i=2002" BrowseName="1:E" DataType="i=11"> | ||
<DisplayName>Variable of Variable C</DisplayName> | ||
<References> | ||
<Reference ReferenceType="HasTypeDefinition" IsForward="true">i=63</Reference> | ||
<Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=2001</Reference> | ||
</References> | ||
</UAVariable> | ||
<UAObject NodeId="ns=1;i=2010" BrowseName="1:AlphaInstance"> | ||
<DisplayName>Alpha Instance</DisplayName> | ||
<References> | ||
<Reference ReferenceType="HasComponent" IsForward="true">ns=1;i=2011</Reference> | ||
<Reference ReferenceType="HasComponent" IsForward="true">ns=1;i=2012</Reference> | ||
<Reference ReferenceType="HasTypeDefinition" IsForward="true">ns=1;i=1001</Reference> | ||
<Reference ReferenceType="ns=1;i=101" IsForward="true">ns=1;i=2012</Reference> | ||
</References> | ||
</UAObject> | ||
<UAVariable NodeId="ns=1;i=2011" BrowseName="1:C" DataType="i=11"> | ||
<DisplayName>C Variable of AlphaType</DisplayName> | ||
<References> | ||
<Reference ReferenceType="HasTypeDefinition" IsForward="true">i=63</Reference> | ||
<Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=2010</Reference> | ||
<Reference ReferenceType="ns=1;i=100" IsForward="true">ns=1;i=2011</Reference> | ||
</References> | ||
</UAVariable> | ||
<UAObject NodeId="ns=1;i=2012" BrowseName="1:B"> | ||
<DisplayName>Object B subtype</DisplayName> | ||
<References> | ||
<Reference ReferenceType="HasTypeDefinition" IsForward="true">ns=1;i=1005</Reference> | ||
<Reference ReferenceType="HasComponent">ns=1;i=2013</Reference> | ||
</References> | ||
</UAObject> | ||
<UAVariable NodeId="ns=1;i=2013" BrowseName="MyVariable" DataType="Boolean"> | ||
<DisplayName>Variable of B-object</DisplayName> | ||
<References> | ||
<Reference ReferenceType="HasTypeDefinition" IsForward="true">i=63</Reference> | ||
</References> | ||
</UAVariable> | ||
</UANodeSet> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# Overview | ||
|
||
This document describes how to map OPCUA data into Semantic Web [6] data, more specifically we describe how to transform OPCUA data into the following 3 standards: | ||
1. The **constraints and rules** are expressed in the SHApes Constraint Language (SHACL) [1] (`shacl.ttl`) | ||
2. The **ontology** data about types, enumerations and other explicit knowledge e is expressed in the Web Ontology Language (OWL)[2] (called `entities.ttl`, or sometimes `knowledge.ttl` or `ontolgoy.ttl`) | ||
3. Representation of the OPCUA **instance** as JSON-LD [3] or more specifically the NGSI-LD[4] standard (called `instances.jsonld`) | ||
|
||
The files are all represented in Resource Description Format[6] serialized in the Turtle[5] or JSON-LD. | ||
|
||
|
||
# Setup for Linux/Windows | ||
|
||
## For Linux and Windows | ||
Target System Linux, tested on `Ubuntu 22.04`. | ||
|
||
In additiona the following must be installed: | ||
|
||
- Python3 >= 3.10 | ||
- VSCode | ||
- Make, bash, git (for Linux) | ||
- GitBash (for Windows) | ||
|
||
Get the code from the IndustryFusion Foundation repo: | ||
|
||
``` | ||
git clone https://github.com/IndustryFusion/DigitalTwin.git | ||
``` | ||
|
||
Find the right directory: | ||
|
||
``` | ||
cd DigitalTwin/semantic-model/opcua/ | ||
``` | ||
|
||
and install the dependencies: | ||
|
||
``` | ||
make setup | ||
``` | ||
|
||
## For Windows only | ||
|
||
In this document, the Python 3 executable is named `python3` which can create a mismatch with the Windows installation. Therefore, the gitBash needs to define an alias for `python3`. | ||
|
||
code ~/.bashrc | ||
|
||
And then add to the end to the file (or to the beginning if it does not exist) | ||
|
||
alias python3="python" | ||
|
||
|
||
|
Oops, something went wrong.