1. Introduction
Sensor observations, positioning data, measurements, mobility information... are commonly published as Time Series data with a timestamp and a value.
Representing Time Series data in RDF drastically raises the verbosity, as each data point is often given its own identifier, for which contextual information is repeated on all data points.
With Time Series Snippets, we allow a data publisher to compact the data points in subsets of a Time Series, called the Snippet, by using SPARQL Common Data Types such as cdt:List
and cdt:Map
.
This way, you can greatly reduce the amount of triples when describing a Time Series.
Time Series Snippets use the following prefix and namespace:
@prefix tss: <https://w3id.org/tss#> ;
A first example illustrates the features of a tss:Snippet
:
<snippet/2026-01-01> a tss : Snippet ; tss : points """[ { "time": "2026-01-01T06:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>, "value": "5.4"^^<http://www.w3.org/2001/XMLSchema#double>, "id": "https://example.org/0"}, { "time": "2026-01-01T06:59:59Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>, "value": "5.2"^^<http://www.w3.org/2001/XMLSchema#double>, "id": "https://example.org/1"}, { "time": "2026-01-01T08:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>, "value": "5.2"^^<http://www.w3.org/2001/XMLSchema#double>, "id": "https://example.org/2"}, { "time": "2026-01-01T09:00:00Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>, "value": "6.1"^^<http://www.w3.org/2001/XMLSchema#double>, "id": "https://example.org/3"}, ]""" ^^ cdt : List ; tss : from "2026-01-01T00:00:00Z" ^^ xsd : dateTime ; tss : until "2026-01-02T00:00:00Z" ^^ xsd : dateTime ; tss : pointType sosa : Observation ; tss : timePath sosa : resultTime ; tss : valuePath sosa : hasSimpleResult ; tss : about [ sosa : madeBySensor <temp_sensor_1> ; sosa : observedProperty <temperature> ; ]; .
The intention of Time Series Snippets is to be a lossless format as, if needed, it can be expanded again. Example 1 for example can be expanded to this RDF dataset:
<https://example.org/0> a sosa : Observation ; sosa : madeBySensor <temp_sensor_1> ; sosa : hasSimpleResult "5.4" ^^ xsd : double ; sosa : observedProperty <temperature> ; sosa : resultTime "2026-01-01T06:00:00Z" ^^ xsd : dateTime . <https://example.org/1> a sosa : Observation ; sosa : madeBySensor <temp_sensor_1> ; sosa : hasSimpleResult "5.2" ^^ xsd : double ; sosa : observedProperty <temperature> ; sosa : resultTime "2026-01-01T06:59:59Z" ^^ xsd : dateTime . <https://example.org/2> a sosa : Observation ; sosa : madeBySensor <temp_sensor_1> ; sosa : hasSimpleResult "5.2" ^^ xsd : double ; sosa : observedProperty <temperature> ; sosa : resultTime "2026-01-01T08:00:02Z" ^^ xsd : dateTime . <https://example.org/3> a sosa : Observation ; sosa : madeBySensor <temp_sensor_1> ; sosa : hasSimpleResult "6.1" ^^ xsd : double ; sosa : observedProperty <temperature> ; sosa : resultTime "2026-01-01T09:00:00Z" ^^ xsd : dateTime .
2. Definitions
A Time Series is a set of data points ordered by timestamp, where each data point consists of a timestamp and corresponding value.
A Snippet describes a subset of a Time Series within a certain period defined by a start and end timestamp, and a description of the entity providing the data points.
A Data Point is a single point of a Time Series containing an ISO timestamp, a value with datatype, and optionally an identifier.
3. Snippet properties
Each Snippet SHOULD have the following properties:
-
tss:points
: acdt:List
of data points where each data point is acdt:Map
with atime
key usingxsd:dateTime
value, with avalue
key for which the value is annotated with a datatype, and optionally anid
key for which the value is an IRI for the current data point. -
tss:from
: starting timestamp (including) of the period covered bytss:points
using anxsd:dateTime
. -
tss:until
: until this timestamp (excluding) of the period covered bytss:points
using anxsd:dateTime
. -
tss:about
: contains statements about a blank node. The statements can be asserted on top of all data points intss:points
when expanding the Snippet. -
tss:pointType
: the RDF type of all data points intss:points
. -
tss:timePath
: the path to use for expanding thetime
property intss:points
. -
tss:valuePath
: the path to use for expanding thevalue
property intss:points
.
Discuss whether these properties are required or optional. E.g., a publisher might decide to do a lossy conversion for their goal, and not include valuePath, pointType and timePath. However, we can still analyze and visualize the data without that information.
3.1. Data Points
tss:points
MUST have a cdt:List
as datatype. Each Data Point itself MUST be a cdt:Map
consisting
of 2 required properties and 1 optional property:
-
time
: the timestamp of the data point using anxsd:dateTime
. -
value
: the value of the data point with corresponding datatype. -
id
: the data point identifier is optionally. When set, this MUST be a named node.
[ { "time" : "2026-01-01T06:00:00Z" ^^ <http://www.w3.org/2001/XMLSchema#dateTime>, "value" : "5.4" ^^ <http://www.w3.org/2001/XMLSchema#double>, "id" : "https://example.org/0" }, { "time" : "2026-01-01T06:59:59Z" ^^ <http://www.w3.org/2001/XMLSchema#dateTime>, "value" : "5.2" ^^ <http://www.w3.org/2001/XMLSchema#double>, "id" : "https://example.org/1" }, { "time" : "2026-01-01T08:00:00Z" ^^ <http://www.w3.org/2001/XMLSchema#dateTime>, "value" : "5.2" ^^ <http://www.w3.org/2001/XMLSchema#double>, "id" : "https://example.org/2" }, { "time" : "2026-01-01T09:00:00Z" ^^ <http://www.w3.org/2001/XMLSchema#dateTime>, "value" : "6.1" ^^ <http://www.w3.org/2001/XMLSchema#double>, "id" : "https://example.org/3" }, ]
3.2. Expanding data points
When tss:timePath
and tss:valuePath
are set (mind this is not required), a Snippet can be expanded to a verbose RDF representation, for example using its original vocabulary.
The properties tss:about
and tss:pointType
will influence that process.
For each Data Point, it can be mapped as follows:
-
When the
id
is set and it is a valid IRI, set this id as the subject. If it is not, create a new blank node and set this as the subject. -
When
tss:pointType
is set, create a triple stating this id is ofrdf:type
the object of the pointType triple. -
Create a triple for the time based on the
tss:timePath
. For unknown intermediary named nodes, a blank node is to be created. -
Similarly, create a triple for the value based on the
tss:valuePath
. -
Now apply the
tss:about
blank node entity to this point.
Discuss whether a SHACL Path makes sense to use as the intermediary steps will be mapped to blank nodes. Probably we could simplify here and make this a tss:timeProperty
instead?