RFC 8428
Sensor Measurement Lists (SenML)
Sensor Measurement Lists (SenML) ๐
okay bestie, let's talk about RFC 8428 ๐. It's called "Sensor Measurement Lists (SenML)", and it's a Standards Track spec from August 2018 with ISSN 2070-1721. The authors are C. Jennings from Cisco, Z. Shelby from ARM, J. Arkko and A. Keranen from Ericsson, and C. Bormann from Universitaet Bremen TZI. Its title block doesn't list anything it obsoletes or updates, so it's standing on its own ๐ฆ.
Abstract โจ
okay so this spec defines a format for representing simple sensor measurements and device parameters inside something called Sensor Measurement Lists, or SenML for short ๐ธ. You can write it in four flavours: JavaScript Object Notation (JSON), Concise Binary Object Representation (CBOR), Extensible Markup Language (XML), and Efficient XML Interchange (EXI). They all share the same SenML data model, which is giving consistency and I'm obsessed ๐ญ. A simple sensor, like a temperature sensor, can use one of these media types over protocols like HTTP or the Constrained Application Protocol (CoAP) to send its measurements or get configured ๐ง.
Status of This Memo ๐
this one is an Internet Standards Track document ๐ฅ.
It's a product of the Internet Engineering Task Force (IETF), and it represents the consensus of the IETF community. It went through public review and was approved for publication by the Internet Engineering Steering Group (IESG) ๐. If you want more on Internet Standards, check out Section 2 of RFC 7841.
Info about its current status, any errata, and how to give feedback lives at https://www.rfc-editor.org/info/rfc8428 ๐.
Copyright Notice ๐
Copyright (c) 2018 IETF Trust and the persons identified as the document authors. All rights reserved ๐.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents, which you'll find at https://trustee.ietf.org/license-info as they stood on the publication date. Read those carefully, bestie, because they spell out your rights and restrictions for this document ๐. Any Code Components pulled out of this document have to include the Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come with no warranty, as the Simplified BSD License describes โญ.
Table of Contents ๐ฆ
1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Requirements and Design Goals . . . . . . . . . . . . . . . . 4
3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 6
4. SenML Structure and Semantics . . . . . . . . . . . . . . . . 6
4.1. Base Fields . . . . . . . . . . . . . . . . . . . . . . . 7
4.2. Regular Fields . . . . . . . . . . . . . . . . . . . . . 7
4.3. SenML Labels . . . . . . . . . . . . . . . . . . . . . . 8
4.4. Extensibility . . . . . . . . . . . . . . . . . . . . . . 9
4.5. Records and Their Fields . . . . . . . . . . . . . . . . 9
4.5.1. Names . . . . . . . . . . . . . . . . . . . . . . . . 9
4.5.2. Units . . . . . . . . . . . . . . . . . . . . . . . . 10
4.5.3. Time . . . . . . . . . . . . . . . . . . . . . . . . 10
4.5.4. Values . . . . . . . . . . . . . . . . . . . . . . . 11
4.6. Resolved Records . . . . . . . . . . . . . . . . . . . . 12
4.7. Associating Metadata . . . . . . . . . . . . . . . . . . 12
4.8. Sensor Streaming Measurement Lists (SenSML) . . . . . . . 12
4.9. Configuration and Actuation Usage . . . . . . . . . . . . 13
5. JSON Representation (application/senml+json) . . . . . . . . 13
5.1. Examples . . . . . . . . . . . . . . . . . . . . . . . . 14
5.1.1. Single Data Point . . . . . . . . . . . . . . . . . . 14
5.1.2. Multiple Data Points . . . . . . . . . . . . . . . . 14
5.1.3. Multiple Measurements . . . . . . . . . . . . . . . . 15
5.1.4. Resolved Data . . . . . . . . . . . . . . . . . . . . 17
5.1.5. Multiple Data Types . . . . . . . . . . . . . . . . . 17
5.1.6. Collection of Resources . . . . . . . . . . . . . . . 18
5.1.7. Setting an Actuator . . . . . . . . . . . . . . . . . 18
6. CBOR Representation (application/senml+cbor) . . . . . . . . 19
7. XML Representation (application/senml+xml) . . . . . . . . . 21
8. EXI Representation (application/senml-exi) . . . . . . . . . 23
9. Fragment Identification Methods . . . . . . . . . . . . . . . 26
9.1. Fragment Identification Examples . . . . . . . . . . . . 26
9.2. Fragment Identification for XML and EXI Formats . . . . . 27
10. Usage Considerations . . . . . . . . . . . . . . . . . . . . 27
11. CDDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
12. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 30
12.1. SenML Units Registry . . . . . . . . . . . . . . . . . . 30
12.2. SenML Labels Registry . . . . . . . . . . . . . . . . . 35
12.3. Media Type Registrations . . . . . . . . . . . . . . . . 36
12.3.1. senml+json Media Type Registration . . . . . . . . . 37
12.3.2. sensml+json Media Type Registration . . . . . . . . 38
12.3.3. senml+cbor Media Type Registration . . . . . . . . . 39
12.3.4. sensml+cbor Media Type Registration . . . . . . . . 41
12.3.5. senml+xml Media Type Registration . . . . . . . . . 42
12.3.6. sensml+xml Media Type Registration . . . . . . . . . 43
12.3.7. senml-exi Media Type Registration . . . . . . . . . 44
12.3.8. sensml-exi Media Type Registration . . . . . . . . . 45
12.4. XML Namespace Registration . . . . . . . . . . . . . . . 47
12.5. CoAP Content-Format Registration . . . . . . . . . . . . 47
13. Security Considerations . . . . . . . . . . . . . . . . . . . 47
14. Privacy Considerations . . . . . . . . . . . . . . . . . . . 48
15. References . . . . . . . . . . . . . . . . . . . . . . . . . 49
15.1. Normative References . . . . . . . . . . . . . . . . . . 49
15.2. Informative References . . . . . . . . . . . . . . . . . 51
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 53
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 54
1. Overview ๐งโโ๏ธ
okay so connecting sensors to the Internet is not new at all, and people have designed plenty of protocols for it ๐ธ. This spec defines a format and media types for carrying simple sensor information over protocols like HTTP [RFC7230] or CoAP [RFC7252]. The whole point of SenML is that processors with very limited capabilities can easily encode a sensor measurement into the media type, while a server parsing the data can collect a huge number of measurements in a relatively efficient way ๐
. SenML works for a bunch of data flow models. The big ones are data feeds pushed from a sensor to a collector, and the web resource model, where the sensor data gets requested as a resource representation, like "GET /sensor/temperature" ๐ฆ.
There are plenty of more complex measurements, and some of them this media type just isn't suitable for ๐. SenML has a vibe of balance, though. It carries some info about the sensor along with the data so the data is self-describing, but it keeps that extra info pretty minimal for efficiency reasons โจ. Other info about the sensor can be discovered by other methods, like the Constrained RESTful Environments (CoRE) Link Format [RFC6690] ๐.
SenML is defined by a data model for measurements and simple metadata about measurements and devices. The data is structured as a single array holding a series of SenML Records. Each Record can have fields like a unique identifier for the sensor, the time the measurement was made, the unit the measurement is in, and the current value of the sensor ๐ฅ. Serializations for this data model are defined for JSON [RFC8259], CBOR [RFC7049], XML [W3C.REC-xml-20081126], and Efficient XML Interchange (EXI) [W3C.REC-exi-20140211] ๐.
Here's an example of a measurement from a temperature gauge, encoded in JSON syntax ๐:
[
{"n":"urn:dev:ow:10e2073a01080063","u":"Cel","v":23.1}
]
In this example, the array has a single SenML Record. It holds a measurement for a sensor named "urn:dev:ow:10e2073a01080063" with a current value of 23.1 degrees Celsius. Literally that's it, that's the tea โ๐.
2. Requirements and Design Goals โจ
okay so the big goal ๐ is to send simple sensor measurements in small packets from loads of constrained devices. Keeping the payload tiny also means SenML can ride along in constrained networks too, like IPv6 over Low-Power Wireless Personal Area Network (6LoWPAN) [RFC4944]. Defining "small code" is honestly hard to pin down, but the vibe is being able to run this on roughly 1 KB of flash on an 8-bit microprocessor ๐ .
Power meters and other big real-world deployments showed that you need to batch multiple measurements into a single HTTP or CoAP request ๐ฆ. This "batch" upload is iconic because it lets the server side handle a massive number of devices efficiently ๐ซถ. It also works great for batch transfers from proxies and storage devices, even when the sensor itself only sends one data item at a time. The measurements can come from several related sensors, or from the same sensor at different times.
The basic design is an array holding a series of measurements. Here's an example with two measurements taken at different times. The value is in the "v" field, the time is in the "t" field, the "n" field holds a unique sensor name, and the unit lives in the "u" field ๐ฆ.
[
{"n":"urn:dev:ow:10e2073a01080063","u":"Cel","t":1.276020076e+09,
"v":23.5},
{"n":"urn:dev:ow:10e2073a01080063","u":"Cel","t":1.276020091e+09,
"v":23.6}
]
Repeating "n" in every SenML Record is a waste of bytes, so there's a concept called the Base Name ๐. A Base Name is just a string that gets prepended to the Name field of all elements in that Record and in any Records that follow it. So a much more compact version of the example above looks like this:
[
{"bn":"urn:dev:ow:10e2073a01080063","u":"Cel","t":1.276020076e+09,
"v":23.5},
{"u":"Cel","t":1.276020091e+09,
"v":23.6}
]
In the above example, the Base Name is in the "bn" field, and the "n" fields in each Record are empty strings, so they are omitted ๐.
Some devices have accurate time and some don't, so SenML supports both absolute and relative times โฐ. Time is represented in floating point as seconds. Values greater than or equal to 2**28 represent an absolute time relative to the Unix epoch. Values less than 2**28 represent time relative to the current time.
A simple sensor with no absolute wall-clock time might take a measurement every second, batch up 60 of them, and then send the batch to a server. In each SenML Record, it would include the relative time each measurement was made compared to the time the batch was sent. If the server has accurate time based on, e.g., the Network Time Protocol (NTP), it may use the time it received the data and the relative offset to replace the times in the SenML with absolute times before saving the SenML information in a document database. Main character energy for the server, honestly ๐.
3. Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here ๐.
This document also uses the following terms:
- SenML Record: One measurement or configuration instance in time presented using the SenML data model.
- SenML Pack: One or more SenML Records in an array structure.
- SenML Label: A short name used in SenML Records to denote different SenML fields (e.g., "v" for "value").
- SenML Field: A component of a record that associates a value to a SenML Label for this record.
- SenSML: Sensor Streaming Measurement List (see Section 4.8).
- SenSML Stream: One or more SenML Records to be processed as a stream.
This document uses the terms "attribute" and "tag" where they occur with the underlying technologies (XML, CBOR [RFC7049], and the CoRE Link Format [RFC6690]); they are not used for SenML concepts, per se. However, note that "attribute" has been widely used in the past as a synonym for the SenML "field" ๐ง.
All comparisons of text strings are performed byte by byte, which results in the comparisons being case sensitive. No sneaky case-insensitive vibes here ๐ โโ๏ธ.
Where arithmetic is used, this specification uses the familiar notation of the programming language C, except that the operator ** stands for exponentiation ๐.
4. SenML Structure and Semantics ๐ธ
Each SenML Pack carries a single array that represents a set of measurements and/or parameters. This array contains a series of SenML Records with several fields described below. There are two kinds of fields: base and regular. Both the base and regular fields can be included in any SenML Record. The base fields apply to the entries in the Record and also to all Records after it up to, but not including, the next Record that has that same base field. All base fields are optional. Regular fields can be included in any SenML Record and apply only to that Record.
4.1. Base Fields
- Base Name: This is a string that is prepended to the names found in the entries.
- Base Time: A base time that is added to the time found in an entry.
- Base Unit: A base unit that is assumed for all entries, unless otherwise indicated. If a record does not contain a Unit value, then the Base Unit is used. Otherwise, the value found in the Unit (if any) is used.
- Base Value: A base value is added to the value found in an entry, similar to Base Time.
- Base Sum: A base sum is added to the sum found in an entry, similar to Base Time.
- Base Version: Version number of the media type format. This field is an optional positive integer and defaults to 10 if not present.
4.2. Regular Fields
- Name: Name of the sensor or parameter. When appended to the Base Name field, this must result in a globally unique identifier for the resource. The name is optional, if the Base Name is present. If the name is missing, the Base Name must uniquely identify the resource. This can be used to represent a large array of measurements from the same sensor without having to repeat its identifier on every measurement ๐.
- Unit: Unit for a measurement value. Optional.
- Value: Value of the entry. Optional if a Sum value is present; otherwise, it's required. Values are represented using basic data types. This specification defines floating-point numbers ("v" field for "Value"), booleans ("vb" for "Boolean Value"), strings ("vs" for "String Value"), and binary data ("vd" for "Data Value"). Exactly one Value field MUST appear unless there is a Sum field, in which case it is allowed to have no Value field ๐.
- Sum: Integrated sum of the values over time. Optional. This field is in the unit specified in the Unit value multiplied by seconds. For historical reasons, it is named "sum" instead of "integral" ๐ค.
- Time: Time when the value was recorded. Optional.
- Update Time: Period of time in seconds that represents the maximum time before this sensor will provide an updated reading for a measurement. Optional. This can be used to detect the failure of sensors or the communications path from the sensor. Ngl, this one is so useful for catching dead sensors ๐ญ.
4.3. SenML Labels
Table 1 gives you the full overview of all SenML fields defined by this document, with their labels and data types ๐.
+---------------+-------+------------+------------+------------+
| Name | Label | CBOR Label | JSON Type | XML Type |
+---------------+-------+------------+------------+------------+
| Base Name | bn | -2 | String | string |
| Base Time | bt | -3 | Number | double |
| Base Unit | bu | -4 | String | string |
| Base Value | bv | -5 | Number | double |
| Base Sum | bs | -6 | Number | double |
| Base Version | bver | -1 | Number | int |
| Name | n | 0 | String | string |
| Unit | u | 1 | String | string |
| Value | v | 2 | Number | double |
| String Value | vs | 3 | String | string |
| Boolean Value | vb | 4 | Boolean | boolean |
| Data Value | vd | 8 | String (*) | string (*) |
| Sum | s | 5 | Number | double |
| Time | t | 6 | Number | double |
| Update Time | ut | 7 | Number | double |
+---------------+-------+------------+------------+------------+
Table 1: SenML Labels
(*) Data Value is a base64-encoded string with the URL-safe alphabet as defined in Section 5 of [RFC4648], with padding omitted. (In CBOR, the octets in the Data Value are encoded using a definite-length byte string, major type 2.)
For details of the JSON representation, see Section 5; for CBOR, see Section 6; and for XML, see Section 7. Lots of options, pick your fave ๐.
4.4. Extensibility
The SenML format can be extended with further custom fields. Both new base and regular fields are allowed. See Section 12.2 for details. Implementations MUST ignore fields they don't recognize unless that field has a label name that ends with the "_" character, in which case an error MUST be generated ๐จ.
All SenML Records in a Pack MUST have the same version number. This is typically done by adding a Base Version field to only the first Record in the Pack or by using the default value ๐ข.
Systems reading one of the objects MUST check for the Base Version field. If this value is a version number larger than the version that the system understands, the system MUST NOT use this object. This allows the version number to indicate that the object contains structure or semantics that is different from what is defined in the present document beyond just making use of the extension points provided here. New version numbers can only be defined in an RFC that updates this specification or its successors. Version drama, but make it make sense ๐ .
4.5. Records and Their Fields
4.5.1. Names โจ
okay so the Name value gets stuck onto the Base Name to make the sensor's full name ๐. That full name has to be unique so it can tell your sensor apart from every other sensor out there, bestie. The full name MUST consist only of characters from "A" to "Z", "a" to "z", and "0" to "9", plus "-", ":", ".", "/", and "_". It also MUST start with a character from "A" to "Z", "a" to "z", or "0" to "9" ๐ซถ. Why so picky? This small set means names can go straight into URIs, even HTTP path segments with no special encoding. A name with "/" in it turns into several path segments, which is a whole vibe ๐ค๏ธ. It also means they drop right into databases and analytics systems without any drama. [RFC5952] has advice on putting an IPv6 address into a name ๐. And if you're worried about long-term stable unique identifiers, check Section 14 for the privacy stuff ๐.
Although it is RECOMMENDED that concatenated names be represented as URIs [RFC3986] or URNs [RFC8141], the restricted character set above is super strict about which URI schemes and URN namespaces you can use ๐. So implementers need to be careful when picking a naming scheme, because the name has to be unique AND fit that character set. One approach is to include a bit string with guaranteed uniqueness, like a 1-wire address [AN1796] ๐ง. Some examples in this document use the device URN namespace from [DEVICE-URN] ๐ . Universally Unique Identifiers (UUIDs) [RFC4122] are another way to make a unique name โจ. The catch is that the restricted character set doesn't allow many URI schemes, like the "tag" scheme [RFC4151] and the "ni" scheme [RFC6920], to be used as names directly ๐. Using URIs with characters outside this set, and any mapping rules between the two, are outside the scope of this document, so that's a different story ๐.
4.5.2. Units ๐
If the Record has no Unit, the Base Unit gets used as the Unit ๐. Having no Unit and no Base Unit at all is allowed, no cap ๐งข. In that case, any info about units that applies to the value has to come from the application context instead ๐ธ.
4.5.3. Time โฐ
If either the Base Time or the Time value is missing, the missing one counts as zero ๐ฆ. The Base Time and Time values get added together to give the time of measurement, so it's basically a team effort ๐.
Values less than 268,435,456 (228) represent time relative to the current time ๐. So a time of zero means the sensor doesn't know the absolute time, and the measurement was made roughly "now" โณ. A negative value means that many seconds in the past from roughly "now" ๐ฐ๏ธ. Positive values up to 228 mean seconds in the future from "now" ๐ฎ. An example of when you'd use positive values is actuation, where the change should happen later, but neither the sender nor the receiver has accurate time available ๐ค.
Values greater than or equal to 228 represent an absolute time relative to the Unix epoch (1970-01-01T00:00Z in UTC time) ๐. They're counted the same way as the Portable Operating System Interface (POSIX) "seconds since the epoch" [TIME_T] ๐งฎ. So the smallest absolute Time value you can express (228) is 1978-07-04 21:24:16 UTC ๐.
Watch out, bestie! Because Time values up to 228 are used for "now"-relative times, and Time and Base Time get added together, you need to make sure the sum doesn't accidentally hit 228 (the absolute time range) when you meant to use relative time ๐จ.
Obviously, SenML Records referenced to "now" are only useful within a specific communication context ๐โโ๏ธ. For example, that could be when the SenML Pack, or a specific Record in a SenSML Stream, was sent. Or they can be used together with other context info that tells you what "now" means ๐บ๏ธ. The expectation for any archival use is that they get turned into UTC-referenced records before that context goes away ๐ฆ. This spec deliberately keeps the accuracy of "now" super vague, since the overall systems using SenML decide that ๐คทโโ๏ธ. For instance, a sensor with no wall-clock time sends a SenML Record with a "now" time over a high-speed RS-485 link to an embedded system with accurate time. That system resolves "now" based on when it received the Record, and the time uncertainty could be within 1 ms โก. At the other extreme, a deployment that sends SenML wind-speed readings over a Low-Earth Orbit (LEO) satellite link from a mountain valley might end up with reception Time values that are easily a dozen minutes off from when the sensor actually read the value ๐๏ธ๐ฐ๏ธ. The uncertainty depends on satellite locations and conditions ๐ญ.
4.5.4. Values ๐
If only one of the Base Sum or Sum value is present, the missing one counts as zero ๐ซ. The Base Sum and Sum values get added together to give the sum of measurement โ. If neither the Base Sum nor the Sum is present, then the measurement doesn't have a Sum value at all ๐ โโ๏ธ.
If the Base Value or Value is not present, the missing one(s) count as zero ๐ญ. The Base Value and Value get added together to give the value of the measurement ๐.
Representing statistical stuff about measurements, like accuracy, can get really complex ๐คฏ. Future specs might add new fields to give better info about the statistical properties of a measurement ๐.
Okay, the summary: a SenML Record is built to hold a single measurement ๐ฏ. If several data values are measured at the same time (like air pressure and altitude), they're best kept as separate Records linked through their Time value ๐. This still applies even when one of the values is more "meta" than the others, like something describing a condition that affects the other measurements taken at the same time ๐.
4.6. Resolved Records ๐งฉ
Sometimes it's really useful to refer to a defined, normalized format for SenML Records ๐ . This normalized format tends to get used for big data apps and as an intermediate form when converting to other formats ๐. Also, if SenML Records are used outside of a SenML Pack, they need to be resolved first so the applicable base values get applied ๐ง.
A SenML Record is called "resolved" if it doesn't contain any base values (labels starting with the character "b"), except for Base Version fields (see below), and it has no relative times โจ. To resolve the Records, the applicable base values of the SenML Pack (if there are any) get applied to the Record ๐. So for the base values in the Record or before it in the Pack, Name and Base Name get concatenated, the Base Time gets added to the Record's time, the Base Unit gets applied if the Record didn't have a Unit, and so on ๐ ๏ธ. On top of that, the Records need to be in chronological order in the Pack โณ. You can see an example of this in Section 5.1.4 ๐ฌ.
The Base Version field MUST NOT be present in resolved Records if the SenML version defined in this document is used. Otherwise, it MUST be present in all the resolved SenML Records ๐.
A future spec that defines new base fields will need to say how that field gets resolved ๐ฎ.
4.7. Associating Metadata ๐๏ธ
SenML is designed to carry the minimum dynamic info about measurements ๐โโ๏ธ. For efficiency reasons, it does not carry a lot of static metadata about the device, object, or sensors ๐จ. Instead, it's assumed that this metadata is carried out of band ๐ธ. For web resources using SenML Packs, this metadata can be made available using the CoRE Link Format [RFC6690] ๐. The most obvious use of this link format is to describe that a resource is available in a SenML format in the first place ๐. The relevant media type indicator goes in the Content-Type (ct=) link attribute, which is defined for the link format in Section 7.2.1 of [RFC7252] ๐.
4.8. Sensor Streaming Measurement Lists (SenSML) ๐
In some usage scenarios, implementations store or transmit SenML in a stream-like way, where data gets collected over time and continuously added to the object ๐โจ. This mode of operation is optional, but systems or protocols that use SenML this way MUST specify that they're doing it ๐ฃ. SenML defines separate media types to indicate Sensor Streaming Measurement Lists (SenSML) for this usage (see Section 12.3.2) ๐. In this situation, the SenSML Stream can be sent and received in a partial fashion. That means a measurement entry can be read as soon as its SenML Record is received, and it doesn't have to wait for the full SenSML Stream to be complete ๐โโ๏ธ๐จ.
If times relative to "now" (see Section 4.5.3) are used in SenML Records of a SenSML Stream, their interpretation of "now" is based on the time when that specific Record is sent in the stream โฑ๏ธ.
4.9. Configuration and Actuation Usage ๐น๏ธ
SenML can also be used for configuring parameters and controlling actuators ๐ค๐ . When a SenML Pack is sent (for example, using an HTTP/CoAP POST or PUT method) and the semantics of the target mean that SenML is interpreted as configuration or actuation, the SenML Records get interpreted as a request. That request asks to change the values of given (sub)resources, identified by their names, to the given values at the given time(s) ๐ฏ. The semantics of the target resource that supports this usage can be described using [RID-CoRE] ๐. Examples of actuation usage are shown in Section 5.1.7 ๐ฌโจ.
5. JSON Representation (application/senml+json) ๐
okay so bestie, this is where SenML gets dressed up in JSON ๐ For the fields in Table 2, the SenML Labels become the JSON object member names inside the objects that represent each SenML Record. Cute, right? ๐ฆ
+---------------+-------+-----------+
| Name | Label | JSON Type |
+---------------+-------+-----------+
| Base Name | bn | String |
| Base Time | bt | Number |
| Base Unit | bu | String |
| Base Value | bv | Number |
| Base Sum | bs | Number |
| Base Version | bver | Number |
| Name | n | String |
| Unit | u | String |
| Value | v | Number |
| String Value | vs | String |
| Boolean Value | vb | Boolean |
| Data Value | vd | String |
| Sum | s | Number |
| Time | t | Number |
| Update Time | ut | Number |
+---------------+-------+-----------+
Table 2: JSON SenML Labels ๐
The root JSON value is an array with one JSON object for each SenML Record. Every field in that table MAY show up in the Records, as long as its member value is the type the table lists. Flexible, iconic ๐
Only the UTF-8 [RFC3629] form of JSON is allowed, so no other encodings are invited to this party ๐
โโ๏ธ String Values use the escape sequences from [RFC8259]. Data Value octets get base64 encoded with the URL-safe alphabet from Section 5 of [RFC4648], and the padding is dropped. Bye bye, = ๐
Here's the big one, so listen up ๐ Systems that receive measurements MUST be able to process the range of floating-point numbers that IEEE double-precision floating-point numbers can represent [IEEE.754]. That's what lets Time values have better than microsecond precision for the next 100 years, which is honestly a whole flex โจ The number of significant digits doesn't matter, so 1.1 means exactly the same thing as 1.10. Same energy, no drama ๐ If the value has an exponent, the "e" MUST be in lower case. Also, to keep things short and processing fast, the mantissa SHOULD be less than 19 characters long, and the exponent SHOULD be less than 5 characters long ๐ซถ
5.1. Examples ๐
5.1.1. Single Data Point ๐ธ
Here's a temperature reading taken approximately "now" by a 1-wire sensor device with the unique 1-wire address of 10e2073a01080063 ๐ก๏ธ
[
{"n":"urn:dev:ow:10e2073a01080063","u":"Cel","v":23.1}
]
5.1.2. Multiple Data Points ๐ฆ
This example shows voltage and current "now", which means at an unspecified time. Main character energy โก
[
{"bn":"urn:dev:ow:10e2073a01080063:","n":"voltage","u":"V","v":120.1},
{"n":"current","u":"A","v":1.2}
]
The next one is similar, but this time the current is reported at Tue Jun 8 18:01:16.001 UTC 2010 and at each second for the previous 5 seconds. Time travel, bestie ๐ง
[
{"bn":"urn:dev:ow:10e2073a0108006:","bt":1.276020076001e+09,
"bu":"A","bver":5,
"n":"voltage","u":"V","v":120.1},
{"n":"current","t":-5,"v":1.2},
{"n":"current","t":-4,"v":1.3},
{"n":"current","t":-3,"v":1.4},
{"n":"current","t":-2,"v":1.5},
{"n":"current","t":-1,"v":1.6},
{"n":"current","v":1.7}
]
Now for SenSML ๐ This example is a stream of measurements that might get sent through a long-lived HTTP POST from the producer to its consumer. Each measurement object can be reported at the time it was measured. It's giving continuous content ๐ญ
[
{"bn":"urn:dev:ow:10e2073a01080063","bt":1.320067464e+09,
"bu":"%RH","v":21.2},
{"t":10,"v":21.3},
{"t":20,"v":21.4},
{"t":30,"v":21.4},
{"t":40,"v":21.5},
{"t":50,"v":21.5},
{"t":60,"v":21.5},
{"t":70,"v":21.6},
{"t":80,"v":21.7},
...
5.1.3. Multiple Measurements ๐ก
This one is humidity data from a mobile device with the 1-wire address 10e2073a01080063, starting at Mon Oct 31 13:24:24 UTC 2011. The device also reports position data, which goes in the same measurement or parameter array as separate entries. Time is what ties together data that belongs together, like a measurement and a parameter linked to it, so it's giving friendship goals ๐ซถ Finally, the device sends extra battery status data at a separate time. Multitasking queen ๐
[
{"bn":"urn:dev:ow:10e2073a01080063","bt":1.320067464e+09,
"bu":"%RH","v":20},
{"u":"lon","v":24.30621},
{"u":"lat","v":60.07965},
{"t":60,"v":20.3},
{"u":"lon","t":60,"v":24.30622},
{"u":"lat","t":60,"v":60.07965},
{"t":120,"v":20.7},
{"u":"lon","t":120,"v":24.30623},
{"u":"lat","t":120,"v":60.07966},
{"u":"%EL","t":150,"v":98},
{"t":180,"v":21.2},
{"u":"lon","t":180,"v":24.30628},
{"u":"lat","t":180,"v":60.07967}
]
This table shows how big this example is in different forms, and how big each form is after gzip compression ๐ฆ Size comparisons are lowkey my fave ๐ค
+----------+------+-----------------+
| Encoding | Size | Compressed Size |
+----------+------+-----------------+
| JSON | 573 | 206 |
| XML | 649 | 235 |
| CBOR | 254 | 196 |
| EXI | 161 | 184 |
+----------+------+-----------------+
Table 3: Size Comparisons ๐
5.1.4. Resolved Data ๐
Here's the example from the previous section, but in resolved format. Every record gets its full name and absolute time, so nothing is left to guesswork ๐
[
{"n":"urn:dev:ow:10e2073a01080063","u":"%RH","t":1.320067464e+09,
"v":20},
{"n":"urn:dev:ow:10e2073a01080063","u":"lon","t":1.320067464e+09,
"v":24.30621},
{"n":"urn:dev:ow:10e2073a01080063","u":"lat","t":1.320067464e+09,
"v":60.07965},
{"n":"urn:dev:ow:10e2073a01080063","u":"%RH","t":1.320067524e+09,
"v":20.3},
{"n":"urn:dev:ow:10e2073a01080063","u":"lon","t":1.320067524e+09,
"v":24.30622},
{"n":"urn:dev:ow:10e2073a01080063","u":"lat","t":1.320067524e+09,
"v":60.07965},
{"n":"urn:dev:ow:10e2073a01080063","u":"%RH","t":1.320067584e+09,
"v":20.7},
{"n":"urn:dev:ow:10e2073a01080063","u":"lon","t":1.320067584e+09,
"v":24.30623},
{"n":"urn:dev:ow:10e2073a01080063","u":"lat","t":1.320067584e+09,
"v":60.07966},
{"n":"urn:dev:ow:10e2073a01080063","u":"%EL","t":1.320067614e+09,
"v":98},
{"n":"urn:dev:ow:10e2073a01080063","u":"%RH","t":1.320067644e+09,
"v":21.2},
{"n":"urn:dev:ow:10e2073a01080063","u":"lon","t":1.320067644e+09,
"v":24.30628},
{"n":"urn:dev:ow:10e2073a01080063","u":"lat","t":1.320067644e+09,
"v":60.07967}
]
5.1.5. Multiple Data Types ๐จ
This sensor is versatile and returns different data types, which is so iconic ๐
[
{"bn":"urn:dev:ow:10e2073a01080063:","n":"temp","u":"Cel","v":23.1},
{"n":"label","vs":"Machine Room"},
{"n":"open","vb":false},
{"n":"nfc-reader","vd":"aGkgCg"}
]
5.1.6. Collection of Resources ๐งบ
This example shows the results of a query to one device that pulls together measurements from other devices. The client fetched information from a device at 2001:db8::2 with a GET operation on http://[2001:db8::2] at Mon Oct 31 16:27:09 UTC 2011. It got two separate values back: a temperature and humidity measurement, plus the results from another device at http://[2001:db8::1], which also had a temperature and humidity measurement. The last record uses the Base Name from the 3rd record but the Base Time from the first record. Plot twist ๐ณ
[
{"bn":"2001:db8::2/","bt":1.320078429e+09,
"n":"temperature","u":"Cel","v":25.2},
{"n":"humidity","u":"%RH","v":30},
{"bn":"2001:db8::1/","n":"temperature","u":"Cel","v":12.3},
{"n":"humidity","u":"%RH","v":67}
]
5.1.7. Setting an Actuator ๐๏ธ
This example shows the SenML that could set the current set point of a typical residential thermostat. That thermostat has a temperature set point, a switch to turn the heat on and off, and a switch to turn on the fan override. Ngl, it's a whole vibe ๐ฅ
[
{"bn":"urn:dev:ow:10e2073a01080063:"},
{"n":"temp","u":"Cel","v":23.1},
{"n":"heat","u":"/","v":1},
{"n":"fan","u":"/","v":0}
]
Next, two different lights get turned on. We're assuming the lights are on a network that can guarantee delivery of messages to both lights within 15 ms (for example, a network using 802.1BA [IEEE802.1BA] and 802.1AS [IEEE802.1AS] for time synchronization). The controller sets the lights to come on at 20 ms in the future from the current time. That way, both lights receive the message, wait until that time, then apply the switch command, so they come on at the exact same moment โจ Synchronized slay ๐
[
{"bt":1.320078429e+09,"bu":"/","n":"2001:db8::3","v":1},
{"n":"2001:db8::4","v":1}
]
Last one! ๐ซถ Two lights get turned off using a non-deterministic network that has high odds of delivering a message in less than 100 ms and uses NTP for time synchronization. The current time is 1320078429. The user just flipped a light switch that turns off two lights. Both lights immediately dim to 50% brightness so the user gets instant feedback that something is changing. Since the network is what it is, the lights will probably dim at somewhat different times. Then, 100 ms in the future, both lights go off at the same time. The instant but not-quite-synchronized dimming feels like a quick response, and the timed-off 100 ms later makes it look like both lights went off together ๐
[
{"bt":1.320078429e+09,"bu":"/","n":"2001:db8::3","v":0.5},
{"n":"2001:db8::4","v":0.5},
{"n":"2001:db8::3","t":0.1,"v":0},
{"n":"2001:db8::4","t":0.1,"v":0}
]
6. CBOR Representation (application/senml+cbor) ๐
okay so the CBOR [RFC7049] version is basically the JSON one as a twin ๐ฏโโ๏ธ, just with a few glow-ups:
- For JSON Numbers, CBOR can use integers, floating-point numbers, or decimal fractions (CBOR Tag 4) ๐ข but you SHOULD pick the one where, once the CBOR value gets turned into an IEEE double-precision, floating-point value, it has exactly the same value as the original JSON Number turned into that same form โจ And for the version number? Only an unsigned integer is allowed. Periodt ๐
- Characters in the String Value get encoded as a text string with a definite length (major type 3) ๐ and the octets in the Data Value get encoded as a byte string with a definite length (major type 2) ๐ฆ
- For compactness, CBOR uses integers for the labels, as listed in Table 4 ๐ง This table is conclusive, meaning there's no plan to define any more integer map keys. Any extensions will use string map keys instead ๐ซถ That way, translators converting between CBOR and JSON can handle all future labels without implementations needing an update. Base values get negative CBOR labels, and everything else gets non-negative labels ๐
- For streaming SenML in the CBOR representation, the array holding the records SHOULD be a CBOR array with an indefinite length ๐ For non-streaming SenML, an array with a definite length MUST be used ๐ฆ
+---------------+-------+------------+
| Name | Label | CBOR Label |
+---------------+-------+------------+
| Base Version | bver | -1 |
| Base Name | bn | -2 |
| Base Time | bt | -3 |
| Base Unit | bu | -4 |
| Base Value | bv | -5 |
| Base Sum | bs | -6 |
| Name | n | 0 |
| Unit | u | 1 |
| Value | v | 2 |
| String Value | vs | 3 |
| Boolean Value | vb | 4 |
| Sum | s | 5 |
| Time | t | 6 |
| Update Time | ut | 7 |
| Data Value | vd | 8 |
+---------------+-------+------------+
Table 4: CBOR Representation: Integers for Map Keys
The following example shows a dump of the CBOR example for the same sensor measurement as in Section 5.1.2 ๐ธ
0000 87 a7 21 78 1b 75 72 6e 3a 64 65 76 3a 6f 77 3a |..!x.urn:dev:ow:|
0010 31 30 65 32 30 37 33 61 30 31 30 38 30 30 36 3a |10e2073a0108006:|
0020 22 fb 41 d3 03 a1 5b 00 10 62 23 61 41 20 05 00 |".A...[..b#aA ..|
0030 67 76 6f 6c 74 61 67 65 01 61 56 02 fb 40 5e 06 |gvoltage.aV..@^.|
0040 66 66 66 66 66 a3 00 67 63 75 72 72 65 6e 74 06 |fffff..gcurrent.|
0050 24 02 fb 3f f3 33 33 33 33 33 33 a3 00 67 63 75 |$..?.333333..gcu|
0060 72 72 65 6e 74 06 23 02 fb 3f f4 cc cc cc cc cc |rrent.#..?......|
0070 cd a3 00 67 63 75 72 72 65 6e 74 06 22 02 fb 3f |...gcurrent."..?|
0080 f6 66 66 66 66 66 66 a3 00 67 63 75 72 72 65 6e |.ffffff..gcurren|
0090 74 06 21 02 f9 3e 00 a3 00 67 63 75 72 72 65 6e |t.!..>...gcurren|
00a0 74 06 20 02 fb 3f f9 99 99 99 99 99 9a a3 00 67 |t. ..?.........g|
00b0 63 75 72 72 65 6e 74 06 00 02 fb 3f fb 33 33 33 |current....?.333|
00c0 33 33 33 |333|
00c3
In CBOR diagnostic notation (Section 6 of [RFC7049]), this is ๐ง
[{-2: "urn:dev:ow:10e2073a0108006:",
-3: 1276020076.001, -4: "A", -1: 5, 0: "voltage", 1: "V", 2: 120.1},
{0: "current", 6: -5, 2: 1.2}, {0: "current", 6: -4, 2: 1.3},
{0: "current", 6: -3, 2: 1.4}, {0: "current", 6: -2, 2: 1.5},
{0: "current", 6: -1, 2: 1.6}, {0: "current", 6: 0, 2: 1.7}]
7. XML Representation (application/senml+xml) ๐
A SenML Pack or Stream can also be represented in XML format, as defined in this section ๐ท
Only the UTF-8 form of XML is allowed ๐บ๐ธ Octets in the Data Value are base64 encoded with the URL-safe alphabet, as defined in Section 5 of [RFC4648], with padding omitted ๐ซง
The following shows an XML example for the same sensor measurement as in Section 5.1.2 โจ
<sensml xmlns="urn:ietf:params:xml:ns:senml">
<senml bn="urn:dev:ow:10e2073a0108006:" bt="1.276020076001e+09"
bu="A" bver="5" n="voltage" u="V" v="120.1"></senml>
<senml n="current" t="-5" v="1.2"></senml>
<senml n="current" t="-4" v="1.3"></senml>
<senml n="current" t="-3" v="1.4"></senml>
<senml n="current" t="-2" v="1.5"></senml>
<senml n="current" t="-1" v="1.6"></senml>
<senml n="current" v="1.7"></senml>
</sensml>
The SenML Stream is represented as a sensml element that contains a series of senml elements, one for each SenML Record ๐ง The SenML fields are represented as XML attributes. For each field defined in this document, Table 5 shows the SenML Labels (used as the XML attribute name) along with the restrictions on the XML attribute values ("type") used in the XML senml elements ๐ฆ
+---------------+-------+----------+
| Name | Label | XML Type |
+---------------+-------+----------+
| Base Name | bn | string |
| Base Time | bt | double |
| Base Unit | bu | string |
| Base Value | bv | double |
| Base Sum | bs | double |
| Base Version | bver | int |
| Name | n | string |
| Unit | u | string |
| Value | v | double |
| String Value | vs | string |
| Data Value | vd | string |
| Boolean Value | vb | boolean |
| Sum | s | double |
| Time | t | double |
| Update Time | ut | double |
+---------------+-------+----------+
Table 5: XML SenML Labels
The RelaxNG [RNC] Schema for the XML is ๐
default namespace = "urn:ietf:params:xml:ns:senml"
namespace rng = "http://relaxng.org/ns/structure/1.0"
senml = element senml {
attribute bn { xsd:string }?,
attribute bt { xsd:double }?,
attribute bv { xsd:double }?,
attribute bs { xsd:double }?,
attribute bu { xsd:string }?,
attribute bver { xsd:int }?,
attribute n { xsd:string }?,
attribute s { xsd:double }?,
attribute t { xsd:double }?,
attribute u { xsd:string }?,
attribute ut { xsd:double }?,
attribute v { xsd:double }?,
attribute vb { xsd:boolean }?,
attribute vs { xsd:string }?,
attribute vd { xsd:string }?
}
sensml =
element sensml {
senml+
}
start = sensml
8. EXI Representation (application/senml-exi) โจ
okay so bestie, if you're sending SenML over something tiny and constrained, EXI is the move ๐ฆ It takes the XML Schema [W3C.REC-xmlschema-1-20041028] structure of SenML and turns the tags and values into binary instead of ASCII text. An EXI representation of SenML SHOULD be made using the strict schema mode of EXI. BUT (ngl this is the plot twist) strict mode doesn't allow tag extensions to the schema, so any extensions get lost in the encoding ๐ญ If you need your extensions to survive, the non-strict schema mode of EXI MAY be used. Choose your fighter ๐
The EXI header MUST include "EXI Options", as defined in [W3C.REC-exi-20140211], with a schemaId set to the value of "a", which means "the schema in this spec." Future revisions to the schema can change the schemaId so older and newer versions stay compatible ๐ง When the data is going over CoAP or HTTP, an EXI Cookie SHOULD NOT be used. It just makes things bigger and repeats what the Content-Type header already says, so it's pure dead weight ๐
Here's the XSD Schema for strict schema-guided EXI processing. It's generated from the RelaxNG, so no vibes were harmed in the making of it ๐
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="urn:ietf:params:xml:ns:senml"
xmlns:ns1="urn:ietf:params:xml:ns:senml">
<xs:element name="senml">
<xs:complexType>
<xs:attribute name="bn" type="xs:string" />
<xs:attribute name="bt" type="xs:double" />
<xs:attribute name="bv" type="xs:double" />
<xs:attribute name="bs" type="xs:double" />
<xs:attribute name="bu" type="xs:string" />
<xs:attribute name="bver" type="xs:int" />
<xs:attribute name="n" type="xs:string" />
<xs:attribute name="s" type="xs:double" />
<xs:attribute name="t" type="xs:double" />
<xs:attribute name="u" type="xs:string" />
<xs:attribute name="ut" type="xs:double" />
<xs:attribute name="v" type="xs:double" />
<xs:attribute name="vb" type="xs:boolean" />
<xs:attribute name="vs" type="xs:string" />
<xs:attribute name="vd" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:element name="sensml">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="ns1:senml" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Now the glow-up ๐ธ Here's a hexdump of the EXI you get from encoding the XML example below. It's the same info as the first example in Section 5.1.2, just in XML instead of JSON, so you're literally seeing one idea in two outfits โจ
<sensml xmlns="urn:ietf:params:xml:ns:senml">
<senml bn="urn:dev:ow:10e2073a01080063:" n="voltage" u="V"
v="120.1"></senml>
<senml n="current" u="A" v="1.2"></senml>
</sensml>
Which compresses with EXI to the following, displayed in hexdump:
0000 a0 30 0d 84 80 f3 ab 93 71 d3 23 2b b1 d3 7b b9 |.0......q.#+..{.|
0010 d1 89 83 29 91 81 b9 9b 09 81 89 81 c1 81 81 b1 |...)............|
0020 99 d2 84 bb 37 b6 3a 30 b3 b2 90 1a b1 58 84 c0 |....7.:0.....X..|
0030 33 04 b1 ba b9 39 32 b7 3a 10 1a 09 06 40 38 |3....92.:....@8|
003f
That example used the bit-packed form of EXI, but there's also a byte-packed form ๐ This one is lowkey iconic because it's way easier for a simple sensor to produce valid EXI without really implementing EXI at all. Picture a temperature sensor that reports tenths of degrees Celsius over a range of 0.0 to 55.0. It would produce an XML SenML file like this:
<sensml xmlns="urn:ietf:params:xml:ns:senml">
<senml n="urn:dev:ow:10e2073a01080063" u="Cel" v="23.1"></senml>
</sensml>
The compressed form, using the byte-alignment option of EXI, for the XML above looks like this:
0000 a0 00 48 80 6c 20 01 06 1d 75 72 6e 3a 64 65 76 |..H.l ...urn:dev|
0010 3a 6f 77 3a 31 30 65 32 30 37 33 61 30 31 30 38 |:ow:10e2073a0108|
0020 30 30 36 33 02 05 43 65 6c 01 00 e7 01 01 00 03 |0063..Cel.......|
0030 01 |.|
0031
A small temperature sensor that only ever makes this one EXI file doesn't need a full EXI implementation ๐ง It can just hard-code the output. It swaps the 1-wire device ID starting at byte 0x14 and going to byte 0x23 for its own device ID, then replaces the value "0xe7 0x01" at location 0x2b and 0x2c with the current temperature. The EXI specification [W3C.REC-exi-20140211] has the full scoop on how floating-point numbers are represented, but for this sensor, the temperature can just be converted to an integer in tenths of degrees (231 in this example). EXI stores 7 bits of the integer in each byte, with the top bit set to one if there are more bytes coming. So the first byte is the low 7 bits of the integer temperature in tenths of degrees plus 0x80. In this example, 231 & 0x7F + 0x80 = 0xE7. The second byte is the integer temperature in tenths of degrees right-shifted 7 bits. In this example, 231 >> 7 = 0x01. Math is slay ๐ฅ
9. Fragment Identification Methods ๐ง
A SenML Pack usually has multiple SenML Records, and for some apps it's super useful to point at just one Record, or a set of them, using a fragment identifier ๐ The fragment identifier only gets interpreted by the client and doesn't change how the representation is retrieved, so the server never even sees it. The SenML fragment identification is modeled after Comma-Separated Value (CSV) fragment identifiers [RFC7111], which is very giving "we borrowed a good idea and made it ours" energy ๐
To select a single SenML Record, use the "rec" scheme followed by a single number. For numbering Records, the first Record is at position 1 (not 0, don't @ me ๐). You can select a range of Records by giving the first and last record numbers separated by a "-" character. Instead of the second number, you can use the "*" character to mean the last SenML Record in the Pack. And a set of Records can be picked with a comma-separated list of Record positions or ranges. Iconic.
(We use the term "selecting a Record" for identifying it as part of the fragment, not in the sense of isolating it from the Pack -- the Record still needs to be interpreted as part of the Pack, e.g., using the base values defined in earlier Records.) ๐ Translation: picking a Record doesn't mean it's suddenly on its own. It still needs the base values from earlier Records to make sense ๐ฆ
9.1. Fragment Identification Examples
The 3rd SenML Record from the "coap://example.com/temp" resource can be selected with:
coap://example.com/temp#rec=3
Records from 3rd to 6th can be selected with:
coap://example.com/temp#rec=3-6
Records from 19th to the last can be selected with:
coap://example.com/temp#rec=19-*
The 3rd and 5th Records can be selected with:
coap://example.com/temp#rec=3,5
To select the Records from third to fifth, the 10th Record, and all Records from 19th to the last:
coap://example.com/temp#rec=3-5,10,19-*
9.2. Fragment Identification for XML and EXI Formats
Along with the SenML fragment identifiers above, the XML and EXI SenML formats can use the syntax defined in the XPointer element() Scheme [XPointerElement] of the XPointer Framework [XPointerFramework] ๐ (This is required by [RFC7303] for media types using the syntax suffix structured with "+xml". For consistency, SenML allows this for the EXI formats too, which is very "we don't do favourites" of us ๐ซถ)
BUT, the big warning ๐จ Fragment identifiers only exist on the client side. They aren't sent over transfer protocols like CoAP or HTTP, so the server can't use them to decide which media type to send. If a server has multiple representations for a resource, it might send JSON or CBOR even when the client used an XML/EXI fragment identifier with that URI ๐ญ To avoid that mess, clients can explicitly request an XML or EXI media type (for example, using the CoAP Accept option) whenever an XML-/EXI-only fragment identifier syntax is in the URI. Main character energy: ask for exactly what you want โจ
10. Usage Considerations ๐
The measurements support sending both the current value of a sensor and an integrated sum ๐ธ For lots of measurements, the sum is way more useful than the current value. For historical reasons this field is called "Sum" instead of "integral", which would more accurately describe what it does (it's giving legacy naming, we love a complicated past ๐). For example, an electrical meter measuring how much energy a computer uses will typically want the cumulative amount of energy used. That's less prone to error than reporting the power every second and making the server add all those power readings together. If the network between the sensor and the meter goes down for a while, the cumulative sum helps reflect what happened while it was down, once it comes back up ๐ฆ A meter like this would usually report a measurement with the unit set to watts, but put the sum of energy used in the "s" field of the measurement. It might optionally include the current power in the "v" field.
Integrated sums are pretty clear for power and energy, but they're less obvious for something like temperature. Still, reporting the sum of temperature makes it easy to compute averages, even when the individual temperature values aren't reported often enough for accurate averages ๐ก๏ธ Implementers are encouraged to report the cumulative sum as well as the raw value of a given sensor. Bestie, do both ๐ซถ
Apps using the cumulative Sum values need to understand that this spec defines them very loosely, and depending on the sensor, they may behave in unexpected ways ๐ต Apps should be able to deal with the following issues:
- Many sensors will allow the cumulative sums to "wrap" back to zero after the value gets sufficiently large.
- Some sensors will reset the cumulative sum back to zero when the device is reset, loses power, or is replaced with a different sensor.
- Applications cannot make assumptions about when the device started accumulating values into the sum.
Good news though: apps can usually make some assumptions about specific sensors that help them handle these problems ๐ง A common one is that for sensors whose measurement values are non-negative, the sum should never get smaller. So if the sum does get smaller, the app knows one of the situations above has happened. Detective work, honestly iconic ๐
Despite the name "Sum", the Sum field is not useful for apps that keep a running count of how many times an event happened, or track a counter like the total number of bytes sent on an interface. Data like that can be sent directly in the Value field ๐
11. CDDL โจ
okay bestie, this section is basically the cheat sheet ๐โจ The JSON and CBOR formats can be described with the Concise Data Definition Language (CDDL) specification [CDDL-CBOR], and it's all laid out in Figure 1 (informative) ๐
SenML-Pack = [1* record]
record = {
? bn => tstr, ; Base Name
? bt => numeric, ; Base Time
? bu => tstr, ; Base Units
? bv => numeric, ; Base Value
? bs => numeric, ; Base Sum
? bver => uint, ; Base Version
? n => tstr, ; Name
? u => tstr, ; Units
? s => numeric, ; Sum
? t => numeric, ; Time
? ut => numeric, ; Update Time
? ( v => numeric // ; Numeric Value
vs => tstr // ; String Value
vb => bool // ; Boolean Value
vd => binary-value ) ; Data Value
* key-value-pair
}
; now define the generic versions
key-value-pair = ( label => value )
label = non-b-label / b-label
non-b-label = tstr .regexp "[A-Zac-z0-9][-_:.A-Za-z0-9]*" / uint
b-label = tstr .regexp "b[-_:.A-Za-z0-9]+" / nint
value = tstr / binary-value / numeric / bool
numeric = number / decfrac
Figure 1: Common CDDL Specification for CBOR and JSON SenML ๐
For JSON, we use text labels and base64url-encoded binary data ๐ธ That's what Figure 2 is for:
bver = "bver" n = "n" s = "s"
bn = "bn" u = "u" t = "t"
bt = "bt" v = "v" ut = "ut"
bu = "bu" vs = "vs" vd = "vd"
bv = "bv" vb = "vb"
bs = "bs"
binary-value = tstr ; base64url encoded
Figure 2: JSON-Specific CDDL Specification for SenML ๐
For CBOR, it's giving integer labels and native binary data ๐ฆ Figure 3 has the whole lineup:
bver = -1 n = 0 s = 5
bn = -2 u = 1 t = 6
bt = -3 v = 2 ut = 7
bu = -4 vs = 3 vd = 8
bv = -5 vb = 4
bs = -6
binary-value = bstr
Figure 3: CBOR-Specific CDDL Specification for SenML ๐ง
12. IANA Considerations ๐
okay so IANA has made a brand new registry called "Sensor Measurement Lists (SenML)" โญ It holds the two subregistries defined in Sections 12.1 and 12.2 ๐ bestie, we're literally so close to the finish line ๐ญ๐ซถ
12.1. SenML Units Registry โจ
okay bestie, IANA made a whole registry for SenML unit symbols called the "SenML Units" registry ๐ The main job here is making sure every symbol points to exactly one kind of measurement, so nobody gets confused ๐ You can look up a lot of these unit definitions in other publications, like [NIST811] and [BIPM] ๐ธ
Units with an asterisk are NOT RECOMMENDED for new implementations to produce ๐ They're still in active use though, so consumers SHOULD implement them, and they should also handle the closer unscaled SI units that the asterisked ones relate to ๐ซถ
+----------+------------------------------------+-------+-----------+
| Symbol | Description | Type | Reference |
+----------+------------------------------------+-------+-----------+
| m | meter | float | RFC 8428 |
| kg | kilogram | float | RFC 8428 |
| g | gram* | float | RFC 8428 |
| s | second | float | RFC 8428 |
| A | ampere | float | RFC 8428 |
| K | kelvin | float | RFC 8428 |
| cd | candela | float | RFC 8428 |
| mol | mole | float | RFC 8428 |
| Hz | hertz | float | RFC 8428 |
| rad | radian | float | RFC 8428 |
| sr | steradian | float | RFC 8428 |
| N | newton | float | RFC 8428 |
| Pa | pascal | float | RFC 8428 |
| J | joule | float | RFC 8428 |
| W | watt | float | RFC 8428 |
| C | coulomb | float | RFC 8428 |
| V | volt | float | RFC 8428 |
| F | farad | float | RFC 8428 |
| Ohm | ohm | float | RFC 8428 |
| S | siemens | float | RFC 8428 |
| Wb | weber | float | RFC 8428 |
| T | tesla | float | RFC 8428 |
| H | henry | float | RFC 8428 |
| Cel | degrees Celsius | float | RFC 8428 |
| lm | lumen | float | RFC 8428 |
| lx | lux | float | RFC 8428 |
| Bq | becquerel | float | RFC 8428 |
| Gy | gray | float | RFC 8428 |
| Sv | sievert | float | RFC 8428 |
| kat | katal | float | RFC 8428 |
| m2 | square meter (area) | float | RFC 8428 |
| m3 | cubic meter (volume) | float | RFC 8428 |
| l | liter (volume)* | float | RFC 8428 |
| m/s | meter per second (velocity) | float | RFC 8428 |
| m/s2 | meter per square second | float | RFC 8428 |
| | (acceleration) | | |
| m3/s | cubic meter per second (flow rate) | float | RFC 8428 |
| l/s | liter per second (flow rate)* | float | RFC 8428 |
| W/m2 | watt per square meter (irradiance) | float | RFC 8428 |
| cd/m2 | candela per square meter | float | RFC 8428 |
| | (luminance) | | |
| bit | bit (information content) | float | RFC 8428 |
| bit/s | bit per second (data rate) | float | RFC 8428 |
| lat | degrees latitude (Note 1) | float | RFC 8428 |
| lon | degrees longitude (Note 1) | float | RFC 8428 |
| pH | pH value (acidity; logarithmic | float | RFC 8428 |
| | quantity) | | |
| dB | decibel (logarithmic quantity) | float | RFC 8428 |
| dBW | decibel relative to 1 W (power | float | RFC 8428 |
| | level) | | |
| Bspl | bel (sound pressure level; | float | RFC 8428 |
| | logarithmic quantity)* | | |
| count | 1 (counter value) | float | RFC 8428 |
| / | 1 (ratio, e.g., value of a switch; | float | RFC 8428 |
| | Note 2) | | |
| % | 1 (ratio, e.g., value of a switch; | float | RFC 8428 |
| | Note 2)* | | |
| %RH | percentage (relative humidity) | float | RFC 8428 |
| %EL | percentage (remaining battery | float | RFC 8428 |
| | energy level) | | |
| EL | seconds (remaining battery energy | float | RFC 8428 |
| | level) | | |
| 1/s | 1 per second (event rate) | float | RFC 8428 |
| 1/min | 1 per minute (event rate, "rpm")* | float | RFC 8428 |
| beat/min | 1 per minute (heart rate in beats | float | RFC 8428 |
| | per minute)* | | |
| beats | 1 (cumulative number of heart | float | RFC 8428 |
| | beats)* | | |
| S/m | siemens per meter (conductivity) | float | RFC 8428 |
+----------+------------------------------------+-------+-----------+
Table 6: IANA Registry for SenML Units
- Note 1: these are assumed to be in World Geodetic System 1984 (WGS84), unless another reference frame is known for the sensor. ๐
- Note 2: a value of 0.0 means the switch is off, 1.0 means on, and 0.5 means half on ๐ The preferred name of this unit is
/. For historical reasons the name%is also provided for the same unit, but heads up, even though that name strongly suggests a percentage (0..100), it is NOT a percentage. It's the absolute ratio! ๐ญ
New entries can be added by Expert Review, as defined in [RFC8126] ๐ Experts should use their own good judgment, but they need to keep these guidelines in mind ๐ง
- There needs to be a real and compelling use for any new unit before it gets added ๐
- Each unit should define its semantic information and be chosen carefully ๐ง Implementers need to remember that the same word can show up in different real-life contexts. For example, degrees when measuring latitude have no semantic relation to degrees when measuring temperature, so two different units are needed ๐
- These measurements are produced by computers for consumption by computers ๐ค The principle is that conversion has to be easy when both reading and writing the media type. A single canonical representation is worth more than the convenience of easy human representations or a little loss of precision in a conversion ๐
- Using SI prefixes such as
kbefore the unit is not recommended. Instead, you can write the value in scientific notation, like 1.2e3 โจ Thekgunit is the exception, since it is an SI base unit. Thegunit is only provided for legacy compatibility ๐ - For a given type of measurement, only one unit type will be defined. So for length, meter is defined, and other lengths like mile, foot, and light year are not allowed ๐ For most cases, the SI unit is preferred ๐ฆ
(Heads up, this one takes some judgment, because even SI isn't totally consistent about it ๐ For instance, for temperature, [ISO-80000-5] defines a quantity, item 5-1 (thermodynamic temperature), and a corresponding unit of 5-1.a (Kelvin). [ISO-80000-5] then goes on to define another quantity, item 5-2 ("Celsius temperature"), and the corresponding unit of 5-2.a (degree Celsius). The latter quantity is defined so that it gives the thermodynamic temperature as a delta from T0 = 275.15 K. ISO 80000-5 is defining both units side by side and isn't really expressing a preference. This is why Celsius temperatures seem exceptionally acceptable in the SenML units list alongside Kelvin ๐ก๏ธ)
- Symbol names that could be easily confused with existing common units, or with units combined with prefixes, should be avoided ๐ซ For example, picking a unit name of
mphfor something that has nothing to do with velocity would be a bad choice, sincemphis commonly used to mean "miles per hour" ๐๏ธ - The following should not be used, because they are common SI prefixes:
Y,Z,E,P,T,G,M,k,h,da,d,c,u,n,p,f,a,z,y,Ki,Mi,Gi,Ti,Pi,Ei,Zi, andYi๐ โโ๏ธ - The following units should not be used, because they are commonly used to represent other measurements:
Ky,Gal,dyn,etg,P,St,Mx,G,Oe,Gb,sb,Lmb,mph,Ci,R,RAD,REM,gal,bbl,qt,degF,Cal,BTU,HP,pH,B/s,psi,Torr,atm,at,bar, andkWh๐ - Unit names are case sensitive, so the correct case has to be used ๐ However, symbols that differ only in case should not be allocated ๐
- A number after a unit usually means the previous unit raised to that power, and
/means the units that follow are reciprocals โ A unit should only have one/in its name โ๏ธ - A good list of common units can be found in the Unified Code for Units of Measure [UCUM] ๐ โจ
12.2. SenML Labels Registry
okay bestie, IANA made a brand new registry called the "SenML Labels" registry ๐ Here's what's already sitting in it:
+--------------+-------+----+-----------+----------+----+-----------+
| Name | Label | CL | JSON Type | XML Type | EI | Reference |
+--------------+-------+----+-----------+----------+----+-----------+
| Base Name | bn | -2 | String | string | a | RFC 8428 |
| Base Time | bt | -3 | Number | double | a | RFC 8428 |
| Base Unit | bu | -4 | String | string | a | RFC 8428 |
| Base Value | bv | -5 | Number | double | a | RFC 8428 |
| Base Sum | bs | -6 | Number | double | a | RFC 8428 |
| Base Version | bver | -1 | Number | int | a | RFC 8428 |
| Name | n | 0 | String | string | a | RFC 8428 |
| Unit | u | 1 | String | string | a | RFC 8428 |
| Value | v | 2 | Number | double | a | RFC 8428 |
| String Value | vs | 3 | String | string | a | RFC 8428 |
| Boolean | vb | 4 | Boolean | boolean | a | RFC 8428 |
| Value | | | | | | |
| Data Value | vd | 8 | String | string | a | RFC 8428 |
| Sum | s | 5 | Number | double | a | RFC 8428 |
| Time | t | 6 | Number | double | a | RFC 8428 |
| Update Time | ut | 7 | Number | double | a | RFC 8428 |
+--------------+-------+----+-----------+----------+----+-----------+
Note that CL = CBOR Label and EI = EXI ID.
Table 7: IANA Registry for SenML Labels
This is basically the same table as Table 1 โจ just with the notes taken out and some columns added for the stuff that's identical across this first batch. New registrations will need their own values though ๐
Every new entry has to define the Name, Label, and XML Type. The CBOR labels SHOULD be left empty ๐ because CBOR uses the string encoding for any new labels anyway. The EI column holds the EXI schemaId value of the first schema that includes the label, or it's empty if the label wasn't meant for EXI. The Reference column SHOULD contain info about where to find out more.
The JSON, CBOR, and EXI types all come from the XML type ๐ฆ XML numeric types like double, float, integer, and int turn into a JSON Number. XML boolean and string become a JSON Boolean and String, respectively. CBOR picks a CBOR type that doesn't lose any information from the JSON value, and EXI just uses the XML types.
New entries can be added by Expert Review as defined in [RFC8126]. Experts should exercise their own good judgment, but they need to consider that shorter labels should have more strict review. New entries should not be made that counteract the advice at the end of Section 4.5.4, so don't go there ๐ญ
All new SenML Labels with "base" semantics (see Section 4.1) MUST start with the character "b". Regular labels MUST NOT start with that character. All new SenML Labels with Value semantics (see Section 4.2) MUST have "Value" in their (long-form) name. Main character energy for naming rules ๐
Extensions that add a label intended for use with XML need to create a new RelaxNG Schema that includes all the labels in the "SenML Labels" registry.
Extensions that add a label intended for use with EXI need to create a new XSD Schema that includes all the labels in the "SenML Labels" registry, and then allocate a new EXI schemaId value. Moving to the next letter in the alphabet is the suggested way to create the new value for the EXI schemaId. Any labels with previously blank ID values SHOULD be updated in the "SenML Labels" registry to have their ID set to this new schemaId value.
Extensions that are mandatory to understand to correctly process the Pack MUST have a label name that ends with the "_" character. Lowkey the most serious rule in the whole list ๐
12.3. Media Type Registrations
The registrations in the subsections below follow the procedures specified in [RFC6838] and [RFC7303] โจ This document registers media types for each serialization format of SenML (JSON, CBOR, XML, and EXI), and also a matching set of media types for streaming use (SenSML; see Section 4.8). Clipboard formats are defined for the JSON and XML forms of SenML, but not for streams or non-textual formats.
Why are there both SenML and streaming SenSML? Because they're not the same data formats ๐ง They need separate negotiation so everyone can tell whether they're supported and which one is being used. The non-streaming format is required to have some sort of end-of-pack syntax that says there will be no more records. Lots of implementations that receive SenML wait for that end-of-pack marker before processing any records. With streaming formats, it's explicitly not required to wait for that marker, and lots of implementations that produce streaming SenSML never send it at all. So implementations that receive streaming SenSML cannot wait for the end-of-pack marker before they start processing records. Since SenML and streaming SenML are different data formats, and there's that separate negotiation requirement, each one needs its own media type. It's giving organization ๐
12.3.1. senml+json Media Type Registration
Here's the JSON one, verbatim:
Type name: application
Subtype name: senml+json
Required parameters: none
Optional parameters: none
Encoding considerations: Must be encoded as using a subset of the
encoding allowed in [RFC8259]. See RFC 8428 for details. This
simplifies implementation of a very simple system and does not impose
any significant limitations as all this data is meant for machine-to-
machine communications and is not meant to be human readable.
Security considerations: See Section 13 of RFC 8428.
Interoperability considerations: Applications MUST ignore any JSON
key-value pairs that they do not understand unless the key ends with
the "_" character, in which case an error MUST be generated. This
allows backwards-compatible extensions to this specification. The
"bver" field can be used to ensure the receiver supports a minimal
level of functionality needed by the creator of the JSON object.
Published specification: RFC 8428
Applications that use this media type: The type is used by systems
that report, e.g., electrical power usage and environmental
information such as temperature and humidity. It can be used for a
wide range of sensor reporting systems.
Fragment identifier considerations: Fragment identification for
application/senml+json is supported by using fragment identifiers as
specified by RFC 8428.
Additional information:
Deprecated alias names for this type: N/A
Magic number(s): N/A
File extension(s): senml
Windows Clipboard Name: "JSON Sensor Measurement List"
Macintosh file type code(s): none
Macintosh Universal Type Identifier code: org.ietf.senml-json
conforms to public.text
Person & email address to contact for further information:
Cullen Jennings <fluffy@iii.ca>
Intended usage: COMMON
Restrictions on usage: None
Author: Cullen Jennings <fluffy@iii.ca>
Change controller: IESG
12.3.2. sensml+json Media Type Registration
Next up is the streaming JSON one ๐ธ
Type name: application
Subtype name: sensml+json
Required parameters: none
Optional parameters: none
Encoding considerations: Must be encoded as using a subset of the
encoding allowed in [RFC8259]. See RFC 8428 for details. This
simplifies implementation of a very simple system and does not impose
any significant limitations as all this data is meant for machine-to-
machine communications and is not meant to be human readable.
Security considerations: See Section 13 of RFC 8428.
Interoperability considerations: Applications MUST ignore any JSON
key-value pairs that they do not understand unless the key ends with
the "_" character, in which case an error MUST be generated. This
allows backwards-compatible extensions to this specification. The
"bver" field can be used to ensure the receiver supports a minimal
level of functionality needed by the creator of the JSON object.
Published specification: RFC 8428
Applications that use this media type: The type is used by systems
that report, e.g., electrical power usage and environmental
information such as temperature and humidity. It can be used for a
wide range of sensor reporting systems.
Fragment identifier considerations: Fragment identification for
application/sensml+json is supported by using fragment identifiers as
specified by RFC 8428.
Additional information:
Deprecated alias names for this type: N/A
Magic number(s): N/A
File extension(s): sensml
Macintosh file type code(s): none
Person & email address to contact for further information:
Cullen Jennings <fluffy@iii.ca>
Intended usage: COMMON
Restrictions on usage: None
Author: Cullen Jennings <fluffy@iii.ca>
Change controller: IESG
12.3.3. senml+cbor Media Type Registration
And last but not least, the CBOR one ๐
Type name: application
Subtype name: senml+cbor
Required parameters: none
Optional parameters: none
Encoding considerations: Must be encoded as using [RFC7049]. See RFC
8428 for details.
Security considerations: See Section 13 of RFC 8428.
Interoperability considerations: Applications MUST ignore any key-
value pairs that they do not understand unless the key ends with the
"_" character, in which case an error MUST be generated. This allows
backwards-compatible extensions to this specification. The "bver"
field can be used to ensure the receiver supports a minimal level of
functionality needed by the creator of the CBOR object.
Published specification: RFC 8428
Applications that use this media type: The type is used by systems
that report, e.g., electrical power usage and environmental
information such as temperature and humidity. It can be used for a
wide range of sensor reporting systems.
Fragment identifier considerations: Fragment identification for
application/senml+cbor is supported by using fragment identifiers as
specified by RFC 8428.
Additional information:
Deprecated alias names for this type: N/A
Magic number(s): N/A
File extension(s): senmlc
Macintosh file type code(s): none
Macintosh Universal Type Identifier code: org.ietf.senml-cbor
conforms to public.data
Person & email address to contact for further information:
Cullen Jennings <fluffy@iii.ca>
Intended usage: COMMON
Restrictions on usage: None
Author: Cullen Jennings <fluffy@iii.ca>
Change controller: IESG
12.3.4. sensml+cbor Media Type Registration โจ
Okay bestie, this one's the CBOR flavour of the sensml registration ๐ฆ Type name is application and subtype name is sensml+cbor ๐ Required parameters: none. Optional parameters: none. Nothing extra to set up, which is so relaxing ๐ธ
Encoding considerations: it MUST be encoded as using [RFC7049]. See RFC 8428 for details ๐
Security considerations: see Section 13 of RFC 8428. Yes, it's serious, so go read it ๐
Interoperability considerations: applications MUST ignore any key-value pairs that they do not understand, unless the key ends with the "_" character. In that case an error MUST be generated ๐จ This is what lets extensions stay backwards-compatible, which is honestly iconic ๐ The "bver" field can be used to make sure the receiver supports the minimal level of functionality the creator of the CBOR object needs ๐ซถ
Published specification: RFC 8428 โจ
Applications that use this media type: systems that report things like electrical power usage and environmental information such as temperature and humidity ๐ It can be used for a wide range of sensor reporting systems, so it's giving main character energy ๐ฅ
Fragment identifier considerations: fragment identification for application/sensml+cbor is supported by using fragment identifiers as specified by RFC 8428 ๐ฆ
Additional information:
- Deprecated alias names for this type: N/A
- Magic number(s): N/A
- File extension(s):
sensmlc - Macintosh file type code(s): none
Person & email address to contact for further information: Cullen Jennings <fluffy@iii.ca> ๐
Intended usage: COMMON. Restrictions on usage: None. ๐
Author: Cullen Jennings <fluffy@iii.ca> ๐ง
Change controller: IESG ๐
12.3.5. senml+xml Media Type Registration ๐
Next up is the XML one, and ngl it's giving very structured vibes ๐
Type name is application and subtype name is senml+xml. Required parameters: none. Optional parameters: none. Easy peasy ๐ธ
Encoding considerations: it MUST be encoded as using [W3C.REC-xml-20081126]. See RFC 8428 for details ๐ฆ
Security considerations: see Section 13 of RFC 8428 ๐
Interoperability considerations: applications MUST ignore any XML tags or attributes that they do not understand, unless the attribute name ends with the "_" character. In that case an error MUST be generated ๐จ This keeps backwards-compatible extensions working, which is so important bestie โจ The "bver" attribute in the senml XML tag can be used to make sure the receiver supports a minimal level of functionality that the creator of the XML SenML Pack needs ๐
Published specification: RFC 8428 โจ
Applications that use this media type: systems that report electrical power usage and environmental information such as temperature and humidity โญ It can be used for a wide range of sensor reporting systems ๐
Fragment identifier considerations: fragment identification for application/senml+xml is supported by using fragment identifiers as specified by RFC 8428 ๐ง
Additional information:
- Deprecated alias names for this type: N/A
- Magic number(s): N/A
- File extension(s):
senmlx - Windows Clipboard Name:
"XML Sensor Measurement List" - Macintosh file type code(s): none
- Macintosh Universal Type Identifier code:
org.ietf.senml-xmlconforms topublic.xml๐
Person & email address to contact for further information: Cullen Jennings <fluffy@iii.ca> ๐
Intended usage: COMMON
Restrictions on usage: None
Author: Cullen Jennings <fluffy@iii.ca> ๐ซถ
Change controller: IESG ๐
12.3.6. sensml+xml Media Type Registration ๐ฆ
Same vibe as the one before, just the sensml flavour ๐ธ Type name is application and subtype name is sensml+xml. Required parameters: none. Optional parameters: none ๐
Encoding considerations: it MUST be encoded as using [W3C.REC-xml-20081126]. See RFC 8428 for details โจ
Security considerations: see Section 13 of RFC 8428 ๐
Interoperability considerations: applications MUST ignore any XML tags or attributes that they do not understand, unless the attribute name ends with the "_" character. In that case an error MUST be generated ๐จ This allows backwards-compatible extensions to this specification ๐ซถ The "bver" attribute in the senml XML tag can be used to make sure the receiver supports a minimal level of functionality that the creator of the XML SenML Pack needs ๐
Published specification: RFC 8428 โจ
Applications that use this media type: systems that report electrical power usage and environmental information such as temperature and humidity ๐ It can be used for a wide range of sensor reporting systems ๐ฅ
Fragment identifier considerations: fragment identification for application/sensml+xml is supported by using fragment identifiers as specified by RFC 8428 ๐ง
Additional information:
- Deprecated alias names for this type: N/A
- Magic number(s): N/A
- File extension(s):
sensmlx - Macintosh file type code(s): none
Person & email address to contact for further information: Cullen Jennings <fluffy@iii.ca> ๐
Intended usage: COMMON
Restrictions on usage: None
Author: Cullen Jennings <fluffy@iii.ca> ๐
Change controller: IESG ๐
12.3.7. senml-exi Media Type Registration ๐ธ
Okay now we're in EXI territory and it's giving compressed-and-cute ๐ฆ Type name is application and subtype name is senml-exi. Required parameters: none. Optional parameters: none โจ
Encoding considerations: it MUST be encoded as using [W3C.REC-exi-20140211]. See RFC 8428 for details ๐
Security considerations: see Section 13 of RFC 8428 ๐
Interoperability considerations: applications MUST ignore any XML tags or attributes that they do not understand, unless the attribute name ends with the "_" character. In that case an error MUST be generated ๐จ This is what lets backwards-compatible extensions to this specification happen ๐ The "bver" attribute in the senml XML tag can be used to make sure the receiver supports a minimal level of functionality that the creator of the XML SenML Pack needs ๐ซถ Further information on using schemas to guide the EXI can be found in RFC 8428 ๐ง
Published specification: RFC 8428 โจ
Applications that use this media type: systems that report electrical power usage and environmental information such as temperature and humidity ๐ It can be used for a wide range of sensor reporting systems ๐ฅ
Fragment identifier considerations: fragment identification for application/senml-exi is supported by using fragment identifiers as specified by RFC 8428 ๐ฆ
Additional information:
- Deprecated alias names for this type: N/A
- Magic number(s): N/A
- File extension(s):
senmle - Macintosh file type code(s): none
- Macintosh Universal Type Identifier code:
org.ietf.senml-exiconforms topublic.data๐
Person & email address to contact for further information: Cullen Jennings <fluffy@iii.ca> ๐
Intended usage: COMMON
Restrictions on usage: None
Author: Cullen Jennings <fluffy@iii.ca> ๐ซถ
Change controller: IESG ๐
12.3.8. sensml-exi Media Type Registration ๐
Last media type in this batch, and it's the sensml EXI version ๐ Type name is application and subtype name is sensml-exi. Required parameters: none. Optional parameters: none ๐ธ
Encoding considerations: it MUST be encoded as using [W3C.REC-exi-20140211]. See RFC 8428 for details ๐ฆ
Security considerations: see Section 13 of RFC 8428 ๐
Interoperability considerations: applications MUST ignore any XML tags or attributes that they do not understand, unless the attribute name ends with the "_" character. In that case an error MUST be generated ๐จ This allows backwards-compatible extensions to this specification ๐ซถ The "bver" attribute in the senml XML tag can be used to make sure the receiver supports a minimal level of functionality that the creator of the XML SenML Pack needs ๐ Further information on using schemas to guide the EXI can be found in RFC 8428 โจ
Published specification: RFC 8428 โจ
Applications that use this media type: systems that report electrical power usage and environmental information such as temperature and humidity ๐ It can be used for a wide range of sensor reporting systems ๐ฅ
Fragment identifier considerations: fragment identification for application/sensml-exi is supported by using fragment identifiers as specified by RFC 8428 ๐ง
Additional information:
- Deprecated alias names for this type: N/A
- Magic number(s): N/A
- File extension(s):
senmle - Macintosh file type code(s): none
Person & email address to contact for further information: Cullen Jennings <fluffy@iii.ca> ๐
Intended usage: COMMON
Restrictions on usage: None
Author: Cullen Jennings <fluffy@iii.ca> ๐
Change controller: IESG ๐
12.4. XML Namespace Registration ๐ฆ
This document registers the following XML namespace in the "IETF XML Registry" defined in [RFC3688] ๐
URI: urn:ietf:params:xml:ns:senml
Registrant Contact: The IESG.
XML: N/A, the requested URIs are XML namespaces ๐ซถ
12.5. CoAP Content-Format Registration ๐ธ
IANA has assigned CoAP Content-Format IDs for the SenML media types in the "CoAP Content-Formats" subregistry within the "Constrained RESTful Environments (CoRE) Parameters" registry [RFC7252] โจ IDs for the JSON, CBOR, and EXI Content-Formats have been assigned in the 0-255 range (Expert Review), and IDs for the XML Content-Formats have been assigned in the 256-9999 range (IETF Review or IESG Approval) ๐ The assigned IDs are shown in the table below ๐
+-------------------------+----------+-----+-----------+
| Media Type | Encoding | ID | Reference |
+-------------------------+----------+-----+-----------+
| application/senml+json | - | 110 | RFC 8428 |
| application/sensml+json | - | 111 | RFC 8428 |
| application/senml+cbor | - | 112 | RFC 8428 |
| application/sensml+cbor | - | 113 | RFC 8428 |
| application/senml-exi | - | 114 | RFC 8428 |
| application/sensml-exi | - | 115 | RFC 8428 |
| application/senml+xml | - | 310 | RFC 8428 |
| application/sensml+xml | - | 311 | RFC 8428 |
+-------------------------+----------+-----+-----------+
Table 8: CoAP Content-Format IDs ๐
13. Security Considerations ๐
Okay, bestie, this part is serious, so let's be real. SenML can carry everything from super public stuff, like the outside temperature in a city, to super private stuff, like patient health info that needs integrity and confidentiality protection ๐ฅบ. And when SenML is used for configuration or actuation, it can change the state of systems and actually affect the physical world. Think turning off a heater or opening a lock ๐. Using SenML maliciously to change system state could have severe consequences, potentially including violation of physical security, property damage, and even loss of life ๐. This is not a drill!!
SenML formats alone do not provide any security. They rely on the protocol that carries them to handle that ๐ซถ. Applications using SenML need to look at the whole context of how these formats will be used to decide whether the security is adequate โจ. Especially for sensitive sensor data and actuation, it's super important to make sure proper security mechanisms are in place to provide things like confidentiality, data integrity, and authentication, depending on what the usage needs ๐ก๏ธ.
The SenML formats defined in this specification don't contain any executable content ๐. However, future extensions could potentially embed application-specific executable content in the data, so keep your eyes open for that ๐.
SenML Records are meant to be interpreted in the context of any applicable base values. If Records get separated from the Record that establishes those base values, the data will be useless or, worse, wrong ๐ฌ. So take care to keep the integrity of a Pack that contains unresolved SenML Records (see Section 4.6) ๐งฉ.
See also Section 14.
14. Privacy Considerations ๐ซฃ
Sensor data is a whole spectrum ๐. On one end you've got info with basically no privacy concerns, like the current temperature in a city. On the other end you've got highly sensitive medical or location data ๐ณ. This specification provides no security protection for the data itself. It's meant to be used inside another container or transfer protocol, like S/MIME [RFC5751] or HTTP with TLS [RFC2818], which can provide integrity, confidentiality, and authentication information about where the data came from ๐.
The Name fields need to uniquely identify the sources or destinations of the values in a SenML Pack ๐ท๏ธ. But using long-term, stable, unique identifiers can be problematic for privacy reasons [RFC6973], depending on the application and on how easily those identifiers could be correlated with other information ๐ต๏ธโโ๏ธ. They should be used with care or avoided, for example as described for IPv6 addresses in [RFC7721] ๐ธ.
15. References ๐
15.1. Normative References
[BIPM] Bureau International des Poids et Mesures, "The International System of Units (SI)", 8th Edition, 2006. ๐
[IEEE.754] IEEE, "Standard for Binary Floating-Point Arithmetic", IEEE Standard 754. ๐งฎ
[NIST811] Thompson, A. and B. Taylor, "Guide for the Use of the International System of Units (SI)", NIST Special Publication 811, DOI 10.6028/NIST.SP.811e2008, March 2008. ๐
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>. ๐
[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003, <https://www.rfc-editor.org/info/rfc3629>. ๐ค
[RFC3688] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688, DOI 10.17487/RFC3688, January 2004, <https://www.rfc-editor.org/info/rfc3688>. ๐๏ธ
[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, <https://www.rfc-editor.org/info/rfc4648>. ๐ก
[RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, DOI 10.17487/RFC6838, January 2013, <https://www.rfc-editor.org/info/rfc6838>. ๐ท๏ธ
[RFC7049] Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", RFC 7049, DOI 10.17487/RFC7049, October 2013, <https://www.rfc-editor.org/info/rfc7049>. ๐ฆ
[RFC7252] Shelby, Z., Hartke, K., and C. Bormann, "The Constrained Application Protocol (CoAP)", RFC 7252, DOI 10.17487/RFC7252, June 2014, <https://www.rfc-editor.org/info/rfc7252>. ๐
[RFC7303] Thompson, H. and C. Lilley, "XML Media Types", RFC 7303, DOI 10.17487/RFC7303, July 2014, <https://www.rfc-editor.org/info/rfc7303>. ๐ฐ
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>. โ๏ธ
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>. ๐
[RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017, <https://www.rfc-editor.org/info/rfc8259>. ๐งพ
[RNC] ISO/IEC, "Information technology -- Document Schema Definition Language (DSDL) -- Part 2: Regular-grammar-based validation -- RELAX NG", ISO/IEC 19757-2, Annex C: RELAX NG Compact syntax, December 2008. ๐งฉ
[TIME_T] The Open Group Base Specifications, "Open Group Standard - Vol. 1: Base Definitions, Issue 7", Section 4.16, "Seconds Since the Epoch", IEEE Standard 1003.1, 2018, <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_16>. โฐ
[W3C.REC-exi-20140211] Schneider, J., Kamiya, T., Peintner, D., and R. Kyusakov, "Efficient XML Interchange (EXI) Format 1.0 (Second Edition)", W3C Recommendation REC-exi-20140211, February 2014, <http://www.w3.org/TR/2014/REC-exi-20140211>. โก
[W3C.REC-xml-20081126] Bray, T., Paoli, J., Sperberg-McQueen, M., Maler, E., and F. Yergeau, "Extensible Markup Language (XML) 1.0 (Fifth Edition)", W3C Recommendation REC-xml-20081126, November 2008, <http://www.w3.org/TR/2008/REC-xml-20081126>. ๐
[W3C.REC-xmlschema-1-20041028] Thompson, H., Beech, D., Maloney, M., and N. Mendelsohn, "XML Schema Part 1: Structures Second Edition", W3C Recommendation REC-xmlschema-1-20041028, October 2004, <http://www.w3.org/TR/2004/REC-xmlschema-1-20041028>. ๐๏ธ
[XPointerElement] Grosso, P., Maler, E., Marsh, J., and N. Walsh, "XPointer element() Scheme", W3C Recommendation REC-xptr-element, March 2003, <https://www.w3.org/TR/2003/REC-xptr-element-20030325/>. ๐
[XPointerFramework] Grosso, P., Maler, E., Marsh, J., and N. Walsh, "XPointer Framework", W3C Recommendation REC-XPointer-Framework, March 2003, <http://www.w3.org/TR/2003/REC-xptr-framework-20030325/>. ๐งญ
15.2. Informative References ๐
Okay bestie, these are the receipts ๐งพ Informative references are the extra reading that backs up the spec. The brackets are the tags, the rest is the citation, all copied exactly.
[AN1796]Linke, B., "Overview of 1-Wire Technology and Its Use", Maxim Integrated, Tutorial 1796, June 2008,<http://pdfserv.maximintegrated.com/en/an/AN1796.pdf>.[CDDL-CBOR]Birkholz, H., Vigano, C., and C. Bormann, "Concise data definition language (CDDL): a notational convention to express CBOR and JSON data structures", Work in Progress, draft-ietf-cbor-cddl-05, August 2018.[DEVICE-URN]Arkko, J., Jennings, C., and Z. Shelby, "Uniform Resource Names for Device Identifiers", Work in Progress, draft-ietf-core-dev-urn-02, July 2018.[IEEE802.1AS]IEEE, "IEEE Standard for Local and Metropolitan Area Networks - Timing and Synchronization for Time-Sensitive Applications in Bridged Local Area Networks", IEEE Standard 802.1AS.[IEEE802.1BA]IEEE, "IEEE Standard for Local and metropolitan area networks--Audio Video Bridging (AVB) Systems", IEEE Standard 802.1BA.[ISO-80000-5]ISO, "Quantities and units - Part 5: Thermodynamics", ISO 80000-5, Edition 1.0, May 2007.[RFC2818]Rescorla, E., "HTTP Over TLS", RFC 2818, DOI 10.17487/RFC2818, May 2000,<https://www.rfc-editor.org/info/rfc2818>.[RFC3986]Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005,<https://www.rfc-editor.org/info/rfc3986>.[RFC4122]Leach, P., Mealling, M., and R. Salz, "A Universally Unique IDentifier (UUID) URN Namespace", RFC 4122, DOI 10.17487/RFC4122, July 2005,<https://www.rfc-editor.org/info/rfc4122>.[RFC4151]Kindberg, T. and S. Hawke, "The 'tag' URI Scheme", RFC 4151, DOI 10.17487/RFC4151, October 2005,<https://www.rfc-editor.org/info/rfc4151>.[RFC4944]Montenegro, G., Kushalnagar, N., Hui, J., and D. Culler, "Transmission of IPv6 Packets over IEEE 802.15.4 Networks", RFC 4944, DOI 10.17487/RFC4944, September 2007,<https://www.rfc-editor.org/info/rfc4944>.[RFC5751]Ramsdell, B. and S. Turner, "Secure/Multipurpose Internet Mail Extensions (S/MIME) Version 3.2 Message Specification", RFC 5751, DOI 10.17487/RFC5751, January 2010,<https://www.rfc-editor.org/info/rfc5751>.[RFC5952]Kawamura, S. and M. Kawashima, "A Recommendation for IPv6 Address Text Representation", RFC 5952, DOI 10.17487/RFC5952, August 2010,<https://www.rfc-editor.org/info/rfc5952>.[RFC6690]Shelby, Z., "Constrained RESTful Environments (CoRE) Link Format", RFC 6690, DOI 10.17487/RFC6690, August 2012,<https://www.rfc-editor.org/info/rfc6690>.[RFC6920]Farrell, S., Kutscher, D., Dannewitz, C., Ohlman, B., Keranen, A., and P. Hallam-Baker, "Naming Things with Hashes", RFC 6920, DOI 10.17487/RFC6920, April 2013,<https://www.rfc-editor.org/info/rfc6920>.[RFC6973]Cooper, A., Tschofenig, H., Aboba, B., Peterson, J., Morris, J., Hansen, M., and R. Smith, "Privacy Considerations for Internet Protocols", RFC 6973, DOI 10.17487/RFC6973, July 2013,<https://www.rfc-editor.org/info/rfc6973>.[RFC7111]Hausenblas, M., Wilde, E., and J. Tennison, "URI Fragment Identifiers for the text/csv Media Type", RFC 7111, DOI 10.17487/RFC7111, January 2014,<https://www.rfc-editor.org/info/rfc7111>.[RFC7230]Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing", RFC 7230, DOI 10.17487/RFC7230, June 2014,<https://www.rfc-editor.org/info/rfc7230>.[RFC7721]Cooper, A., Gont, F., and D. Thaler, "Security and Privacy Considerations for IPv6 Address Generation Mechanisms", RFC 7721, DOI 10.17487/RFC7721, March 2016,<https://www.rfc-editor.org/info/rfc7721>.[RFC8141]Saint-Andre, P. and J. Klensin, "Uniform Resource Names (URNs)", RFC 8141, DOI 10.17487/RFC8141, April 2017,<https://www.rfc-editor.org/info/rfc8141>.[RID-CoRE]Shelby, Z., Vial, M., Groves, C., Zhu, J., and B. Silverajan, Ed., "Reusable Interface Definitions for Constrained RESTful Environments", Work in Progress, draft-ietf-core-interfaces-12, June 2018.[UCUM]Schadow, G. and C. McDonald, "The Unified Code for Units of Measure", Version 2.1, Regenstrief Institute and the UCUM Organization, November 2017,<http://unitsofmeasure.org/ucum.html>.
Acknowledgements ๐ซถ
Huge thank-you to everyone who gave review comments, you're literally the reason this spec is so good ๐ Alexander Pelov, Alexey Melnikov, Andrew McClure, Andrew McGregor, Bjoern Hoehrmann, Christian Amsuess, Christian Groves, Daniel Peintner, Jan-Piet Mens, Jim Schaad, Joe Hildebrand, John Klensin, Karl Palsson, Lennart Duhrsen, Lisa Dusseault, Lyndsay Campbell, Martin Thomson, Michael Koster, Peter Saint-Andre, Roni Even, and Stephen Farrell ๐
Authors' Addresses ๐
Here's where to find the people who wrote this. The details are copied exactly:
Cullen Jennings
Cisco
400 3rd Avenue SW
Calgary, AB T2P 4H2
Canada
Email: fluffy@iii.ca
Zach Shelby
ARM
150 Rose Orchard
San Jose 95134
United States of America
Phone: +1-408-203-9434
Email: zach.shelby@arm.com
Jari Arkko
Ericsson
Jorvas 02420
Finland
Email: jari.arkko@piuha.net
Ari Keranen
Ericsson
Jorvas 02420
Finland
Email: ari.keranen@ericsson.com
Carsten Bormann
Universitaet Bremen TZI
Postfach 330440
Bremen D-28359
Germany
Phone: +49-421-218-63921
Email: cabo@tzi.org
๐ฆ where this page comes from
- ietf: rfc8428 2018-08
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms