diff --git a/23-019.adoc b/23-019.adoc index 4129fac..c373603 100644 --- a/23-019.adoc +++ b/23-019.adoc @@ -12,6 +12,8 @@ :published-date: 2029-03-30 :fullname: Hylke van der Schaaf :fullname_2: Steve Liang +:fullname_3: Humaid Kidwai +:fullname_4: Kathi Schleidt :docsubtype: implementation :keywords: ogcdoc, OGC document, API, OData, openapi, html, MQTT :submitting-organizations: Fraunhofer-Gesellschaft, Germany; University of Calgary, Canada; SensorUp Inc., Canada; Keys, USA; DataCove e.U., Austria @@ -48,9 +50,11 @@ include::sections/clause_07a_meta_model.adoc[] include::sections/clause_07b_sensing_entities.adoc[] -include::sections/clause_07c_sampling_entities.adoc[] +include::sections/clause_07c_sensing_OM_extension.adoc[] -include::sections/clause_07d_actuation_entities.adoc[] +include::sections/clause_07d_sampling_entities.adoc[] + +include::sections/clause_07e_actuation_entities.adoc[] include::sections/clause_08a_abstract_api_overview.adoc[] diff --git a/images/GRP0001.png b/images/GRP0001.png new file mode 100644 index 0000000..8b29c25 Binary files /dev/null and b/images/GRP0001.png differ diff --git a/images/GRP0002.png b/images/GRP0002.png new file mode 100644 index 0000000..c63e063 Binary files /dev/null and b/images/GRP0002.png differ diff --git a/images/README.adoc b/images/README.adoc deleted file mode 100644 index 12e6fb0..0000000 --- a/images/README.adoc +++ /dev/null @@ -1,5 +0,0 @@ -Image files for graphics go here. Image files for figures go in the "figures" directory. Only place in here images not used in figures (e.g., as parts of tables, as logos, etc.) - -Each graphic is a separate file with the naming convention: - -"GRPn.xxx" where "n" is a sequential number with leading zeroes appropriate for the total number of graphics and "xxx" is the appropriate extension for the file type. diff --git a/metanorma.yml b/metanorma.yml index b0db9dc..16d7980 100644 --- a/metanorma.yml +++ b/metanorma.yml @@ -2,5 +2,5 @@ metanorma: source: files: - - document.adoc + - 23-019.adoc diff --git a/sections/clause_06_overview.adoc b/sections/clause_06_overview.adoc index 80e7c58..c674de3 100644 --- a/sections/clause_06_overview.adoc +++ b/sections/clause_06_overview.adoc @@ -1,11 +1,103 @@ -[obligation=informative] +[[overview1]] == SensorThings API overview -Clauses not Containing Normative Material -Paragraph +[[who-should-use]] +=== Who should use the OGC SensorThings API -=== Relation to Observations, Measurements and Samples + +Organizations that need web-based platforms to manage, store, share, and analyze IoT-based sensor observation data should use the OGC SensorThings API. The OGC SensorThings API simplifies and accelerates the development of IoT applications. Application developers can use this open Standard to connect to various IoT devices and create innovative applications without worrying the daunting heterogeneous protocols of the different IoT devices, gateways and services. IoT device manufacturers can also use OGC SensorThings API as the API can be embedded within various IoT hardware and software platforms, so that the various IoT devices can effortlessly connect with the OGC Standard-compliant servers around the world. In summary, the OGC SensorThings API is transforming the numerous disjointed IoT systems into a fully connected platform where complex tasks can be synchronized and performed. + + +[[benefits]] +=== Benefits of the OGC SensorThings API + +In today’s world, most IoT devices (e.g., sensors and actuators) have proprietary software interfaces defined by their manufacturers and used selectively. New APIs are often required and developed on an as-needed basis, often in an environment with resource limitations and associated risks. This situation requires significant investment on the part of developers for each new sensor or project involving multiple systems and on the part of the providers of sensors, gateways, and portals or services where observations and measurements are required. + +As a standardized data model and interface for sensors in the WoT and IoT<>, the OGC SensorThings API offers the following benefits: (1) it permits the proliferation of new high value services with lower overhead of development and wider reach, (2) it lowers the risks, time and cost across a full IoT product cycle, and (3) it simplifies the connections between devices-to-devices and devices-to-applications. + + +[[overview2]] +=== SensorThings API Overview + +The OGC SensorThings API data model consists of three main parts: (1) the Sensing part, (2) the Sampling part and (3) the Tasking part. Additionally, SensorThings API supports the following two extensions to the data model: (1) the Sensing Extension (Observations & Measurements) and (2) the Relations extension + +The Sensing part allows IoT devices and applications to CREATE, READ, UPDATE, and DELETE (__i.e.__, HTTP POST, GET, PATCH, and DELETE) IoT data and metadata in a SensorThings service. +The Sensing part is designed based on the OGC/ISO Observation, Measurements and Samples (OMS) model [OGC 20-004r3 and ISO 19156:2023]. An Observation is modeled as an act that produces a result whose value is an estimate of a property of a given Feature. An Observation instance is characterized by its event time (e.g., resultTime and phenonmenonTime), Feature, ObservedProperty, and the procedure used (often a Sensor). Moreover, Things are also modeled in the SensorThings API. A Thing draws from the same concept as a Host in OMS where a Host is defined as a collection of Observers (defined as Sensor in SensorThings API). Formally, its definition follows the ITU-T definition: “__an object of the physical world (physical things) or the information world (virtual things) that is capable of being identified and integrated into communication networks__” [ITU-T Y.2060]. +The geographical Locations of Things are useful in almost every application and as a result are included as well. For the Things whose location changed, the HistoricalLocations entities offer the history of the Thing’s locations. A Thing also can have multiple Datastreams. A Datastream is a collection of Observations grouped by the same ObservedProperty, Sensor and optionally by Feature and ObservingProcedure. An Observation is an event performed by a Sensor that produces a result whose value is an estimate of an ObservedProperty of any given Feature which may be a proximate or ultimate FeatureofInterest. Details of each above described entity are provided in <>. + +The Sampling part is a new addition to the SensorThings API. As is often the case, an Observation may not be a true representation of the intended Feature's Property that an Observer may be trying to Observe. Sampling is a common strategy to understand the characteristics of an otherwise difficult-to-measure Property of any feature-of-interest. In order to generate Samplings, a Sampler, that may be any physical device or even a human being part of a survey campaign, must carefully select a SamplingProcedure. Samplings may be generated by a sequence of SamplingProcedures (and vice-versa), however a Sampler must employ a unique SamplingProcedure to maintain unique Sampling-Sampler-SamplingProcedure relationships. In scenarios where a Feature is not directly available for Sampling, a PreparationProcedure composed of multiple PreparationSteps may optionally be used to generate a PreparedFeature. The entities are explained in detail in <>. + +The Tasking part provides a standard way for parameterizing - also called tasking - of taskable IoT devices, such as individual sensors and actuators, composite consumer / commercial / industrial / smart cities in-situ platforms, mobile and wearable devices, or even unmanned systems platforms such as drones, satellites, connected and autonomous vehicles, etc. A Task defines a control action executed by an Actuator. Actuator is modeled to describe a device that is equipped with Tasking Capabilities. A TaskingCapability characterizes an Actuator's (or in some cases, a Thing's) ability to trigger a change in ActuableProperties of any FeatureOfInterest by executing the given Task. The Tasking Data Model thus mirrors the Sensing Data Model. Each of these entities are elaborated further in <>. + +The <> and <> are optional extensions to the data model that may be used for extended data modelling requirements. + +[[observations-measurements]] +=== SensorThings API and Relation to ISO/OGC Observations, Measurements and Samples + +Managing and retrieving observations and metadata from IoT sensor systems is one of the most common use cases. As a result, SensorThings API’s sensing part is designed based on the OMS model. OMS defines models for the exchange of information describing observation acts, their results as well as the feature involved in sampling when making observations. + + +SensorThings API defines nine entities for the IoT sensing applications and two additional entities in the OM extension. <> lists each component and its relationship with OMS. SensorThings API uses the term of Sensor to describe the Observer that is used in generating an Observation, instead of using OMS’ term of Observer. + + +[[tab-sensing-entities]] +.SensorThings API Sensing entities and equivalent concepts in OMS 3.0 +|=== +|SensorThings API Entities |OMS 3.0 Concepts + +|Thing +|Host + +|Datastream +|- + +|Sensor +|Observer + +|Deployment +|Deployment + +|Observation +|Observation + +|ObservingProcedure +|Observing Procedure + +|ObservedProperty +|Observed Property + +|Feature +|Feature +|=== + + +[[revision-differences]] +=== SensorThings API 2.0 changes from 1.1 +[#sta-changes,reftext='{table-caption} {counter:table-num}'] +.Changes in the SensorThings API 2.0 data model compared to v1.x +[width="100%",cols="5,20",options="header"] +|==== +| *Entity* | *Changes* +| Sensor | description attribute is now optional and not mandatory +| Thing | description attribute is now optional and not mandatory +| Location | description attribute is now optional and not mandatory +| Datastream | description attribute is now optional and not mandatory + +resultType replaces the observationType attribute, this eliminates MultiDatastream entity + +unitOfMeasurement SHALL be embedded within the observedType attribute and does not exist as an independent attribute within the Datastream entity + +A Datastream can link to multiple ObservedProperties which was only possible with MultiDatastream entity earlier. The SWE-Common based observationType attribute eliminates the need for having a separate MultiDatastream entity + +A Datastream can now be partitioned by the Feature it observes as an optional link between Datastream and Feature is introduced + +| ObservedProperty | description attribute is now optional and not mandatory +| Observation | properties replaces the parameters attribute + +An Observation may or may not link to any Feature in contrast to the mandatory link between Observation and FeatureOfInterest from v1.x +| Feature | The Feature entity replaces the FeatureOfInterest entity from 1.x as it now takes the role of UltimateFeatureOfInterest or ProximateFeatureOfInterest depending upon the context and links with Observation and Datastream entities +|==== === Relation to OASIS-OData @@ -15,4 +107,3 @@ The OGC SensorThings API v2 interface is not an OData interface. It specifies a An SensorThings API Server implementation can implement the full OData specification. An OData client can access a SensorThings API service. -EDIOR: Verify this is true. diff --git a/sections/clause_07a_meta_model.adoc b/sections/clause_07a_meta_model.adoc index b6217ea..dd666c9 100644 --- a/sections/clause_07a_meta_model.adoc +++ b/sections/clause_07a_meta_model.adoc @@ -1,15 +1,14 @@ -[[meta-data-model]] -== Meta Data Model +[[OData-Entity-Model]] +== OData Entity Model -This chapter describes the SensorThings API meta model that is used to describe the SensorThings API data model and its data model extensions. -The meta model is also used to specify the rest and pub-sub apis. -It is based on the ODATA Meta Model +Every OData service utilizes an entity model which MAY be distributed over several schemas. The service describes this model through a metadata document accessible by a simple HTTP _GET_ request to the /$metadata path. This chapter describes an overview of the types of entities in the metadata document that will be used to describe the SensorThings API data model and its data model extensions. +The entities listed below are also used to describe the REST and MQTT bindings of the SensorThings API service. * https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part1-protocol.html#sec_DataModel * https://docs.oasis-open.org/odata/odata-csdl-json/v4.01/odata-csdl-json-v4.01.html#sec_EntityModel -The meta model consists of the following elements: +The data model consists of the following elements: * `Entity Type`: named, structured, keyed element that defines the properties and relations of Entities. The key of an Entity Type consists of one or more primitive properties of the Entity Type. diff --git a/sections/clause_07b_sensing_entities.adoc b/sections/clause_07b_sensing_entities.adoc index d8fd30d..f1d7eca 100644 --- a/sections/clause_07b_sensing_entities.adoc +++ b/sections/clause_07b_sensing_entities.adoc @@ -1,28 +1,41 @@ -[[sensing-entities]] -=== Sensing Entities - - +:sectnums: |,all| +:sectanchors: +[[sensing-entities1]] +== The SensorThings API Sensing Entities All data model requirements classes are grouped in the following requirements class: - [requirements_class] -.Sensing Entities - ==== [%metadata] identifier:: {identifier}/req-class/datamodel/sensing obligation:: requirement subject:: Target Type: Data Model requirement:: {identifier}/req-class/datamodel/sensing/thing +requirement:: {identifier}/req-class/datamodel/sensing/location +requirement:: {identifier}/req-class/datamodel/sensing/historical-location +requirement:: {identifier}/req-class/datamodel/sensing/datastream +requirement:: {identifier}/req-class/datamodel/sensing/deployment requirement:: {identifier}/req-class/datamodel/sensing/sensor +requirement:: {identifier}/req-class/datamodel/sensing/observed-property +requirement:: {identifier}/req-class/datamodel/sensing/observing-procedure +requirement:: {identifier}/req-class/datamodel/sensing/observation +requirement:: {identifier}/req-class/datamodel/sensing/feature ==== +[[sensing-entities2]] +=== Sensing Entities -==== Requirement Class: Thing +The OGC SensorThings API v2.0 depicts the Core Sensing entities in Figure {counter:figure-num} +[#img-sta-core,link=images/GRP0001.png, reftext='{figure-caption} {counter:figure-num}', title='Sensing Core'] +image::images/GRP0001.png[Sensing Core, align="center"] -[requirements_class] -.thing +In this section, we define each entity depicted in <> and its relationships with other entities. Additionally, we also provide examples to model the entities in different contexts. + +[[thing]] +==== Thing + +[requirements_class] ==== [%metadata] identifier:: {identifier}/req-class/datamodel/sensing/thing @@ -32,25 +45,614 @@ requirement:: {identifier}/req/datamodel/sensing/thing/properties requirement:: {identifier}/req/datamodel/sensing/thing/relations ==== -The Thing is a cool Entity that can be anything. -Say something about OMS-Host, OMS-Deployment, FeatureOfInterest and Locations +The SensorThings API follows the ITU-T definition, i.e., with regard to the Internet of Things, a thing is an object of the physical world (physical things) or the information world (virtual things) that is capable of being identified and integrated into communication networks [ITU-T Y.2060]. A Thing is related to the Platform entity as described in Section 4.9.2.1 of [OGC 16-079] in a way that any entity that can be modelled as a Thing MAY be subsequently translated to a Platform and vice versa. + +[example%unnumbered] +==== +*Thing Examples* + +- A weather forecasting facility that houses multiple weather sensors deployed across several sites +- A drone that mounts a LiDAR sensor for mapping purposes +- An upstream oil well that is equipped with compound gas detection devices +==== [requirement] ==== [%metadata] identifier:: {identifier}/req/datamodel/sensing/thing/properties -Each Thing entity SHALL have the mandatory properties and MAY have the optional properties listed in Table XX. +Each Thing entity SHALL have the mandatory properties and MAY have the optional properties listed in Table {counter:table-num}. ==== - +[#thing-properties,reftext='{table-caption} {counter:table-num}'] +.Properties of a Thing entity +[width="100%",cols="5,17,3,3,3",options="header"] +|==== +| *Name* | *Definition* | *Data Type* | *Usage* | *Multiplicity* +| `id` | A unique, read-only property that serves as an identifier for the entity. Its value is computed by the server when creating or updating the entity unless specified by the client | ANY | Required | One +| `name` | A property provides a label for Thing entity, commonly a descriptive name. | String | Required | One +| `description` | This is a short description of the corresponding Thing entity. | String | Optional | Zero-to-one +| `properties` | A JSON Object containing user-annotated properties as key-value pairs. | JSON Object | Optional | Zero to One +|==== [requirement] ==== [%metadata] identifier:: {identifier}/req/datamodel/sensing/thing/relations +Each Thing entity SHALL have the direct relation between a Thing entity and other entity types listed in Table {counter:table-num}. +==== + +[#thing-relations,reftext='{table-caption} {counter:table-num}'] +.Direct relation between a Thing entity and other entity types +[width="100%",cols="5,5,10,10",options="header"] +|==== +| *Entity Name* | *Role* | *Multiplicity* | *Description* +| `Location` | Locations | Many optional to many optional | The Location entity locates the Thing. Multiple Things MAY be located at the same Location. A Thing MAY not have a Location. A Thing SHOULD have only one Location. -Each Thing entity SHALL have the direct relation between a Thing entity and other entity types listed in Table XX. + However, in some complex use cases, a Thing MAY have more than one Location representations. In such case, the Thing MAY have more than one Locations. These Locations SHALL have different encodingTypes and the encodingTypes SHOULD be in different spaces (e.g., one encodingType in Geometrical space and one encodingType in Topological space). +| `HistoricalLocation` | HistoricalLocations | One mandatory to many optional | A Thing has zero-to-many HistoricalLocations. A HistoricalLocation has one-and-only-one Thing. +| `Datastream` | Datastreams | One mandatory to many optional | A Thing MAY have zero-to-many Datastreams. +|==== + + + + + +[[location]] +==== Location + +[requirements_class] ==== +[%metadata] +identifier:: {identifier}/req-class/datamodel/sensing/location +obligation:: requirement +subject:: Target Type: Data Model +requirement:: {identifier}/req/datamodel/sensing/location/properties +requirement:: {identifier}/req/datamodel/sensing/location/relations +==== + +The Location entity geo-locates the Thing or the Things it associated with. A Thing’s Location entity is defined as the last known location of the Thing. + +The Feature can be either a proximate feature of interest or the ultimate feature of interest depending upon the context of the Observation. +For __in-situ__ sensing applications, the Location MAY describe the coordinates of where the Thing is located. The Feature is the entity for which the value of a property was determined by the Sensor. The ObservedProperty in this case MAY characterize only the area around the sensing device or it MAY characterize the larger observedArea that the sensing application intends to capture. Thus, depending upon the feature-of-interest, the Feature can then be either a ProximateFeatureOfInterest or UltimateFeatureOfInterest. +For __ex-situ__ sensing applications, the Location MAY describe the coordinates of where the Thing is located, whereas the feature MAY be the point location of the observed Feature. + +Section 7.1.4 of [OGC 20-082r4 and ISO 19156:2023] provides a detailed explanation of observation location. + +[example%unnumbered] +==== +*Location Examples* + +- An air quality sensing facility's Location can be the physical location where the facility is situated, but the (proximate) Feature that is characterized by the Observation could be the air envelope around the Sensor which is subsequently used to estimate the air quality of the district where the facility is situated. +- A drone that mounts a LiDAR Sensor may have its Location as the geo-referenced area over which the drone is scheduled to fly, whereas the Feature could be the individual objects mapped by the Sensor within that geo-referenced area +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/location/properties + +Each Location entity SHALL have the mandatory properties and MAY have the optional properties listed in Table {counter:table-num}. +==== +[#location-properties,reftext='{table-caption} {counter:table-num}'] +.Properties of a Location entity +[width="100%",cols="5,17,3,3,3",options="header"] +|==== +| *Name* | *Definition* | *Data Type* | *Usage* | *Multiplicity* +| `id` | A unique, read-only property that serves as an identifier for the entity. Its value is computed by the server when creating or updating the entity unless specified by the client | ANY | Required | One +| `name` | A property provides a label for Location entity, commonly a descriptive name. | String | Required | One +| `encodingType` | The encoding type of the Location property. | String | Required | One +| `location` | The identifiable location of the Thing | ANY | Required | One +| `description` | The description about the Location | String | Optional | Zero-to-one +| `properties` | A JSON Object containing user-annotated properties as key-value pairs. | JSON Object | Optional | Zero to One +|==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/location/relations +Each Location entity SHALL have the direct relation between a Location entity and other entity types listed in Table {counter:table-num}. +==== + +[#location-relations,reftext='{table-caption} {counter:table-num}'] +.Direct relation between a Location entity and other entity types +[width="100%",cols="5,5,10,10",options="header"] +|==== +| *Entity Name* | *Role* | *Multiplicity* | *Description* +| `Thing` | Things | Many optional to many optional | Multiple Things MAY locate at the same Location. A Thing MAY not have a Location. +| `HistoricalLocation` | HistoricalLocations | Many optional to many optional | A Location MAY have zero-to-many HistoricalLocations. One HistoricalLocation SHALL have one or more Locations. +|==== + + + + +[[historicallocation]] +==== HistoricalLocation + +[requirements_class] +==== +[%metadata] +identifier:: {identifier}/req-class/datamodel/sensing/historical-location +obligation:: requirement +subject:: Target Type: Data Model +requirement:: {identifier}/req/datamodel/sensing/historical-location/properties +requirement:: {identifier}/req/datamodel/sensing/historical-location/relations +requirement:: {identifier}/req/datamodel/sensing/historical-location/create-update-delete/historical-location-auto-creation +requirement:: {identifier}/req/datamodel/sensing/historical-location/create-update-delete/historical-location-manual-creation +==== + +A Thing’s HistoricalLocation entity set provides the times of the current (i.e., last known) and previous locations of the Thing. It can be used to model the path observed by a moving Thing. + +[example%unnumbered] +==== +*HistoricalLocation Examples* + +- A drone that measures methane leaks over a large basin may want to record the trajectory through which it flies. HistoricalLocation should then record the individual Locations of the drone over time + +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/historical-location/properties + +Each HistoricalLocation entity SHALL have the mandatory properties and MAY have the optional properties listed in Table {counter:table-num}. +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/historical-location/relations + +Each HistoricalLocation entity SHALL have the direct relation between a HistoricalLocation entity and other entity types listed in Table {counter:table-num}. +==== + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/historical-location/create-update-delete/historical-location-auto-creation + +When a Thing has a new Location, a new HistoricalLocation SHALL be created and added to the Thing automatically by the service. The current Location of the Thing SHALL only be added to this autogenerated HistoricalLocation automatically by the service, and SHALL not be created as HistoricalLocation directly by user. +==== + +The HistoricalLocation can also be created, updated and deleted. +One use case is to migrate historical observation data from an existing observation data management system to a SensorThings API system. +Another use case is to track the Location of a Thing, when a permanent network connection is not available. +If the Location of a Thing is changed at a later time, when a network connection is available again, then the auto-generated Time of the HistoricalLocation entity would not reflect the time when the Thing was actually at the set Location, but only the time at which the change was sent to the server. +To resolve this, the Location of a Thing can also be changed by adding a HistoricalLocation. +If the time of a manually created HistoricalLocation is later than the time of all existing HistoricalLocations, then the Location of the Thing is updated to the Location of this manually created HistoricalLocation. + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/historical-location/create-update-delete/historical-location-manual-creation + +When a user directly adds new HistoricalLocation, and the time of this new HistoricalLocation is later than the latest HistoricalLocation for the Thing, then the Locations of the Thing are changed to the Locations of this new HistoricalLocation. +==== + +[#historical-location-properties,reftext='{table-caption} {counter:table-num}'] +.Properties of a HistoricalLocation entity +[width="100%",cols="5,17,3,3,3",options="header"] +|==== +| *Name* | *Definition* | *Data Type* | *Usage* | *Multiplicity* +| `id` | A unique, read-only property that serves as an identifier for the entity. Its value is computed by the server when creating or updating the entity unless specified by the client | ANY | Required | One +| `time` | The time when the Thing is known at the Location. | TM_Instant | Required | One +|==== + + +[#historical-location-relations,reftext='{table-caption} {counter:table-num}'] +.Direct relation between a HistoricalLocation entity and other entity types +[width="100%",cols="5,5,10,10",options="header"] +|==== +| *Entity Name* | *Role* | *Multiplicity* | *Description* +| `Location` | Locations | Many optional to many mandatory | A Location can have zero-to-many HistoricalLocations. One HistoricalLocation SHALL have one or many Locations. +| `Thing` | Thing | Many optional to one mandatory | A HistoricalLocation has one-and-only-one Thing. One Thing MAY have zero-to-many HistoricalLocations. +|==== + + + + +[[datastream]] +==== Datastream + +[requirements_class] +==== +[%metadata] +identifier:: {identifier}/req-class/datamodel/sensing/datastream +obligation:: requirement +subject:: Target Type: Data Model +requirement:: {identifier}/req/datamodel/sensing/datastream/properties +requirement:: {identifier}/req/datamodel/sensing/datastream/relations +==== + +A Datastream groups a collection of Observations into a time series measuring the same ObservedProperty by the same Sensor for the same Feature for the same Thing. + +[example%unnumbered] +==== +*Datastream Examples* + +- An air quality monitoring station may have multiple Datastreams each recording a specific pollutant measured by the sensors +- A sensor that measures multiple ObservedProperties can generate a single Datastream of composite observationTypes + +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/datastream/properties + +Each Datastream entity SHALL have the mandatory properties and MAY have the optional properties listed in Table {counter:table-num}. +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/datastream/relations + +Each Datastream entity SHALL have the direct relation between a Datastream entity and other entity types listed in Table {counter:table-num}. +==== + + + +[#datastream-properties,reftext='{table-caption} {counter:table-num}'] +.Properties of a Datastream entity +[width="100%",cols="5,17,3,3,3",options="header"] +|==== +| *Name* | *Definition* | *Data Type* | *Usage* | *Multiplicity* +| `id` | A unique, read-only property that serves as an identifier for the entity. Its value is computed by the server when creating or updating the entity unless specified by the client | ANY | Required | One +| `name` | A property provides a label for Datastream entity, commonly a descriptive name | String | Required | One +| `description` | The description of the Datastream entity. | String | Optional | Zero-to-one +| `observationType` | The type of Observation (with unit of measurement AND unique result type), which is used by the service to encode observations | JSON Object (SWE-Common) +(see <>) | Required | One +| `observedArea` | The spatial bounding box of the spatial extent of the Feature that belong to the Observations associated with this Datastream | Geometry | Optional | Zero-to-one +| `phenomenonTime` | The temporal interval of the phenomenon times of all observations belonging to this Datastream | TM_Period | Optional | Zero-to-one +| `resultTime` | The temporal interval of the result times of all observations belonging to this Datastream | TM_Period | Optional | Zero-to-one +| `properties` | A JSON Object containing user-annotated properties as key-value pairs | JSON Object | Optional | Zero-to-one +|==== + + +[#datastream-relations,reftext='{table-caption} {counter:table-num}'] +.Direct relation between a Datastream entity and other entity types +[width="100%",cols="5,5,10,10",options="header"] +|==== +| *Entity Name* | *Role* | *Multiplicity* | *Description* +| `Thing` | Thing | Many optional to one mandatory | A Thing has zero-to-many Datastreams. A Datastream entity SHALL only link to a Thing as a collection of Observations +| `Sensor` | Sensor | Many optional to one mandatory | The Observations in a Datastream are performed by one-and-only-one Sensor. One Sensor MAY produce zero-to-many Observations in different Datastreams +| `ObservedProperty` | ObservedProperty | Many optional to many mandatory | The Observations of a Datastream SHALL observe the same ObservedProperty. The Observations of different Datastreams MAY observe the same ObservedProperty +| `Observation` | Observations | One mandatory to many optional | A Datastream has zero-to-many Observations. One Observation SHALL occur in one-and-only-one Datastream +| `Feature` | UltimateFeatureOfInterest | Many optional to one optional | The Feature has the role UltimateFeatureOfInterest so that all the Observations in a Datastream pertain only to the same linked Feature +|==== + + +The observationType defines the result types for specialized single and multi observations based on the JSON encoding of the SWE Common Data Model [OGC 08-094r1 and OGC 17-011r2]. This also obsoletes MultiDatastreams as the same information can be described using the SWE Common definition types. + + +.Example {counter:examples}: A Datastream observationType example measuring a scalar Observation +[source,json] +---- +{ + "type": "Quantity", + "definition": "http://sensorml.com/ont/swe/property/SpectralRadiance", + "label": "Radiance", + "description": "Radiance measured on band1", + "uom": { "code": "W.m-2.Sr-1.um-1" }, +} +---- + +.Example {counter:examples}: A Datastream observationType example measuring an Observation that can take categorical values from a predefined code space +[source,json] +---- +{ + "type": "CategoryRange", + "definition": "http://sweet.jpl.nasa.gov/2.0/timeGeologic.owl#GeologicTime", + "label": "Approximate Dating", + "description": "Approximate geological dating expressed as a range of geological eras", + "codeSpace": "http://sweet.jpl.nasa.gov/2.0/timeGeologic.owl#Era", +} +---- + +.Example {counter:examples}: A Datastream observationType example measuring multiple observedProperties +[source,json] +---- +{ + "type": "DataArray", + "label": "Measurement Table", + "elementType": { + "name": "measurement", + "type": "DataRecord", + "fields": [ + { + "name": "temp", + "type": "Quantity", + "definition": "http://mmisw.org/ont/cf/parameter/air_temperature", + "label": "Air Temperature", + "uom": { "code": "Cel" } + }, + { + "name": "press", + "type": "Quantity", + "definition": "http://mmisw.org/ont/cf/parameter/air_pressure_at_mean_sea_level", + "label": "Air Pressure", + "uom": { "code": "mbar" } + } + ] + } +} +---- + + +[#datastream-value-codes,reftext='{table-caption} {counter:table-num}'] +.List of some SWE Common types for defining observationTypes based on the UML classes in SWE Common Data Model (OGC 08-094r1 and OGC 17-011r2) +[width="100%",cols="15,5",options="header"] + +* `SWE:DataRecordType` +* `SWE:DataArrayType` +* `SWE:VectorType` +* `SWE:CategoryRangeType` + + + + +[[sensor]] +==== Sensor + +[requirements_class] +==== +[%metadata] +identifier:: {identifier}/req-class/datamodel/sensing/sensor +obligation:: requirement +subject:: Target Type: Data Model +requirement:: {identifier}/req/datamodel/sensing/sensor/properties +requirement:: {identifier}/req/datamodel/sensing/sensor/relations +==== + +A Sensor is an instrument that observes a property or phenomenon with the goal of producing an estimate of the value of the property + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/sensor/properties + +Each Sensor entity SHALL have the mandatory properties and MAY have the optional properties listed in Table {counter:table-num}. +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/sensor/relations + +Each Sensor entity SHALL have the direct relation between a Sensor entity and other entity types listed in Table {counter:table-num}. +==== + + +[#sensor-properties,reftext='{table-caption} {counter:table-num}'] +.Properties of a Sensor entity +[width="100%",cols="5,17,3,3,3",options="header"] +|==== +| *Name* | *Definition* | *Data Type* | *Usage* | *Multiplicity* +| `id` | A unique, read-only property that serves as an identifier for the entity. Its value is computed by the server when creating or updating the entity unless specified by the client | ANY | Required | One +| `name` | A property provides a label for Sensor entity, commonly a descriptive name. | String | Required | One +| `description` | The description of the Sensor entity. | String | Optional | Zero-to-one +| `encodingType` | The encoding type of the metadata property. Its value is one of the ValueCode enumeration (see <> for the available ValueCode) | ValueCode | Required | One +| `metadata` | The detailed description of the Sensor or system. The metadata type is defined by encodingType | String | Required | One +| `properties` | A JSON Object containing user-annotated properties as key-value pairs | JSON Object | Optional | Zero-to-one +|==== + + +[#sensor-relations,reftext='{table-caption} {counter:table-num}'] +.Direct relation between a Sensor entity and other entity types +[width="100%",cols="5,5,10,10",options="header"] +|==== +| *Entity Name* | *Role* | *Multiplicity* | *Description* +| `Datastream` | Datastreams | One mandatory to many optional | The Observations of a Datastream are measured with the same Sensor. One Sensor MAY produce zero-to-many Observations in different Datastreams +|==== + + +[#sensor-encodingType-value-codes,reftext='{table-caption} {counter:table-num}'] +.List of some code values used for identifying types for the encodingType of the Sensor entity +[width="100%",cols="15,5",options="header"] +|==== +| *Sensor encodingType* | *ValueCode Value* +| `PDF` | application/pdf +| `SensorML` | http://www.opengis.net/doc/IS/SensorML/2.0 +| `HTML` | text/html +|==== + +The Sensor encodingType allows clients to know how to interpret metadata’s value. Currently SensorThings API defines two common Sensor metadata encodingTypes. Most sensor manufacturers provide their sensor datasheets in a PDF format. As a result, PDF is a Sensor encodingType supported by SensorThings API. The second Sensor encodingType is SensorML. Lastly, some sensor datasheets are HTML documents rather than PDFs. Other encodingTypes are permitted (e.g., text/plain). Note that the metadata property may contain either a URL to metadata content (e.g., an https://, ftp://, etc. link to a PDF, SensorML, or HTML document) or the metadata content itself (in the case of text/plain or other encodingTypes that can be represented as valid JSON). It is up to clients to perform string parsing necessary to properly handle metadata content. + +[[observedproperty]] +==== ObservedProperty + +[requirements_class] +==== +[%metadata] +identifier:: {identifier}/req-class/datamodel/sensing/observed-property +obligation:: requirement +subject:: Target Type: Data Model +requirement:: {identifier}/req/datamodel/sensing/observed-property/properties +requirement:: {identifier}/req/datamodel/sensing/observed-property/relations +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/observed-property/properties + +Each ObservedProperty entity SHALL have the mandatory properties and MAY have the optional properties listed in Table {counter:table-num}. +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/observed-property/relations + +Each ObservedProperty entity SHALL have the direct relation between an ObservedProperty entity and other entity types listed in Table {counter:table-num}. +==== + + +[#observed-property-properties,reftext='{table-caption} {counter:table-num}'] +.Properties of an ObservedProperty entity +[width="100%",cols="5,17,3,3,3",options="header"] +|==== +| *Name* | *Definition* | *Data Type* | *Usage* | *Multiplicity* +| `id` | A unique, read-only property that serves as an identifier for the entity. Its value is computed by the server when creating or updating the entity unless specified by the client | ANY | Required | One +| `name` | A property provides a label for ObservedProperty entity, commonly a descriptive name. | String | Required | One +| `definition` | The URI of the ObservedProperty. Dereferencing this URI SHOULD result in a representation of the definition of the ObservedProperty | URI | Required | One +| `description` | A description about the ObservedProperty | String | Optional | Zero-to-one +| `properties` | A JSON Object containing user-annotated properties as key-value pairs | JSON Object | Optional | Zero-to-one +|==== + + +[#observed-property-relations,reftext='{table-caption} {counter:table-num}'] +.Direct relation between an ObservedProperty entity and other entity types +[width="100%",cols="5,5,10,10",options="header"] +|==== +| *Entity Name* | *Role* | *Multiplicity* | *Description* +| `Datastream` | Datastreams | One mandatory to many optional | The Observations of a Datastream observe the same ObservedProperty. The Observations of different Datastreams MAY observe the same ObservedProperty. +|==== + + + + +[[observation]] +==== Observation + +[requirements_class] +==== +[%metadata] +identifier:: {identifier}/req-class/datamodel/sensing/observation +obligation:: requirement +subject:: Target Type: Data Model +requirement:: {identifier}/req/datamodel/sensing/observation/properties +requirement:: {identifier}/req/datamodel/sensing/observation/relations +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/observation/properties + +Each Observation entity SHALL have the mandatory properties and MAY have the optional properties listed in Table {counter:table-num}. +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/observation/relations + +Each Observation entity SHALL have the direct relation between an Observation entity and other entity types listed in Table {counter:table-num}. +==== + + +[#observation-properties,reftext='{table-caption} {counter:table-num}'] +.Properties of an Observation entity +[width="100%",cols="5,17,3,3,3",options="header"] +|==== +| *Name* | *Definition* | *Data Type* | *Usage* | *Multiplicity* +| `id` | A unique, read-only property that serves as an identifier for the entity. Its value is computed by the server when creating or updating the entity unless specified by the client | ANY | Required | One +| `phenomenonTime` | The time instant or period of when the Observation happens. + +Note: Many resource-constrained sensing devices do not have a clock. As a result, a client may omit phenomenonTime when POST new Observations, even though phenomenonTime is a mandatory property. When a SensorThings service receives a POST Observations without phenomenonTime, the service SHALL assign the current server time to the value of the phenomenonTime | TM_Object | Optional | Zero-to-one +| `result` | The estimated value of an ObservedProperty from the Observation. | ANY | Required | One +| `resultTime` | The time of the Observation’s result was generated + +Note: Many resource-constrained sensing devices do not have a clock. As a result, a client may omit resultTime when POST new Observations, even though resultTime is a mandatory property. When a SensorThings service receives a POST Observations without resultTime, the service SHALL assign a null value to the resultTime. | TM_Instant | Optional | Zero-to-one +| `validTime` | The time period during which the result may be used | TM_Period | Optional | Zero-to-one +| `properties` | A JSON Object containing user-annotated properties as key-value pairs (usually showing the environmental conditions during measurement) | JSON Object | Optional | Zero-to-one +|==== + + +[#observation-relations,reftext='{table-caption} {counter:table-num}'] +.Direct relation between an Observation entity and other entity types +[width="100%",cols="5,5,10,10",options="header"] +|==== +| *Entity Name* | *Role* | *Multiplicity* | *Description* +| `Datastream` | Datastream | Many optional to one mandatory | A Datastream can have zero-to-many Observations. One Observation SHALL occur in one-and-only-one Datastream +| `Feature` | ProximateFeatureOfInterest | Many optional to one optional | The Feature observed by the Observation. The relationship is optional and SHALL exist in cases where the observed Feature is a proxy of the actual Feature +|==== + +[additional-notes] +==== +*NOTE*: For an Observation, either the direct ProximateFeatureOfInterest or the indirect UltimateFeatureOfInterest SHALL exist. +==== + + +[[feature]] +==== Feature + +[requirements_class] +==== +[%metadata] +identifier:: {identifier}/req-class/datamodel/sensing/feature +obligation:: requirement +subject:: Target Type: Data Model +requirement:: {identifier}/req/datamodel/sensing/feature/properties +requirement:: {identifier}/req/datamodel/sensing/feature/relations +==== + +An Observation assigns a value to a property of a subject by applying an ObservingProcedure. The subject is the Feature that can take the role of ProximateFeatureOfInterest or ultimateFeatureOfInterest of the Observation [OGC 20-082r4 and ISO 19156:2023]. +In cases where estimating the value of a property of interest is not possible directly, a proxy feature MAY be used. Such an application typically requires Sampling the UltimateFeatureOfInterest such that the observed Feature represents an approximation of the domain feature. +In many sensing applications, the Observations’ Feature can be ambiguous with the Location of the Thing. Thus the concept of roles is introduced to better describe the relationship between an Observation and it's Feature. + +[example%unnumbered] +==== +*Feature Examples* + + +- The Feature of a WiFi enabled thermostat can be the Location of the thermostat (i.e., the living room where the thermostat is located in). However, in such cases, it is recommended to use the Location entity to store this information while the Feature entity (with the role of proximateFeatureOfInterest) can be used to model the ambient indoor atmosphere around the thermostat that approximates the overall room's temperature. + +- In the case of remote sensing, the Feature observed can be the individual geographical parcel or swath that is being sensed, while the Location entity can maintain the larger geographical region that is being monitored. +==== + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/feature/properties + +Each Feature entity SHALL have the mandatory properties and MAY have the optional properties listed in Table {counter:table-num}. +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/feature/relations + +Each Feature entity SHALL have the direct relation between a Feature entity and other entity types listed in Table {counter:table-num}. +==== + + +[#feature-properties,reftext='{table-caption} {counter:table-num}'] +.Properties of a Feature entity +[width="100%",cols="5,17,3,3,3",options="header"] +|==== +| *Name* | *Definition* | *Data Type* | *Usage* | *Multiplicity* +| `id` | A unique, read-only property that serves as an identifier for the entity. Its value is computed by the server when creating or updating the entity unless specified by the client | ANY | Required | One +| `name` | A property provides a label for Feature entity, commonly a descriptive name. | String | Required | One +| `description` | The description about the Feature | String | Optional | Zero-to-one +| `encodingType` | The encoding type of the feature property | String | Required | One +| `feature` | The detailed description of the feature. The data type is defined by encodingType | ANY | Required | Zero-to-one +| `properties` | A JSON Object containing user-annotated properties as key-value pairs | JSON Object | Optional | Zero-to-one +|==== +[#feature-relations,reftext='{table-caption} {counter:table-num}'] +.Direct relation between a Feature entity and other entity types +[width="100%",cols="5,5,10,10",options="header"] +|==== +| *Entity Name* | *Role* | *Multiplicity* | *Description* +| `Observation` | Observations | One optional to many optional | A Feature MAY have zero-to-many Observations. An Observation SHOULD observe at most one Feature +| `Datastream` | Datastreams | One optional to many optional | There MAY be multiple Datastreams observing the same Feature as a Feature MAY have multiple properties of interest. However a Datastream SHOULD link to at most one Feature of interest. +|==== \ No newline at end of file diff --git a/sections/clause_07c_sensing_OM_extension.adoc b/sections/clause_07c_sensing_OM_extension.adoc new file mode 100644 index 0000000..02d19f9 --- /dev/null +++ b/sections/clause_07c_sensing_OM_extension.adoc @@ -0,0 +1,147 @@ +:sectnums: |,all| +:sectanchors: +[[sensing-OM-extension]] +=== Sensing Extension (Observations & Measurements) + +All Sensing Extension (Observations & Measurements) requirements classes are grouped in the following requirements class: + +[requirements_class] +==== +[%metadata] +identifier:: {identifier}/req-class/datamodel/sensing-extension-om +obligation:: requirement +subject:: Target Type: Data Model +requirement:: {identifier}/req-class/datamodel/sensing/deployment +requirement:: {identifier}/req-class/datamodel/sensing/observing-procedure +==== + +[[sensing-entities-om-extn]] +==== Sensing Extension (Observations & Measurements) Entities + +The Sensing Extension (Observations & Measurements) is described by the entities in Figure {counter:figure-num} +[#img-sta-extn,link=images/GRP0002.png, reftext='{figure-caption} {counter:figure-num}', title='Sensing Extension (Observations & Measurements)'] +image::images/GRP0002.png["Sensing Extension (Observations & Measurements)", align="center"] + +[[deployment]] +===== Deployment + +[requirements_class] +==== +[%metadata] +identifier:: {identifier}/req-class/datamodel/sensing/deployment +obligation:: requirement +subject:: Target Type: Data Model +requirement:: {identifier}/req/datamodel/sensing/deployment/properties +requirement:: {identifier}/req/datamodel/sensing/deployment/relations +==== + +A Deployment is the association of Sensors to the Thing that hosts them and produces Datastreams from the associated Sensors. The Deployment entity is optional and the draft does not mandate defining the entity when modelling sensing applications. + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/deployment/properties + +Each Deployment entity SHALL have the mandatory properties and MAY have the optional properties listed in Table {counter:table-num}. +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/deployment/relations + +Each Deployment entity SHALL have the direct relation between a Deployment entity and other entity types listed in Table {counter:table-num}. +==== + +[#deployment-properties,reftext='{table-caption} {counter:table-num}'] +.Properties of a Deployment entity +[width="100%",cols="5,17,3,3,3",options="header"] +|==== +| *Name* | *Definition* | *Data Type* | *Usage* | *Multiplicity* +| `id` | A unique, read-only property that serves as an identifier for the entity. Its value is computed by the server when creating or updating the entity unless specified by the client | ANY | Required | One +| `name` | A property provides a label for Deployment entity, commonly a descriptive name. | String | Required | One +| `description` | The description of the Deployment entity. | String | Optional | Zero-to-one +| `properties` | A JSON Object containing user-annotated properties as key-value pairs | JSON Object | Optional | Zero-to-one +| `position` | The detailed description of the Sensor or system. The metadata type is defined by encodingType | String | Required | One +| `time` | The time instant or period of when the Sensors are deployed and they start producing Datastreams | TM_Object | Optional | Zero-to-one +|==== + + +[#deployment-relations,reftext='{table-caption} {counter:table-num}'] +.Direct relation between a Deployment entity and other entity types +[width="100%",cols="5,5,10,10",options="header"] +|==== +| *Entity Name* | *Role* | *Multiplicity* | *Description* +| `Sensor` | Sensor | Many optional to one mandatory | Each Deployment links to one Sensor in order to maintain information regarding the relative position of the Sensor with respect to the Host (Thing), to record its deployment time and other additional infortmation. If a sensor is redeployed on to the same Host again, the same Datastream MAY be reused but the same Deployment entity cannot be re-used +| `Datastream` | Datastreams | One optional to many optional | The Deployment entity MAY be used to indicate the current state of the zero-to-many Datastreams, whether it is still open or the deployment time has expired +| `Thing` | Host | Many optional to one mandatory | Each Deployment MUST be associated with one and only one Thing. The Thing has the role of the Host as it hosts the associated Sensors +|==== + + +[example%unnumbered] +==== +*Deployment Examples* + +- The assignment of an array of Sensors onto a platform within a Thing that monitors speed limit and driver distraction on a freeway +- The information pertaining to the orientation of moving Sensors when observing moving Features can be described by a Deployment +==== + + +[[observingprocedure]] +===== ObservingProcedure + +[requirements_class] +==== +[%metadata] +identifier:: {identifier}/req-class/datamodel/sensing/observing-procedure +obligation:: requirement +subject:: Target Type: Data Model +requirement:: {identifier}/req/datamodel/sensing/observing-procedure/properties +requirement:: {identifier}/req/datamodel/sensing/observing-procedure/relations +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/observing-procedure/properties + +Each ObservingProcedure entity SHALL have the mandatory properties and MAY have the optional properties listed in Table {counter:table-num}. +==== + + +[requirement] +==== +[%metadata] +identifier:: {identifier}/req/datamodel/sensing/observing-procedure/relations + +Each ObservingProcedure entity SHALL have the direct relation between an ObservingProcedure entity and other entity types listed in Table {counter:table-num}. +==== + + +[#observing-procedure-properties,reftext='{table-caption} {counter:table-num}'] +.Properties of an ObservingProcedure entity +[width="100%",cols="5,17,3,3,3",options="header"] +|==== +| *Name* | *Definition* | *Data Type* | *Usage* | *Multiplicity* +| `id` | A unique, read-only property that serves as an identifier for the entity. Its value is computed by the server when creating or updating the entity unless specified by the client | ANY | Required | One +| `name` | A property provides a label for ObservingProcedure entity, commonly a descriptive name. | String | Required | One +| `definition` | The URI of the ObservingProcedure. Dereferencing this URI SHOULD result in a representation of the definition of the ObservingProcedure | URI | Optional | Zero-to-one +| `description` | A description about the ObservingProcedure | String | Optional | Zero-to-one +| `properties` | A JSON Object containing user-annotated properties as key-value pairs | JSON Object | Optional | Zero-to-one +|==== + + +[#observing-procedure-relations,reftext='{table-caption} {counter:table-num}'] +.Direct relation between an ObservingProcedure entity and other entity types +[width="100%",cols="5,5,10,10",options="header"] +|==== +| *Entity Name* | *Role* | *Multiplicity* | *Description* +| `Datastream` | Datastreams | One mandatory to many optional | The ObservingProcedure can be shared by multiple Datastreams + +The Datastreams can also be partitioned by the multiple ObservingProcedures used by the same Sensor for the same ObservedProperty +| `ObservedProperty` | ObservedProperties | Many optional to many mandatory | ObservingProcedure MAY be reused for observing one-to-many ObservedProperties +| `Sensor` | Sensors | Many optional to many optional | A Sensor MAY measure an ObservedProperty using zero-to-many ObservingProcedures +|==== diff --git a/sections/clause_07c_sampling_entities.adoc b/sections/clause_07d_sampling_entities.adoc similarity index 100% rename from sections/clause_07c_sampling_entities.adoc rename to sections/clause_07d_sampling_entities.adoc diff --git a/sections/clause_07d_actuation_entities.adoc b/sections/clause_07e_actuation_entities.adoc similarity index 100% rename from sections/clause_07d_actuation_entities.adoc rename to sections/clause_07e_actuation_entities.adoc