INTER-LAYER – Data and Semantics to Data and Semantics (DS2DS): Translating raw data into RDF

(Getting Ready) Scenario description

Lets assume that we have an IoT artifact that is to be integrated into INTER-IoT ecosystem. Internally it has communication based on JSON messages with implicit semantics (not formalized as schema or ontology). Since INTER-IoT has communication based on JSON-LD, messages coming from connected artifacts at some point need to be translated from JSON to RDF. This recipe focuses on the preparation of data to be consumed by INTER-IoT on the example of JSON file. Note, that this functionality is usually handled by INTER-MW bridge components that act as a proxy between IoT artifact and INTER-IoT.

Recipe ingredients

  • JSON file that represents data published by the IoT artifact, e.g.:
{
    "id": "myDevice-wastecontainer-sensor-345",
    "type": "DeviceModel",
    "category": {
        "value": ["sensor"]
    },
    "function": {
        "value": ["sensing"]
    },
    "modelName": {
        "value": "S4Container 345"
    },
    "name": {
        "value": "myDevice Sensor for Containers 345"
    },
    "brandName": {
        "value": "myDevice"
    },
    "manufacturerName": {
        "value": "myDevice Inc."
    },
    "controlledProperty": {
        "value": ["fillingLevel", "temperature"]
    }
}
  • Target RDF structure that was design for IoT artifact's data, e.g.:
[ a <http://inter-iot.eu/syntax/FIWAREv2#Entity> ;
<http://inter-iot.eu/syntax/FIWAREv2#hasAttribute>
    [ a     <http://inter-iot.eu/syntax/FIWAREv2#Attribute> ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasName> "name" ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasValue>
        [   <http://inter-iot.eu/syntax/FIWAREv2#hasAttrValue>"myDevice Sensor for Containers 345"^^<http://www.w3.org/2001/XMLSchema#string> 
        ]
    ],
    [ a     <http://inter-iot.eu/syntax/FIWAREv2#Attribute> ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasName> "modelName" ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasValue>
        [   <http://inter-iot.eu/syntax/FIWAREv2#hasAttrValue>"S4Container 345"^^<http://www.w3.org/2001/XMLSchema#string> 
        ]
    ],
    [ a     <http://inter-iot.eu/syntax/FIWAREv2#Attribute> ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasName> "brandName" ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasValue>
        [   <http://inter-iot.eu/syntax/FIWAREv2#hasAttrValue>"myDevice"^^<http://www.w3.org/2001/XMLSchema#string> 
        ]
    ],
    [ a     <http://inter-iot.eu/syntax/FIWAREv2#Attribute> ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasName> "manufacturerName" ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasValue>
        [   <http://inter-iot.eu/syntax/FIWAREv2#hasAttrValue>"myDevice Inc."^^<http://www.w3.org/2001/XMLSchema#string>
        ]
    ],
    [ a     <http://inter-iot.eu/syntax/FIWAREv2#Attribute> ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasName> "category" ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasValue>
        [ a <http://inter-iot.eu/syntax/FIWAREv2#Array> ; 
            <http://inter-iot.eu/syntax/FIWAREv2#hasElement>
            [ a <http://inter-iot.eu/syntax/FIWAREv2#ArrayElement> ;
                <http://inter-iot.eu/syntax/FIWAREv2#hasNumber> "1"^^
                <http://www.w3.org/2001/XMLSchema#int> ; 
                <http://inter-iot.eu/syntax/FIWAREv2#hasValue> "sensor"^^
                <http://www.w3.org/2001/XMLSchema#string> 
            ]
        ]
    ],
    [ a     <http://inter-iot.eu/syntax/FIWAREv2#Attribute> ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasName> "function" ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasValue>
        [ a <http://inter-iot.eu/syntax/FIWAREv2#Array> ; 
            <http://inter-iot.eu/syntax/FIWAREv2#hasElement>
            [ a <http://inter-iot.eu/syntax/FIWAREv2#ArrayElement> ;
                <http://inter-iot.eu/syntax/FIWAREv2#hasNumber> "1"^^
                <http://www.w3.org/2001/XMLSchema#int> ; 
                <http://inter-iot.eu/syntax/FIWAREv2#hasValue> "sensing"^^
                <http://www.w3.org/2001/XMLSchema#string> 
            ]
        ]
    ],
    [ a     <http://inter-iot.eu/syntax/FIWAREv2#Attribute> ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasName> "controlledProperty" ;
        <http://inter-iot.eu/syntax/FIWAREv2#hasValue>
        [ a <http://inter-iot.eu/syntax/FIWAREv2#Array> ; 
            <http://inter-iot.eu/syntax/FIWAREv2#hasElement>
            [ a <http://inter-iot.eu/syntax/FIWAREv2#ArrayElement> ;
                <http://inter-iot.eu/syntax/FIWAREv2#hasNumber> "1"^^
                <http://www.w3.org/2001/XMLSchema#int> ; 
                <http://inter-iot.eu/syntax/FIWAREv2#hasValue> "fillingLevel"^^
                <http://www.w3.org/2001/XMLSchema#string> 
            ],
            [ a <http://inter-iot.eu/syntax/FIWAREv2#ArrayElement> ;
                <http://inter-iot.eu/syntax/FIWAREv2#hasNumber> "2"^^
                <http://www.w3.org/2001/XMLSchema#int> ; 
                <http://inter-iot.eu/syntax/FIWAREv2#hasValue> "temperature"^^
                <http://www.w3.org/2001/XMLSchema#string> 
            ]
        ]
    ]
] ;
<http://inter-iot.eu/syntax/FIWAREv2#hasId> "myDevice-wastecontainer-sensor-345" ;
<http://inter-iot.eu/syntax/FIWAREv2#hasName> "myDevice Sensor for Containers 345" ;
<http://inter-iot.eu/syntax/FIWAREv2#hasType> "DeviceModel"
]

Prerequisites

(How to Do it)

The transformation from native format to RDF in JSON-LD syntax is call syntactic translation. It can be implemented following the guidelines from Recipe 8 - Syntactic translation.

In the presented example JSON is based on FIWARE NGSI specification.

In INTER-IoT GIT repository demonstration code for FIWARE syntactic translator is in the test/FIWAREDemonstration.java class. The main method there loads the *.json files from text/resources/FIWARE/v2 directory and applies the syntactic translator to convert FIWARE NGSIv2 JSON to Jena Model, and back to JSON, simulating a two-way syntactic conversion. The implementation of the FIWARE syntactic translator is in the eu.interiot.translators.syntax.FIWARE package, where FIWAREv2Translator is the class that implements syntactic translation for NGSIv2 JSON.

(How it Works)

After the syntactic translation is executed we should get the following message in the INTER-IoT format (produced from the original message by the bridge to be consumed by INTER-MW):

{
  "@graph": [
    {
      "@graph": [
        {
          "@id": "InterIoTMsg:meta66b05c61-d687-45a3-b5fb-6864bbec3b69",
          "@type": [
            "InterIoTMsg:Thing_Update",
            "InterIoTMsg:meta"
          ],
          "InterIoTMsg:conversationID": "conv99528eba-eb2d-47e8-9ee6-9dd40d19f89a",
          "InterIoTMsg:dateTimeStamp": "2017-05-22T22:19:30.281+02:00",
          "InterIoTMsg:messageID": "msg7e484a2c-f959-486e-8da0-31143f457234"
        }
      ],
      "@id": "InterIoTMsg:metadata"
    },
    {
      "@graph": [
        {
          "@id": "_:ub26bL47C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#Attribute",
          "http://inter-iot.eu/syntax/FIWAREv2#hasName": "brandName",
          "http://inter-iot.eu/syntax/FIWAREv2#hasValue": "myDevice"
        },
        {
          "@id": "_:ub26bL27C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#ArrayElement",
          "http://inter-iot.eu/syntax/FIWAREv2#hasNumber": {
            "@type": "xsd:int",
            "@value": "1"
          },
          "http://inter-iot.eu/syntax/FIWAREv2#hasValue": "fillingLevel"
        },
        {
          "@id": "_:ub26bL25C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#Array",
          "http://inter-iot.eu/syntax/FIWAREv2#hasElement": [
            {
              "@id": "_:ub26bL36C3"
            },
            {
              "@id": "_:ub26bL27C3"
            }
          ]
        },
        {
          "@id": "_:ub26bL74C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#Attribute",
          "http://inter-iot.eu/syntax/FIWAREv2#hasName": "function",
          "http://inter-iot.eu/syntax/FIWAREv2#hasValue": {
            "@id": "_:ub26bL79C3"
          }
        },
        {
          "@id": "_:ub26bL81C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#ArrayElement",
          "http://inter-iot.eu/syntax/FIWAREv2#hasNumber": {
            "@type": "xsd:int",
            "@value": "1"
          },
          "http://inter-iot.eu/syntax/FIWAREv2#hasValue": "sensing"
        },
        {
          "@id": "_:ub26bL2C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#Attribute",
          "http://inter-iot.eu/syntax/FIWAREv2#hasName": "modelName",
          "http://inter-iot.eu/syntax/FIWAREv2#hasValue": "S4Container 345"
        },
        {
          "@id": "_:ub26bL79C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#Array",
          "http://inter-iot.eu/syntax/FIWAREv2#hasElement": {
            "@id": "_:ub26bL81C3"
          }
        },
        {
          "@id": "_:ub26bL20C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#Attribute",
          "http://inter-iot.eu/syntax/FIWAREv2#hasName": "controlledProperty",
          "http://inter-iot.eu/syntax/FIWAREv2#hasValue": {
            "@id": "_:ub26bL25C3"
          }
        },
        {
          "@id": "_:ub26bL63C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#ArrayElement",
          "http://inter-iot.eu/syntax/FIWAREv2#hasNumber": {
            "@type": "xsd:int",
            "@value": "1"
          },
          "http://inter-iot.eu/syntax/FIWAREv2#hasValue": "meter"
        },
        {
          "@id": "_:ub26bL11C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#Attribute",
          "http://inter-iot.eu/syntax/FIWAREv2#hasName": "manufacturerName",
          "http://inter-iot.eu/syntax/FIWAREv2#hasValue": "myDevice Inc."
        },
        {
          "@id": "_:ub26bL61C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#Array",
          "http://inter-iot.eu/syntax/FIWAREv2#hasElement": {
            "@id": "_:ub26bL63C3"
          }
        },
        {
          "@id": "_:ub26bL0C1",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#Entity",
          "http://inter-iot.eu/syntax/FIWAREv2#hasAttribute": [
            {
              "@id": "_:ub26bL2C3"
            },
            {
              "@id": "_:ub26bL56C3"
            },
            {
              "@id": "_:ub26bL47C3"
            },
            {
              "@id": "_:ub26bL20C3"
            },
            {
              "@id": "_:ub26bL74C3"
            },
            {
              "@id": "_:ub26bL11C3"
            }
          ],
          "http://inter-iot.eu/syntax/FIWAREv2#hasId": "myDevice-wastecontainer-sensor-345",
          "http://inter-iot.eu/syntax/FIWAREv2#hasName": "myDevice Sensor for Containers 345",
          "http://inter-iot.eu/syntax/FIWAREv2#hasType": "DeviceModel"
        },
        {
          "@id": "_:ub26bL36C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#ArrayElement",
          "http://inter-iot.eu/syntax/FIWAREv2#hasNumber": {
            "@type": "xsd:int",
            "@value": "2"
          },
          "http://inter-iot.eu/syntax/FIWAREv2#hasValue": "temperature"
        },
        {
          "@id": "_:ub26bL56C3",
          "@type": "http://inter-iot.eu/syntax/FIWAREv2#Attribute",
          "http://inter-iot.eu/syntax/FIWAREv2#hasName": "category",
          "http://inter-iot.eu/syntax/FIWAREv2#hasValue": {
            "@id": "_:ub26bL61C3"
          }
        }
      ],
      "@id": "InterIoTMsg:payload"
    }
  ],
  "@context": {
    "InterIoTMsg": "http://inter-iot.eu/message/",
    "InterIoT": "http://inter-iot.eu/",
    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "xsd": "http://www.w3.org/2001/XMLSchema#"
  }
}

The output is in JSON-LD syntax, and is composed from two RDF graphs - metadata and payload. The former contains message metadata (technical) information used by INTER-MW, and is not part of syntactic translation but part of output message leaving the bridge. The latter, contains data syntactically translated from the original message into RDF data model for the IoT artifact.

Wrapping things up

After applying this recipe original message is translated into JSON-LD message with RDF following the RDF data model proposed for the IoT artifact that is connected to INTER-IoT. This step enables further communication, where message should be send to INTER-MW in INTER-IoT JSON-LD format.

Note, that this recipe is wrote from the perspective of communication from the IoT artifact to INTER-IoT, however one can consider communication in the opposite direction i.e. IoT artifact consumes message from INTER-IoT ecosystem. In such case, translation should be done from IoT artifact RDF data model to original format e.g. JSON following FIWARE NGSI specification.