TIC 4.0
FLAT to JSON 2024.010
Introduction
TIC 4.0 uses the JSON format as default because it allows to express an array of subjects (for several sub-subjects) or observed properties (for different combinations of timestamps, pom, pomt, names, etc). JSON is also the default file format for many protocols, such as REST and MQTT, which are extensively used to share data or publish IoT data. These arrays give us a high flexibility thanks to the hierarchical structure. Other hierarchical structures, such as XML, are possible in TIC 4.0 lbut we recommend using JSON as default.
Although the JSON is very powerful, other formats that are required for data processing at low level and program level and which are not compatible with hierarchical structures. So we require a solution to be able to express the same content in a flat format. It is important to be able to identify unambiguously the array elements and id if necessary.
The hierarchical structure allows to include in a single message many timestamps of many concepts per subject of many subjects per the main subject, without limits.
Using a flat format we are limited to only one timestamp per message, and to add in the name the critical information to identify what subject, concept, observed property and point of measurement are related.
ou can download the example here
A flat format is more suitable for low-level implementation such as PLCs or software code. JSON is better for sharing extensive messages. Both are valid in TIC 4.0.
This document contains the rules to convert the JSON structure into a Flat one (2022.005 will cover Flat to JSON).
This conversion is related to the opposite one JSON to FLAT https://tic40.atlassian.net/l/cp/kS1uF9qD
FLAT to JSON: the general concept
The main goal of the conversion is to ensure that all the FLAT message information is transferred in a JSON message after the conversion. One flat message will become one JSON message as the JSON format does not have the limitations of the FLAT format.
Rules to transform FLAT to JSON:
Check integrity: Messages to be transformed to TIC 4.0 from FLAT needs to follow the expected format.
Each key field of the message will be split by the "|" separator but also special symbols like "#" and "@" will be analysed:
When a "|" is found it means that the string before the symbol is the parent object and the string after is the child object or property.
When a "@" is found it means that the previous object is an array of elements, being the elements after the next "|" the object / properties of the first element of the array.
If "@" has an id string (ie "@sts01") it means that all elements with the same id belong to the same element of the array.
When a "#" is found it means that the string between two "#" (ie #unit#) is a property that should be included in the object. The content after the second "#" is the value of the property (ie #unit#meter will transform in the property "unit": "meter")
Exceptions to the "." rule:
When a value for the already know lists pom (see TIC4.0 Semantic | pom: Where in the subject (device or process) ) is found, the expected property should be included in the object (ie if "output" word is found, this will transform in the property "pom": "output")
When a value for the already know lists pomt is found (see TIC4.0 Semantic | Where/When in the timeline “pomt”: ), the expected property should be included in the object (ie if "actual" word is found, this will transform the property "pomt": "actual")
When a value for the already know lists pomp is found (see TIC4.0 Semantic | pomp: Process Started or Ended ), the expected property should be included in the object (ie if "started" word is found, this will transform the property "pomp": "started")
Example 1
One FLAT message with two “CHE”, each one with two “powersource” and two “spreader”:
{
"msg|id": "001",
"msg|version": "2022.003",
"msg|timestamp": "2022-02-14T08:23:55.000Z",
"msg|sample": 1,
"che|@1|id": "CC_098723412308947",
"che|@1|name": "RTG01",
"che|@1|number": "1",
"che|@1|arrayid": "1",
"che|@1|powersource|@Main_genset.id": "VOLVO_PQOWINFÑWAN238492723423",
"che|@1|powersource|@Main_genset|name": "genset_RTG01",
"che|@1|powersource|@Main_genset|number": "24",
"che|@1|powersource|@Main_genset|arrayid": "Main_genset",
"che|@1|powersource|@Main_genset|on|status|ioutput|actual|timestamp": "2022-02-14T07:52:50.616Z",
"che|@1|powersource|@Main_genset|on|status|ioutput|actual|value": "true",
"che|@1|powersource|@Main_genset|on|status|ioutput|actual|offtoontime": "5",
"che|@1|powersource|@aux_genset|id": "VOLVO_PQOWINFÑWAN238493452723423",
"che|@1|powersource|@aux_genset|name": "genset_RTG01",
"che|@1|powersource|@aux_genset|number": "28",
"che|@1|powersource|@aux_genset|arrayid": "aux_genset",
"che|@1|powersource|@aux_genset.on.status.ioutput.actual.timestamp": "2022-02-14T07:52:50.616Z",
"che|@1|powersource|@aux_genset.on.status.ioutput.actual.value": "true",
"che|@1|powersource|@aux_genset.on.status.ioutput.actual.offtoontime": "5",
"che|@1|spreader|@1|id": "broma_P1113",
"che|@1|spreader|@1|name": "seaside",
"che|@1|spreader|@1|number": "1",
"che|@1|spreader|@1|arrayid": "1",
"che|@|spreader|@1|on|status|ioutput|actual|timestamp": "2022-02-14T07:52:50.616Z",
"che|@1|spreader|@1|on|status|ioutput|actual|value": "true",
"che|@1|spreader|@1|on|status|ioutput|actual|offtoontime": "5",
"che|@1|spreader|@2|id": "broma_P1117",
"che|@1|spreader|@2|name": "landside",
"che|@1|spreader|@2|number": "33",
"che|@1|spreader|@2|arrayid": "2",
"che|@1|spreader|@2|on|status|ioutput|actual|timestamp": "2022-02-14T07:52:50.616Z",
"che|@1|spreader|@2|on|status|ioutput|actual|value": "true",
"che|@1|spreader|@2|on|status|ioutput|actual|offtoontime": "5",
"che|@2|id": "CC23894570234875092",
"che|@2|name": "RTG02",
"che|@2|number": "2",
"che|@2|arrayid": "2",
"che|@2|powersource|@Main_genset|id": "VOLVO_PQOWINFÑWAN2384927239",
"che|@2|powersource|@Main_genset|name": "Main_genset",
"che|@2|powersource|@Main_genset|number": "33",
"che|@2|powersource|@Main_genset|arrayid": "Main_genset",
"che|@2|powersource|@Main_genset|on|status|ioutput|actual|timestamp": "2022-02-14T07:52:50.616Z",
"che|@2|powersource|@Main_genset|on|status|ioutput|actual|value": "true",
"che|@2|powersource|@Main_genset|on|status|ioutput|actual|offtoontime": "5",
"che|@2|powersource|@aux_genset|id": "VOLVO_PQOWINFÑWAN23849453427239",
"che|@2|powersource|@aux_genset|name": "Aux_genset",
"che|@2|powersource|@aux_genset|number": "33",
"che|@2|powersource|@aux_genset|arrayid": "aux_genset",
"che|@2|powersource|@aux_genset|on|status|ioutput|actual|timestamp": "2022-02-14T07:52:50.616Z",
"che|@2|powersource|@aux_genset|on|status|ioutput|actual|value": "true",
"che|@2|powersource|@aux_genset|on|status|ioutput|actual|offtoontime": "5",
"che|@2|spreader|@1|id": "broma_P1155",
"che|@2|spreader|@1|name": "seaside",
"che|@2|spreader|@1|number": "1",
"che|@2|spreader|@1|arrayid": "1",
"che|@2|spreader|@1|on|status|ioutput|actual|timestamp": "2022-02-14T07:52:50.616Z",
"che|@2|spreader|@1|on|status|ioutput|actual|value": "true",
"che|@2|spreader|@1|on|status|ioutput|actual|offtoontime": "5",
"che|@2|spreader|@2|id": "broma_P11156",
"che|@2|spreader|@2|name": "landside",
"che|@2|spreader|@2|number": "33",
"che|@2|spreader|@2|arrayid": "2",
"che|@2|spreader|@2|on|status|ioutput|actual|timestamp": "2022-02-14T07:52:50.616Z",
"che|@2|spreader|@2|on|status|ioutput|actual|value": "true",
"che|@2|spreader|@2|on|status|ioutput|actual|offtoontime": "5"
}
{
"msg": {
"id": "001",
"version": "2022.003",
"timestamp": "2022-02-14T08:23:55.000Z",
"sample": 1
},
"che": [{
"id": "CC_098723412308947",
"name": "RTG01",
"number": "1",
"arrayid": "1",
"powersource": [{
"id": "VOLVO_PQOWINFÑWAN238492723423",
"name": "genset_RTG01",
"number": "24",
"arrayid": "Main_genset",
"on": {
"status": [{
"pomt": "actual",
"pom": "ioutput",
"timestamp": "2022-02-14T07:52:50.616Z",
"value": "true",
"offtoontime": "5"
}
]
}
}, {
"id": "VOLVO_PQOWINFÑWAN238493452723423",
"name": "genset_RTG01",
"number": "28",
"arrayid": "aux_genset",
"on": {
"status": [{
"pomt": "actual",
"pom": "ioutput",
"timestamp": "2022-02-14T07:52:50.616Z",
"value": "true",
"offtoontime": "5"
}
]
}
}
],
"spreader": [{
"id": "broma_P1113",
"name": "seaside",
"number": "1",
"arrayid": "1",
"on": {
"status": [{
"pomt": "actual",
"pom": "ioutput",
"timestamp": "2022-02-14T07:52:50.616Z",
"value": "true",
"offtoontime": "5"
}
]
}
}, {
"id": "broma_P1117",
"name": "landside",
"number": "33",
"arrayid": "2",
"on": {
"status": [{
"pomt": "actual",
"pom": "ioutput",
"timestamp": "2022-02-14T07:52:50.616Z",
"value": "true",
"offtoontime": "5"
}
]
}
}
]
}, {
"id": "CC23894570234875092",
"name": "RTG02",
"number": "2",
"arrayid": "2",
"powersource": [{
"id": "VOLVO_PQOWINFÑWAN2384927239",
"name": "Main_genset",
"number": "33",
"arrayid": "Main_genset",
"on": {
"status": [{
"pomt": "actual",
"pom": "ioutput",
"timestamp": "2022-02-14T07:52:50.616Z",
"value": "true",
"offtoontime": "5"
}
]
}
}, {
"id": "VOLVO_PQOWINFÑWAN23849453427239",
"name": "Aux_genset",
"number": "33",
"arrayid": "aux_genset",
"on": {
"status": [{
"pomt": "actual",
"pom": "ioutput",
"timestamp": "2022-02-14T07:52:50.616Z",
"value": "true",
"offtoontime": "5"
}
]
}
}
],
"spreader": [{
"id": "broma_P1155",
"name": "seaside",
"number": "1",
"arrayid": "1",
"on": {
"status": [{
"pomt": "actual",
"pom": "ioutput",
"timestamp": "2022-02-14T07:52:50.616Z",
"value": "true",
"offtoontime": "5"
}
]
}
}, {
"id": "broma_P11156",
"name": "landside",
"number": "33",
"arrayid": "2",
"on": {
"status": [{
"pomt": "actual",
"pom": "ioutput",
"timestamp": "2022-02-14T07:52:50.616Z",
"value": "true",
"offtoontime": "5"
}
]
}
}
]
}
]
}
Example 2
Open Source Code
The backend of this code is publicly available at
GitHub - Fundacion-Valenciaport/TIC4.0: TIC4.0 Repository
© Copyright - TIC 4.0 All rights reserved | Design web by Fundación Valenciaport