
Revision 4.1.0, 2026-09-03
## Abstract
This specification defines a lightweight data format for representing sensor network objects in Sensor Network Object Notation (SNON). Representations are defined in JavaScript Object Notation (JSON) using the SNON data model. A complex system of sensor network devices can use SNON for hierarchical and peer-to-peer sensor discovery and inventory to create self-describing graphs of the sensor network topology and the measurement characteristics and values for the sensors and series they contain.
## Table of Contents
1. [Introduction to SNON](#intro)
1.1 [What is SNON?](#intro.what)
1.2 [How does SNON compare to other standards?](#intro.for)
1.3 [Why use SNON?](#intro.why)
1.4 [What does SNON look like?](#intro.examples)
1.5 [How are SNON fragments related?](#intro.related)
1.6 [How are SNON fragments used?](#intro.used)
1.7 [SNON Terms and Definitions](#intro.terms)
2. [SNON Data Model](#data)
2.1 [SNON Fragments](#data.fragments)
2.2 [SNON Packs](#data.packs)
2.3 [Common SNON Fields](#data.entity)
2.4 [Value SNON Fields](#data.value)
2.5 [Series SNON Fields](#data.series)
2.6 [Sensor SNON Fields](#data.sensor)
2.7 [Measurand SNON Fields](#data.measurand)
2.8 [Device SNON Fields](#data.device)
2.9 [Location SNON Fields](#data.location)
2.10 [Relationship SNON Fields](#data.rel)
3. [SNON Entity Relationships](#rel)
3.1 [Relationship Model](#rel.model)
3.2 [General Relationships](#rel.general)
3.3 [Series and Sensor Relationships](#rel.series)
3.4 [Custom Relationships](#rel.custom)
4. [SNON Examples](#examples)
5. [SNON Schema](#schema)
6. [SNON Security](#security)
6.1 [Encryption and Signing](#security.encryption)
6.2 [PKI](#security.pki)
7. [SNON Transports](#transports)
7.1 [Serial](#transports.serial)
7.2 [CloudEvents](#transports.cloudevents)
7.3 [MQTT](#transports.mqtt)
8. [SNON License](#license)
9. [SNON Changelog](#changelog)
## 1. Introduction to SNON
### 1.1 What is SNON?
SNON (Sensor Network Object Notation) is an open and interoperable data representation for sensor network data exchange.
SNON defines a transport-agnostic message-fragment-based data exchange format for interoperable data exchange between the participants in a sensor network, such as measuring instruments, edge devices, gateways, processing devices, control systems, databases, historians, dashboards, visualization and reporting engines.
Terms used in this specification are defined in [Section 1.7](#intro.terms). Note in particular that "sensor" denotes a part of a device rather than a complete instrument.
#### What use cases is SNON designed for?
* Representing sensor topologies, devices, sensors, series and values
* Enabling discovery of sensor topologies, devices, sensors and series
* Managing changes in sensor topologies and relationships over time
* Encapsulating sensor data for transport, e.g. over serial protocols, [MQTT](https://mqtt.org/) or [CloudEvents](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md)
* Enabling efficient bulk transport of summarized and aggregated sensor data
* Providing source attestation and secured transport of sensor data
#### What is SNON not intended to solve?
SNON occupies one layer of a larger stack. It is a data model together with a JSON encoding of that model, and as such, it is not a transport, not a service interface, and not an ontology:
* Because SNON is not a transport, it does not define how bytes reach their destination. Fragments are carried over whatever transport a system already uses, with [Section 7](#transports) providing bindings for serial links, MQTT and CloudEvents. SNON fragments and packs may equally be sent over HTTP, WebSockets, or written to files, as needed.
* Because SNON is not a service interface, it does not require a server, a session, or a request/response exchange. A fragment is self-contained and self-identifying. This makes SNON usable over one-way and broadcast links such as radio telemetry, RS-485 multidrop connections and satellite downlinks, where a query-based API cannot operate at all.
* Because SNON is not an ontology, it does not require RDF processing, a reasoner, or a shared vocabulary beyond the measurement units and quantity conventions of [ISO 80000-1:2009](https://www.iso.org/standard/30669.html) and [ISO/IEC Guide 99:2007](https://www.iso.org/obp/ui/#iso:std:iso-iec:guide:99:ed-1:v2:en). A device with a few kilobytes of program space can emit conformant SNON.
### 1.2 How does SNON compare to other standards?
| Standard | Scope | Relationship to SNON |
| -------- | ----- | -------------------- |
| [SenML (RFC 8428)](https://datatracker.ietf.org/doc/html/rfc8428) | Compact representation of measurements and parameters | Overlapping scope at the value level. SenML is deliberately minimal and carries no discovery or topology model. SNON entity IDs and SenML names are interchangeable; see [Section 2.4](#data.value). |
| [OGC SensorThings API](https://docs.ogc.org/is/18-088/18-088.html) | REST service interface for sensor observations and metadata | Closest conceptual model. An SNON series corresponds closely to a SensorThings Datastream, and an SNON measurand to an ObservedProperty. SensorThings specifies a server and a query language; SNON specifies only a lightweight representation. |
| [W3C/OGC SSN and SOSA](https://www.w3.org/TR/vocab-ssn/) | Ontology for sensors, observations, samples and actuators | Semantic layer above SNON. SNON fragments can be mapped to SOSA classes where linked data processing is required, without imposing that cost on constrained devices. |
| [W3C WoT Thing Description](https://www.w3.org/TR/wot-thing-description/) | Machine-readable description of a Thing's interfaces and metadata | Complementary. A Thing Description says how to interact with a device; SNON says what the device measures and what it measured. |
| [Eclipse Sparkplug (ISO/IEC 20237)](https://sparkplug.eclipse.org/) | MQTT topic namespace, payload and session state model for industrial IoT | Overlapping scope over MQTT. Sparkplug derives identity from topic position and requires session state, birth certificates and sequence numbers. SNON fragments carry their own identity and may be processed in any order. |
| [OPC UA (IEC 62541)](https://opcfoundation.org/) | Address space, information model and services for industrial automation | Richer and heavier weight, and difficult to implement in resource-limited embedded devices that communicate over intermittent and one-way communication channels. SNON targets deployments where an OPC UA server is impractical, and can act as an export representation from one and a data source to one. |
| [i3X (CESMII)](https://www.i3x.dev/) | Vendor-agnostic API for browsing, reading, writing and subscribing to contextualized manufacturing information | Complementary, at a higher layer. i3X standardizes how applications query an information platform; SNON standardizes what a device publishes into one. An i3X server can expose SNON-sourced data as typed instances, and SNON can act as the device-side representation feeding it. |
| [ISO/IEC 81346](https://www.iso.org/standard/82229.html), [ANSI/ISA-5.1](https://www.isa.org/isa5-1/) | Reference designation and instrument tagging conventions | Adopted, not replaced. Carried in the sensor tag, device tag and location tag fields. |
| [CloudEvents](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md), [MQTT](https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html), [JOSE](https://tools.ietf.org/html/rfc7515) | Event envelope, messaging, signing and encryption | Used directly. SNON defines bindings rather than substitutes. |
### 1.3 Why use SNON?
Three properties distinguish SNON from the representations above.
Fragments are order-independent. Every fragment carries the entity ID of what it describes, so a receiver that processes the same set of fragments in any order arrives at the same state. There is no session to establish, no sequence number to track, and no cost to a receiver joining a stream part-way through.
Description is separated from measurement. Series, sensor, measurand, device and location fragments describe the network; value fragments carry readings. A description is sent once and cached, so a sensor reporting every second does not resend its unit, range and accuracy every second.
Self-description is multi-lingual and optional. Display names, units and enumeration labels may be given in any number of languages simultaneously, and every descriptive field may be omitted where it is not needed.
In summary:
* SNON is easy for people to read and write
* SNON is easy for machines to parse and generate
* SNON is multi-lingual and supports self-description using multiple languages at the same time
* SNON is highly compressible, to reduce storage and network usage
* SNON is based on [JSON](https://json.org/), which is widely supported by most platforms and programming languages
* SNON is sensor independent, and uses conventions familiar to programmers who have worked with common sensor platforms
* SNON is self-describing and extensible, with features only required when needed
* SNON makes sensor data exchange interoperability easy
### 1.4 What does SNON look like?
SNON consists of a series of "fragments" (JSON objects) that specify the topology and historical state of a sensor network. SNON fragments can be processed in any order, and as long as the same set of fragments are processed at least once, every SNON fragment receiver will converge to the same eventually-consistent state without requiring any additional coordination.
Here are some examples of SNON in action:
#### Example 1.4.1a: Value fragment containing a single measured value
[
{
"eID": "urn:uuid:cd9f930e-a3b4-423a-850b-3c81135f0f7e",
"v": ["28.1"],
"vT": ["2014-08-20T14:32:57.126532Z"]
}
]
This value fragment represents a single sampled measurement taken at a given point in time.
#### Example 1.4.1b: Value fragment containing multiple measured values
[
{
"eID": "urn:uuid:cd9f930e-a3b4-423a-850b-3c81135f0f7e",
"v": ["29.1", "28.9", "27.5", "28.1"],
"vT": ["2014-08-20T14:32:11.462734Z", "2014-08-20T14:32:28.842937Z", "2014-08-20T14:32:39.278485Z", "2014-08-20T14:32:57.126532Z"]
}
]
This value fragment represents four sampled measurements, taken at four different points in time. This is equivalent to four single-value fragments such as that shown in example 1.4.1a, and is typically stored as four separate values.
#### Example 1.4.1c: Value fragment containing a summary of multiple measured values
[
{
"eID": "urn:uuid:cd9f930e-a3b4-423a-850b-3c81135f0f7e",
"v": ["28.4"],
"vMax": ["29.1"],
"vMin": ["27.5"],
"vT": ["2014-08-20T14:32:00.000000Z/PT1M"]
}
]
This value fragment represents a time interval, and summarizes all of the samples taken within that time interval.
#### Example 1.4.1d: Interoperability with SenML measurements
[
{
"n": "urn:uuid:cd9f930e-a3b4-423a-850b-3c81135f0f7e",
"v": 28.4,
"t": 1.276020076e+09
}
]
To integrate SenML records into the SNON model, the SenML name is used as the SNON entity ID. Note that SenML records that depend on a base name cannot be processed out of order.
#### Example 1.4.2: Series fragment identifying measurements of a measurand by a sensor
[
{
"eID":"urn:uuid:cd9f930e-a3b4-423a-850b-3c81135f0f7e",
"eC": "series",
"eN": {"zh": "冷却水温度", "*": "Cooling Water Temperature"},
"eR": {
"child_of": ["urn:uuid:1c43d52a-ad3b-465e-a230-868251251f94"],
"measurand": ["urn:uuid:e079baf5-a894-4539-a3ce-7d7c7efdb3b3"]
}
}
]
This series fragment represents a series named "Cooling Water Temperature" (in English) that is measured by a specific sensor (see Example 1.4.4), and has measured values for a specific quantity (see Example 1.4.3). As this fragment has the same Entity ID as the value fragments in example 1.4.1, that means that those values are associated with this series.
#### Example 1.4.3: Measurand fragment representing a quantity of measurement
[
{
"eID": "urn:uuid:e079baf5-a894-4539-a3ce-7d7c7efdb3b3",
"eC": "measurand",
"eN": { "*": "Temperature" },
"meU": "°C",
"meT": "numeric",
"meAq": "sample",
"meDU": { "en-us": "°F", "*": "°C" },
"meUS": { "en-us": " ℉", "*": " ℃" },
"meUSx": { "en-us": " degrees Fahrenheit", "*": " degrees Celsius" }
}
]
This measurand (a definition of the quantity to be measured) fragment represents measurements of temperature.
#### Example 1.4.4: Sensor fragment representing the sensing element of a measuring instrument
[
{
"eID": "urn:uuid:1c43d52a-ad3b-465e-a230-868251251f94",
"eC": "sensor",
"eN": {"*": "Cooling Supply Temperature Element"},
"eR": {
"child_of": ["urn:uuid:324875ea-034c-401e-aec7-eb010de6a2c8"],
"measurand": ["urn:uuid:e079baf5-a894-4539-a3ce-7d7c7efdb3b3"]
},
"sT": "TE1123"
}
]
This sensor fragment represents the sensing element, within the device in Example 1.4.5, that measures the temperature of the cooling water supply.
#### Example 1.4.5: Device fragment representing a physical device
[
{
"eID": "urn:uuid:324875ea-034c-401e-aec7-eb010de6a2c8",
"eC": "device",
"eN": {"*": "Cooling Supply Temperature Monitor"},
"eR": {
"child_of": ["urn:uuid:385bbd11-568c-4508-a1b9-9c3d8f4e3e57"]
}
}
]
This device fragment represents a physical (or logical) device that includes a collection of devices and/or sensors.
#### Example 1.4.6: Location fragment representing the location of a device
[
{
"eID": "urn:uuid:385bbd11-568c-4508-a1b9-9c3d8f4e3e57",
"eC": "location",
"eN": {"*": "Level 2, bay 4"}
}
]
This location fragment represents a location of a device.
See [Section 4](#examples) for more examples.
### 1.5 How are SNON fragments related?

Figure 1 - Fragment Relationships
Each fragment has the following primary relationships:
* Each value fragment is associated with one series or one sensor fragment by entity ID
* Each series fragment is associated with zero or more value fragments by entity ID
* Each series fragment is associated with zero or one measurand fragment by relation
* Each series fragment is associated with one sensor fragment by relation
* Each sensor fragment is associated with zero or more value fragments by entity ID
* Each sensor fragment is associated with zero or more series fragments by relation
* Each sensor fragment is associated with zero or one measurand fragment by relation
* Each sensor fragment is associated with zero or more device fragments by relation
* Each measurand fragment is associated with zero or more series fragments by relation
* Each measurand fragment is associated with zero or more sensor fragments by relation
* Each device fragment is associated with zero or more device fragments by relation
* Each device fragment is associated with zero or more location fragments by relation
* Each device fragment is associated with zero or more sensor fragments by relation
* Each location fragment is associated with zero or more device fragments by relation
* Each location fragment is associated with zero or more location fragments by relation
See [Section 3](#rel) for details on additional relationships.
### 1.6 How are SNON fragments used?
When an SNON fragment sender wants to forward sensor data to an SNON fragment receiver, the sender constructs SNON fragments, packages them together into packs when supported, and transports these fragments or packs over transport protocols such as MQTT, Websockets, HTTP, etc.
There are three primary use cases:
1. Sensor definition publishing - An SNON fragment sender publishes series, sensor, measurand, device and location fragments that are used to create/update a sensor catalog.
2. Sensor value publishing - An SNON fragment sender publishes values for one or more series.
3. Sensor value subscription - An SNON fragment receiver receives values for one or more series, and sets an actuator.
### 1.7 SNON Terms and Definitions
For the purposes of this document, the following terms and definitions apply.
Terms taken from [ISO 80000-1:2009](https://www.iso.org/standard/30669.html) and [ISO/IEC Guide 99:2007](https://www.iso.org/obp/ui/#iso:std:iso-iec:guide:99:ed-1:v2:en) (VIM) are reproduced with their source. Where SNON uses a term in a narrower or different sense than common industry usage, this is stated in a NOTE.
#### Metrological terms
**1.7.1 quantity**
Property of a phenomenon, body or substance, where the property has a magnitude that can be expressed as a number and a reference.
[SOURCE: ISO/IEC Guide 99:2007, 1.1]
**1.7.2 quantity value**
Number and reference together expressing the magnitude of a quantity.
[SOURCE: ISO/IEC Guide 99:2007, 1.19]
NOTE: In SNON, the number is carried in a value field and the reference is carried by the measurement unit of the measurand.
**1.7.3 measurement unit**
Real scalar quantity, defined and adopted by convention, with which any other quantity of the same kind can be compared to express the ratio of the two quantities as a number.
[SOURCE: ISO/IEC Guide 99:2007, 1.9]
**1.7.4 measurement**
Process of experimentally obtaining one or more quantity values that can reasonably be attributed to a quantity.
[SOURCE: ISO/IEC Guide 99:2007, 2.1]
**1.7.5 measurand**
Quantity intended to be measured.
[SOURCE: ISO/IEC Guide 99:2007, 2.3]
NOTE: SNON represents a measurand as an SNON measurand fragment (1.7.16). The measurand describes what is being measured, not what is doing the measuring.
**1.7.6 measuring instrument**
Device used for making measurements, alone or in conjunction with one or more supplementary devices.
[SOURCE: ISO/IEC Guide 99:2007, 3.1]
NOTE: SNON represents a measuring instrument as an SNON device fragment (1.7.18).
**1.7.7 measurement resolution**
Smallest change in a quantity being measured that causes a perceptible change in the corresponding indication.
[SOURCE: ISO/IEC Guide 99:2007, 4.14]
NOTE: Carried in the measurement resolution ("meR") field.
**1.7.8 maximum permissible measurement error**
Extreme value of measurement error, with respect to a known reference quantity value, permitted by specifications or regulations for a given measurement, measuring instrument, or measuring system.
[SOURCE: ISO/IEC Guide 99:2007, 4.26]
NOTE: Carried in the measurement accuracy ("meAc") field. ISO/IEC Guide 99:2007, 2.13 defines measurement accuracy as a qualitative concept that is not given a numerical value, so SNON does not use that term for a field value.
#### SNON terms
**1.7.9 SNON fragment**
JSON object conforming to this specification that describes an entity or carries measured values for an entity.
**1.7.10 SNON pack**
JSON array containing one or more SNON fragments.
**1.7.11 SNON entity**
Anything that SNON can describe and that is identified by an entity ID.
**1.7.12 SNON entity ID**
Globally unique URN identifying an entity.
**1.7.13 SNON entity class**
Kind of SNON entity, identified by the value of the entity class ("eC") field of an SNON fragment.
NOTE 1: The entity classes defined by this specification are "value", "series", "sensor", "measurand", "device", "location" and "relationship".
NOTE 2: The entity class "value" identifies a fragment that carries values for a series or sensor entity. It does not identify an entity of its own; a value fragment carries the entity ID of the series or sensor whose values it reports. Every other entity class identifies an entity with its own entity ID.
**1.7.14 measurement type**
Kind of data represented by a value, determining how the contents of the value, value max and value min fields are to be interpreted.
NOTE 1: The measurement types defined by this specification are "enumeration", "numeric", "string", "url", "iso8601" and "ordinal". Carried in the measurement type ("meT") field of a measurand. Where no measurand is related, or where the related measurand does not specify a measurement type, the measurement type is "numeric".
NOTE 2: The measurement type is a property of the measurand, not of an individual value. All values for a series or sensor share one measurement type.
NOTE 3: Not to be confused with the entity class (1.7.13), which identifies the kind of entity, or with the entity display type ("eT") field, which carries a human-readable description of the kind of entity.
**1.7.15 SNON value**
SNON fragment carrying one or more measured values, together with the time at which each was measured, calculated or summarized, for the series or sensor identified by its entity ID.
**1.7.16 SNON measurand**
SNON entity describing a measurand, including its measurement unit, data type and display characteristics.
**1.7.17 SNON sensor**
SNON entity representing the part of a device that performs measurements of a single measurand.
NOTE 1: An SNON sensor corresponds to the sensing element of a measuring instrument (ISO/IEC Guide 99:2007, 3.8), not to a complete instrument. A temperature transmitter is represented in SNON as a device containing one or more sensors, even though such a product is commonly called "a sensor" in general industry usage. The complete instrument is represented as an SNON device.
NOTE 2: A sensor may carry values directly by entity ID where no separate series identity is required.
**1.7.18 SNON device**
SNON entity representing a physical or logical measuring instrument, which may contain sensors and other devices.
**1.7.19 SNON location**
SNON entity representing a place at which a location, device or sensor is situated. Locations can be nested.
**1.7.20 SNON series**
SNON entity identifying the ongoing measurement of one measurand by one sensor, to which value fragments are associated by entity ID.
NOTE 1: An SNON series is an identity, not a container. A series fragment holds no values; value fragments carry the same entity ID as the series they belong to. A series exists as soon as it is described, whether or not any value has been measured, and is not bounded in time.
NOTE 2: An SNON series is not a series of measurements in the metrological sense. A metrological series is a bounded set of replicate measurements taken under stated conditions in order to characterise repeatability; an SNON series makes no claim about the conditions under which its values were obtained. The metrological sense corresponds more closely to a single summary value (1.7.22).
NOTE 3: An SNON series is not a chart series. A chart series is a presentation grouping chosen by whoever draws the chart and may be resampled, filtered or assembled from several sources. A chart series is commonly rendered from one SNON series, but several SNON series may be combined into one chart series, and one SNON series may be rendered as several.
NOTE 4: An SNON series corresponds closely to the identity of a time series in time series storage systems, and to a datastream in sensor observation interfaces.
**1.7.21 SNON relationship**
Directed association between two SNON entities, expressed either in the entity relationships field of an SNON fragment or as an SNON relationship fragment.
**1.7.22 summary value**
Value whose value time specifies a time interval rather than a point in time, and which reports a summarization of the measurements taken during that interval, such as a min, max and average value.
**1.7.23 immediate value update**
Request to set the value of a series or sensor, sent as a value fragment in which the value time field is omitted or specifies a time that has already passed, and which is applied by the receiving fragment sender at the time the request is received.
NOTE 1: An immediate value update is a request, not a report of a measurement. It is the only case in which the value time field may be omitted from a value fragment, and it is therefore not required to satisfy the value fragment schema.
NOTE 2: A request specifying a value time in the future is not an immediate value update; it is applied when that time is reached.
NOTE 3: Only a single value may be set by an immediate value update.
**1.7.24 numeric string**
JSON string containing the representation of a single number.
NOTE 1: A numeric string consists of an optional sign, an integer part, an optional fractional part introduced by a decimal point, and an optional exponent introduced by "e" or "E" with an optional sign. A trailing decimal point with no following digits is not permitted. "1500", "1.5e3", "+007" and "-1.5E-3" are all numeric strings.
NOTE 2: An SNON fragment receiver shall accept exponent notation wherever a numeric string is permitted. An SNON fragment sender should not use exponent notation where a representation without an exponent is available, as some receivers do not handle it correctly.
NOTE 3: A numeric string is not required to be normalized. "1500", "1.5e3" and "1.500e3" all represent the same number, and a receiver shall treat them as equal in value. They are not interchangeable as strings: the written form carries significant figures, and altering it invalidates any signature over the fragment.
NOTE 4: The representations "NaN", "Infinity" and "-Infinity" are not numeric strings and shall not be used. Where a measurement cannot be represented, the value error ("vE") field is used instead.
#### Roles
**1.7.25 SNON fragment sender**
Implementation that generates SNON fragments and makes them available to fragment receivers.
**1.7.26 SNON fragment receiver**
Implementation that accepts SNON fragments and applies them to its own state.
## 2. SNON Data Model
### 2.1 SNON Fragments
SNON defines seven "fragments": JSON objects used to exchange data between fragment senders and fragment receivers within a sensor network.
* [value fragment](#data.value) - Represents one or more *measurements* for a given *series* or *sensor* identified by its entity ID
* [series fragment](#data.series) - Identifies the ongoing measurement of one *measurand* by one *sensor*
* [sensor fragment](#data.sensor) - Represents the part of a *device* that performs *measurements* of a single *measurand*
* [measurand fragment](#data.measurand) - Represents a *measurand*, the quantity intended to be measured
* [device fragment](#data.device) - Represents a *measuring instrument*, which may contain sensors and other devices
* [location fragment](#data.location) - Represents a place at which a location, device or sensor is situated
* [relationship fragment](#data.rel) - Represents a *relationship* between two SNON entities
SNON fragments may be transported using other protocols such as [CloudEvents](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md). See [Section 7](#transports) for more details on how SNON works with transport protocols.
An SNON fragment receiver keeps track of each entity ID received, together with its corresponding non-value fragment. When a subsequent non-value fragment is received, it shall become the active version only when its eUT is newer in time than that of the active version (a fragment without an eUT has an implicit eUT of 1970-01-01T00:00:00Z), and the version it replaces may be kept as a historical record; otherwise it may be stored as a historical record. A fragment identical to one already stored shall not be stored again. An SNON fragment sender shall not send two different non-value fragments with the same entity ID and eUT.
Value fragments shall be stored without replacement. A value identical to one already stored for the same entity ID and value time shall not be stored again.
An SNON fragment receiver shall not discard a value fragment because of other non-value fragments it has or has not yet received. For example, a value fragment is accepted even if a non-value fragment with the same entity ID has not yet been received.
### 2.2 SNON Packs
SNON defines a "pack": A JSON array containing one or more SNON fragments.
SNON pack may be signed and/or encrypted using the JOSE JWE and JWS standards, as described in [Section 6](#security).

Figure 2 - SNON Object Model
#### Example 2.2.1: An SNON pack with two fragments
[
{
"eID":"urn:uuid:cd9f930e-a3b4-423a-850b-3c81135f0f7e",
"eC": "series",
"eN": {"zh": "冷却水温度", "*": "Cooling Water Temperature"}
},
{
"eID": "urn:uuid:cd9f930e-a3b4-423a-850b-3c81135f0f7e",
"v": ["28.1"],
"vT": ["2014-08-20T14:32:57.126853Z"]
}
]
#### Example 2.2.2: An encrypted SNON pack using JOSE JWE encryption
[
{
"encrypted_key": "YO03wcQVvap0_Z1i06zS9P9zy3FL8j1-3DeKpimAsgz4cM2Q4mHK7jdqLYaLVjHFf4jPT2PwV1Vm1DRPdT0H93qWO2fACX1Z5q0eGYaO15g91pd4HYXwTIfCkQL2uCGOzIvi7lbuiaV9kqCoAOkEeD-IPEmAXXAFPaY4UY4Jlw28KXdHj9JKVaLZhPnAwv6i59TOxOCAlrbhRSKXDzmzHXxK7hoo6N2dfxbQiTY7m7aYj_c-XwvcBf-x1i5vJ15BID4oUEZizvCT5EG1nZ3CF0xGfEc_8uQFa1lAY4rog3LqTtCYq2pvrEsCnpFfxRSwbh57gxy0T7ejnG_oSNL-dQ",
"iv":"G7qbtZKCry2IQvmL",
"protected":"eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4R0NNIn0",
"tag":"YFxioUzLdUfCMSJdm5eVjw",
"ciphertext":"H6HMYwGUY6y8vZeBT9w8D-nhu9irDT3qI7tWXElI2SR_AgaeQN-Im3AsTh4Wcf72imd466wspYoKRl-EptHNPfYHg2WxOOfVSC3iZwR7ovRHZ-3E_U9La4AY0_9fnKXDN_d0g8ssHhks6exEiJYWQfFyEs_V57wsIXEmelFXxbHBq7vkFptIxITYVvDOa_LsQ5eu5AnFXYRKdHE9Ih8E4qAs6b8KslZ3vVd06Kn0PApBmEOo56IF_0mgDMfv_RuMDfXrdnl83p5bffCX3qoyfxquLRT-fYFiNb5au9IaA1HOpKuJa-QkfcyWVz2u8ATtfrCS9TdYfDkgRHPCAzZEf0AUJejGhEIOT2l4Dr2tmK3_NDodqetYT9C298P2RiWqdx6p4doPMWOWb4iwm0kzcPnNqqu97OQyLofjHR4vJ2VsWibmMz6hTKnLooarpAjGylFaTO4KocAm0ybuMrQueldsk1nD7BYfzrrsIeWlVf5TYHyYbG7nJ4PgEVQV4PwoTVabrcRnJhrDNV5nC_mBYCKpdLnrSTlmiDn1-VtkrF7mdKR1NcRB9TWSCtO9Nj0ldLkalZy-tDXS4zrOoMz1Mm9_ol8Cw9Bih3agg4yFXppI5pxay_U8yOZ0oVYzIIP0DP0bVaLMv2WkjVDRJXIM8oupzgNM-k_ThTfwhkGq5NJSBsBvvRjl_gvYvfvc1fEIR7fcr_XIsqM5G4XbeniezeAWXi6olRLUV_wezJMa7U0eqAjGde4mAFRn3IjtUJvkbl-0ea8hbH7nqbsO3Mo"
}
]
### 2.3 Common SNON Fields
All SNON Fragments may contain the following JSON fields:
| Field Name | Label | JSON Type | Description | Mandatory |
| ------------- | ------------- | ------------- | ------------- | --------- |
| Entity ID | eID | JSON String | Globally unique identifier of the entity.
Uniquely identifies the entity, allowing SNON fragment receivers to determine which device the fragment contents or relationship applies to. Every SNON fragment sender shall ensure that each entity ID is globally unique by using a technique such as random or MAC-based UUID generation as described in [RFC 4122](https://tools.ietf.org/html/rfc4122), a hash-based URN namespace such as urn-5, or a urn namespace that permits unique identification such as the [RFC 9039](https://datatracker.ietf.org/doc/html/rfc9039) "dev" namespace.
The value of this field shall be formatted as an [RFC 8141](https://tools.ietf.org/html/rfc8141) URN.
Example 2.3.1{
"eID": "urn:uuid:cd9f930e-a3b4-423a-850b-3c81135f0f7e"
} | Mandatory |
| Entity class | eC | JSON String | SNON Fragment type.
Identifies what the entity represents.
The value of this field shall be one of the following strings:
a) "value"
b) "series"
c) "sensor"
d) "measurand"
e) "device"
f) "location"
g) "relationship"
If this field is not present, the default value shall be "value".
Example 2.3.2{
"eC": "series"
} | Mandatory
(optional for value fragments) |
| Entity update time | eUT | JSON String | Time when the entity was updated.
Indicates when an entity was changed.
The value of this field shall contain a JSON String with the value of the update time in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) extended representation date/time format ("YYYY-MM-DDTHH:MM:SS.ssssssZ").
In most sensor systems, non-value entities are immutable. However, when entities change over time, this field is mandatory in order to provide eventually consistent state when processing fragments out-of-order. This allows for the determination of each time ranges when a different version of the entity is in effect.
Example 2.3.3{
"eUT": "2014-08-20T14:32:57.126853Z"
} | Mandatory on change
(Not permitted in value fragments) |
| Entity display name | eN | JSON Object | Descriptive Name of the entity.
Provides a set of human-readable names that describe the entity, allowing SNON fragment receivers to list and identify the entity to end users.
The value of this field shall contain one or more JSON Strings, each with a name specifying the language tag as defined in [RFC 5646](https://tools.ietf.org/html/rfc5646), and a value containing a descriptive name of the entity in that language-region.
A name of "*" is used as a default language-region, as defined in [RFC 4647](https://tools.ietf.org/html/rfc4647).
Example 2.3.4{
"eN": {
"zh": "冷却水温度",
"en": "Cooling Water Temperature"
}
} | Optional
(Not permitted in value fragments) |
| Entity display type | eT | JSON Object | Descriptive Name of the type of the entity.
Provides a set of human-readable names that describe the entity type.
The value of this field shall contain one or more JSON Strings, each with a name specifying the language tag as defined in [RFC 5646](https://tools.ietf.org/html/rfc5646), and a value containing a descriptive name of the entity in that language-region.
A name of "*" is used as a default language-region, as defined in [RFC 4647](https://tools.ietf.org/html/rfc4647).
Example 2.3.5:{
"eT": {
"zh": "温度传感器",
"en": "Temperature Sensor"
}
} | Optional
(Not permitted in value fragments) |
| Entity relationships | eR | JSON Object containing JSON Arrays of JSON Strings | Globally unique identifiers of related entities.
Identifies relationships between entities. Each relationship is a JSON object with the name specifying the type of relationship, and the value containing an array of URIs specifying the related entities. Relationships are described in more detail in [Section 3](#rel).
The value of each ID shall be formatted as an [RFC 8141](https://tools.ietf.org/html/rfc8141) URN.
Example 2.3.6{
"eR": {
"child_of": ["urn:uuid:cd9f930e-a3b4-423a-850b-3c81135f0f7e"]
}
} | Optional
(Not permitted in value fragments) |
| Extensions | ext | JSON Object | Contains user-defined fields extending a fragment.
Example 2.3.7{
"ext": {
"modbus": {
"unitID": "1",
"address": "7036",
"type": "IF32"
}
}
} | Optional |
### 2.4 Value SNON Fields
Value SNON fragments may also contain the following JSON fields:
| Field Name | Label | JSON Type | Description | Mandatory |
| ------------- | ------------- | ------------- | ------------- | --------- |
| Value time | vT | JSON Array of JSON Strings | Indication of one or more points in time or durations in time associated with measured values.
Provides an indication of when values were measured.
The value of this field shall contain one or more JSON Strings, with the contents of each string corresponding to the time a value was measured, in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) extended representation date/time format ("YYYY-MM-DDTHH:MM:SS.ssssssZ"), or time interval format (e.g. "YYYY-MM-DDTHH:MM:SS.ssssssZ/PTxx.xxxxxxS").
When multiple times are included in a value fragment, subsequent value times can be in time interval format (e.g. "YYYY-MM-DDTHH:MM:SS.ssssssZ/PTxx.xxxxxxS") or relative time interval format (e.g. "PTxx.xxxxxxS"). Fractional seconds are optional and can be variable length. All value array fields shall have the same number of entries, with the order consistent across fields.
Example 2.4.1{
"v": ["10", "11", "12"],
"vT": ["2014-08-20T14:32:56Z", "2014-08-20T14:32:57Z/PT1S", "PT1S"]
} | Mandatory
Not required for section 7.1 device update requests |
| Value | v | JSON Array of JSON Strings | Indication of one or more values measured from the sensor.
Provides an indication of a measured value at a given point in time.
The value of this field shall contain one or more JSON Strings, with the contents of each string corresponding to the measurement type. All value array fields shall have the same number of entries, with the order consistent across fields.
If a min and max are provided, the value represents the average value over the acquisition period specified in the value time field.
Example 2.4.2{
"v": ["10"],
"vT": ["2014-08-20T14:32:56.125853Z"]
} | Mandatory |
| Value max | vMax | JSON Array of JSON Strings | Indication of one or more maximum values measured from the sensor.
Provides an indication of a maximum measured value during a given interval in time. Min/Max/Average values are typically used when sensor samples a value at a higher rate then is reported, and when the envelope contains important information.
The value of this field shall contain one or more JSON Strings, with the contents of each string corresponding to the measurement type. All value array fields shall have the same number of entries, with the order consistent across fields.
Example 2.4.3{
"v": ["10"],
"vMax": ["12"],
"vMin": ["8"],
"vT": ["2014-08-20T14:32:56.125853Z"]
} | Optional |
| Value min | vMin | JSON Array of JSON Strings | Indication of one or more minimum values measured from the sensor.
Provides an indication of a minimum measured value during a given interval in time. Min/Max/Average values are typically used when sensor samples a value at a higher rate then is reported, and when the envelope contains important information.
The value of this field shall contain one or more JSON Strings, with the contents of each string corresponding to the measurement type. All value array fields shall have the same number of entries, with the order consistent across fields.
Example 2.4.4{
"v": ["10"],
"vMax": ["12"],
"vMin": ["8"],
"vT": ["2014-08-20T14:32:56.125853Z"]
} | Optional |
| Value timeout | vTo | JSON Array of JSON Strings | Indication of the timeout associated with each value.
Provides a measure of how long a given value should be considered valid. If the specified time duration since the value time has been exceeded, the corresponding value shall no longer be considered valid.
When present, this field overrides a measurement timeout field.
The value of this field shall contain one or more JSON Strings, each containing a numeric string measured in seconds.
Example 2.4.5{
"v": ["10"],
"vT": ["2014-08-20T14:32:56.125853Z"],
"vTo": ["0.1"]
} | Optional |
| Value error | vE | JSON String | Indication that errors are present.
Provides an indication of errors associated with value or set of values.
The value of this field shall contain a string describing the error. The contents of the error string is sensor-dependent.
Example 2.4.6{
"v": ["10"],
"vT": ["2014-08-20T14:32:56.125853Z"],
"vE": "Out of Calibration"
} | Optional |
Value, value max, value min and value timeout fields carrying numeric or ordinal measurements are numeric strings (see [Section 1.7](#intro.terms)). SNON receivers shall compare them by numeric value rather than by string equality, and shall not rewrite them in place: a numeric string is reproduced exactly as received when a fragment is forwarded, and when a signature over that fragment is verified.
Value fragments shall contain an "eID" field and may include an "eC" field set to "value".
#### Value Fragment Schema
"value_fragment": {
"type": "object",
"required": [
"eID",
"v",
"vT"
],
"properties": {
"eID": { "$ref": "#/$defs/type_id" },
"eC": { "type": "string",
"enum": [ "value" ] },
"v": { "$ref": "#/$defs/type_string_array" },
"vT": { "$ref": "#/$defs/type_iso8601_timeduration_array" },
"vMax": { "$ref": "#/$defs/type_string_array" },
"vMin": { "$ref": "#/$defs/type_string_array" },
"vTo": { "$ref": "#/$defs/type_nonnegative_numeric_string_array" },
"vE": { "type": "string" },
"ext": { "$ref": "#/$defs/type_extensions" }
},
"additionalProperties": false
}
#### SenML Interoperability (Draft)
Value fragments in [SenML (RFC 8428)](https://datatracker.ietf.org/doc/html/rfc8428) format are supported by using same value for the SNON entity ID and the SenML name. SenML records that depend on a base name cannot be processed out of order.
Recommendations for SNON and SenML integration:
* Prefer using resolved records that do not depend on SenML base fields, as these significantly complicate processing, especially when measurements are missing or received out of order.
* The SenML units "u" field and update time "ut" field can be omitted, as these are specified by the SNON measurand measurement unit "meU" and measurement timeout "meTo" fields.
* Avoid using the SenML "s" field, as this should be stored in the value or as a separate series.
* The SenML "v", "vs", "vb", and "vd" fields are used as the measurement value.
* Additional calculations are required to resolve time field values when relative times are used.
A typical use case for SNON together with SenML is to enable discovery and self-description of SenML measurements.
### 2.5 Series SNON Fields
Series SNON fragments may also contain the following measurement fields that will be used unless overridden by a measurand:
* Measurement span low ("meSL")
* Measurement span high ("meSH")
* Measurement display low ("meDL")
* Measurement display high ("meDH")
* Measurement display unit ("meDU")
* Measurement update rate ("meUR")
* Measurement timeout ("meTo")
* Measurement resolution ("meR")
* Measurement accuracy ("meAc")
Measurand fields are described in [Section 2.7](#data.measurand).
#### Series Fragment Schema
"series_fragment": {
"type": "object",
"required": [
"eID",
"eC"
],
"properties": {
"eID": { "$ref": "#/$defs/type_id" },
"eC": { "type": "string",
"enum": [ "series" ] },
"eUT": { "$ref": "#/$defs/type_iso8601_time" },
"eT": { "$ref": "#/$defs/type_intl_name" },
"eN": { "$ref": "#/$defs/type_intl_name" },
"eR": { "$ref": "#/$defs/type_relations" },
"meSL": { "$ref": "#/$defs/type_numeric_string" },
"meSH": { "$ref": "#/$defs/type_numeric_string" },
"meDL": { "$ref": "#/$defs/type_numeric_string" },
"meDH": { "$ref": "#/$defs/type_numeric_string" },
"meDU": { "$ref": "#/$defs/type_intl_name" },
"meUR": { "$ref": "#/$defs/type_nonnegative_numeric_string" },
"meTo": { "$ref": "#/$defs/type_nonnegative_numeric_string" },
"meR": { "$ref": "#/$defs/type_nonnegative_numeric_string" },
"meAc": { "$ref": "#/$defs/type_nonnegative_numeric_string" },
"ext": { "$ref": "#/$defs/type_extensions" }
},
"additionalProperties": false
}
### 2.6 Sensor SNON Fields
Sensor SNON Fragments may also contain the following JSON fields:
| Field Name | Label | JSON Type | Description | Mandatory |
| ------------- | ------------- | ------------- | ------------- | --------- |
| Sensor tag | sT | JSON String | Identification tag for the entity.
The value of this field shall be a string containing the P&ID letters and loop number as defined in [ANSI/ISA-S5.1](https://www.isa.org/isa5-1/), RDS tag as defined in [ISO/IEC 81346](https://www.iso.org/standard/82229.html), or contain a user-defined tag values.
Example 2.6.1{
"sT": "TE1123"
} | Optional |
#### Sensor Fragment Schema
"sensor_fragment": {
"type": "object",
"required": [
"eID",
"eC"
],
"properties": {
"eID": { "$ref": "#/$defs/type_id" },
"eC": { "type": "string",
"enum": [ "sensor" ] },
"eUT": { "$ref": "#/$defs/type_iso8601_time" },
"eT": { "$ref": "#/$defs/type_intl_name" },
"eN": { "$ref": "#/$defs/type_intl_name" },
"eR": { "$ref": "#/$defs/type_relations" },
"sT": { "type": "string" },
"ext": { "$ref": "#/$defs/type_extensions" }
},
"additionalProperties": false
}
### 2.7 Measurand SNON Fields
Measurand SNON fragments may also contain the following JSON fields:
| Field Name | Label | JSON Type | Description | Mandatory |
| ------------- | ------------- | ------------- | ------------- | --------- |
| Measurement unit | meU | JSON String | Unit indicator for values of this measurand.
Identifies the unit in which values of this measurand are expressed.
The value of this field shall be formatted as either:
a) an [ISO 80000-1:2009](https://www.iso.org/standard/30669.html) special symbol (or [SI unit symbol](http://www.bipm.org/en/si/si_brochure/)),
b) a combination of symbols for units, as defined in 7.2.2 of [ISO 80000-1:2009](https://www.iso.org/standard/30669.html),
c) a SenML unit as defined in [RFC 8428](https://datatracker.ietf.org/doc/html/rfc8428) or [RFC 8798](https://datatracker.ietf.org/doc/html/rfc8798),
d) an empty string, representing a unitless value, or,
e) a custom (non-SI) value.
If this field is not present, the default value shall be an empty string.
NOTE: While SI prefix conversion may be performed for display (e.g. 27.8 m/s -> 100 km/h), SNON measurement unit fields should always specify units without metric prefixes.
Example 2.7.1{
"meU": "m/s"
} | Optional |
| Measurement type | meT | JSON String | Data type indicator for values of this measurand.
Identifies what data type is stored in the value associated with a measurement.
The value of this field shall contain one of the following:
a) "enumeration" – The value shall contain a string representation of an integer, which corresponds to a string specified in the measurement label field,
b) "numeric" – The value shall contain a numeric string,
c) "string" – The value shall consist of a UTF-8 string value,
d) "url" – The value shall contain a string representation of a URL (including data URIs as defined in [RFC 2397](https://tools.ietf.org/html/rfc2397)),
e) "iso8601" – The value shall contain a string representation of an [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) time or duration, or,
f) "ordinal" – The value shall contain a numeric string with no fractional or exponent part, referring to a position or rank.
If this field is not present, the default value shall be "numeric".
Example 2.7.2{
"meT": "numeric"
} | Optional |
| Measurement acquire | meAq | JSON String | Data Acquisition indicator for values of this measurand.
Identifies what method is used by the sensor to acquire a value.
The value of this field shall contain one of the following:
a) "sample" – The value represents a measurement made at the start of value time,
b) "count" – The value represents an increasing count, measured at the start of value time,
c) "triggered" – The value represents a measurement, captured at the end of the value time,
d) "summary" – the value represents a summarization of measurements that occurred during the value time range,
e) "derived" – The value represents calculations of measurements, valid for the start of value time.
If this field is not present, the default value shall be "sample".
Example 2.7.3{
"meAq": "sample"
} | Optional |
| Measurement unit prefix | meUP | JSON Object | Descriptive Name of the prefix to be displayed before the measured value.
Provides a set of human-readable prefixes that come before the value of this measurand, allowing SNON fragment receivers to display sensor measurements to end users.
The value of this field shall contain one or more JSON Strings, each with a name specifying the language tag as defined in [RFC 5646](https://tools.ietf.org/html/rfc5646), and a value containing a prefix in that language-region, to be displayed before the value of the measurement. The string shall include any required separating space between the prefix and the number.
A name of "*" is used as a default language-region, as defined in [RFC 4647](https://tools.ietf.org/html/rfc4647).
Example 2.7.4{
"meUP": {
"zh": "约",
"*": "≈"
}
} | Optional |
| Measurement unit prefix extended | meUPx | JSON Object | Extended descriptive Name of the prefix to be displayed before the measured value.
Provides a long-form set of human-readable prefixes that come before the value of this measurand, allowing SNON fragment receivers to display sensor measurements to end users.
The value of this field shall contain one or more JSON Strings, each with a name specifying the language tag as defined in [RFC 5646](https://tools.ietf.org/html/rfc5646), and a value containing a long-form prefix in that language-region, to be displayed before the value of the measurement. The string shall include any required separating space between the prefix and the number.
A name of "*" is used as a default language-region, as defined in [RFC 4647](https://tools.ietf.org/html/rfc4647).
Example 2.7.5{
"meUPx": {
"zh": "大约",
"*": "Approx. "
}
} | Optional |
| Measurement unit suffix | meUS | JSON Object | Descriptive Name of the suffix to be displayed after the measured value.
Provides a set of human-readable suffixes that come after the value of this measurand, allowing SNON fragment receivers to display sensor measurements to end users.
The value of this field shall contain one or more JSON Strings, each with a name specifying the language tag as defined in [RFC 5646](https://tools.ietf.org/html/rfc5646), and a value containing a suffix in that language-region, to be displayed after the value of the measurement. The string shall include any required separating space between the number and the unit.
A name of "*" is used as a default language-region, as defined in [RFC 4647](https://tools.ietf.org/html/rfc4647).
Example 2.7.6{
"meUS": {
"zh": "摄氏度",
"*": " ℃"
}
} | Optional |
| Measurement unit suffix extended | meUSx | JSON Object | Extended descriptive Name of the suffix to be displayed after the measured value.
Provides a long-form set of human-readable suffixes that come after the value of this measurand, allowing SNON fragment receivers to display sensor measurements to end users.
The value of this field shall contain one or more JSON Strings, each with a name specifying the language tag as defined in [RFC 5646](https://tools.ietf.org/html/rfc5646), and a value containing a long-form suffix in that language-region, to be displayed after the value of the measurement. The string shall include any required separating space between the number and the unit.
A name of "*" is used as a default language-region, as defined in [RFC 4647](https://tools.ietf.org/html/rfc4647).
Example 2.7.7{
"meUSx": {
"zh": "摄氏度",
"*": " degrees Celsius"
}
} | Optional |
| Measurement label | meL | JSON Object of JSON Objects | Descriptive Name of enumeration values.
Provides a set of human-readable values corresponding to enumerated values of a measurand with a measurement type of "enumeration", allowing SNON fragment receivers to display sensor measurements to end users.
The value of this field shall contain a JSON Object, with each object contained being a JSON Object containing one or more JSON Strings, each with a name specifying the language tag as defined in [RFC 5646](https://tools.ietf.org/html/rfc5646), and a value containing a long-form suffix in that language-region, to be displayed before the value of the measurement.
A name of "*" is used as a default language-region, as defined in [RFC 4647](https://tools.ietf.org/html/rfc4647).
Example 2.7.8{
"meL": {
"0":{
"zh": "阀门开启",
"*": "Valve Open"
},
"1":{
"zh": "阀门关闭",
"*": "Valve Closed"
}
}
} | Optional |
| Measurement span low | meSL | JSON String | Indication of the minimum operating value.
Provides an indication of the lowest operating value where the sensor is rated to be within its normal error band.
The value of this field shall match the type specified in the series or measurand measurement type field, and is limited to types "numeric" and "ordinal".
Example 2.7.9{
"meSL":"-100"
} | Optional |
| Measurement span high | meSH | JSON String | Indication of the maximum operating value.
Provides an indication of the highest operating value where the sensor is rated to be within its normal error band.
The value of this field shall match the type specified in the series or measurand measurement type field, and is limited to types "numeric" and "ordinal".
Example 2.7.10{
"meSH":"100"
} | Optional |
| Measurement display low | meDL | JSON String | Indication of the minimum value for display purposes.
Provides an indication of the lowest value the sensor is expected to return during normal operation. This permits an SNON fragment receiver to size charts and other display outputs appropriately.
The value of this field shall match the type specified in the series or measurand measurement type field, and is limited to types "numeric" and "ordinal".
Example 2.7.11{
"meDL":"0"
} | Optional |
| Measurement display high | meDH | JSON String | Indication of the maximum value for display purposes.
Provides an indication of the highest value the sensor is expected to return during normal operation. This permits an SNON fragment receiver to size charts and other display outputs appropriately.
The value of this field shall match the type specified in the series or measurand measurement type field, and is limited to types "numeric" and "ordinal".
Example 2.7.12{
"meDH":"50"
} | Optional |
| Measurement display unit | meDU | JSON Object | Indication of the unit used for display purposes.
Provides an indication of what unit should be used for display purposes. This permits a specific directive for how an SNON fragment receiver should convert from SI base units.
The value of this field shall contain one or more JSON Strings, each with a name specifying the language tag as defined in [RFC 5646](https://tools.ietf.org/html/rfc5646), and a value containing either:
a) a combination of [ISO 80000-1:2009](https://www.iso.org/standard/30669.html) special symbol (or [SI unit symbol](http://www.bipm.org/en/si/si_brochure/)), optionally including SI prefixes,
b) an SI prefix, or,
c) a custom (non-SI) value.
A name of "*" is used as a default language-region, as defined in [RFC 4647](https://tools.ietf.org/html/rfc4647).
Example 2.7.13{
"meU": "m/s",
"meDU": {
"en-us":"mile/hr",
"*":"km/hr"
}
} | Optional |
| Measurement update rate | meUR | JSON String | Indication of the maximum rate at which a sensor value will be updated.
Provides an indication of the shortest interval that a sensor value can be polled to obtain a new reading. This permits an SNON fragment sender to determine the rate at which values should be generated.
The value of this field shall be a numeric string, measured in seconds.
Example 2.7.14{
"meUR":"0.1"
} | Optional |
| Measurement timeout | meTo | JSON String | Indication of the timeout associated with each measurement.
If the specified time duration since the value time has been exceeded, the corresponding value shall no longer be considered valid.
The value of this field shall be a numeric string, measured in seconds.
Example 2.7.15{
"meTo":"10"
} | Optional |
| Measurement resolution | meR | JSON String | Indication of the smallest detectable change measurable by the sensor.
Provides an indication of the smallest detectable change of the value being measured that will result in a different value reading. This permits an SNON fragment sender to determine significant figures.
The value of this field shall be a numeric string corresponding to the measurement unit of the measurand.
Example 2.7.16{
"meR":"0.1"
} | Optional
Only valid for measurement type "numeric" |
| Measurement accuracy | meAc | JSON String | Indication of the maximum permissible measurement error.
Provides an indication of the largest difference, in either direction, permitted between a measured value and a reference quantity value, as stated by the manufacturer or by an applicable specification or regulation. This permits an SNON fragment receiver to judge whether a difference between two values is significant.
NOTE 1: This is the figure commonly labelled "accuracy" on instrument datasheets. In the sense of ISO/IEC Guide 99:2007 it is a maximum permissible measurement error (see 1.7.8), not a measurement accuracy, and it is not a measurement uncertainty.
NOTE 2: Where a datasheet states the error relative to the measurement span, the sender converts it to an absolute value using the span. Where it is stated relative to the reading, the sender gives the largest absolute error over the span.
The value of this field shall be a non-negative numeric string corresponding to the measurement unit of the measurand. Accuracy shall be +/- the specified value.
Example 2.7.17{
"meAc":"0.1"
} | Optional
Only valid for measurement type "numeric" |
#### Measurand Fragment Schema
"measurand_fragment": {
"type": "object",
"required": [
"eID",
"eC"
],
"properties": {
"eID": { "$ref": "#/$defs/type_id" },
"eC": { "type": "string",
"enum": [ "measurand" ] },
"eUT": { "$ref": "#/$defs/type_iso8601_time" },
"eT": { "$ref": "#/$defs/type_intl_name" },
"eN": { "$ref": "#/$defs/type_intl_name" },
"eR": { "$ref": "#/$defs/type_relations" },
"meU": { "type": "string" },
"meT": { "type": "string",
"enum": [ "enumeration", "numeric", "string", "url", "iso8601", "ordinal"] },
"meAq": { "type": "string",
"enum": [ "sample", "count", "triggered", "summary", "derived"] },
"meUP": { "$ref": "#/$defs/type_intl_name" },
"meUS": { "$ref": "#/$defs/type_intl_name" },
"meUPx": { "$ref": "#/$defs/type_intl_name" },
"meUSx": { "$ref": "#/$defs/type_intl_name" },
"meL": { "$ref": "#/$defs/type_intl_enum" },
"meSL": { "$ref": "#/$defs/type_numeric_string" },
"meSH": { "$ref": "#/$defs/type_numeric_string" },
"meDL": { "$ref": "#/$defs/type_numeric_string" },
"meDH": { "$ref": "#/$defs/type_numeric_string" },
"meDU": { "$ref": "#/$defs/type_intl_name" },
"meUR": { "$ref": "#/$defs/type_nonnegative_numeric_string" },
"meTo": { "$ref": "#/$defs/type_nonnegative_numeric_string" },
"meR": { "$ref": "#/$defs/type_nonnegative_numeric_string" },
"meAc": { "$ref": "#/$defs/type_nonnegative_numeric_string" },
"ext": { "$ref": "#/$defs/type_extensions" }
},
"additionalProperties": false
}
### 2.8 Device SNON Fields
Device SNON Fragments may also contain the following JSON fields:
| Field Name | Label | JSON Type | Description | Mandatory |
| ------------- | ------------- | ------------- | ------------- | --------- |
| Device tag | dT | JSON String | Identification tag for the device.
The value of this field shall be a string containing RDS tag as defined in [ISO/IEC 81346](https://www.iso.org/standard/82229.html) or contain a user-defined tag values.
Example 2.8.1{
"dT": "-K1-B1"
} | Optional |
#### Device Fragment Schema
"device_fragment": {
"type": "object",
"required": [
"eID",
"eC"
],
"properties": {
"eID": { "$ref": "#/$defs/type_id" },
"eC": { "type": "string",
"enum": [ "device" ] },
"eUT": { "$ref": "#/$defs/type_iso8601_time" },
"eT": { "$ref": "#/$defs/type_intl_name" },
"eN": { "$ref": "#/$defs/type_intl_name" },
"eR": { "$ref": "#/$defs/type_relations" },
"dT": { "type": "string" },
"ext": { "$ref": "#/$defs/type_extensions" }
},
"additionalProperties": false
}
### 2.9 Location SNON Fields
Location SNON Fragments may also contain the following JSON fields:
| Field Name | Label | JSON Type | Description | Mandatory |
| ------------- | ------------- | ------------- | ------------- | --------- |
| Location tag | lT | JSON String | Identification tag for the location.
The value of this field shall be a string containing RDS tag as defined in [ISO/IEC 81346](https://www.iso.org/standard/82229.html) or contain a user-defined tag values.
Example 2.9.1{
"lT": "++2.BAA2"
} | Optional |
#### Location Fragment Schema
"location_fragment": {
"type": "object",
"required": [
"eID",
"eC"
],
"properties": {
"eID": { "$ref": "#/$defs/type_id" },
"eC": { "type": "string",
"enum": [ "location" ] },
"eUT": { "$ref": "#/$defs/type_iso8601_time" },
"eT": { "$ref": "#/$defs/type_intl_name" },
"eN": { "$ref": "#/$defs/type_intl_name" },
"eR": { "$ref": "#/$defs/type_relations" },
"lT": { "type": "string" },
"ext": { "$ref": "#/$defs/type_extensions" }
},
"additionalProperties": false
}
### 2.10 Relationship SNON Fields
Relationship SNON Fragments may also contain the following JSON fields:
| Field Name | Label | JSON Type | Description | Mandatory |
| ------------- | ------------- | ------------- | ------------- | --------- |
| Relationship source | rS | JSON String | Indicates the source of the relationship.
The value of this field shall be an entity ID.
Example 2.10.1{
"rS": "urn:urn-5:3b905aa9c63d454d9e8ac30084e7271bc662e88e68e811d9cfe3c73bf62eb9f6"
} | Mandatory |
| Relationship destination | rD | JSON String | Indicates the destination of the relationship.
The value of this field shall be an entity ID.
Example 2.10.2{
"rD": "urn:uuid:731f0515-078d-48cf-a136-99e57ad21b8b"
} | Mandatory |
| Relationship type | rT | JSON String | Indicates the type of relationship.
The value of this field shall be an string indicating the relationship type (See [section 3](#rel)).
Example 2.10.3{
"rT": "child_of"
} | Mandatory |
Relationship objects can be used to express any relationship that can be specified using an entity relationship field, but are separate from the entities being linked.
#### Relationship Fragment Schema
"relationship_fragment": {
"type": "object",
"required": [
"eID",
"eC",
"rS",
"rD",
"rT"
],
"properties": {
"eID": { "$ref": "#/$defs/type_id" },
"eC": { "type": "string",
"enum": [ "relationship" ] },
"eUT": { "$ref": "#/$defs/type_iso8601_time" },
"eT": { "$ref": "#/$defs/type_intl_name" },
"eN": { "$ref": "#/$defs/type_intl_name" },
"eR": { "$ref": "#/$defs/type_relations" },
"rS": { "$ref": "#/$defs/type_id" },
"rD": { "$ref": "#/$defs/type_id" },
"rT": { "type": "string" },
"ext": { "$ref": "#/$defs/type_extensions" }
},
"additionalProperties": false
}
## 3. SNON Entity Relationships
### 3.1 Relationship Model
The relationship model between entities is defined according to the following model:

Figure 3 - SNON Relationship Model
Relationships are expressed in relationship fragments or as the contents of the entity relationship field within a fragment. When using a entity relationship field within a fragment, the relationship source is the entity ID of the fragment the entity relationship field is contained in.
#### Example 3.1.1: Equivalent Relationships in SNON fragments
[
{
"eID":"urn:uuid:13818320-a6f9-4caa-8660-d39ab5bdb6aa",
"eC": "device",
"eR": {
"child_of": [ "urn:uuid:ca343afd-bc22-4188-b58c-7ab624a800cd" ]
}
}
]
[
{
"eID":"urn:uuid:c0f44d6e-ad62-4f4d-9518-6c778fb1522d",
"eC": "relationship",
"rS": "urn:uuid:13818320-a6f9-4caa-8660-d39ab5bdb6aa",
"rD": "urn:uuid:ca343afd-bc22-4188-b58c-7ab624a800cd",
"rT": "child_of"
}
]
Relationship fragments enable more expressive relationships compared with using relationship fields within existing fragments:
1. Relationships can be created after the relationship source has been created
1. Relationships can be created by different system components then the entities being linked
1. Relationships can be created where the relationship source or relationship destination is another relationship fragment, allowing relationships with relationships
### 3.2 General Relationships
The following general relationships are defined as part of SNON:
| Relationship Type | Description |
| ----------------- | ------------- |
| "child_of" | Defines hierarchies between entities.
Figure 4 shows how child_of relationships can be used to associate series with sensors, and sensors with devices:
Figure 4 - SNON "child_of" Relationships between series, sensors and devices
Figure 5 shows how child_of relationships can be used to associate devices with larger devices:
Figure 5 - SNON "child_of" Relationships between devices
Figure 6 shows how child_of relationships can be used to associate devices with locations, and locations with locations:
Figure 6 - SNON "child_of" Relationships between devices and locations
|
| "measurand" | Indicates what measured quantity a given sensor is measuring.
Figure 7 shows how measurand relationships can be used to indicate which measured quantity is being measured by a given sensor:
Figure 7 - SNON "measurand" Relationships for series and sensors
|
| "powered_by" | Defines power supply relationships between entities. Figure 8 shows how powered_by relationships can be used to indicate which devices are supplied power by which devices:
Figure 8 - SNON "powered_by" Relationships between devices
|
| "timesync_by" | Defines time synchronization relationships between entities.
Figure 9 shows how timesync_by relationships can be used to indicate which devices are supplied time synchronzation by which devices:
Figure 9 - SNON "timesync_by" Relationships between devices
|
| "connected_to" | Defines network connectivity relationships between entities.
Figure 10 shows how connected_to relationships can be used to indicate which devices are connected to which devices:
Figure 10 - SNON "connected_to" Relationships between devices
|
| "located_at" | Defines a dynamic location of a given device or sensor.
Figure 11 shows how located_at relationships can be used to indicate a series that specifies the location of a device:
Figure 11 - SNON "located_at" Relationships for devices
|
| "measured_from" | Defines that devices or relationships a given sensor is measuring.
Figure 12 shows how measured_from relationships can be used to indicate that which sensors measure which devices or relationships:
Figure 12 - SNON "measured_from" Relationships between devices
|
### 3.3 Series and Sensor Relationships
The following relationships from a series or sensor to a second series are
defined as part of SNON:
| Relationship Type | Description |
| ----------------- | ------------- |
| "health" | Indicates sensor health. Each "health" relationship indicates that the health of a specific sensor or series is indicated by a second series.
Figure 13 shows an example of a "health" relationship:
Figure 13 - SNON "health" Relationships
|
| "setpoint" | Indicates sensor setpoint. Each "setpoint" relationship indicates that the desired value/range of a specific sensor or series is indicated by a second series.
Figure 14 shows an example of a "setpoint" relationship:
Figure 14 - SNON "setpoint" Relationships
|
| "alarms" | Indicates sensor alarms. Each "alarms" relationship indicates that the alarms threshold value/range of a specific sensor or series is indicated by a second series.
Figure 15 shows an example of two "alarms" relationships:
Figure 15 - SNON "alarms" Relationships
|
| "alarm_inhibit" | Indicates that sensor alarms are to be inhibit. Each "alarm_inhibit" relationship indicates that any alarms for a specific sensor or series should be inhibited as indicated by a second series.
Figure 16 shows an example of an "alarm_inhibit" relationship:
Figure 16 - SNON "alarm_inhibit" Relationships
|
| "indeterminate" | Indicates sensor indeterminacy. Each "indeterminate" relationship indicates that the indeterminacy of a specific sensor or series is indicated by a second series.
Figure 17 shows an example of an "indeterminate" relationship:
Figure 17 - SNON "indeterminate" Relationships
|
| "flag" | Indicates unreliable sensor measurements that should not be included in aggregated values/statistical analysis. Each "flag" relationship indicates that the flag status of a specific sensor or series is indicated by a second series.
Figure 18 shows an example of an "flag" relationship:
Figure 18 - SNON "flag" Relationships
|
### 3.4 Custom Relationships
Custom relationships can be defined as part of an SNON-based system. For example, a custom "interrupts" relationship can associate a device with a relationship between two other devices:
| Relationship Type | Description |
| ----------------- | ------------- |
| "interrupts" | This relationship indicates that a "powered_by" relationship is conditional.
Figure 19 shows how interrupts relationships can be used to indicate that power supplied to a device can be interrupted by a second device:
Figure 19 - SNON "interrupts" Relationships between devices
|
## 4. SNON Examples
#### Example 4.1: A value fragment representing a single measured value:
[
{
"eID": "urn:uuid:e129c1d6-0ac9-474a-948e-813ff3dc4e31",
"v" : ["29.3"],
"vT" : ["2014-08-20T14:32:46.125678Z"]
}
]
#### Example 4.2: Compact form of Example 4.1:
[{"eID":"urn:uuid:e129c1d6-0ac9-474a-948e-813ff3dc4e31","v":["29.3"],"vT":["2014-08-20T14:32:46.125678Z"]}]
#### Example 4.3: A value fragment representing two values, measured at different times:
[
{
"eID": "urn:uuid:e129c1d6-0ac9-474a-948e-813ff3dc4e31",
"v" : ["29.3", "30.3"],
"vT" : ["2014-08-20T14:32:56.125678Z", "2014-08-20T14:33:06.125678Z"]
}
]
#### Example 4.4: A value fragment representing two values, with the second time expressed as a duration since the first time:
[
{
"eID": "urn:uuid:e129c1d6-0ac9-474a-948e-813ff3dc4e31",
"v" : ["29.3", "30.3"],
"vT" : ["2014-08-20T14:32:56.125678Z", "PT10S"]
}
]
#### Example 4.5: A value fragment representing a value with an associated duration, rather than a point in time:
[
{
"eID": "urn:uuid:e129c1d6-0ac9-474a-948e-813ff3dc4e31",
"v" : ["29.3"],
"vT" : ["2014-08-20T14:32:56.125678Z/PT10S"]
}
]
#### Example 4.6: A value fragment representing a value with minimum and maximum:
[
{
"eID": "urn:uuid:e129c1d6-0ac9-474a-948e-813ff3dc4e31",
"v" : ["29.3"],
"vMin" : ["28.1"],
"vMax" : ["33.2"],
"vT" : ["2014-08-20T14:32:56.125678Z"]
}
]
#### Example 4.7: An SNON pack containing two value fragments, each for a different sensor:
[
{
"eID": "urn:uuid:e129c1d6-0ac9-474a-948e-813ff3dc4e31",
"v" : ["29.3"],
"vT" : ["2014-08-20T14:32:56.125678Z"]
},
{
"eID": "urn:uuid:322ea74e-d914-44be-a95f-bb97b60b140b",
"v" : ["-102.2"],
"vT" : ["2014-08-20T14:32:56.125678Z"]
}
]
#### Example 4.8: A series fragment associated with one or more value fragments, and linking them to a sensor and a measurand:
[
{
"eID": "urn:uuid:e129c1d6-0ac9-474a-948e-813ff3dc4e31",
"eC": "series",
"eN": { "*": "L1-E Voltage" },
"eR": {
"child_of": [ "urn:uuid:188b39c5-0b90-4850-b3cd-38f52558ca6f" ],
"measurand": [ "urn:uuid:866f4a0d-62cc-4324-bff1-b682a806df81" ]
}
}
]
#### Example 4.9: A measurand fragment representing the value quantity of the series in Example 4.8:
[
{
"eID": "urn:uuid:866f4a0d-62cc-4324-bff1-b682a806df81",
"eC": "measurand",
"eN": { "*": "120 VAC Nominal Voltage" },
"meU": "V",
"meT": "numeric",
"meAq": "sample",
"meDU": { "*": "V" },
"meDL": "110",
"meDH": "130",
"meUR": "2",
"meTo": "5"
}
]
#### Example 4.10: A sensor fragment associated with the device in Example 4.11:
[
{
"eID": "urn:uuid:188b39c5-0b90-4850-b3cd-38f52558ca6f",
"eC": "sensor",
"eN": { "*": "3 Phase Voltage" },
"eR": {
"child_of": [ "urn:uuid:0300ba2e-8e46-4f11-9c2e-4237e9651783" ]
}
}
]
#### Example 4.11: A device fragment associated with the location in Example 4.12:
[
{
"eID": "urn:uuid:0300ba2e-8e46-4f11-9c2e-4237e9651783",
"eC": "device",
"eN": { "*": "Power Meter" },
"eR": {
"child_of": [ "urn:uuid:9dffc589-b4b6-4a71-a213-125f05bb9766" ]
}
}
]
#### Example 4.12: A location fragment:
[
{
"eID": "urn:uuid:9dffc589-b4b6-4a71-a213-125f05bb9766",
"eC": "location",
"eN": { "*": "L113" }
}
]
## 5. SNON Schema
SNON fragments can be validated using the following schema:
https://www.snon.org/v4.1/snon-fragment-schema.json
SNON packs can be validated using the following schema:
https://www.snon.org/v4.1/snon-schema.json
The following constraints are not validated by these schemas, and shall be validated by the SNON fragment receiver:
* Equal number of array items in value time, value, value max, value min and value timeout
* First item in value time shall be an ISO 8601 time (subsequent items may be an ISO 8601 duration)
* If there is a value time, at least one of value shall be present
* Contents of value, value max and value min shall correspond to measurement type
* Validity of SNON fragments contained within a JWS "payload" or JWE "ciphertext" field
* Ensuring that there is zero or one "measurand" relationship between a series and a measurand
* Ensuring that there is zero or one "measurand" relationship between a sensor and a measurand
* Ensuring that "child_of" relationships in series fragments are only permitted with one sensor entity
* Values of measurement type "numeric" or "ordinal" shall be numeric strings
* Values of measurement type "ordinal" shall have no fractional or exponent part
## 6. SNON Security
### 6.1 Encryption and Signing
Sensor data often must be encrypted to protect confidentiality, and signed to protect integrity and demonstrate the authenticity of the source of the data. SNON specifies the use of JSON Object Signing and Encryption (JOSE) as described in [RFC 7516](https://tools.ietf.org/html/rfc7516) and [RFC 7515](https://tools.ietf.org/html/rfc7515), although other encryption and signing standards may also be used.
An SNON pack shall be used as the plaintext, and JWE or JWS JSON Serialization shall be used for the encrypted or signed representation, as shown in the below example:
#### Example 6.1.1: A pack of SNON fragments to be protected:
[{"eID":"urn:uuid:fa164ee2-f1b7-43ee-8202-e61bc005db2b","v":["1"],"vT":["2017-11-29T03:32:03.752633Z"]},{"eID":"urn:uuid:c4c0b0b6-f1c5-4695-9370-d925f8370c07","v":["0"],"vT":["2017-11-29T03:32:03.752935Z"]},{"eID":"urn:uuid:d90526a1-4e62-493e-870c-6216216a03c8","v":["0"],"vT":["2017-11-29T03:32:03.752633Z"]},{"eID":"urn:uuid:12b976ea-4867-42b1-bcc6-f6b1d5e938e7","v":["0"],"vT":["2017-11-29T03:32:03.752633Z"]}]
#### Example 6.1.2: JWE representation when encrypted using RSA v1.5, according to [RFC 7520](https://tools.ietf.org/html/rfc7520#section-5.1):
[{"tag":"5DlAaLHKrg5JBCh604TtfQ","protected":"eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4R0NNIn0","iv":"QIuWxaOOwgIfw6oo","ciphertext":"fwk4KeCiC6rItJ_TD5kn7ymRn7eX-Ckqi0k3N18sEsksF39f2KBezt609IeZQuIqxFBheeLWucwuWa-tpYiWv-zDVUkQ-AhDNwdzo1tPevLOiUytU2NkCjK0uX6yazdaBHxVXFUbwa1HDQ_9-8H_wbpF1pPMrs5kBXt2cHUBdjpTopSfn0Q_rD8iHgz0s7eyMjWjSGqM5Fhg7T79qMwvRtqlyWIuqHVR40U2Gmhk4gy9VOXomq_P7qHeYB507zlAAxggsbYSJvwq6biluilqW5lPbDCR9MSsWjYFggSPr_aGDw6VN-_kXjkVvnBqRkq1B2AU6aKwD47CuBYSCBJDqcHMhKdwQmJ_M4xyg4k0EYl2iwEd7UDKkylzlxi0kfQ4sClW6DHyc_tiymT1ntPkL0l5cerK47kr8CarmJyRCWlQk_kasXr9AXsB9w6mu7obXzdX80FBQJmjzgXYhPC_mcVj6gKQNIyXoFIhlr7ZIEKnYRAwddvtk04Y5amCgBw0sDpS1j-GDimGmZ3iVCV4wsLeih0Ybv5oEqbgE3HiOteLl-8Q4fqP034rTtgNfT0ZxkmnybZyres1C3hwrmfmu-Z1srZ5HsIQuOqovhFE_68i","encrypted_key":"fCeHnQCXO5KqBeYaoqoJ6iFuVTHRcvhh6p7k5LrS6iA3f9XhExjLybggze8v_QpJzLoVXbD31aT1uUTiAyQ93GzsswbMR1X7jWeZnehX8cUbccjkhW2udoXYHe1Du-QibCBgc2K-Psp2Mt17Wg1rqmgGkJ5R36V_uOyBKthY_8AbXabzhgGN9H-A8WwfD6-iB69WjeLrHlmE0psn6jF07cPNzFV2j8rgaED6ejULCE54y3qh6f-9AAMdNH1G2GyjYBhbEg2rSJC80-q95prpnscjUKrNspdV8QzTlg1_AVBEqOqLvEAwWschDMgIFU-Y1HWWSm1JeftxpHfERCySXQ"}]
#### Example 6.1.3: JWS representation when signed using RSA v1.5, according to [RFC 7520](https://tools.ietf.org/html/rfc7520#section-4.1):
[{"protected":"eyJhbGciOiJSUzI1NiJ9","signature":"EyRkR84B0GJiOtVETZI6tj2biUJzACY2MBcggz3NWu8uCm5FWYfndwJw0pI7ouGaAhpgre3YmK1XoFZhWDFlrPBAx5vKaAsiqIGPvaNX3PTjnw4auEaETSraW5bT1Zg9ZOCGg3o6jwWVVjQecGevZulqfCiEe3bKV48cRHu4WOQG_PoqYdHC4Jw1ugOgpiqCqzaRi34Fek2h3lisufD5dFBJG36UZStYfpSNComfbdhNxe-zQhl42hyE_SG_qUIIHVFmKCOiSLJMPM3TWXKKFWL-B3jNC1Gx79c0mPgfncuXZUCgK8YhD7qOlyR-HXtwdzJ2z7lja186uzdoTnoV9w","header":{"kid":"urn:uuid:bd8dd740-ccd9-4e80-aae9-f1c9ebea754f"},"payload":"W3siZW50aXR5SUQiOiJ1cm46dXVpZDpmYTE2NGVlMi1mMWI3LTQzZWUtODIwMi1lNjFiYzAwNWRiMmIiLCJ2YWx1ZSI6WyIxIl0sInZhbHVlVGltZSI6WyIyMDE3LTExLTI5VDAzOjMyOjAzLjc1MloiXX0seyJlbnRpdHlJRCI6InVybjp1dWlkOmM0YzBiMGI2LWYxYzUtNDY5NS05MzcwLWQ5MjVmODM3MGMwNyIsInZhbHVlIjpbIjAiXSwidmFsdWVUaW1lIjpbIjIwMTctMTEtMjlUMDM6MzI6MDMuNzUyWiJdfSx7ImVudGl0eUlEIjoidXJuOnV1aWQ6ZDkwNTI2YTEtNGU2Mi00OTNlLTg3MGMtNjIxNjIxNmEwM2M4IiwidmFsdWUiOlsiMCJdLCJ2YWx1ZVRpbWUiOlsiMjAxNy0xMS0yOVQwMzozMjowMy43NTJaIl19LHsiZW50aXR5SUQiOiJ1cm46dXVpZDoxMmI5NzZlYS00ODY3LTQyYjEtYmNjNi1mNmIxZDVlOTM4ZTciLCJ2YWx1ZSI6WyIwIl0sInZhbHVlVGltZSI6WyIyMDE3LTExLTI5VDAzOjMyOjAzLjc1MloiXX1d"}]
Nesting of signatures and encryption is defined in section 6 of [RFC 7520](https://tools.ietf.org/html/rfc7520#section-6).
When traversing relationships, it is important to verify the signature of each fragment in the chain.
If sensor IDs are used as MQTT topic names, it is strongly recommended that these be opaque (or hashes) to ensure that information is not leaked. This is why the use of hierarchical MQTT topic names are not recommended, as this will leak information about relationships between sensors.
### 6.2 PKI
A common problem in sensor network security is secure enrolment, where a semi-trusted sensor needs to securely establish its identity to a trusted processing system or repository over an untrusted network. SNON can be used to simplify this problem by treating device public keys as sensor values.
Assume the following:
1. A sensor network platform has a trusted CA which can be used to issue and verify certificates associated with the SNON fragment sender
2. When a new SNON fragment sender is being deployed, a new certificate/private key is generated for that SNON fragment sender
3. The private key is held by the SNON fragment sender, and the public certificate is published as a sensor value ("certificate sensor value fragment")
When the SNON fragment sender first connects to the sensor network platform, it sends its public certificate as a signed value fragment. The sensor network platform can verify that the SNON fragment sender's public certificate is signed by the CA certificate, and that the signature is valid.
This allows the sensor network platform to determine that the SNON fragment sender possesses a valid certificate, signed by the trusted CA, and that there have been no alterations while traversing the untrusted network, as an attacker cannot undetectably alter the data without possessing the SNON fragment sender's assigned private key.
#### Example 6.2.1: A series and value fragment describing the public certificate of a sensor:
[
{
"eID": "urn:uuid:338a889f-f03b-410b-9968-76ca5726ad00",
"eC": "series",
"eN": { "*": "Public Key" },
"eR": {
"child_of": [ "urn:uuid:3ca41441-820a-479a-84bd-af5ffdafeb09" ]
}
},
{
"eID": "urn:uuid:338a889f-f03b-410b-9968-76ca5726ad00",
"v": [
"data:application/x-pem-file;base64,LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUU1ekNDQXMrZ0F3SUJBZ0lDRUFBd0RRWUpLb1pJaHZjTkFRRUxCUUF3VmpFTE1Ba0dBMVVFQmhNQ1EwRXgKQ3pBSkJnTlZCQWdNQWtKRE1Rb3dDQVlEVlFRSERBRWdNUTB3Q3dZRFZRUUtEQVJUVGs5T01RMHdDd1lEVlFRTApEQVJFWlcxdk1SQXdEZ1lEVlFRRERBZFRUazlPSUVOQk1CNFhEVEl4TURFd016RTNNREl6T1ZvWERUSXlNREl3Ck5URTNNREl6T1Zvd1R6RUxNQWtHQTFVRUJoTUNRMEV4Q3pBSkJnTlZCQWdNQWtKRE1RMHdDd1lEVlFRS0RBUlQKVGs5T01RMHdDd1lEVlFRTERBUkVaVzF2TVJVd0V3WURWUVFEREF4VFRrOU9JRVY0WVcxd2JHVXdnZ0VpTUEwRwpDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQyttL05FOUh3c1ZEUVltZEtSVlR4NXBCK1NQMERoCjk0LzIwVlNqeWxiZDgxYStHVnppUXJ4YVJLMGhIbnNyTkUzbDRFdFZUZzlTeGR3dm54TUQxcjl1NEtKejErdVQKWndWLzVJOEpmaVJWM1hwNERCdjVOUUNTcGRZTUl4Z0k0cXNHRkhrRExKd1k4YUQzOFRoZ1VIMnFIQ3RVa3ZqMgpaejJ1bmw0MmxnSlFFc0xNNTZ2eTBBZ2srWlBwc1dRL3g3aWZ3UkFNd29EWDBuMnhnU1BNOUw1NUUvNzNDN1RQCnlzK2FNVk1OakkzckJ4V3paQzVmSGh1dS9mZ2pDRVhhdW91ZWM4MXI1OEN5Z1FYOWhxMTlmTnI5WCtpZUc2dWkKYkcwcG50WlpsYmNUY3Z1bjJVdWlNeHhVRnczRFNoUElBdS9GMHNTSDhvenJsSERFelZ2ZUZ5VDNBZ01CQUFHagpnY1V3Z2NJd0NRWURWUjBUQkFJd0FEQVJCZ2xnaGtnQmh2aENBUUVFQkFNQ0JhQXdNd1lKWUlaSUFZYjRRZ0VOCkJDWVdKRTl3Wlc1VFUwd2dSMlZ1WlhKaGRHVmtJRU5zYVdWdWRDQkRaWEowYVdacFkyRjBaVEFkQmdOVkhRNEUKRmdRVTZYN1BWNGcvMkROODgzeGMzMlVFQ0Y3ckJBQXdId1lEVlIwakJCZ3dGb0FVM2tBbXYzVElPakRzbFJ1NApxSW5FMllkd0cwZ3dEZ1lEVlIwUEFRSC9CQVFEQWdYZ01CMEdBMVVkSlFRV01CUUdDQ3NHQVFVRkJ3TUNCZ2dyCkJnRUZCUWNEQkRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQWdFQUJWbm9kdklacWpBcVVUcXJZQkdhQzB2NWQ0ZlAKTkluYU1pY3N6T3ppbUw2SjhlYTNhY016Q2tIcGVkUldydG1BdjZUdWdhTmI3NDVmdVFMODk5VzJTdjduZWk4VgptRlBTUTdUNmc4SFpraXVvekVHRlZFbGx1RDNQbUY0NFBJeFhjZnJRVHZ5c3hSaDhpNkpiQi9neVo3bkdHNll3CkJSR1B6NUVudDdjai9QSjBSaWhrTEVnM09md2FYUUtQT2ZlNmhMdmFZVGxSejFPaHIrUWNxRDZiL1pSK0o0aE4KeUJUT2l1WUlMb2c5Q0VhaUVmOThiQzZpb0Z2NVBBTlk4dCtnZjZzN1NtMFI3M0JSZG5TUHJtUHlxK05YZDVvRQpvV1J3d2ZmaVpFNUJheDNIZmt1L1pjV1JyZ1dLRFhDOHdDZ0hvSHpPQVBWTVdKSXc2MDVWN01qUkg5L3ViTEQ3CjNGN2FDaDlLK2Vtb29sOW9iZkJWeW9NdUREdUZZd3NwTFdsWjlSM0FmL3gxV0I3N3RrNjlXMEFoanVJTGFyaGUKWFprTXZ3WEptSGl5QzA5SWZYK1ZlNnNoM09vN0x6L2EwQ2hudHRNaGx0VmdtOXd3YVZNV1JEQ3NhSUhhNmh0OQpsZlptZ3pGWHV3SGpJOCtjcWpHVm8vbHZ3NFl3RnphMG5WQVZpWm1tRE00UW5vMzdjamQydFpwUEdyVlhsRDJOCmJRMFpwNmxHdEVtTjgwRllqeDhOdTUxbnYzcDJDQStPSWZ5bXZIbmNON2puWkdDWXRZWjhMaVNoTDdlYS82YVQKSlZSbWRoTkdlSmNKSlZzVHJpOHNqYitJdmZNQStnNUhmY0xjQ0pxd3NtK0twQXVDTkN5UHMvdi8yeG54VFlzeApob2lYSnZGNnJYS2lnY2s9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
],
"vT": [ "2021-01-03T17:08:57.252633Z" ]
}
]
## 7. SNON Transports
### 7.1 SNON Serial Transport
SNON data is often streamed over serial connections such as an RS-485 connection, radio broadcast channels, and TCP/IP sockets. These connections may be point-to-point, point-to-multipoint, or broadcast, and may be connection-based or connectionless. This serial protocol uses newline-delimited JSON ([JSONL](https://jsonlines.org)) to send requests and receive responses from an SNON fragment sender.
#### Request Sending Live Updates
An SNON fragment sender may automatically send out updates each time a fragment is created, with sent fragments contained in a JSON array.
An SNON fragment receiver requests that listening SNON fragment senders start sending updates by sending the following message:
#### Example 7.1.1 - Request send live updates
[true]
#### Request Not Sending Live Updates
An SNON fragment receiver requests that listening SNON fragment senders stop sending updates by sending the following message:
#### Example 7.1.2 - Request not send live updates
[false]
#### Request Values
An SNON fragment receiver requests that listening SNON fragment senders send all current fragments by sending the following message:
#### Example 7.1.3 - Request send all fragments
{}
An SNON fragment receiver requests that listening SNON fragment senders send a fragment for a specific entity ID by sending the following message:
#### Example 7.1.4 - Request send all fragments with a specific entity ID
{"eID": "urn:uuid:e129c1d6-0ac9-474a-948e-813ff3dc4e31"}
An SNON fragment receiver requests that listening SNON fragment senders send all current fragments of a given entity class by sending the following message:
#### Example 7.1.5 - Request send all fragments with a device entity class
{"eC": "device"}
#### Example 7.1.6 - Request send all fragments with a relationship entity class
{"eC": "relationship"}
An SNON fragment receiver requests that listening SNON fragment senders send all current fragments with a specific relationship by sending the following message:
#### Example 7.1.7 - Request send all fragments with a specific entity relationship
{"eR": {"child_of": ["urn:uuid:338a889f-f03b-410b-9968-76ca5726ad00"]}}
A typical discovery process would involve the following steps:
1. Send a request for all entities with an entity class of "device"
2. For each device entity ID, send a request for all children of that device to find all sensors
3. For each sensor entity ID, send a request for all children of that sensor to find all series
4. For each series entity ID, send a request for that entity ID to get the series fragment and the current value fragment
5. If no series entity IDs, send a request for the sensor entity ID to get the sensor fragment and the current value fragment
#### Request to Update a Value
An SNON fragment receiver requests that listening SNON fragment senders update the value of an entity by sending a value fragment:
#### Example 7.1.8 - Request to update a specific value
{
"eID": "urn:uuid:e129c1d6-0ac9-474a-948e-813ff3dc4e31",
"v" : ["29.3"]
}
Only a single array item for the value is permitted. If the value time field ("vT") is omitted (an "immediate value update"), as in the example above, the update should be applied immediately. This is a special case which is only permitted when updating a sensor or series value. Value times in the past are also applied immediately. A value time in the future indicates that the value should be changed when that time is reached.
If a value update is accepted, a value fragment containing the updated value will immediately be sent to the receiver. Error handling for when value updates are not accepted is out of scope of this standard, and is typically implemented using a separate error sensor or series, which uses numeric or text strings to indicate device errors.
### 7.2 SNON CloudEvents Transport
The Cloud Native Computing Foundation (CNCF) [CloudEvents standard](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md) provides a standard way to connect systems where the change of state in one system causes code to execute in another system.
When used to transport an SNON fragment, the following CloudEvents are used:
| Field Name | Data Type | Description | Mandatory |
| ------------- | ------------- | ------------- | --------- |
| specversion | JSON String | The version of the CloudEvents specification which the event uses. This enables the interpretation of the context. Compliant event producers shall use the value "1.0". | Mandatory |
| type | JSON String | Type of occurrence which has happened.
Shall be set to the major version value "org.snon.v4". | Mandatory |
| dataschema | JSON String | A link to the schema that the data attribute adheres to.
Shall be set to the value "https://www.snon.org/v4.1/snon-fragment-schema.json". | Optional |
| source | JSON String | Identifies the context in which an event happened.
Shall be set to the entity ID of the device that is sending the event. | Mandatory |
| id | JSON String | Identifies the event.
Shall be set to "urn:urn-5:" followed by the SHA-256 hash, in lowercase hexadecimal, of the RFC 8785 canonical form of the data member. | Mandatory |
| subject | JSON String | This describes the subject of the event in the context of the event producer (identified by source).
If used, shall be set to entity ID specified in the transported SNON fragment. | Optional |
| time | JSON String | Timestamp of when the event happened.
Shall be set to the time the event is generated. | Optional |
| data | JSON Object | The event payload.
Shall be set to an SNON Fragment. | Mandatory |
To transport multiple fragments, or to transport the contents of an SNON pack, multiple CloudEvents shall be used.
#### Example 7.2: An example of an SNON fragment transported in a CloudEvent:
{
"specversion": "1.0",
"type": "org.snon.v4",
"dataschema": "https://www.snon.org/v4.1/snon-fragment-schema.json",
"source": "urn:uuid:407ec909-2519-4a2a-980b-ee75a47020ad",
"id": "urn:urn-5:286e51f354664ede945b510294eac65ca886d3f86129e6a24be4c5e9ce43eef0",
"time": "2014-08-20T14:34:56.125678Z",
"data" : {
"eID": "urn:uuid:1635a44f-b770-4418-8f05-e721823e8e41",
"v" : ["29.3"],
"vT" : ["2014-08-20T14:32:46.125678Z"]
}
}
### 7.3 SNON MQTT Transport
SNON fragments can be transported using an [MQTT broker](https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html).
Topics should be structured as follows:
Root Topic
/snon/# Subscribe to receive all SNON fragments from the device
/snon/ Subscribe to receive SNON fragments for a specific entity ID
The MQTT topic for each message sent by an SNON fragment sender shall contain a root topic followed by the "snon/" string and the entity ID of the fragment being sent. SNON fragment receivers shall take the entity ID from the fragment, not from the topic.
The MQTT message payload for each message sent by an SNON fragment sender shall contain the SNON fragment in a JSON array.
The SNON fragment sender shall publish the active version of each non-value fragment as a retained message when connecting to a broker, and shall update the retained message whenever a new version of that non-value fragment is sent. Value fragments shall be published with the RETAIN flag set to 0, so that they do not replace the retained non-value fragment for the same entity ID. This allows a client to subscribe to the root plus "snon/#" and immediately receive the non-value fragments for all entities, followed by value fragments as they are published.
When an SNON fragment sender stops publishing messages for an entity ID, it should remove the corresponding retained message by publishing a retained zero-byte message to that topic. This removes the fragment from the broker only, and does not delete the entity. SNON fragment receivers shall ignore zero-byte messages.
## 8. SNON License
Clear BSD License
Copyright (c) 2014 – 2021, NetApp, Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted (subject to the limitations in the disclaimer below) provided that the
following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
* Neither the name of NetApp, Inc. nor the names of its contributors may be used
to endorse or promote products derived from this software without specific prior
written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## 9. SNON Changelog
### SNON 4.1 2026-09-03
Non-backward compatible changes:
* meSL/meSH/meDL/meDH restricted to numeric and ordinal
* Relaxed numeric string validation to permit exponent notation for value timeout, measurement span, measurement display, measurement update rate, measurement timeout, measurement resolution and measurement accuracy fields.
* CloudEvents "id" is now the SHA-256 hash of the RFC 8785 canonical form of the data member
Backward compatible changes:
* Updated introduction and added comparison to other standards
* Added terms and definitions, general cleanup for terminology consistency
* Clarified that eUT must be specified on entity changes, explicit rules for when to replace.
* Clarified that the serial protocol uses JSONL framing
* MQTT and SenML recommendations no longer draft status
* Added a definition of "numeric string", clarifying that exponent notation has always been permitted in value, value max and value min fields, and specifying receiver and sender obligations, comparison by value, and exact reproduction
* Clarified that measurement accuracy carries a maximum permissible measurement error, consistent with ISO/IEC Guide 99:2007, and permitted a value of zero
### SNON 4.0 2026-04-12
Non-backward compatible changes:
* Added new "Entity update time" field
* Added "iso8601" strings as supported Measurement Type
* Added "ordinal" as a supported Measurement Type
* Fixed schema to permit relationship fragments to have an entity relationship field
* Added draft guidance for interoperability with [SenML (RFC 8428)](https://datatracker.ietf.org/doc/html/rfc8428)
* Added device tags and location tags to provide interoperability with [ISO/IEC 81346 Structuring principles and reference designations](https://www.iso.org/standard/82229.html)
Backward compatible changes:
* Retired support for SNON 3.x style long field names. SNON 4.x implementations can automatically convert SNON v3.x long field names to the corresponding short names. SNON 4.x style short names are backwards compatible with SNON 3.x.
* Renamed SNON "collections" to "packs", and added clarifications that these can be sent as HTTP streams
* Clarified that any URN namespace that is globally unique can be used for entity IDs
* Clarified description of "eN" to "Entity Display Name"
* Clarified description of "eT" to "Entity Display Type"
* Added section for serial transport
* Added draft section for [MQTT](https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html) transport
### [SNON 3.0.1 2021-01-12](v3/index.html)
* Allow some measurement fields in series fragment (overridden if in measurand)
### [SNON 3.0 2020-12-27](v3/index.html)
Non-backward compatible changes:
* Retired SNON messages
* Retired precedentID
* Added series fragments and measurand fragments to replace precedentID
* entityID now mandatory
* entityTag replaced with sensorTag
* Retired derived_from relationship
Backward compatible changes:
* Fixed incorrect JSON data type for sensor tag field
* Updated CloudEvents spec reference to version 1.0.1
* Added relationship fragments
* Terms and definitions now follow [ISO 80000-1:2009](https://www.iso.org/standard/30669.html) and [ISO/IEC Guide 99:2007](https://www.iso.org/obp/ui/#iso:std:iso-iec:guide:99:ed-1:v2:en)
* Added provenance extension
### [SNON 2.1 2019-08-15](v2.1/index.html)
* Added encapsulation guidance for CNCF [CloudEvents](https://github.com/cloudevents/spec/blob/v1.0.1/spec.md)
* Added Entity Tag for ISA-5.1 naming conventions
### [SNON 2.0 2017-11-28](v2/index.html)
* Added JSON schema
* Specified where user-defined fields are allowed
* Relaxation of field restrictions to improve linked messages
* SNON Messages now can contain multiple SNON Fragments
* sensorHierarchy deprecated. Replaced by deviceID and sensorRelations/deviceRelations
* valueUncertainty, valueSequence, valueSession and valueHealth deprecated
* location field deprecated, replace with sensorRelations/deviceRelations
* Relations added for thresholds, setpoints, alarms, inhibit, indeterminate and flags
* Added Sensor Catalog use cases
* Internationalization support
### [SNON 1.0 / 0.3 2015-08-04](v1/index.html)
* Added additional detail on how to use SNON with MQTT
* Retired messageHash and messageSignature in favor of [JOSE](https://tools.ietf.org/html/rfc7520)
* Addition of field short names for low-resource platforms
* Additional examples added
### SNON 0.2 2015-07-05
* Addition of value timeout and value sequence fields
* Clarification of measureUnit and measureLabel fields
### SNON 0.1 2014-09-24
Please report errors, suggestions, etc, at https://github.com/dslik/snon-spec