RFC 8428

Sensor Measurement Lists (SenML)

๐Ÿ“… published August 2018, from ietf

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 (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:

  1. Many sensors will allow the cumulative sums to "wrap" back to zero after the value gets sufficiently large.
  2. Some sensors will reset the cumulative sum back to zero when the device is reset, loses power, or is replaced with a different sensor.
  3. 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 ๐Ÿงš

  1. There needs to be a real and compelling use for any new unit before it gets added ๐Ÿ’–
  2. 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 ๐ŸŒˆ
  3. 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 ๐Ÿ’œ
  4. Using SI prefixes such as k before the unit is not recommended. Instead, you can write the value in scientific notation, like 1.2e3 โœจ The kg unit is the exception, since it is an SI base unit. The g unit is only provided for legacy compatibility ๐Ÿ“
  5. 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 ๐ŸŒก๏ธ)

  1. 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 mph for something that has nothing to do with velocity would be a bad choice, since mph is commonly used to mean "miles per hour" ๐ŸŽ๏ธ
  2. 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, and Yi ๐Ÿ™…โ€โ™€๏ธ
  3. 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, and kWh ๐Ÿ’€
  4. Unit names are case sensitive, so the correct case has to be used ๐Ÿ”  However, symbols that differ only in case should not be allocated ๐Ÿ™…
  5. 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 โœŒ๏ธ
  6. 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-xml conforms to public.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-exi 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.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.


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