EdgeX Unit of Measure (UoM)
Status
Approved by TSC Vote on 3/16/2022
This ADR began under a different ADR pull request. The prior ADR recommended a UoM per device resource and just allowed for the association of an arbitrary set of unit of measure references against the resource. However, it did not include any specific units of measure or validation of those units against the actual profiles (and ultimately the associated readings). See the previous UoM ADR for details and prior debate.
Implementation: to be determined, but could be as soon as Kamakura (Spring 2022).
Context
Unit of measurement (UoM) is defined as "a standard amount of a physical quantity, such as length, mass, energy, etc, specified multiples of which are used to express magnitudes of that physical quantity". In EdgeX, data collected from sensors are physical quantities which should be associated to some unit of measure to express magnitude of that physical quantity. For example, if EdgeX collected a temperature reading from a thermostat as 45
, the user of that sensor reading would want to know if the unit of measure for the 45
quantity was expressed in Celsius, Fahrenheit or even the Kelvin scale.
Since the founding of the project, there has been consensus that a unit of measure should be associated to any sensor or metric quantity collected by EdgeX. Also since the founding of the project, a unit of measure has therefore been specified (directly or indirectly) to each device resource (found in device profiles) and associated values collected as part of readings.
The unit of measure was, however, in all cases just a string reference to some arbitrary unit (which may or may not be in a UoM standard) to be interpreted by the consumer of EdgeX data. The reporting sensor/device or programmer of the device service could choose what UoM string was associated to the device resources (and readings produced by the device service) as the unit of measure for any piece of data. Per the temperature example above, the unit of measure could have been "F" or "C", "Celsius" or "Fahrenheit", or any other representation. In other words, the associated unit of measure for all data in EdgeX was left to agreement and interpretation by the data provider/producer and EdgeX data consumer.
There are various specifications and standards around unit of measure. Specifically, there are several options to choose from as it relates to the exchange of data in electronic communications - and units of measure associated in that exchange. As examples, two big competing standards around EDI (electronic data exchange) that both have associated unit of measure codes are:
- ANSI X12: EDI standard used mostly in the US
- EDIFACT: UN EDI standard used mostly in Europe and Asia
The Unified Code for Units of Measure provides an alternative list (not a standard) that is used by various organizations like OSGI and the Eclipse Foundation.
While standards exist, use by various open source projects (especially IoT/edge projects) is inconsistent and haphazard. Groups like oneM2M seem to define their own selection of units in specifications per vertical (home for example) while Kura doesn't even appear to use the UoM JSR (a Java related unit of measure specification for Java applications like Kura).
Decision
It would be speculative and inappropriate for EdgeX to select a unit of measure standard which is not widely adopted in the industry or choose a static unit of measure list that is incomplete with regard to possible IoT / edge use case needs. At this time, there does not appear to be a single and unequivocal standard for units of measure that encompasses all EdgeX related use cases (now and in the future).
Therefore, EdgeX chooses not to select or adopt a unit of measure specification, standard, or code list to apply across the platform. Instead, EdgeX adopters will be allowed to optionally specify which unit of measure specification, standard, or unit of measure code list they would like used in their instance(s) of EdgeX.
Specifying the Units of Measure
Units of measure allowed by the instance of EdgeX will be specified in a configuration file (in YAML format called uom.yaml
by default). Note: the UoM configuration is a separate configuration YAML file (separate from the metadata service configuration file - configuration.yaml
).
EdgeX 3.0
For EdgeX 3.0 the UoM definition file is changed to YAML instead of TOML format.
The units of measure in the configuration file can be attributed, optionally, to a specification, document, or other UoM definition source. The source
only helps provide the location of documentation about the origins and details of the units specified for the reader, but it will not be used or checked by EdgeX. An optional default source can be provided at the top level configuration (as shown in the examples below) so that other sources are only needed when there are specific units used that are not found in the default source.
The units of measure can be categorized for better organization and to allow for different sources to be specified for different units. The categories are defined by the YAML section names (the UoM dot labels).
Sample YAML unit of measure configuration
Source: reference to source for all UoM if not specified below
Units:
temperature:
Source: www.weather.com
Values:
- C
- F
- K
weights:
Source: www.usa.gov/federal-agencies/weights-and-measures-division
Values:
- lbs
- ounces
- kilos
- grams
Specifying the UoM File Location
The location of the UoM file will be specified in core metadata's configuration (currently in res/configuration.yaml
) - see example A below.
Example Metadata Configuration - location of of the UoM configuration file
Writable:
UoM:
Validation: false ## false (meaning off) by default
## in the non-writable area - example file specified to units of measure
UoM:
UoMFile: ./res/uom.yaml # the UoMFile location can be either absolute or relative path location
The location of the UoM file should point to an accessible file (relative to application executable or absolute path). The file must be something that the service can reach (ex: in shared volume, volume mount, etc.) in order to allow for the adopter to provide the units of measure independently during configuration/setup of the EdgeX instance without requiring a build of the metadata service or a reconstruction of the Docker image/container.
Info
In future versions, multiple UoM definition files might be specified. This may help the organization of the units in the future.
Note
The environmental overrides can be used to specify and override the location of the UoM configuration file.
Info
It was discussed that the file location could be done via URI and even allow for HTTP, HTTPS or other protocol access of the file. For this first implementation, it was decided (per Monthly Architect's meeting of 2/28/22) to only allow for a simple file path reference (relative or absolute). Future implementation can consider URI use.
Specifying Validation on or off
Additionally, in metadata's configuration, a configuration option for unit of measure validation being on
or off
will be provided (note Validation
in both example above). The location of the UoM file is static, but the ability to turn validation on/off is dynamic and therefore in the writable area of configuration. For backward compatibility, validation will be off by default.
Note
on
and off
are specified by boolean values true
and false
in the configuration file.
Validation of the Units of Measure
Core metadata will read the units of measure from its configuration file. Like all configuration information, this data will be stored in the configuration service (Consul today) on initial startup of the core metadata service.
When validation is turned on
(Writable.UoM.validation is set to true), all device profile units
(in device resource, device properties) will be validated against the list of units of measure by core metadata. In other words, when a device profile is created or updated or when a device resource is added or updated via the core metadata API, the units specified in the device resource's units
field (see resource example below) will be checked against the valid list of UoM provided via core metadata configuration. If the units
value matches any one of the configuration units of measure, then the device resource is considered valid - allowing the create or update operation to continue.
If the units
value does not match any one of the configuration units of measure, then the device profile or device resource operation (create or update) is rejected (error code 500 is returned) and an appropriate error message is returned in the response to the caller of the core metadata API.
Note
Importantly (as discussed in Core WG 2/17/22), the units
field on a profile is and shall remain optional. If the units
field is not specified in the device profile, then it is assumed that the device resource does not have well defined units of measure. In other words, core metadata will not fail a profile with no units
field specified on a device resource.
In the example device resource below, core metadata would check that C
is in the list of units of measure in the configuration.
deviceResources:
-
name: "RoomTemperature"
isHidden: false
description: "Room Temperature x10 °C (Read Only)"
attributes:
{ primaryTable: "INPUT_REGISTERS", startingAddress: 3, rawType: "Int16" }
properties:
valueType: "Float32"
readWrite: "R"
scale: 0.1
units: "C" ## core metadata checks this value against its list of valid units of measure
By checking the units
property of the device resources (on creation or updates of the device profile or create/update of the device resources), and rejecting any additions or changes that include non-valid units of measure, then we can be assured that all readings created by the device service will contain valid units by default (assuming that validation of the units of measure is always on) or that the units are inconsequential (when the units
field is not specified for a device resource). This means, the units in a reading do not need to be validated separately.
Considerations
Validation important and architecturally significant
Based on discussion in the Core WG meeting of 2/3/22, it was decided that without validation and some valid list of actual UoM, the ADR was just adding metadata to the profile and thus did not even rise to the level of "significant" architectural decision. It was further felt that in order to really provide any value to adopters and to get adherence to their chosen units of measure, EdgeX had to allow for a valid list of units of measure to be specified and be used to check profile units - but in a way that is easy to configure/provide without having to rebuild a service for example. If the units of measure were defined just in the standard configuration file, it would make it hard to change this list in deployments.
This new UoM ADR is the result of that discussion. In general, it specifies, through adopter provided configuration, the exact unit of measures that are allowed for the EdgeX instance and any optional reference (such as a specification) where those units are defined. It does so through a separate core metadata configuration file making it easier to change.
Use of SenML
SenML was suggested as a specification (currently a proposed standard) from which EdgeX may draw some guidance or inspiration with regard to unit of measure representation in "simple sensor measurements and device parameters."
In fact, SenML defines a simple data model (in JSON, CBOR, XML, EXI) for the exchange of what EdgeX would call readings. A JSON example is below:
[{"n":"urn:dev:ow:10e2073a01080063","u":"Cel","v":23.1}]
In the example above, the array (what EdgeX would consider a collection of readings) has a single SenML Record with a measurement for a sensor named "urn:dev:ow:10e2073a01080063" with a current value of 23.1 for degrees measured in Celsius (Cel) unit of measure. However, SenML suggests the use of short names for the keys in most cases, but long names could be used. In which case, the JSON SenML reading would look like the following:
[{"Name":"urn:dev:ow:10e2073a01080063","Unit":"Cel","Value":23.1}]
In this way, the parallels to EdgeX model are, by accident, uncanny - at least in the JSON instance. SenML goes to much more depth to provide extensions and more definitions around measurements. But at its base, the EdgeX format is not unlike SenML and could easily be aligned with SenML in the future (or allow for an application service to export in SenML with an additional function fairly easily and if there were demand).
However, on the basis of "unit of measure", SenML is actually light on details. With regard to UoM, the SenML specification only says:
Quote
If the Record has no Unit, the Base Unit is used as the Unit. Having no Unit and no Base Unit is allowed; any information that may be required about units applicable to the value then needs to be provided by the application context.
A SenML Units Registry provides for a list of unit symbols (the "SenML Units registry"). This list could be used as one of the sources for EdgeX UoM definition.
SenML should be examined for future versions of EdgeX with regard to data model, but its relevance to unit of measure is believed to be minimal at this time.
Future Considerations/Additions/Improvements
In the future, validation may be turned on
or off
per device service; allowing the decision to validate units of measure to be accomplished on a service or even allow the device service to validate/not validate based on particular devices.
In the future, additional criteria may be added to the unit of measure information to all for more specific (or allowing more granularity) validation. For example, the category of units of measure could be specified in a device resource so that a profile's units are validated against specific sources or collections of unit of measure.
Use of URI to specify the unit of measures file was discussed. This would be novel with regard to providing EdgeX information. Per core working group of 2/17/22 and then again at the monthly architect's meeting of 2/28/22, we may look to use a URI to specify a configuration file to specify UoM in the future. Indeed, URIs may be used (an EdgeX 3.0 consideration) to point to device profiles, configuration files, and other information in the future. This would even allow multiple EdgeX instances to use the same configuration or profile (multiple EdgeX instances using the same URI to use a shared profile for example). However, it was deemed scope creep and too much to do for this first iteration.
Initially, this ADR allowed for the UoM to also or alternately to be defined in the standard metadata service configuration file (`configuration.yaml'). During the Core WG meeting of 3/3/22, it was decided to simplify the design and strictly limit UoM to a separate configuration file. If future use cases or adopters request inline definition, this can be implemented in a future release.
Consequences
- Validation could impact performance. Therefore allowing it to be turned on or off is critical to some use cases. However, it will only impact performance of profile creation/updates (and associated device resources) in core metadata.
References
UoM Standards
- https://ediacademy.com/blog/x12-unit-of-measurement-codes/
- https://unece.org/fileadmin/DAM/cefact/recommendations/rec20/rec20_rev3_Annex2e.pdf
- https://en.wikipedia.org/wiki/Unified_Code_for_Units_of_Measure
- https://www.ogc.org/standards/sensorthings
- https://datatracker.ietf.org/doc/html/rfc8428
- https://datatracker.ietf.org/doc/html/rfc8428#section-12.1
UoM Tools and Databases
- https://ucum.nlm.nih.gov/ucum-lhc/demo.html
- https://project-haystack.org/doc/Units
- https://github.com/fantom-lang/fantom/blob/master/etc/sys/units.txt
- https://gs1.github.io/UnitConverterUNECERec20/