idnits 2.17.1 draft-ietf-asdf-sdf-11.txt: -(5): Line appears to be too long, but this could be caused by non-ascii characters in UTF-8 encoding -(3743): Line appears to be too long, but this could be caused by non-ascii characters in UTF-8 encoding Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- == There are 4 instances of lines with non-ascii characters in the document. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** There are 45 instances of too long lines in the document, the longest one being 100 characters in excess of 72. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (28 February 2022) is 787 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 1015 -- Looks like a reference, but probably isn't: '2' on line 1015 -- Looks like a reference, but probably isn't: '3' on line 1015 -- Possible downref: Non-RFC (?) normative reference: ref. 'SPDX' == Outdated reference: A later version (-04) exists of draft-bormann-jsonpath-iregexp-02 == Outdated reference: A later version (-13) exists of draft-irtf-t2trg-rest-iot-09 Summary: 1 error (**), 0 flaws (~~), 4 warnings (==), 5 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 ASDF M. Koster, Ed. 3 Internet-Draft PassiveLogic 4 Intended status: Standards Track C. Bormann, Ed. 5 Expires: 1 September 2022 Universität Bremen TZI 6 28 February 2022 8 Semantic Definition Format (SDF) for Data and Interactions of Things 9 draft-ietf-asdf-sdf-11 11 Abstract 13 The Semantic Definition Format (SDF) is a format for domain experts 14 to use in the creation and maintenance of data and interaction models 15 in the Internet of Things. It was created as a common language for 16 use in the development of the One Data Model liaison organization 17 (OneDM) definitions. Tools convert this format to database formats 18 and other serializations as needed. 20 An SDF specification describes definitions of SDF Objects and their 21 associated interactions (Events, Actions, Properties), as well as the 22 Data types for the information exchanged in those interactions. 24 // A JSON format representation of SDF 1.0 was defined in version 25 // (-00) of this document; version (-05) was designated as an 26 // _implementation draft_, labeled SDF 1.1, at the IETF110 meeting of 27 // the ASDF WG (2021-03-11). The present version (-11) collects a 28 // few smaller changes as input to the 2022-02-28 ASDF WG interim. 29 // It also removes deprecated elements from SDF 1.0. 31 About This Document 33 This note is to be removed before publishing as an RFC. 35 Status information for this document may be found at 36 https://datatracker.ietf.org/doc/draft-ietf-asdf-sdf/. 38 Discussion of this document takes place on the A Semantic Definition 39 Format for Data and Interactions of Things (ASDF) Working Group 40 mailing list (mailto:asdf@ietf.org), which is archived at 41 https://mailarchive.ietf.org/arch/browse/asdf/. 43 Source for this draft and an issue tracker can be found at 44 https://github.com/ietf-wg-asdf/SDF. 46 Status of This Memo 48 This Internet-Draft is submitted in full conformance with the 49 provisions of BCP 78 and BCP 79. 51 Internet-Drafts are working documents of the Internet Engineering 52 Task Force (IETF). Note that other groups may also distribute 53 working documents as Internet-Drafts. The list of current Internet- 54 Drafts is at https://datatracker.ietf.org/drafts/current/. 56 Internet-Drafts are draft documents valid for a maximum of six months 57 and may be updated, replaced, or obsoleted by other documents at any 58 time. It is inappropriate to use Internet-Drafts as reference 59 material or to cite them other than as "work in progress." 61 This Internet-Draft will expire on 1 September 2022. 63 Copyright Notice 65 Copyright (c) 2022 IETF Trust and the persons identified as the 66 document authors. All rights reserved. 68 This document is subject to BCP 78 and the IETF Trust's Legal 69 Provisions Relating to IETF Documents (https://trustee.ietf.org/ 70 license-info) in effect on the date of publication of this document. 71 Please review these documents carefully, as they describe your rights 72 and restrictions with respect to this document. Code Components 73 extracted from this document must include Revised BSD License text as 74 described in Section 4.e of the Trust Legal Provisions and are 75 provided without warranty as described in the Revised BSD License. 77 Table of Contents 79 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 80 1.1. Terminology and Conventions . . . . . . . . . . . . . . . 4 81 2. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 6 82 2.1. Example Definition . . . . . . . . . . . . . . . . . . . 6 83 2.2. Elements of an SDF model . . . . . . . . . . . . . . . . 8 84 2.2.1. sdfObject . . . . . . . . . . . . . . . . . . . . . . 9 85 2.2.2. sdfProperty . . . . . . . . . . . . . . . . . . . . . 10 86 2.2.3. sdfAction . . . . . . . . . . . . . . . . . . . . . . 11 87 2.2.4. sdfEvent . . . . . . . . . . . . . . . . . . . . . . 11 88 2.2.5. sdfData . . . . . . . . . . . . . . . . . . . . . . . 12 89 2.2.6. sdfThing . . . . . . . . . . . . . . . . . . . . . . 12 90 3. SDF structure . . . . . . . . . . . . . . . . . . . . . . . . 12 91 3.1. Information block . . . . . . . . . . . . . . . . . . . . 13 92 3.2. Namespaces block . . . . . . . . . . . . . . . . . . . . 14 93 3.3. Definitions block . . . . . . . . . . . . . . . . . . . . 15 95 4. Names and namespaces . . . . . . . . . . . . . . . . . . . . 16 96 4.1. Structure . . . . . . . . . . . . . . . . . . . . . . . . 16 97 4.2. Contributing global names . . . . . . . . . . . . . . . . 16 98 4.3. Referencing global names . . . . . . . . . . . . . . . . 17 99 4.4. sdfRef . . . . . . . . . . . . . . . . . . . . . . . . . 18 100 4.5. sdfRequired . . . . . . . . . . . . . . . . . . . . . . . 19 101 4.6. Common Qualities . . . . . . . . . . . . . . . . . . . . 20 102 4.7. Data Qualities . . . . . . . . . . . . . . . . . . . . . 21 103 4.7.1. sdfType . . . . . . . . . . . . . . . . . . . . . . . 23 104 4.7.2. sdfChoice . . . . . . . . . . . . . . . . . . . . . . 24 105 5. Keywords for definition groups . . . . . . . . . . . . . . . 26 106 5.1. sdfObject . . . . . . . . . . . . . . . . . . . . . . . . 26 107 5.2. sdfProperty . . . . . . . . . . . . . . . . . . . . . . . 27 108 5.3. sdfAction . . . . . . . . . . . . . . . . . . . . . . . . 28 109 5.4. sdfEvent . . . . . . . . . . . . . . . . . . . . . . . . 29 110 5.5. sdfData . . . . . . . . . . . . . . . . . . . . . . . . . 29 111 6. High Level Composition . . . . . . . . . . . . . . . . . . . 30 112 6.1. Paths in the model namespaces . . . . . . . . . . . . . . 30 113 6.2. Modular Composition . . . . . . . . . . . . . . . . . . . 31 114 6.2.1. Use of the "sdfRef" keyword to re-use a definition . 31 115 6.3. sdfThing . . . . . . . . . . . . . . . . . . . . . . . . 32 116 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 32 117 7.1. Media Type . . . . . . . . . . . . . . . . . . . . . . . 32 118 7.2. IETF URN Sub-namespace for Unit Names 119 (urn:ietf:params:unit) . . . . . . . . . . . . . . . . . 33 120 7.3. Registries . . . . . . . . . . . . . . . . . . . . . . . 33 121 8. Security Considerations . . . . . . . . . . . . . . . . . . . 33 122 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 34 123 9.1. Normative References . . . . . . . . . . . . . . . . . . 34 124 9.2. Informative References . . . . . . . . . . . . . . . . . 35 125 Appendix A. Formal Syntax of SDF . . . . . . . . . . . . . . . . 37 126 Appendix B. json-schema.org Rendition of SDF Syntax . . . . . . 41 127 Appendix C. Data Qualities inspired by json-schema.org . . . . . 79 128 C.1. type "number", type "integer" . . . . . . . . . . . . . . 80 129 C.2. type "string" . . . . . . . . . . . . . . . . . . . . . . 80 130 C.3. type "boolean" . . . . . . . . . . . . . . . . . . . . . 81 131 C.4. type "array" . . . . . . . . . . . . . . . . . . . . . . 81 132 C.5. type "object" . . . . . . . . . . . . . . . . . . . . . . 81 133 C.6. Implementation notes . . . . . . . . . . . . . . . . . . 82 134 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 82 135 Contributors . . . . . . . . . . . . . . . . . . . . . . . . . . 82 136 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 83 138 1. Introduction 140 The Semantic Definition Format (SDF) is a format for domain experts 141 to use in the creation and maintenance of data and interaction models 142 in the Internet of Things. It was created as a common language for 143 use in the development of the One Data Model liaison organization 144 (OneDM) definitions. Tools convert this format to database formats 145 and other serializations as needed. 147 An SDF specification describes definitions of SDF Objects and their 148 associated interactions (Events, Actions, Properties), as well as the 149 Data types for the information exchanged in those interactions. 151 // A JSON format representation of SDF 1.0 was defined in version 152 // (-00) of this document; version (-05) was designated as an 153 // _implementation draft_, labeled SDF 1.1, at the IETF110 meeting of 154 // the ASDF WG (2021-03-11). The present version (-11) collects a 155 // few smaller changes as input to the 2022-02-28 ASDF WG interim. 156 // It also removes deprecated elements from SDF 1.0. 158 1.1. Terminology and Conventions 160 Thing: A physical item that is also made available in the Internet 161 of Things. The term is used here for Things that are notable for 162 their interaction with the physical world beyond interaction with 163 humans; a temperature sensor or a light might be a Thing, but a 164 router that employs both temperature sensors and indicator lights 165 might exhibit less Thingness, as the effects of its functioning 166 are mostly on the digital side. 168 Affordance: An element of an interface offered for interaction, 169 defining its possible uses or making clear how it can or should be 170 used. The term is used here for the digital interfaces of a Thing 171 only; it might also have physical affordances such as buttons, 172 dials, and displays. 174 Quality: A metadata item in a definition or declaration which says 175 something about that definition or declaration. A quality is 176 represented in SDF as an entry in a JSON map (object) that serves 177 as a definition or declaration. 179 Entry: A key-value pair in a map. (In JSON maps, sometimes also 180 called "member".) 182 Block: One or more entries in a JSON map that is part of an SDF 183 specification; these entries together serve a specific function. 185 Group: An entry in the main SDF map and in certain nested 186 definitions that has a Class Name Keyword as its key and a map of 187 definition entries (Definition Group) as a value. 189 Class Name Keyword: One of sdfThing, sdfObject, sdfProperty, 190 sdfAction, sdfEvent, or sdfData; the Classes for these type 191 keywords are capitalized and prefixed with sdf. 193 Class: Abstract term for the information that is contained in groups 194 identified by a Class Name Keyword. 196 Property: An affordance that can potentially be used to read, write, 197 and/or observe state on an Object. (Note that Entries are often 198 called properties in other environments; in this document, the 199 term Property is specifically reserved for affordances, even if 200 the map key "properties" might be imported from a data definition 201 language with the other semantics.) 203 Action: An affordance that can potentially be used to perform a 204 named operation on an Object. 206 Event: An affordance that can potentially be used to obtain 207 information about what happened to an Object. 209 Object: A grouping of Property, Action, and Event definitions; the 210 main "atom" of reusable semantics for model construction. (Note 211 that JSON maps are often called JSON objects due to JSON's 212 JavaScript heritage; in this document, the term Object is 213 specifically reserved for the above grouping, even if the type 214 name "object" might be imported from a data definition language 215 with the other semantics.) 217 Element: A part or an aspect of something abstract; used here in its 218 usual English definition. (Occasionally, also used specifically 219 for the elements of JSON arrays.) 221 Definition: An entry in a Definition Group; the entry creates a new 222 semantic term for use in SDF models and associates it with a set 223 of qualities. 225 Declaration: A reference to and a use of a definition within an 226 enclosing definition, intended to create component instances 227 within that enclosing definition. Every declaration can also be 228 used as a definition for reference in a different place. 230 Protocol Binding: A companion document to an SDF specification that 231 defines how to map the abstract concepts in the specification into 232 the protocols in use in a specific ecosystem. Might supply URL 233 components, numeric IDs, and similar details. 235 The term "byte" is used in its now-customary sense as a synonym for 236 "octet". 238 Conventions: 240 * The singular form is chosen as the preferred one for the keywords 241 defined here. 243 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 244 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 245 "OPTIONAL" in this document are to be interpreted as described in 246 BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all 247 capitals, as shown here. 249 2. Overview 251 2.1. Example Definition 253 We start with an example for the SDF definition of a simple Object 254 called "Switch" (Figure 1). 256 { 257 "info": { 258 "title": "Example file for OneDM Semantic Definition Format", 259 "version": "2019-04-24", 260 "copyright": "Copyright 2019 Example Corp. All rights reserved.", 261 "license": "https://example.com/license" 262 }, 263 "namespace": { 264 "cap": "https://example.com/capability/cap" 265 }, 266 "defaultNamespace": "cap", 267 "sdfObject": { 268 "Switch": { 269 "sdfProperty": { 270 "value": { 271 "description": "The state of the switch; false for off and true for on.", 272 "type": "boolean" 273 } 274 }, 275 "sdfAction": { 276 "on": { 277 "description": "Turn the switch on; equivalent to setting value to true." 278 }, 279 "off": { 280 "description": "Turn the switch off; equivalent to setting value to false." 281 }, 282 "toggle": { 283 "description": "Toggle the switch; equivalent to setting value to its complement." 284 } 285 } 286 } 287 } 288 } 290 Figure 1: A simple example of an SDF definition file 292 This is a model of a switch. The state value declared in the 293 sdfProperty group, represented by a Boolean, will be true for "on" 294 and will be false for "off". The actions on or off declared in the 295 sdfAction group are redundant with setting the value and are in the 296 example to illustrate that there are often different ways of 297 achieving the same effect. The action toggle will invert the value 298 of the sdfProperty value, so that 2-way switches can be created; 299 having such action will avoid the need for first retrieving the 300 current value and then applying/setting the inverted value. 302 The sdfObject group lists the affordances of instances of this 303 object. The sdfProperty group lists the property affordances 304 described by the model; these represent various perspectives on the 305 state of the object. Properties can have additional qualities to 306 describe the state more precisely. Properties can be annotated to be 307 read, write or read/write; how this is actually done by the 308 underlying transfer protocols is not described in the SDF model but 309 left to companion protocol bindings. Properties are often used with 310 RESTful paradigms [I-D.irtf-t2trg-rest-iot], describing state. The 311 sdfAction group is the mechanism to describe other interactions in 312 terms of their names, input, and output data (no data are used in the 313 example), as in a POST method in REST or in a remote procedure call. 314 The example toggle is an Action that changes the state based on the 315 current state of the Property named value. (The third type of 316 affordance is Events, which are not described in this example.) 318 In the JSON representation, note how (with the exception of the info 319 group) maps that have keys taken from the SDF vocabulary (info, 320 namespace, sdfObject) alternate in nesting with maps that have keys 321 that are freely defined by the model writer (Switch, value, on, 322 etc.); the latter usually use the named<> production in the formal 323 syntax of SDF (Appendix A), while the former SDF-defined vocabulary 324 items are often, but not always, called _qualities_. 326 2.2. Elements of an SDF model 328 The SDF language uses six predefined Class Name Keywords for modeling 329 connected Things which are illustrated in Figure 2. 331 ,--------. 332 |sdfThing| 333 |--------| 334 `--------' 335 | 336 | 337 ,---------. 338 |sdfObject| 339 |---------| 340 `---------' 341 | 342 ,-----------. ,---------. ,--------. 343 |sdfProperty| |sdfAction| |sdfEvent| 344 |-----------| |---------| |--------| 345 `-----------' `---------' `--------' 346 | 348 ,-------. 349 |sdfData| 350 |-------| 351 `-------' 353 Figure 2: Main classes used in SDF models 355 The six main Class Name Keywords are discussed below. 357 2.2.1. sdfObject 359 Objects, the items listed in an sdfObject group, are the main "atom" 360 of reusable semantics for model construction. It aligns in scope 361 with common definition items from many IoT modeling systems, for 362 example ZigBee Clusters [ZCL], OMA SpecWorks LwM2M Objects [OMA], and 363 OCF Resource Types [OCF]. 365 An sdfObject contains a set of sdfProperty, sdfAction, and sdfEvent 366 definitions that describe the interaction affordances associated with 367 some scope of functionality. 369 For the granularity of definition, sdfObject definitions are meant to 370 be kept narrow enough in scope to enable broad reuse and 371 interoperability. For example, defining a light bulb using separate 372 sdfObject definitions for on/off control, dimming, and color control 373 affordances will enable interoperable functionality to be configured 374 for diverse product types. An sdfObject definition for a common on/ 375 off control may be used to control may different kinds of Things that 376 require on/off control. 378 Optional qualities "minItems" and "maxItems" can be used to define 379 sdfObjects as arrays. 381 2.2.2. sdfProperty 383 sdfProperty is used to model elements of state within sdfObject 384 instances. 386 An instance of sdfProperty may be associated with some protocol 387 affordance to enable the application to obtain the state variable 388 and, optionally, modify the state variable. Additionally, some 389 protocols provide for in-time reporting of state changes. (These 390 three aspects are described by the qualities readable, writable, and 391 observable defined for an sdfProperty.) 393 Definitions in sdfProperty groups include the definitions from 394 sdfData groups, however, they actually also declare a Property with 395 the given qualities to be potentially present in the containing 396 Object. 398 For definitions in sdfProperty and sdfData, SDF provides qualities 399 that can constrain the structure and values of data allowed in an 400 instance of these data, as well as qualities that associate semantics 401 to these data, for engineering units and unit scaling information. 403 For the data definition within sdfProperty or sdfData, SDF borrows 404 some vocabulary proposed for the drafts 4 and 7 of the json- 405 schema.org "JSON Schema" format (collectively called JSO here), 406 enhanced by qualities that are specific to SDF. Details about the 407 former are in Appendix C. For the current version of SDF, data are 408 constrained to be of simple types (number, string, Boolean), JSON 409 maps composed of named data ("objects"), and arrays of these types. 410 Syntax extension points are provided that can be used to provide 411 richer types in future versions of this specification (possibly more 412 of which can be borrowed from json-schema.org). 414 Note that sdfProperty definitions (and sdfData definitions in 415 general) are not intended to constrain the formats of data used for 416 communication over network interfaces. Where needed, data 417 definitions for payloads of protocol messages are expected to be part 418 of the protocol binding. 420 2.2.3. sdfAction 422 The sdfAction group contains declarations of Actions, model 423 affordances that, when triggered, have more effect than just reading, 424 updating, or observing Thing state, often resulting in some outward 425 physical effect (which, itself, cannot be modeled in SDF). From a 426 programmer's perspective, they might be considered to be roughly 427 analogous to method calls. 429 Actions may have data parameters; these are modeled as a single item 430 of input data and output data, each. (Where multiple parameters need 431 to be modeled, an "object" type can be used to combine these 432 parameters into one.) Actions may be long-running, that is to say 433 that the effects may not take place immediately as would be expected 434 for an update to an sdfProperty; the effects may play out over time 435 and emit action results. Actions may also not always complete and 436 may result in application errors, such as an item blocking the 437 closing of an automatic door. 439 Actions may have (or lack) qualities of idempotency and side-effect 440 safety. 442 The current version of SDF only provides data constraint modeling and 443 semantics for the input and output data of definitions in sdfAction 444 groups. Again, data definitions for payloads of protocol messages, 445 and detailed protocol settings for invoking the action, are expected 446 to be part of the protocol binding. 448 2.2.4. sdfEvent 450 The sdfEvent group contains declarations of Events, which can model 451 affordances that inform about "happenings" associated with an 452 instance of an Object; these may result in a signal being stored or 453 emitted as a result. 455 Note that there is a trivial overlap with sdfProperty state changes, 456 which may also be defined as events but are not generally required to 457 be defined as such. However, Events may exhibit certain ordering, 458 consistency, and reliability requirements that are expected to be 459 supported in various implementations of sdfEvent that do distinguish 460 sdfEvent from sdfProperty. For instance, while a state change may 461 simply be superseded by another state change, some events are 462 "precious" and need to be preserved even if further events follow. 464 The current version of SDF only provides data constraint modeling and 465 semantics for the output data of Event affordances. Again, data 466 definitions for payloads of protocol messages, and detailed protocol 467 settings for invoking the action, are expected to be part of the 468 protocol binding. 470 2.2.5. sdfData 472 Definitions in sdfData groups are provided separately from those in 473 sdfProperty groups to enable common modeling patterns, data 474 constraints, and semantic anchor concepts to be factored out for data 475 items that make up sdfProperty items and serve as input and output 476 data for sdfAction and sdfEvent items. 478 It is a common use case for such a data definition to be shared 479 between an sdfProperty item and input or output parameters of an 480 sdfAction or output data provided by an sdfEvent. sdfData definitions 481 also enable factoring out extended application data types such as 482 mode and machine state enumerations to be reused across multiple 483 definitions that have similar basic characteristics and requirements. 485 2.2.6. sdfThing 487 Back at the top level, the sdfThing groups enables definition of 488 models for complex devices that will use one or more sdfObject 489 definitions. 491 A definition in an sdfThing group can refine the metadata of the 492 definitions it is composed from: other definitions in sdfThing groups 493 definitions in sdfObject groups. 495 3. SDF structure 497 SDF definitions are contained in SDF files. One or more SDF files 498 can work together to provide the definitions and declarations that 499 are the payload of the SDF format. 501 A SDF definition file contains a single JSON map (JSON object). This 502 object has three blocks: the information block, the namespaces block, 503 and the definitions block. 505 3.1. Information block 507 The information block contains generic meta data for the file itself 508 and all included definitions. To enable tool integration, the 509 information block is optional in the grammar of SDF; most processes 510 for working with SDF files will have policies that only SDF models 511 with an info block can be processed. It is therefore RECOMMENDED 512 that SDF validator tools emit a warning when no information block is 513 found. 515 The keyword (map key) that defines an information block is "info". 516 Its value is a JSON map in turn, with a set of entries that represent 517 qualities that apply to the included definition. 519 Qualities of the information block are shown in Table 1. 521 +===========+========+==========+=================================+ 522 | Quality | Type | Required | Description | 523 +===========+========+==========+=================================+ 524 | title | string | no | A short summary to be displayed | 525 | | | | in search results, etc. | 526 +-----------+--------+----------+---------------------------------+ 527 | version | string | no | The incremental version of the | 528 | | | | definition, format TBD | 529 +-----------+--------+----------+---------------------------------+ 530 | copyright | string | no | Link to text or embedded text | 531 | | | | containing a copyright notice | 532 +-----------+--------+----------+---------------------------------+ 533 | license | string | no | Link to text or embedded text | 534 | | | | containing license terms | 535 +-----------+--------+----------+---------------------------------+ 537 Table 1: Qualities of the Information Block 539 While the format of the version string is marked as TBD, it is 540 intended to be lexicographically increasing over the life of a model: 541 a newer model always has a version string that string-compares higher 542 than all previous versions. This is easily achieved by following the 543 convention to start the version with an [RFC3339] date-time or, if 544 new versions are generated less frequently than once a day, just the 545 full-date (i.e., YYYY-MM-DD); in many cases, that will be all that is 546 needed (see Figure 1 for an example). 548 The license string is preferably either a URI that points to a web 549 page with an unambiguous definition of the license, or an [SPDX] 550 license identifier. (For models to be handled by the One Data Model 551 liaison group, this will typically be "BSD-3-Clause".) 553 3.2. Namespaces block 555 The namespaces block contains the namespace map and the 556 defaultNamespace setting. 558 The namespace map is a map from short names for URIs to the namespace 559 URIs themselves. 561 The defaultNamespace setting selects one of the entries in the 562 namespace map by giving its short name. The associated URI (value of 563 this entry) becomes the default namespace for the SDF definition 564 file. 566 +==================+========+==========+=======================+ 567 | Quality | Type | Required | Description | 568 +==================+========+==========+=======================+ 569 | namespace | map | no | Defines short names | 570 | | | | mapped to namespace | 571 | | | | URIs, to be used as | 572 | | | | identifier prefixes | 573 +------------------+--------+----------+-----------------------+ 574 | defaultNamespace | string | no | Identifies one of the | 575 | | | | prefixes in the | 576 | | | | namespace map to be | 577 | | | | used as a default in | 578 | | | | resolving identifiers | 579 +------------------+--------+----------+-----------------------+ 581 Table 2: Namespaces Block 583 The following example declares a set of namespaces and defines cap as 584 the default namespace. By convention, the values in the namespace 585 map contain full URIs without a fragment identifier, and the fragment 586 identifier is then added, if needed, where the namespace entry is 587 used. 589 "namespace": { 590 "cap": "https://example.com/capability/cap", 591 "zcl": "https://zcl.example.com/sdf" 592 }, 593 "defaultNamespace": "cap" 595 If no defaultNamespace setting is given, the SDF definition file does 596 not contribute to a global namespace. As the defaultNamespace is set 597 by giving a namespace short name, its presence requires a namespace 598 map that contains a mapping for that namespace short name. 600 If no namespace map is given, no short names for namespace URIs are 601 set up, and no defaultNamespace can be given. 603 3.3. Definitions block 605 The Definitions block contains one or more groups, each identified by 606 a Class Name Keyword (there can only be one group per keyword; the 607 actual grouping is just a shortcut and does not carry any specific 608 semantics). The value of each group is a JSON map (object), the keys 609 of which serve for naming the individual definitions in this group, 610 and the corresponding values provide a set of qualities (name-value 611 pairs) for the individual definition. (In short, we speak of the map 612 entries as "named sets of qualities".) 614 Each group may contain zero or more definitions. Each identifier 615 defined creates a new type and term in the target namespace. 616 Declarations have a scope of the current definition block. 618 A definition may in turn contain other definitions. Each definition 619 is a named set of qualities, i.e., it consists of the newly defined 620 identifier and a set of key-value pairs that represent the defined 621 qualities and contained definitions. 623 An example for an Object definition is given in Figure 3: 625 "sdfObject": { 626 "foo": { 627 "sdfProperty": { 628 "bar": { 629 "type": "boolean" 630 } 631 } 632 } 633 } 635 Figure 3: Example Object definition 637 This example defines an Object "foo" that is defined in the default 638 namespace (full address: #/sdfObject/foo), containing a property that 639 can be addressed as #/sdfObject/foo/sdfProperty/bar, with data of 640 type boolean. 642 Some of the definitions are also declarations: the definition of the 643 entry "bar" in the property "foo" means that each instance of a "foo" 644 can have zero or one instance of a "bar". Entries within 645 sdfProperty, sdfAction, and sdfEvent, within sdfObject entries, are 646 declarations. Similarly, entries within an sdfThing describe 647 instances of sdfObject (or nested sdfThing) that form part of 648 instances of the Thing. 650 4. Names and namespaces 652 SDF definition files may contribute to a global namespace, and may 653 reference elements from that global namespace. (An SDF definition 654 file that does not set a defaultNamespace does not contribute to a 655 global namespace.) 657 4.1. Structure 659 Global names look exactly like https:// URIs with attached fragment 660 identifiers. 662 There is no intention to require that these URIs can be dereferenced. 663 (However, as future versions of SDF might find a use for 664 dereferencing global names, the URI should be chosen in such a way 665 that this may become possible in the future.) 667 The absolute URI of a global name should be a URI as per Section 3 of 668 [RFC3986], with a scheme of "https" and a path (hier-part in 669 [RFC3986]). For the present version of this specification, the query 670 part should not be used (it might be used in later versions). 672 The fragment identifier is constructed as per Section 6 of [RFC6901]. 674 4.2. Contributing global names 676 The fragment identifier part of a global name defined in an SDF 677 definition file is constructed from a JSON pointer that selects the 678 element defined for this name in the SDF definition file. 680 The absolute URI part is a copy of the default namespace, i.e., the 681 default namespace is always the target namespace for a name for which 682 a definition is contributed. When emphasizing that name definitions 683 are contributed to the default namespace, we therefore also call it 684 the "target namespace" of the SDF definition file. 686 E.g., in Figure 1, definitions for the following global names are 687 contributed: 689 * https://example.com/capability/cap#/sdfObject/Switch 690 * https://example.com/capability/cap#/sdfObject/Switch/sdfProperty/ 691 value 693 * https://example.com/capability/cap#/sdfObject/Switch/sdfAction/on 695 * https://example.com/capability/cap#/sdfObject/Switch/sdfAction/off 697 Note the #, which separates the absolute-URI part (Section 4.3 of 698 [RFC3986]) from the fragment identifier part. 700 4.3. Referencing global names 702 A name reference takes the form of the production curie in 703 [W3C.NOTE-curie-20101216] (note that this excludes the production 704 safe-curie), but also limiting the IRIs involved in that production 705 to URIs as per [RFC3986] and the prefixes to ASCII characters 706 [RFC0020]. 708 A name that is contributed by the current SDF definition file can be 709 referenced by a Same-Document Reference as per Section 4.4 of 710 [RFC3986]. As there is little point in referencing the entire SDF 711 definition file, this will be a # followed by a JSON pointer. This 712 is the only kind of name reference to itself that is possible in an 713 SDF definition file that does not set a default namespace. 715 Name references that point outside the current SDF definition file 716 need to contain curie prefixes. These then reference namespace 717 declarations in the namespaces block. 719 For example, if a namespace prefix is defined: 721 "namespace": { 722 "foo": "https://example.com/" 723 } 725 Then this reference to that namespace: 727 { "sdfRef": "foo:#/sdfData/temperatureData" } 729 references the global name: 731 "https://example.com/#/sdfData/temperatureData" 733 Note that there is no way to provide a URI scheme name in a curie, so 734 all references outside of the document need to go through the 735 namespace map. 737 Name references occur only in specific elements of the syntax of SDF: 739 * copying elements via sdfRef values 741 * pointing to elements via sdfRequired value elements 743 4.4. sdfRef 745 In a JSON map establishing a definition, the keyword "sdfRef" is used 746 to copy all of the qualities of the referenced definition, indicated 747 by the included name reference, into the newly formed definition. 748 (This can be compared to the processing of the "$ref" keyword in 749 [I-D.handrews-json-schema-validation].) 751 For example, this reference: 753 "temperatureProperty": { 754 "sdfRef": "#/sdfData/temperatureData" 755 } 757 creates a new definition "temperatureProperty" that contains all of 758 the qualities defined in the definition at /sdfData/temperatureData. 760 The sdfRef member need not be the only member of a map. Additional 761 members may be present with the intention to override parts of the 762 referenced map. More formally, for a JSON map that contains an 763 sdfRef member, the semantics is defined to be as if the following 764 steps were performed: 766 1. The JSON map that contains the sdfRef member is copied into a 767 variable named "patch". 769 2. The sdfRef member of the copy in "patch" is removed. 771 3. the JSON pointer that is the value of the sdfRef member is 772 dereferenced and the result is copied into a variable named 773 "original". 775 4. The JSON Merge Patch algorithm [RFC7396] is applied to patch the 776 contents of "original" with the contents of "patch". 778 5. The result of the Merge Patch is used in place of the value of 779 the original JSON map. 781 TODO: Make sure that the grammar in Appendix A allows specifying the 782 null values that are necessary to remove members in a merge-patch. 784 4.5. sdfRequired 786 The keyword "sdfRequired" is provided to apply a constraint that 787 defines for which declarations corresponding data are mandatory in an 788 instance conforming the current definition. 790 The value of "sdfRequired" is an array of name references (JSON 791 pointers), each indicating one declaration that is mandatory to be 792 represented. 794 The example in Figure 4 shows two required elements in the sdfObject 795 definition for "temperatureWithAlarm", the sdfProperty 796 "currentTemperature", and the sdfEvent "overTemperatureEvent". The 797 example also shows the use of JSON pointer with "sdfRef" to use a 798 pre-existing definition in this definition, for the "alarmType" data 799 (sdfOutputData) produced by the sdfEvent "overTemperatureEvent". 801 { 802 "sdfObject": { 803 "temperatureWithAlarm": { 804 "sdfRequired": [ 805 "#/sdfObject/temperatureWithAlarm/sdfProperty/currentTemperature", 806 "#/sdfObject/temperatureWithAlarm/sdfEvent/overTemperatureEvent" 807 ], 808 "sdfData":{ 809 "temperatureData": { 810 "type": "number" 811 } 812 }, 813 "sdfProperty": { 814 "currentTemperature": { 815 "sdfRef": "#/sdfObject/temperatureWithAlarm/sdfData/temperatureData" 816 } 817 }, 818 "sdfEvent": { 819 "overTemperatureEvent": { 820 "sdfOutputData": { 821 "type": "object", 822 "properties": { 823 "alarmType": { 824 "sdfRef": "cap:#/sdfData/alarmTypes/quantityAlarms", 825 "const": "OverTemperatureAlarm" 826 }, 827 "temperature": { 828 "sdfRef": "#/sdfObject/temperatureWithAlarm/sdfData/temperatureData" 829 } 830 } 831 } 832 } 833 } 834 } 835 } 836 } 838 Figure 4: Using sdfRequired 840 4.6. Common Qualities 842 Definitions in SDF share a number of qualities that provide metadata 843 for them. These are listed in Table 3. None of these qualities are 844 required or have default values that are assumed if the quality is 845 absent. If a label is required for an application and no label is 846 given in the SDF model, the last part (reference-token, Section 3 of 847 [RFC6901]) of the JSON pointer to the definition can be used. 849 +=============+==============+===================================+ 850 | Quality | Type | Description | 851 +=============+==============+===================================+ 852 | description | text | long text (no constraints) | 853 +-------------+--------------+-----------------------------------+ 854 | label | text | short text (no constraints) | 855 +-------------+--------------+-----------------------------------+ 856 | $comment | text | source code comments only, no | 857 | | | semantics | 858 +-------------+--------------+-----------------------------------+ 859 | sdfRef | sdf-pointer | (see Section 4.4) | 860 +-------------+--------------+-----------------------------------+ 861 | sdfRequired | pointer-list | (see Section 4.5, applies to | 862 | | | qualities of properties, of data) | 863 +-------------+--------------+-----------------------------------+ 865 Table 3: Common Qualities 867 4.7. Data Qualities 869 Data qualities are used in sdfData and sdfProperty definitions, which 870 are named sets of data qualities (abbreviated as named-sdq). 872 Appendix C lists data qualities inspired by the various proposals at 873 json-schema.org; the intention is that these (information model 874 level) qualities are compatible with the (data model) semantics from 875 the versions of the json-schema.org proposal they were imported from. 877 Table 4 lists data qualities defined specifically for the present 878 specification. 880 +===============+================+========================+=========+ 881 | Quality | Type | Description | Default | 882 +===============+================+========================+=========+ 883 | (common) | | Section 4.6 | | 884 +---------------+----------------+------------------------+---------+ 885 | unit | string | unit name (note 1) | N/A | 886 +---------------+----------------+------------------------+---------+ 887 | scaleMinimum | number | lower limit of value | N/A | 888 | | | in units given by | | 889 | | | unit (note 2) | | 890 +---------------+----------------+------------------------+---------+ 891 | scaleMaximum | number | upper limit of value | N/A | 892 | | | in units given by | | 893 | | | unit (note 2) | | 894 +---------------+----------------+------------------------+---------+ 895 | nullable | boolean | indicates a null | true | 896 | | | value is available | | 897 | | | for this type | | 898 +---------------+----------------+------------------------+---------+ 899 | contentFormat | string | content type (IANA | N/A | 900 | | | media type string | | 901 | | | plus parameters), | | 902 | | | encoding | | 903 +---------------+----------------+------------------------+---------+ 904 | sdfType | string | sdfType enumeration | N/A | 905 | | (Section | (extensible) | | 906 | | 4.7.1) | | | 907 +---------------+----------------+------------------------+---------+ 908 | sdfChoice | named set of | named alternatives | N/A | 909 | | data qualities | | | 910 | | (Section | | | 911 | | 4.7.2) | | | 912 +---------------+----------------+------------------------+---------+ 913 | enum | array of | abbreviation for | N/A | 914 | | strings | string-valued named | | 915 | | | alternatives | | 916 +---------------+----------------+------------------------+---------+ 918 Table 4: SDF-defined Qualities of sdfData 920 1. Note that the quality unit was called units in SDF 1.0. The unit 921 name SHOULD be as per the SenML Units Registry or the Secondary 922 Units Registry in [IANA.senml] as specified by Sections 4.5.1 and 923 12.1 of [RFC8428] and Section 3 of [RFC8798], respectively. 925 Exceptionally, if a registration in these registries cannot be 926 obtained or would be inappropriate, the unit name can also be a 927 URI that is pointing to a definition of the unit. Note that SDF 928 processors are not expected to (and normally SHOULD NOT) 929 dereference these URIs; they may be useful to humans, though. A 930 URI unit name is distinguished from a registered unit name by the 931 presence of a colon; registered unit names that contain a colon 932 (at the time of writing, none) can therefore not be used in SDF. 934 For use by translators into ecosystems that require URIs for unit 935 names, the URN sub-namespace "urn:ietf:params:unit" is provided 936 (Section 7.2); URNs from this sub-namespace MUST NOT be used in a 937 unit quality, in favor of simply notating the unit name (e.g., kg 938 instead of urn:ietf:params:unit:kg). 940 2. these qualities were included in SDF 1.0, but were not fully 941 defined; they are not included in SDF 1.1. In 1.next, they will 942 be replaced by qualities to express scaling that are more aligned 943 with the processes that combine ecosystem and instance specific 944 information with an SDF model. 946 4.7.1. sdfType 948 SDF defines a number of basic types beyond those provided by JSON or 949 JSO. These types are identified by the sdfType quality, which is a 950 text string from a set of type names defined by SDF. 952 To aid interworking with [I-D.handrews-json-schema-validation] 953 implementations, it is RECOMMENDED that sdfType is always used in 954 conjunction with the type quality inherited from 955 [I-D.handrews-json-schema-validation], in such a way as to yield a 956 common representation of the type's values in JSON. 958 Values for sdfType that are defined in SDF 1.1 are shown in Table 5. 959 This table also gives a description of the semantics of the sdfType, 960 the conventional value for type to be used with the sdfType value, 961 and a conventional JSON representation for values of the type. 963 +=============+=============+========+==========================+ 964 | sdfType | Description | type | JSON Representation | 965 +=============+=============+========+==========================+ 966 | byte-string | A sequence | string | base64url without | 967 | | of zero or | | padding (Section 3.4.5.2 | 968 | | more bytes | | of [RFC8949]) | 969 +-------------+-------------+--------+--------------------------+ 970 | unix-time | A point in | number | POSIX time | 971 | | civil time | | (Section 3.4.2 of | 972 | | (note 1) | | [RFC8949]) | 973 +-------------+-------------+--------+--------------------------+ 975 Table 5: Values defined in SDF 1.1 for sdfType quality 977 (1) Note that the definition of unix-time does not imply the 978 capability to represent points in time that fall on leap seconds. 979 More date/time-related sdfTypes are likely to be added in future 980 versions of this specification. 982 In SDF 1.0, a similar concept was called subtype. 984 4.7.2. sdfChoice 986 Data can be a choice of named alternatives, called sdfChoice. Each 987 alternative is identified by a name (string, key in the JSON object 988 used to represent the choice) and a set of dataqualities (object, the 989 value in the JSON object used to represent the choice). 991 sdfChoice merges the functions of two constructs found in 992 [I-D.handrews-json-schema-validation]: 994 * enum 996 What would have been 998 "enum": ["foo", "bar", "baz"] 1000 in SDF 1.0, is often best represented as: 1002 "sdfChoice": { 1003 "foo": { "description": "This is a foonly"}, 1004 "bar": { "description": "As defined in the second world congress"}, 1005 "baz": { "description": "From zigbee foobaz"} 1006 } 1008 This allows the placement of other dataqualities such as 1009 description in the example. 1011 If an enum needs to use a data type different from text string, 1012 e.g. what would have been 1014 "type": "number", 1015 "enum": [1, 2, 3] 1017 in SDF 1.0, is represented as: 1019 "type": "number", 1020 "sdfChoice": { 1021 "a-better-name-for-alternative-1": { "const": 1 }, 1022 "alternative-2": { "const": 2 }, 1023 "the-third-alternative": { "const": 3 } 1024 } 1025 where the string names obviously would be chosen in a way that is 1026 descriptive for what these numbers actually stand for; sdfChoice 1027 also makes it easy to add number ranges into the mix. 1029 (Note that const can also be used for strings as in the previous 1030 example, e.g., if the actual string value is indeed a crucial 1031 element for the data model.) 1033 * anyOf 1035 [I-D.handrews-json-schema-validation] provides a type union called 1036 anyOf, which provides a choice between anonymous alternatives. 1038 What could have been 1040 "anyOf": [ 1041 {"type": "array", "minItems": 3, "maxItems": "3", "items": { 1042 "$ref": "#/sdfData/rgbVal"}}, 1043 {"type": "array", "minItems": 4, "maxItems": "4", "items": { 1044 "$ref": "#/sdfData/cmykVal"}} 1045 ] 1047 in [I-D.handrews-json-schema-validation] can be more descriptively 1048 notated in SDF as: 1050 "sdfChoice": { 1051 "rgb": {"type": "array", "minItems": 3, "maxItems": "3", "items": { 1052 "sdfRef": "#/sdfData/rgbVal"}}, 1053 "cmyk": {"type": "array", "minItems": 4, "maxItems": "4", "items": { 1054 "sdfRef": "#/sdfData/cmykVal"}} 1055 } 1057 Note that there is no need in SDF for the type intersection construct 1058 allOf or the peculiar type-xor construct oneOf found in 1059 [I-D.handrews-json-schema-validation]. 1061 As a simplification for readers of SDF specifications accustomed to 1062 the [I-D.handrews-json-schema-validation] enum keyword, this is 1063 retained, but limited to a choice of text string values, such that 1065 "enum": ["foo", "bar", "baz"] 1067 is syntactic sugar for 1068 "sdfChoice": { 1069 "foo": { "const": "foo"}, 1070 "bar": { "const": "bar"}, 1071 "baz": { "const": "baz"} 1072 } 1074 5. Keywords for definition groups 1076 The following SDF keywords are used to create definition groups in 1077 the target namespace. All these definitions share some common 1078 qualities as discussed in Section 4.6. 1080 5.1. sdfObject 1082 The sdfObject keyword denotes a group of zero or more Object 1083 definitions. Object definitions may contain or include definitions 1084 of Properties, Actions, Events declared for the object, as well as 1085 data types (sdfData group) to be used in this or other Objects. 1087 The qualities of an sdfObject include the common qualities, 1088 additional qualities are shown in Table 6. None of these qualities 1089 are required or have default values that are assumed if the quality 1090 is absent. 1092 +=============+===========+=============================+ 1093 | Quality | Type | Description | 1094 +=============+===========+=============================+ 1095 | (common) | | Section 4.6 | 1096 +-------------+-----------+-----------------------------+ 1097 | sdfProperty | property | zero or more named property | 1098 | | | definitions for this object | 1099 +-------------+-----------+-----------------------------+ 1100 | sdfAction | action | zero or more named action | 1101 | | | definitions for this object | 1102 +-------------+-----------+-----------------------------+ 1103 | sdfEvent | event | zero or more named event | 1104 | | | definitions for this object | 1105 +-------------+-----------+-----------------------------+ 1106 | sdfData | named-sdq | zero or more named data | 1107 | | | type definitions that might | 1108 | | | be used in the above | 1109 +-------------+-----------+-----------------------------+ 1110 | minItems | number | (array) Minimum number of | 1111 | | | sdfObject instances in | 1112 | | | array | 1113 +-------------+-----------+-----------------------------+ 1114 | maxItems | number | (array) Maximum number of | 1115 | | | sdfObject instances in | 1116 | | | array | 1117 +-------------+-----------+-----------------------------+ 1119 Table 6: Qualities of sdfObject 1121 5.2. sdfProperty 1123 The sdfProperty keyword denotes a group of zero or more Property 1124 definitions. 1126 Properties are used to model elements of state. 1128 The qualities of a Property definition include the data qualities 1129 (and thus the common qualities), see Section 4.7, additional 1130 qualities are shown in Table 7. 1132 +============+=========+===============================+=========+ 1133 | Quality | Type | Description | Default | 1134 +============+=========+===============================+=========+ 1135 | (data) | | Section 4.7 | | 1136 +------------+---------+-------------------------------+---------+ 1137 | readable | boolean | Reads are allowed | true | 1138 +------------+---------+-------------------------------+---------+ 1139 | writable | boolean | Writes are allowed | true | 1140 +------------+---------+-------------------------------+---------+ 1141 | observable | boolean | flag to indicate asynchronous | true | 1142 | | | notification is available | | 1143 +------------+---------+-------------------------------+---------+ 1145 Table 7: Qualities of sdfProperty 1147 5.3. sdfAction 1149 The sdfAction keyword denotes a group of zero or more Action 1150 definitions. 1152 Actions are used to model commands and methods which are invoked. 1153 Actions have parameter data that are supplied upon invocation. 1155 The qualities of an Action definition include the common qualities, 1156 additional qualities are shown in Table 8. 1158 +===============+===========+============================+ 1159 | Quality | Type | Description | 1160 +===============+===========+============================+ 1161 | (common) | | Section 4.6 | 1162 +---------------+-----------+----------------------------+ 1163 | sdfInputData | map | data qualities of the | 1164 | | | input data for an Action | 1165 +---------------+-----------+----------------------------+ 1166 | sdfOutputData | map | data qualities of the | 1167 | | | output data for an Action | 1168 +---------------+-----------+----------------------------+ 1169 | sdfData | named-sdq | zero or more named data | 1170 | | | type definitions that | 1171 | | | might be used in the above | 1172 +---------------+-----------+----------------------------+ 1174 Table 8: Qualities of sdfAction 1176 sdfInputData defines the input data of the action. sdfOutputData 1177 defines the output data of the action. As discussed in 1178 Section 2.2.3, a set of data qualities with type "object" can be used 1179 to substructure either data item, with optionality indicated by the 1180 data quality required. 1182 5.4. sdfEvent 1184 The sdfEvent keyword denotes zero or more Event definitions. 1186 Events are used to model asynchronous occurrences that may be 1187 communicated proactively. Events have data elements which are 1188 communicated upon the occurrence of the event. 1190 The qualities of sdfEvent include the common qualities, additional 1191 qualities are shown in Table 9. 1193 +===============+===========+============================+ 1194 | Quality | Type | Description | 1195 +===============+===========+============================+ 1196 | (common) | | Section 4.6 | 1197 +---------------+-----------+----------------------------+ 1198 | sdfOutputData | map | data qualities of the | 1199 | | | output data for an Event | 1200 +---------------+-----------+----------------------------+ 1201 | sdfData | named-sdq | zero or more named data | 1202 | | | type definitions that | 1203 | | | might be used in the above | 1204 +---------------+-----------+----------------------------+ 1206 Table 9: Qualities of sdfEvent 1208 sdfOutputData defines the output data of the action. As discussed in 1209 Section 2.2.4, a set of data qualities with type "object" can be used 1210 to substructure the output data item, with optionality indicated by 1211 the data quality required. 1213 5.5. sdfData 1215 The sdfData keyword denotes a group of zero or more named data type 1216 definitions (named-sdq). 1218 An sdfData definition provides a reusable semantic identifier for a 1219 type of data item and describes the constraints on the defined type. 1220 It is not itself a declaration, i.e., it does not cause any of these 1221 data items to be included in an affordance definition. 1223 The qualities of sdfData include the data qualities (and thus the 1224 common qualities), see Section 4.7. 1226 6. High Level Composition 1228 The requirements for high level composition include the following: 1230 * The ability to represent products, standardized product types, and 1231 modular products while maintaining the atomicity of Objects. 1233 * The ability to compose a reusable definition block from Objects, 1234 for example a single plug unit of an outlet strip with on/off 1235 control, energy monitor, and optional dimmer objects, while 1236 retaining the atomicity of the individual objects. 1238 * The ability to compose Objects and other definition blocks into a 1239 higher level thing that represents a product, while retaining the 1240 atomicity of objects. 1242 * The ability to enrich and refine a base definition to have 1243 product-specific qualities and quality values, e.g. unit, range, 1244 and scale settings. 1246 * The ability to reference items in one part of a complex definition 1247 from another part of the same definition, for example to summarize 1248 the energy readings from all plugs in an outlet strip. 1250 6.1. Paths in the model namespaces 1252 The model namespace is organized according to terms that are defined 1253 in the definition files that are present in the namespace. For 1254 example, definitions that originate from an organization or vendor 1255 are expected to be in a namespace that is specific to that 1256 organization or vendor. There is expected to be an SDF namespace for 1257 common SDF definitions used in OneDM. 1259 The structure of a path in a namespace is defined by the JSON 1260 Pointers to the definitions in the files in that namespace. For 1261 example, if there is a file defining an object "Switch" with an 1262 action "on", then the reference to the action would be 1263 "ns:/sdfObject/Switch/sdfAction/on" where ns is the namespace prefix 1264 (short name for the namespace). 1266 6.2. Modular Composition 1268 Modular composition of definitions enables an existing definition 1269 (could be in the same file or another file) to become part of a new 1270 definition by including a reference to the existing definition within 1271 the model namespace. 1273 6.2.1. Use of the "sdfRef" keyword to re-use a definition 1275 An existing definition may be used as a template for a new 1276 definition, that is, a new definition is created in the target 1277 namespace which uses the defined qualities of some existing 1278 definition. This pattern will use the keyword "sdfRef" as a quality 1279 of a new definition with a value consisting of a reference to the 1280 existing definition that is to be used as a template. 1282 In the definition that uses "sdfRef", new qualities may be added and 1283 existing qualities from the referenced definition may be overridden. 1284 (Note that JSON maps (objects) do not have a defined order, so the 1285 SDF processor may see these overrides before seeing the sdfRef.) 1287 As a convention, overrides are intended to be used only for further 1288 restricting the set of data values, as shown in Figure 5: any value 1289 for a cable-length also is a valid value for a length, with the 1290 additional restriction that the length cannot be smaller than 5 cm. 1291 (This is labeled as a convention as it cannot be checked in the 1292 general case; a quality of implementation consideration for a tool 1293 might be to provide at least some form of checking.) Note that a 1294 description is provided that overrides the description of the 1295 referenced definition; as this quality is intended for human 1296 consumption there is no conflict with the intended goal. 1298 "sdfData": 1299 "length" : { 1300 "type": "number", 1301 "minimum": 0, 1302 "unit": "m" 1303 "description": "There can be no negative lengths." 1304 } 1305 ... 1306 "cable-length" : { 1307 "sdfRef": "#/sdfData/length" 1308 "minimum": 5e-2, 1309 "description": "Cables must be at least 5 cm." 1310 } 1312 Figure 5 1314 6.3. sdfThing 1316 An sdfThing is a set of declarations and qualities that may be part 1317 of a more complex model. For example, the object declarations that 1318 make up the definition of a single socket of an outlet strip could be 1319 encapsulated in an sdfThing, and the socket-thing itself could be 1320 used in a declaration in the sdfThing definition for the outlet 1321 strip. 1323 sdfThing definitions carry semantic meaning, such as a defined 1324 refrigerator compartment and a defined freezer compartment, making up 1325 a combination refrigerator-freezer product. 1327 An sdfThing may be composed of sdfObjects and other sdfThings. 1329 The qualities of sdfThing are shown in Table 10. 1331 +===========+========+=============+ 1332 | Quality | Type | Description | 1333 +===========+========+=============+ 1334 | (common) | | Section 4.6 | 1335 +-----------+--------+-------------+ 1336 | sdfThing | thing | | 1337 +-----------+--------+-------------+ 1338 | sdfObject | object | | 1339 +-----------+--------+-------------+ 1341 Table 10: Qualities of sdfThing 1343 7. IANA Considerations 1345 7.1. Media Type 1347 IANA is requested to add the following Media-Type to the "Media 1348 Types" registry. 1350 +==========+======================+=======================+ 1351 | Name | Template | Reference | 1352 +==========+======================+=======================+ 1353 | sdf+json | application/sdf+json | RFC XXXX, Section 7.1 | 1354 +----------+----------------------+-----------------------+ 1356 Table 11 1358 // RFC Ed.: please replace RFC XXXX with this RFC number and remove 1359 this note. 1361 Type name: application 1362 Subtype name: sdf+json 1363 Required parameters: none 1364 Optional parameters: none 1365 Encoding considerations: binary (JSON is UTF-8-encoded text) 1366 Security considerations: Section 8 of RFC XXXX 1367 Interoperability considerations: none 1368 Published specification: Section 7.1 of RFC XXXX 1369 Applications that use this media type: Tools for data and 1370 interaction modeling in the Internet of Things 1371 Fragment identifier considerations: A JSON Pointer fragment 1372 identifier may be used, as defined in Section 6 of [RFC6901]. 1373 Person & email address to contact for further information: ASDF WG 1374 mailing list (asdf@ietf.org), or IETF Applications and Real-Time 1375 Area (art@ietf.org) 1376 Intended usage: COMMON 1377 Restrictions on usage: none 1378 Author/Change controller: IETF 1379 Provisional registration: no 1381 7.2. IETF URN Sub-namespace for Unit Names (urn:ietf:params:unit) 1383 IANA is requested to register the following value in the "IETF URN 1384 Sub-namespace for Registered Protocol Parameter Identifiers" 1385 registry, following the template in [RFC3553]: 1387 Registry name: unit 1389 Specification: RFC XXXX 1391 Repository: combining the symbol values from the SenML Units 1392 Registry and the Secondary Units Registry in [IANA.senml] as 1393 specified by Sections 4.5.1 and 12.1 of [RFC8428] and Section 3 of 1394 [RFC8798], respectively (which by the registration policy are 1395 guaranteed to be non-overlapping). 1397 Index value: Percent-encoding (Section 2.1 of [RFC3986]) is required 1398 of any characters in unit names as required by ABNF rule "pchar" 1399 in Section 3.3 of [RFC3986], specifically at the time of writing 1400 for the unit names "%" (deprecated in favor of "/"), "%RH", "%EL". 1402 7.3. Registries 1404 (TBD: After future additions, check if we need any.) 1406 8. Security Considerations 1408 Some wider issues are discussed in [RFC8576]. 1410 (Specifics: TBD.) 1412 9. References 1414 9.1. Normative References 1416 [IANA.params] 1417 IANA, "Uniform Resource Name (URN) Namespace for IETF 1418 Use", . 1420 [IANA.senml] 1421 IANA, "Sensor Measurement Lists (SenML)", 1422 . 1424 [RFC0020] Cerf, V., "ASCII format for network interchange", STD 80, 1425 RFC 20, DOI 10.17487/RFC0020, October 1969, 1426 . 1428 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1429 Requirement Levels", BCP 14, RFC 2119, 1430 DOI 10.17487/RFC2119, March 1997, 1431 . 1433 [RFC3339] Klyne, G. and C. Newman, "Date and Time on the Internet: 1434 Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002, 1435 . 1437 [RFC3553] Mealling, M., Masinter, L., Hardie, T., and G. Klyne, "An 1438 IETF URN Sub-namespace for Registered Protocol 1439 Parameters", BCP 73, RFC 3553, DOI 10.17487/RFC3553, June 1440 2003, . 1442 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 1443 Resource Identifier (URI): Generic Syntax", STD 66, 1444 RFC 3986, DOI 10.17487/RFC3986, January 2005, 1445 . 1447 [RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally 1448 Unique IDentifier (UUID) URN Namespace", RFC 4122, 1449 DOI 10.17487/RFC4122, July 2005, 1450 . 1452 [RFC6901] Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed., 1453 "JavaScript Object Notation (JSON) Pointer", RFC 6901, 1454 DOI 10.17487/RFC6901, April 2013, 1455 . 1457 [RFC7396] Hoffman, P. and J. Snell, "JSON Merge Patch", RFC 7396, 1458 DOI 10.17487/RFC7396, October 2014, 1459 . 1461 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1462 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1463 May 2017, . 1465 [RFC8428] Jennings, C., Shelby, Z., Arkko, J., Keranen, A., and C. 1466 Bormann, "Sensor Measurement Lists (SenML)", RFC 8428, 1467 DOI 10.17487/RFC8428, August 2018, 1468 . 1470 [RFC8610] Birkholz, H., Vigano, C., and C. Bormann, "Concise Data 1471 Definition Language (CDDL): A Notational Convention to 1472 Express Concise Binary Object Representation (CBOR) and 1473 JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, 1474 June 2019, . 1476 [RFC8798] Bormann, C., "Additional Units for Sensor Measurement 1477 Lists (SenML)", RFC 8798, DOI 10.17487/RFC8798, June 2020, 1478 . 1480 [RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object 1481 Representation (CBOR)", STD 94, RFC 8949, 1482 DOI 10.17487/RFC8949, December 2020, 1483 . 1485 [RFC9165] Bormann, C., "Additional Control Operators for the Concise 1486 Data Definition Language (CDDL)", RFC 9165, 1487 DOI 10.17487/RFC9165, December 2021, 1488 . 1490 [SPDX] "SPDX License List", . 1492 [W3C.NOTE-curie-20101216] 1493 Birbeck, M. and S. McCarron, "CURIE Syntax 1.0", World 1494 Wide Web Consortium NOTE NOTE-curie-20101216, 16 December 1495 2010, . 1497 9.2. Informative References 1499 [ECMA-262] Ecma International, "ECMAScript 2020 Language 1500 Specification", ECMA Standard ECMA-262, 11th Edition, June 1501 2020, . 1504 [I-D.bormann-jsonpath-iregexp] 1505 Bormann, C., "I-Regexp: An Interoperable Regexp Format", 1506 Work in Progress, Internet-Draft, draft-bormann-jsonpath- 1507 iregexp-02, 17 January 2022, 1508 . 1511 [I-D.handrews-json-schema-validation] 1512 Wright, A., Andrews, H., and B. Hutton, "JSON Schema 1513 Validation: A Vocabulary for Structural Validation of 1514 JSON", Work in Progress, Internet-Draft, draft-handrews- 1515 json-schema-validation-02, 17 September 2019, 1516 . 1519 [I-D.irtf-t2trg-rest-iot] 1520 Keranen, A., Kovatsch, M., and K. Hartke, "Guidance on 1521 RESTful Design for Internet of Things Systems", Work in 1522 Progress, Internet-Draft, draft-irtf-t2trg-rest-iot-09, 26 1523 February 2022, . 1526 [I-D.wright-json-schema] 1527 Wright, A. and H. Andrews, "JSON Schema: A Media Type for 1528 Describing JSON Documents", Work in Progress, Internet- 1529 Draft, draft-wright-json-schema-01, 16 April 2017, 1530 . 1533 [OCF] "OCF Resource Type Specification", 1534 . 1537 [OMA] "OMA LightweightM2M (LwM2M) Object and Resource Registry", 1538 . 1541 [RFC8576] Garcia-Morchon, O., Kumar, S., and M. Sethi, "Internet of 1542 Things (IoT) Security: State of the Art and Challenges", 1543 RFC 8576, DOI 10.17487/RFC8576, April 2019, 1544 . 1546 [ZCL] "The ZigBee Cluster Library", Zigbee Wireless 1547 Networking pp. 239-271, 1548 DOI 10.1016/b978-0-7506-8597-9.00006-9, 2008, 1549 . 1551 Appendix A. Formal Syntax of SDF 1553 This appendix describes the syntax of SDF using CDDL [RFC8610]. Note 1554 that this appendix was derived from Ari Keranen's "alt-schema" and 1555 Michael Koster's "schema", with a view of covering the syntax that is 1556 currently in use at the One Data Model playground repository. 1558 This appendix shows the framework syntax only, i.e., a syntax with 1559 liberal extension points. Since this syntax is nearly useless in 1560 finding typos in an SDF specification, a second syntax, the 1561 validation syntax, is defined that does not include the extension 1562 points. The validation syntax can be generated from the framework 1563 syntax by leaving out all lines containing the string EXTENSION- 1564 POINT; as this is trivial, the result is not shown here. 1566 This appendix makes use of CDDL "features" as defined in Section 4 of 1567 [RFC9165]. A feature named "1.0" is used to indicate parts of the 1568 syntax being deprecated towards SDF 1.1, and a feature named "1.1" is 1569 used to indicate new syntax intended for SDF 1.1. Features whose 1570 names end in "-ext" indicate extension points for further evolution. 1572 start = sdf-syntax 1574 sdf-syntax = { 1575 ? info: sdfinfo ; This will be required in most process policies, but not a syntax error 1576 ? namespace: named 1577 ? defaultNamespace: text 1578 ? sdfThing: named ; Thing is a composition of objects that work together in some way 1579 ? sdfProduct: named ; Product is a composition of things and objects that can model a SKU-level instance of a product 1580 ? sdfObject: named ; Object is a set of Properties, Actions, and Events that together perform a particular function 1581 ? sdfProperty: named ; Property represents the state of an instance of an object 1582 ? sdfAction: named ; Action is a directive to invoke an application layer verb associated with an object 1583 ? sdfEvent: named ; Event represents an occurrence of something associated with an object 1584 ? sdfData: named ; Data represents a piece of information that can be the state of a property or a parameter to an action or a signal in an event 1585 EXTENSION-POINT<"top-ext"> 1586 } 1588 sdfinfo = { 1589 ? title: text 1590 ? version: text 1591 ? copyright: text 1592 ? license: text 1593 EXTENSION-POINT<"info-ext"> 1594 } 1596 ; Shortcut for a map that gives names to instances of X (has text keys and values of type X) 1597 named = { * text => X } 1598 EXTENSION-POINT = ( * (text .feature f) => any ) ; only used in framework syntax 1600 sdf-pointer = text ; .regexp curie-regexp -- TO DO! 1601 pointer-list = [* sdf-pointer] ; ISSUE: no point in having an empty list, no? but used for sdfRequired in odmobject-multiple_axis_joystick.sdf.json 1603 commonqualities = ( 1604 ? description: text ; long text (no constraints) 1605 ? label: text ; short text (no constraints); default to key 1606 ? $comment: text ; source code comments only, no semantics 1607 ? sdfRef: sdf-pointer 1608 ? sdfRequired: pointer-list ; applies to qualities of properties, of data 1609 ) 1611 ; for building hierarchy 1612 thingqualities = { 1613 commonqualities 1614 ? sdfObject: named 1615 ? sdfThing: named 1616 EXTENSION-POINT<"thing-ext"> 1617 } 1619 productqualities = thingqualities ; ISSUE: get rid of sdfProduct? 1621 ; for single objects, or for arrays of objects (1.2) 1622 objectqualities = { 1623 commonqualities 1624 ? ("minItems" .feature "1.2") => number 1625 ? ("maxItems" .feature "1.2") => number 1626 ? sdfProperty: named 1627 ? sdfAction: named 1628 ? sdfEvent: named 1629 ? sdfData: named 1630 EXTENSION-POINT<"object-ext"> 1631 } 1633 propertyqualities = dataqualities ; the definitions in sdfData are declarations in sdfProperty 1635 parameter-list = 1636 pointer-list .feature (["1.0", "pointerlist-as-parameter"]) / 1637 dataqualities .feature (["1.1", "dataqualities-as-parameter"]) 1639 actionqualities = { 1640 commonqualities 1641 ? sdfInputData: parameter-list ; sdfRequiredInputData applies here (a bit redundant) 1642 ? ("sdfRequiredInputData" .feature "1.0") => pointer-list 1643 ? sdfOutputData: parameter-list ; sdfRequired applies here 1644 ? sdfData: named ; zero or more named data type definitions that might be used in the above 1645 EXTENSION-POINT<"action-ext"> 1647 } 1649 eventqualities = { 1650 commonqualities 1651 ? sdfOutputData: parameter-list ; sdfRequired applies here 1652 ? sdfData: named ; zero or more named data type definitions that might be used in the above 1653 EXTENSION-POINT<"event-ext"> 1654 } 1656 dataqualities = { ; also propertyqualities 1657 commonqualities 1658 jsonschema 1659 ? ("units" .feature "1.0") => text 1660 ? ("unit" .feature "1.1") => text 1661 ? ("scaleMinimum" .feature "1.0") => number 1662 ? ("scaleMaximum" .feature "1.0") => number 1663 ? observable: bool 1664 ? readable: bool 1665 ? writable: bool 1666 ? nullable: bool 1667 ? ("subtype" .feature "1.0") => "byte-string" / "unix-time" 1668 / (text .feature "subtype-ext") ; EXTENSION-POINT 1669 ? ("sdfType" .feature "1.1") => "byte-string" / "unix-time" 1670 / (text .feature "sdftype-ext") ; EXTENSION-POINT 1671 ? contentFormat: text 1672 EXTENSION-POINT<"data-ext"> 1673 } 1675 allowed-types = number / text / bool / null 1676 / [* number] / [* text] / [* bool] 1677 / {* text => any} 1678 / (any .feature "allowed-ext") ; EXTENSION-POINT 1680 compound-type = ( 1681 "type" => ("object" .feature "1.1") 1682 ? required: [+text] 1683 ? properties: named 1684 ) 1686 choice-type = ( 1687 ("sdfChoice" .feature "1.1") => named 1688 ) 1690 jsonschema = ( 1691 ? (("type" => "number" / "string" / "boolean" / "integer" / "array") 1692 // compound-type 1693 // choice-type 1694 // (type: text .feature "type-ext") ; EXTENSION-POINT 1696 ) 1697 ? "enum" => [+ text] ; limited to text strings in SDF 1.1 1698 ? ("enum" .feature "1.0") => [+ allowed-types] ; should validate against type 1699 ? const: allowed-types ; should validate against type 1700 ? default: allowed-types ; should validate against type 1701 ; number/integer constraints 1702 ? minimum: number 1703 ? maximum: number 1704 ? exclusiveMinimum: bool / number ; jso draft 4/7 1705 ? exclusiveMaximum: bool / number ; jso draft 4/7 1706 ? multipleOf: number ; ISSUE: Do we need this? 1707 ; text string constraints 1708 ? minLength: number 1709 ? maxLength: number 1710 ? pattern: text ; regexp 1711 ? format: "date-time" / "date" / "time" 1712 / "uri" / "uri-reference" / "uuid" 1713 / (text .feature "format-ext") ; EXTENSION-POINT 1714 ; array constraints 1715 ? minItems: number 1716 ? maxItems: number 1717 ? uniqueItems: bool 1718 ? items: { ;;; ultimately, this will be mostly recursive, but, for now 1719 ;;; let's find out what we actually need 1720 ? sdfRef: sdf-pointer ; import limited to the subset that we allow here... 1721 ? description: text ; long text (no constraints) 1722 ? $comment: text ; source code comments only, no semantics 1723 ; commonqualities, ; -- ISSUE: should leave this out for non-complex data types, but need the above three 1724 ? ((type: "number" / "string" / "boolean" / "integer") ; no "array" 1725 // compound-type 1726 // choice-type ; do we really need arrays of choices? 1727 // (type: text .feature "itemtype-ext") ; EXTENSION-POINT 1728 ) 1729 ; jso subset 1730 ? minimum: number 1731 ? maximum: number 1732 ? "enum" => [+ text] ; limited to text strings in SDF 1.1 1733 ? ("enum" .feature "1.0") => [+ any] 1734 ? format: text 1735 ? minLength: number 1736 ? maxLength: number 1737 EXTENSION-POINT<"items-ext"> 1738 } 1739 ) 1741 Appendix B. json-schema.org Rendition of SDF Syntax 1743 This appendix describes the syntax of SDF defined in Appendix A, but 1744 using a version of the description techniques advertised on json- 1745 schema.org [I-D.handrews-json-schema-validation]. 1747 The appendix shows both the validation and the framework syntax. 1748 Since most of the lines are the same between these two files, those 1749 lines are shown only once, with a leading space, in the form of a 1750 unified diff. Lines leading with a - are part of the validation 1751 syntax, and lines leading with a + are part of the framework syntax. 1753 { 1754 - "title": "sdf-validation.cddl", 1755 + "title": "sdf-framework.cddl", 1756 "$schema": "http://json-schema.org/draft-07/schema#", 1757 "$ref": "#/definitions/sdf-syntax", 1758 "definitions": { 1759 "sdf-syntax": { 1760 "type": "object", 1761 "properties": { 1762 "info": { 1763 "$ref": "#/definitions/sdfinfo" 1764 }, 1765 "namespace": { 1766 "type": "object", 1767 "additionalProperties": { 1768 "type": "string" 1769 } 1770 }, 1771 "defaultNamespace": { 1772 "type": "string" 1773 }, 1774 "sdfThing": { 1775 "type": "object", 1776 "additionalProperties": { 1777 "$ref": "#/definitions/thingqualities" 1778 } 1779 }, 1780 "sdfProduct": { 1781 "type": "object", 1782 "additionalProperties": { 1783 "$ref": "#/definitions/productqualities" 1784 } 1785 }, 1786 "sdfObject": { 1787 "type": "object", 1788 "additionalProperties": { 1789 "$ref": "#/definitions/objectqualities" 1790 } 1791 }, 1792 "sdfProperty": { 1793 "type": "object", 1794 "additionalProperties": { 1795 "$ref": "#/definitions/propertyqualities" 1796 } 1797 }, 1798 "sdfAction": { 1799 "type": "object", 1800 "additionalProperties": { 1801 "$ref": "#/definitions/actionqualities" 1802 } 1803 }, 1804 "sdfEvent": { 1805 "type": "object", 1806 "additionalProperties": { 1807 "$ref": "#/definitions/eventqualities" 1808 } 1809 }, 1810 "sdfData": { 1811 "type": "object", 1812 "additionalProperties": { 1813 "$ref": "#/definitions/dataqualities" 1814 } 1815 } 1816 }, 1817 - "additionalProperties": false 1818 + "additionalProperties": { 1819 + } 1820 }, 1821 "sdfinfo": { 1822 "type": "object", 1823 "properties": { 1824 "title": { 1825 "type": "string" 1826 }, 1827 "version": { 1828 "type": "string" 1829 }, 1830 "copyright": { 1831 "type": "string" 1832 }, 1833 "license": { 1834 "type": "string" 1835 } 1836 }, 1838 - "additionalProperties": false 1839 + "additionalProperties": { 1840 + } 1841 }, 1842 "thingqualities": { 1843 "type": "object", 1844 "properties": { 1845 "description": { 1846 "type": "string" 1847 }, 1848 "label": { 1849 "type": "string" 1850 }, 1851 "$comment": { 1852 "type": "string" 1853 }, 1854 "sdfRef": { 1855 "$ref": "#/definitions/sdf-pointer" 1856 }, 1857 "sdfRequired": { 1858 "$ref": "#/definitions/pointer-list" 1859 }, 1860 "sdfObject": { 1861 "type": "object", 1862 "additionalProperties": { 1863 "$ref": "#/definitions/objectqualities" 1864 } 1865 }, 1866 "sdfThing": { 1867 "type": "object", 1868 "additionalProperties": { 1869 "$ref": "#/definitions/thingqualities" 1870 } 1871 } 1872 }, 1873 - "additionalProperties": false 1874 + "additionalProperties": { 1875 + } 1876 }, 1877 "sdf-pointer": { 1878 "type": "string" 1879 }, 1880 "pointer-list": { 1881 "type": "array", 1882 "items": { 1883 "$ref": "#/definitions/sdf-pointer" 1884 } 1885 }, 1886 "objectqualities": { 1887 "type": "object", 1888 "properties": { 1889 "description": { 1890 "type": "string" 1891 }, 1892 "label": { 1893 "type": "string" 1894 }, 1895 "$comment": { 1896 "type": "string" 1897 }, 1898 "sdfRef": { 1899 "$ref": "#/definitions/sdf-pointer" 1900 }, 1901 "sdfRequired": { 1902 "$ref": "#/definitions/pointer-list" 1903 }, 1904 "minItems": { 1905 "type": "number" 1906 }, 1907 "maxItems": { 1908 "type": "number" 1909 }, 1910 "sdfProperty": { 1911 "type": "object", 1912 "additionalProperties": { 1913 "$ref": "#/definitions/propertyqualities" 1914 } 1915 }, 1916 "sdfAction": { 1917 "type": "object", 1918 "additionalProperties": { 1919 "$ref": "#/definitions/actionqualities" 1920 } 1921 }, 1922 "sdfEvent": { 1923 "type": "object", 1924 "additionalProperties": { 1925 "$ref": "#/definitions/eventqualities" 1926 } 1927 }, 1928 "sdfData": { 1929 "type": "object", 1930 "additionalProperties": { 1931 "$ref": "#/definitions/dataqualities" 1932 } 1933 } 1935 }, 1936 - "additionalProperties": false 1937 + "additionalProperties": { 1938 + } 1939 }, 1940 "propertyqualities": { 1941 "$ref": "#/definitions/dataqualities" 1942 }, 1943 "dataqualities": { 1944 "anyOf": [ 1945 { 1946 "type": "object", 1947 "properties": { 1948 "type": { 1949 "type": "string", 1950 "enum": [ 1951 "number", 1952 "string", 1953 "boolean", 1954 "integer", 1955 "array" 1956 ] 1957 }, 1958 "enum": { 1959 "type": "array", 1960 "items": { 1961 - "type": "string" 1962 + "$ref": "#/definitions/allowed-types" 1963 }, 1964 "minItems": 1 1965 }, 1966 "const": { 1967 "$ref": "#/definitions/allowed-types" 1968 }, 1969 "default": { 1970 "$ref": "#/definitions/allowed-types" 1971 }, 1972 "minimum": { 1973 "type": "number" 1974 }, 1975 "maximum": { 1976 "type": "number" 1977 }, 1978 "exclusiveMinimum": { 1979 "anyOf": [ 1980 { 1981 "type": "boolean" 1982 }, 1983 { 1984 "type": "number" 1985 } 1986 ] 1987 }, 1988 "exclusiveMaximum": { 1989 "anyOf": [ 1990 { 1991 "type": "boolean" 1992 }, 1993 { 1994 "type": "number" 1995 } 1996 ] 1997 }, 1998 "multipleOf": { 1999 "type": "number" 2000 }, 2001 "minLength": { 2002 "type": "number" 2003 }, 2004 "maxLength": { 2005 "type": "number" 2006 }, 2007 "pattern": { 2008 "type": "string" 2009 }, 2010 "format": { 2011 - "type": "string", 2012 - "enum": [ 2013 - "date-time", 2014 - "date", 2015 - "time", 2016 - "uri", 2017 - "uri-reference", 2018 - "uuid" 2019 + "anyOf": [ 2020 + { 2021 + "type": "string", 2022 + "const": "date-time" 2023 + }, 2024 + { 2025 + "type": "string", 2026 + "const": "date" 2027 + }, 2028 + { 2029 + "type": "string", 2030 + "const": "time" 2031 + }, 2032 + { 2033 + "type": "string", 2034 + "const": "uri" 2035 + }, 2036 + { 2037 + "type": "string", 2038 + "const": "uri-reference" 2039 + }, 2040 + { 2041 + "type": "string", 2042 + "const": "uuid" 2043 + }, 2044 + { 2045 + "type": "string" 2046 + } 2047 ] 2048 }, 2049 "minItems": { 2050 "type": "number" 2051 }, 2052 "maxItems": { 2053 "type": "number" 2054 }, 2055 "uniqueItems": { 2056 "type": "boolean" 2057 }, 2058 "items": { 2059 "anyOf": [ 2060 { 2061 "type": "object", 2062 "properties": { 2063 "type": { 2064 "type": "string", 2065 "enum": [ 2066 "number", 2067 "string", 2068 "boolean", 2069 "integer" 2070 ] 2071 }, 2072 "sdfRef": { 2073 "$ref": "#/definitions/sdf-pointer" 2074 }, 2075 "description": { 2076 "type": "string" 2077 }, 2078 "$comment": { 2079 "type": "string" 2080 }, 2081 "minimum": { 2082 "type": "number" 2083 }, 2084 "maximum": { 2085 "type": "number" 2086 }, 2087 "enum": { 2088 "type": "array", 2089 - "items": { 2090 - "type": "string" 2091 - }, 2092 "minItems": 1 2093 }, 2094 "format": { 2095 "type": "string" 2096 }, 2097 "minLength": { 2098 "type": "number" 2099 }, 2100 "maxLength": { 2101 "type": "number" 2102 } 2103 }, 2104 - "additionalProperties": false 2105 + "additionalProperties": { 2106 + } 2107 }, 2108 { 2109 "type": "object", 2110 "properties": { 2111 "type": { 2112 "type": "string", 2113 "const": "object" 2114 }, 2115 "required": { 2116 "type": "array", 2117 "items": { 2118 "type": "string" 2119 }, 2120 "minItems": 1 2121 }, 2122 "properties": { 2123 "type": "object", 2124 "additionalProperties": { 2125 "$ref": "#/definitions/dataqualities" 2126 } 2128 }, 2129 "sdfRef": { 2130 "$ref": "#/definitions/sdf-pointer" 2131 }, 2132 "description": { 2133 "type": "string" 2134 }, 2135 "$comment": { 2136 "type": "string" 2137 }, 2138 "minimum": { 2139 "type": "number" 2140 }, 2141 "maximum": { 2142 "type": "number" 2143 }, 2144 "enum": { 2145 "type": "array", 2146 - "items": { 2147 - "type": "string" 2148 - }, 2149 "minItems": 1 2150 }, 2151 "format": { 2152 "type": "string" 2153 }, 2154 "minLength": { 2155 "type": "number" 2156 }, 2157 "maxLength": { 2158 "type": "number" 2159 } 2160 }, 2161 - "additionalProperties": false 2162 + "additionalProperties": { 2163 + } 2164 }, 2165 { 2166 "type": "object", 2167 "properties": { 2168 "sdfChoice": { 2169 "type": "object", 2170 "additionalProperties": { 2171 "$ref": "#/definitions/dataqualities" 2172 } 2173 }, 2174 "sdfRef": { 2175 "$ref": "#/definitions/sdf-pointer" 2177 }, 2178 "description": { 2179 "type": "string" 2180 }, 2181 "$comment": { 2182 "type": "string" 2183 }, 2184 "minimum": { 2185 "type": "number" 2186 }, 2187 "maximum": { 2188 "type": "number" 2189 }, 2190 "enum": { 2191 "type": "array", 2192 - "items": { 2193 - "type": "string" 2194 - }, 2195 "minItems": 1 2196 }, 2197 "format": { 2198 "type": "string" 2199 }, 2200 "minLength": { 2201 "type": "number" 2202 }, 2203 "maxLength": { 2204 "type": "number" 2205 } 2206 }, 2207 - "additionalProperties": false 2208 + "additionalProperties": { 2209 + } 2210 + }, 2211 + { 2212 + "type": "object", 2213 + "properties": { 2214 + "type": { 2215 + "type": "string" 2216 + }, 2217 + "sdfRef": { 2218 + "$ref": "#/definitions/sdf-pointer" 2219 + }, 2220 + "description": { 2221 + "type": "string" 2222 + }, 2223 + "$comment": { 2224 + "type": "string" 2225 + }, 2226 + "minimum": { 2227 + "type": "number" 2228 + }, 2229 + "maximum": { 2230 + "type": "number" 2231 + }, 2232 + "enum": { 2233 + "type": "array", 2234 + "minItems": 1 2235 + }, 2236 + "format": { 2237 + "type": "string" 2238 + }, 2239 + "minLength": { 2240 + "type": "number" 2241 + }, 2242 + "maxLength": { 2243 + "type": "number" 2244 + } 2245 + }, 2246 + "additionalProperties": { 2247 + } 2248 } 2249 ] 2250 }, 2251 "description": { 2252 "type": "string" 2253 }, 2254 "label": { 2255 "type": "string" 2256 }, 2257 "$comment": { 2258 "type": "string" 2259 }, 2260 "sdfRef": { 2261 "$ref": "#/definitions/sdf-pointer" 2262 }, 2263 "sdfRequired": { 2264 "$ref": "#/definitions/pointer-list" 2265 }, 2266 + "units": { 2267 + "type": "string" 2268 + }, 2269 "unit": { 2270 "type": "string" 2271 }, 2272 + "scaleMinimum": { 2273 + "type": "number" 2274 + }, 2275 + "scaleMaximum": { 2276 + "type": "number" 2277 + }, 2278 "observable": { 2279 "type": "boolean" 2280 }, 2281 "readable": { 2282 "type": "boolean" 2283 }, 2284 "writable": { 2285 "type": "boolean" 2286 }, 2287 "nullable": { 2288 "type": "boolean" 2289 }, 2290 + "subtype": { 2291 + "anyOf": [ 2292 + { 2293 + "type": "string", 2294 + "const": "byte-string" 2295 + }, 2296 + { 2297 + "type": "string", 2298 + "const": "unix-time" 2299 + }, 2300 + { 2301 + "type": "string" 2302 + } 2303 + ] 2304 + }, 2305 "sdfType": { 2306 - "type": "string", 2307 - "enum": [ 2308 - "byte-string", 2309 - "unix-time" 2310 + "anyOf": [ 2311 + { 2312 + "type": "string", 2313 + "const": "byte-string" 2314 + }, 2315 + { 2316 + "type": "string", 2317 + "const": "unix-time" 2318 + }, 2319 + { 2320 + "type": "string" 2321 + } 2322 ] 2323 }, 2324 "contentFormat": { 2325 "type": "string" 2326 } 2327 }, 2328 - "additionalProperties": false 2329 + "additionalProperties": { 2330 + } 2331 }, 2332 { 2333 "type": "object", 2334 "properties": { 2335 "type": { 2336 "type": "string", 2337 "const": "object" 2338 }, 2339 "required": { 2340 "type": "array", 2341 "items": { 2342 "type": "string" 2343 }, 2344 "minItems": 1 2345 }, 2346 "properties": { 2347 "type": "object", 2348 "additionalProperties": { 2349 "$ref": "#/definitions/dataqualities" 2350 } 2351 }, 2352 "enum": { 2353 "type": "array", 2354 "items": { 2355 - "type": "string" 2356 + "$ref": "#/definitions/allowed-types" 2357 }, 2358 "minItems": 1 2359 }, 2360 "const": { 2361 "$ref": "#/definitions/allowed-types" 2362 }, 2363 "default": { 2364 "$ref": "#/definitions/allowed-types" 2365 }, 2366 "minimum": { 2367 "type": "number" 2368 }, 2369 "maximum": { 2370 "type": "number" 2371 }, 2372 "exclusiveMinimum": { 2373 "anyOf": [ 2374 { 2375 "type": "boolean" 2376 }, 2377 { 2378 "type": "number" 2379 } 2380 ] 2381 }, 2382 "exclusiveMaximum": { 2383 "anyOf": [ 2384 { 2385 "type": "boolean" 2386 }, 2387 { 2388 "type": "number" 2389 } 2390 ] 2391 }, 2392 "multipleOf": { 2393 "type": "number" 2394 }, 2395 "minLength": { 2396 "type": "number" 2397 }, 2398 "maxLength": { 2399 "type": "number" 2400 }, 2401 "pattern": { 2402 "type": "string" 2403 }, 2404 "format": { 2405 - "type": "string", 2406 - "enum": [ 2407 - "date-time", 2408 - "date", 2409 - "time", 2410 - "uri", 2411 - "uri-reference", 2412 - "uuid" 2413 + "anyOf": [ 2414 + { 2415 + "type": "string", 2416 + "const": "date-time" 2417 + }, 2418 + { 2419 + "type": "string", 2420 + "const": "date" 2421 + }, 2422 + { 2423 + "type": "string", 2424 + "const": "time" 2425 + }, 2426 + { 2427 + "type": "string", 2428 + "const": "uri" 2429 + }, 2430 + { 2431 + "type": "string", 2432 + "const": "uri-reference" 2433 + }, 2434 + { 2435 + "type": "string", 2436 + "const": "uuid" 2437 + }, 2438 + { 2439 + "type": "string" 2440 + } 2441 ] 2442 }, 2443 "minItems": { 2444 "type": "number" 2445 }, 2446 "maxItems": { 2447 "type": "number" 2448 }, 2449 "uniqueItems": { 2450 "type": "boolean" 2451 }, 2452 "items": { 2453 "anyOf": [ 2454 { 2455 "type": "object", 2456 "properties": { 2457 "type": { 2458 "type": "string", 2459 "enum": [ 2460 "number", 2461 "string", 2462 "boolean", 2463 "integer" 2464 ] 2466 }, 2467 "sdfRef": { 2468 "$ref": "#/definitions/sdf-pointer" 2469 }, 2470 "description": { 2471 "type": "string" 2472 }, 2473 "$comment": { 2474 "type": "string" 2475 }, 2476 "minimum": { 2477 "type": "number" 2478 }, 2479 "maximum": { 2480 "type": "number" 2481 }, 2482 "enum": { 2483 "type": "array", 2484 - "items": { 2485 - "type": "string" 2486 - }, 2487 "minItems": 1 2488 }, 2489 "format": { 2490 "type": "string" 2491 }, 2492 "minLength": { 2493 "type": "number" 2494 }, 2495 "maxLength": { 2496 "type": "number" 2497 } 2498 }, 2499 - "additionalProperties": false 2500 + "additionalProperties": { 2501 + } 2502 }, 2503 { 2504 "type": "object", 2505 "properties": { 2506 "type": { 2507 "type": "string", 2508 "const": "object" 2509 }, 2510 "required": { 2511 "type": "array", 2512 "items": { 2513 "type": "string" 2515 }, 2516 "minItems": 1 2517 }, 2518 "properties": { 2519 "type": "object", 2520 "additionalProperties": { 2521 "$ref": "#/definitions/dataqualities" 2522 } 2523 }, 2524 "sdfRef": { 2525 "$ref": "#/definitions/sdf-pointer" 2526 }, 2527 "description": { 2528 "type": "string" 2529 }, 2530 "$comment": { 2531 "type": "string" 2532 }, 2533 "minimum": { 2534 "type": "number" 2535 }, 2536 "maximum": { 2537 "type": "number" 2538 }, 2539 "enum": { 2540 "type": "array", 2541 - "items": { 2542 - "type": "string" 2543 - }, 2544 "minItems": 1 2545 }, 2546 "format": { 2547 "type": "string" 2548 }, 2549 "minLength": { 2550 "type": "number" 2551 }, 2552 "maxLength": { 2553 "type": "number" 2554 } 2555 }, 2556 - "additionalProperties": false 2557 + "additionalProperties": { 2558 + } 2559 }, 2560 { 2561 "type": "object", 2562 "properties": { 2563 "sdfChoice": { 2564 "type": "object", 2565 "additionalProperties": { 2566 "$ref": "#/definitions/dataqualities" 2567 } 2568 }, 2569 "sdfRef": { 2570 "$ref": "#/definitions/sdf-pointer" 2571 }, 2572 "description": { 2573 "type": "string" 2574 }, 2575 "$comment": { 2576 "type": "string" 2577 }, 2578 "minimum": { 2579 "type": "number" 2580 }, 2581 "maximum": { 2582 "type": "number" 2583 }, 2584 "enum": { 2585 "type": "array", 2586 - "items": { 2587 - "type": "string" 2588 - }, 2589 "minItems": 1 2590 }, 2591 "format": { 2592 "type": "string" 2593 }, 2594 "minLength": { 2595 "type": "number" 2596 }, 2597 "maxLength": { 2598 "type": "number" 2599 } 2600 }, 2601 - "additionalProperties": false 2602 + "additionalProperties": { 2603 + } 2604 + }, 2605 + { 2606 + "type": "object", 2607 + "properties": { 2608 + "type": { 2609 + "type": "string" 2610 + }, 2611 + "sdfRef": { 2612 + "$ref": "#/definitions/sdf-pointer" 2613 + }, 2614 + "description": { 2615 + "type": "string" 2616 + }, 2617 + "$comment": { 2618 + "type": "string" 2619 + }, 2620 + "minimum": { 2621 + "type": "number" 2622 + }, 2623 + "maximum": { 2624 + "type": "number" 2625 + }, 2626 + "enum": { 2627 + "type": "array", 2628 + "minItems": 1 2629 + }, 2630 + "format": { 2631 + "type": "string" 2632 + }, 2633 + "minLength": { 2634 + "type": "number" 2635 + }, 2636 + "maxLength": { 2637 + "type": "number" 2638 + } 2639 + }, 2640 + "additionalProperties": { 2641 + } 2642 } 2643 ] 2644 }, 2645 "description": { 2646 "type": "string" 2647 }, 2648 "label": { 2649 "type": "string" 2650 }, 2651 "$comment": { 2652 "type": "string" 2653 }, 2654 "sdfRef": { 2655 "$ref": "#/definitions/sdf-pointer" 2656 }, 2657 "sdfRequired": { 2658 "$ref": "#/definitions/pointer-list" 2660 }, 2661 + "units": { 2662 + "type": "string" 2663 + }, 2664 "unit": { 2665 "type": "string" 2666 }, 2667 + "scaleMinimum": { 2668 + "type": "number" 2669 + }, 2670 + "scaleMaximum": { 2671 + "type": "number" 2672 + }, 2673 "observable": { 2674 "type": "boolean" 2675 }, 2676 "readable": { 2677 "type": "boolean" 2678 }, 2679 "writable": { 2680 "type": "boolean" 2681 }, 2682 "nullable": { 2683 "type": "boolean" 2684 }, 2685 + "subtype": { 2686 + "anyOf": [ 2687 + { 2688 + "type": "string", 2689 + "const": "byte-string" 2690 + }, 2691 + { 2692 + "type": "string", 2693 + "const": "unix-time" 2694 + }, 2695 + { 2696 + "type": "string" 2697 + } 2698 + ] 2699 + }, 2700 "sdfType": { 2701 - "type": "string", 2702 - "enum": [ 2703 - "byte-string", 2704 - "unix-time" 2705 + "anyOf": [ 2706 + { 2707 + "type": "string", 2708 + "const": "byte-string" 2709 + }, 2710 + { 2711 + "type": "string", 2712 + "const": "unix-time" 2713 + }, 2714 + { 2715 + "type": "string" 2716 + } 2717 ] 2718 }, 2719 "contentFormat": { 2720 "type": "string" 2721 } 2722 }, 2723 - "additionalProperties": false 2724 + "additionalProperties": { 2725 + } 2726 }, 2727 { 2728 "type": "object", 2729 "properties": { 2730 "sdfChoice": { 2731 "type": "object", 2732 "additionalProperties": { 2733 "$ref": "#/definitions/dataqualities" 2734 } 2735 }, 2736 "enum": { 2737 "type": "array", 2738 "items": { 2739 - "type": "string" 2740 + "$ref": "#/definitions/allowed-types" 2741 }, 2742 "minItems": 1 2743 }, 2744 "const": { 2745 "$ref": "#/definitions/allowed-types" 2746 }, 2747 "default": { 2748 "$ref": "#/definitions/allowed-types" 2749 }, 2750 "minimum": { 2751 "type": "number" 2752 }, 2753 "maximum": { 2754 "type": "number" 2755 }, 2756 "exclusiveMinimum": { 2757 "anyOf": [ 2758 { 2759 "type": "boolean" 2760 }, 2761 { 2762 "type": "number" 2763 } 2764 ] 2765 }, 2766 "exclusiveMaximum": { 2767 "anyOf": [ 2768 { 2769 "type": "boolean" 2770 }, 2771 { 2772 "type": "number" 2773 } 2774 ] 2775 }, 2776 "multipleOf": { 2777 "type": "number" 2778 }, 2779 "minLength": { 2780 "type": "number" 2781 }, 2782 "maxLength": { 2783 "type": "number" 2784 }, 2785 "pattern": { 2786 "type": "string" 2787 }, 2788 "format": { 2789 - "type": "string", 2790 - "enum": [ 2791 - "date-time", 2792 - "date", 2793 - "time", 2794 - "uri", 2795 - "uri-reference", 2796 - "uuid" 2797 + "anyOf": [ 2798 + { 2799 + "type": "string", 2800 + "const": "date-time" 2801 + }, 2802 + { 2803 + "type": "string", 2804 + "const": "date" 2805 + }, 2806 + { 2807 + "type": "string", 2808 + "const": "time" 2809 + }, 2810 + { 2811 + "type": "string", 2812 + "const": "uri" 2813 + }, 2814 + { 2815 + "type": "string", 2816 + "const": "uri-reference" 2817 + }, 2818 + { 2819 + "type": "string", 2820 + "const": "uuid" 2821 + }, 2822 + { 2823 + "type": "string" 2824 + } 2825 ] 2826 }, 2827 "minItems": { 2828 "type": "number" 2829 }, 2830 "maxItems": { 2831 "type": "number" 2832 }, 2833 "uniqueItems": { 2834 "type": "boolean" 2835 }, 2836 "items": { 2837 "anyOf": [ 2838 { 2839 "type": "object", 2840 "properties": { 2841 "type": { 2842 "type": "string", 2843 "enum": [ 2844 "number", 2845 "string", 2846 "boolean", 2847 "integer" 2848 ] 2849 }, 2850 "sdfRef": { 2851 "$ref": "#/definitions/sdf-pointer" 2853 }, 2854 "description": { 2855 "type": "string" 2856 }, 2857 "$comment": { 2858 "type": "string" 2859 }, 2860 "minimum": { 2861 "type": "number" 2862 }, 2863 "maximum": { 2864 "type": "number" 2865 }, 2866 "enum": { 2867 "type": "array", 2868 - "items": { 2869 - "type": "string" 2870 - }, 2871 "minItems": 1 2872 }, 2873 "format": { 2874 "type": "string" 2875 }, 2876 "minLength": { 2877 "type": "number" 2878 }, 2879 "maxLength": { 2880 "type": "number" 2881 } 2882 }, 2883 - "additionalProperties": false 2884 + "additionalProperties": { 2885 + } 2886 }, 2887 { 2888 "type": "object", 2889 "properties": { 2890 "type": { 2891 "type": "string", 2892 "const": "object" 2893 }, 2894 "required": { 2895 "type": "array", 2896 "items": { 2897 "type": "string" 2898 }, 2899 "minItems": 1 2900 }, 2901 "properties": { 2902 "type": "object", 2903 "additionalProperties": { 2904 "$ref": "#/definitions/dataqualities" 2905 } 2906 }, 2907 "sdfRef": { 2908 "$ref": "#/definitions/sdf-pointer" 2909 }, 2910 "description": { 2911 "type": "string" 2912 }, 2913 "$comment": { 2914 "type": "string" 2915 }, 2916 "minimum": { 2917 "type": "number" 2918 }, 2919 "maximum": { 2920 "type": "number" 2921 }, 2922 "enum": { 2923 "type": "array", 2924 - "items": { 2925 - "type": "string" 2926 - }, 2927 "minItems": 1 2928 }, 2929 "format": { 2930 "type": "string" 2931 }, 2932 "minLength": { 2933 "type": "number" 2934 }, 2935 "maxLength": { 2936 "type": "number" 2937 } 2938 }, 2939 - "additionalProperties": false 2940 + "additionalProperties": { 2941 + } 2942 }, 2943 { 2944 "type": "object", 2945 "properties": { 2946 "sdfChoice": { 2947 "type": "object", 2948 "additionalProperties": { 2949 "$ref": "#/definitions/dataqualities" 2950 } 2951 }, 2952 "sdfRef": { 2953 "$ref": "#/definitions/sdf-pointer" 2954 }, 2955 "description": { 2956 "type": "string" 2957 }, 2958 "$comment": { 2959 "type": "string" 2960 }, 2961 "minimum": { 2962 "type": "number" 2963 }, 2964 "maximum": { 2965 "type": "number" 2966 }, 2967 "enum": { 2968 "type": "array", 2969 - "items": { 2970 - "type": "string" 2971 - }, 2972 "minItems": 1 2973 }, 2974 "format": { 2975 "type": "string" 2976 }, 2977 "minLength": { 2978 "type": "number" 2979 }, 2980 "maxLength": { 2981 "type": "number" 2982 } 2983 }, 2984 - "additionalProperties": false 2985 + "additionalProperties": { 2986 + } 2987 + }, 2988 + { 2989 + "type": "object", 2990 + "properties": { 2991 + "type": { 2992 + "type": "string" 2993 + }, 2994 + "sdfRef": { 2995 + "$ref": "#/definitions/sdf-pointer" 2996 + }, 2997 + "description": { 2998 + "type": "string" 2999 + }, 3000 + "$comment": { 3001 + "type": "string" 3002 + }, 3003 + "minimum": { 3004 + "type": "number" 3005 + }, 3006 + "maximum": { 3007 + "type": "number" 3008 + }, 3009 + "enum": { 3010 + "type": "array", 3011 + "minItems": 1 3012 + }, 3013 + "format": { 3014 + "type": "string" 3015 + }, 3016 + "minLength": { 3017 + "type": "number" 3018 + }, 3019 + "maxLength": { 3020 + "type": "number" 3021 + } 3022 + }, 3023 + "additionalProperties": { 3024 + } 3025 } 3026 ] 3027 }, 3028 "description": { 3029 "type": "string" 3030 }, 3031 "label": { 3032 "type": "string" 3033 }, 3034 "$comment": { 3035 "type": "string" 3036 }, 3037 "sdfRef": { 3038 "$ref": "#/definitions/sdf-pointer" 3039 }, 3040 "sdfRequired": { 3041 "$ref": "#/definitions/pointer-list" 3042 }, 3043 + "units": { 3044 + "type": "string" 3045 + }, 3046 "unit": { 3047 "type": "string" 3048 }, 3049 + "scaleMinimum": { 3050 + "type": "number" 3051 + }, 3052 + "scaleMaximum": { 3053 + "type": "number" 3054 + }, 3055 "observable": { 3056 "type": "boolean" 3057 }, 3058 "readable": { 3059 "type": "boolean" 3060 }, 3061 "writable": { 3062 "type": "boolean" 3063 }, 3064 "nullable": { 3065 "type": "boolean" 3066 }, 3067 - "sdfType": { 3068 - "type": "string", 3069 - "enum": [ 3070 - "byte-string", 3071 - "unix-time" 3072 - ] 3073 - }, 3074 + "subtype": { 3075 + "anyOf": [ 3076 + { 3077 + "type": "string", 3078 + "const": "byte-string" 3079 + }, 3080 + { 3081 + "type": "string", 3082 + "const": "unix-time" 3083 + }, 3084 + { 3085 + "type": "string" 3086 + } 3087 + ] 3088 + }, 3089 + "sdfType": { 3090 + "anyOf": [ 3091 + { 3092 + "type": "string", 3093 + "const": "byte-string" 3094 + }, 3095 + { 3096 + "type": "string", 3097 + "const": "unix-time" 3098 + }, 3099 + { 3100 + "type": "string" 3101 + } 3102 + ] 3103 + }, 3104 "contentFormat": { 3105 "type": "string" 3106 } 3107 }, 3108 - "additionalProperties": false 3109 + "additionalProperties": { 3110 + } 3111 + }, 3112 + { 3113 + "type": "object", 3114 + "properties": { 3115 + "type": { 3116 + "type": "string" 3117 + }, 3118 + "enum": { 3119 + "type": "array", 3120 + "items": { 3121 + "$ref": "#/definitions/allowed-types" 3122 + }, 3123 + "minItems": 1 3124 + }, 3125 + "const": { 3126 + "$ref": "#/definitions/allowed-types" 3127 + }, 3128 + "default": { 3129 + "$ref": "#/definitions/allowed-types" 3130 + }, 3131 + "minimum": { 3132 + "type": "number" 3133 + }, 3134 + "maximum": { 3135 + "type": "number" 3136 + }, 3137 + "exclusiveMinimum": { 3138 + "anyOf": [ 3139 + { 3140 + "type": "boolean" 3141 + }, 3142 + { 3143 + "type": "number" 3144 + } 3145 + ] 3146 + }, 3147 + "exclusiveMaximum": { 3148 + "anyOf": [ 3149 + { 3150 + "type": "boolean" 3151 + }, 3152 + { 3153 + "type": "number" 3154 + } 3155 + ] 3156 + }, 3157 + "multipleOf": { 3158 + "type": "number" 3159 + }, 3160 + "minLength": { 3161 + "type": "number" 3162 + }, 3163 + "maxLength": { 3164 + "type": "number" 3165 + }, 3166 + "pattern": { 3167 + "type": "string" 3168 + }, 3169 + "format": { 3170 + "anyOf": [ 3171 + { 3172 + "type": "string", 3173 + "const": "date-time" 3174 + }, 3175 + { 3176 + "type": "string", 3177 + "const": "date" 3178 + }, 3179 + { 3180 + "type": "string", 3181 + "const": "time" 3182 + }, 3183 + { 3184 + "type": "string", 3185 + "const": "uri" 3186 + }, 3187 + { 3188 + "type": "string", 3189 + "const": "uri-reference" 3190 + }, 3191 + { 3192 + "type": "string", 3193 + "const": "uuid" 3194 + }, 3195 + { 3196 + "type": "string" 3197 + } 3198 + ] 3199 + }, 3200 + "minItems": { 3201 + "type": "number" 3202 + }, 3203 + "maxItems": { 3204 + "type": "number" 3205 + }, 3206 + "uniqueItems": { 3207 + "type": "boolean" 3208 + }, 3209 + "items": { 3210 + "anyOf": [ 3211 + { 3212 + "type": "object", 3213 + "properties": { 3214 + "type": { 3215 + "type": "string", 3216 + "enum": [ 3217 + "number", 3218 + "string", 3219 + "boolean", 3220 + "integer" 3221 + ] 3222 + }, 3223 + "sdfRef": { 3224 + "$ref": "#/definitions/sdf-pointer" 3225 + }, 3226 + "description": { 3227 + "type": "string" 3228 + }, 3229 + "$comment": { 3230 + "type": "string" 3231 + }, 3232 + "minimum": { 3233 + "type": "number" 3234 + }, 3235 + "maximum": { 3236 + "type": "number" 3237 + }, 3238 + "enum": { 3239 + "type": "array", 3240 + "minItems": 1 3241 + }, 3242 + "format": { 3243 + "type": "string" 3244 + }, 3245 + "minLength": { 3246 + "type": "number" 3247 + }, 3248 + "maxLength": { 3249 + "type": "number" 3250 + } 3251 + }, 3252 + "additionalProperties": { 3253 + } 3254 + }, 3255 + { 3256 + "type": "object", 3257 + "properties": { 3258 + "type": { 3259 + "type": "string", 3260 + "const": "object" 3261 + }, 3262 + "required": { 3263 + "type": "array", 3264 + "items": { 3265 + "type": "string" 3266 + }, 3267 + "minItems": 1 3268 + }, 3269 + "properties": { 3270 + "type": "object", 3271 + "additionalProperties": { 3272 + "$ref": "#/definitions/dataqualities" 3273 + } 3274 + }, 3275 + "sdfRef": { 3276 + "$ref": "#/definitions/sdf-pointer" 3277 + }, 3278 + "description": { 3279 + "type": "string" 3280 + }, 3281 + "$comment": { 3282 + "type": "string" 3283 + }, 3284 + "minimum": { 3285 + "type": "number" 3286 + }, 3287 + "maximum": { 3288 + "type": "number" 3289 + }, 3290 + "enum": { 3291 + "type": "array", 3292 + "minItems": 1 3293 + }, 3294 + "format": { 3295 + "type": "string" 3296 + }, 3297 + "minLength": { 3298 + "type": "number" 3299 + }, 3300 + "maxLength": { 3301 + "type": "number" 3302 + } 3303 + }, 3304 + "additionalProperties": { 3305 + } 3306 + }, 3307 + { 3308 + "type": "object", 3309 + "properties": { 3310 + "sdfChoice": { 3311 + "type": "object", 3312 + "additionalProperties": { 3313 + "$ref": "#/definitions/dataqualities" 3314 + } 3315 + }, 3316 + "sdfRef": { 3317 + "$ref": "#/definitions/sdf-pointer" 3318 + }, 3319 + "description": { 3320 + "type": "string" 3321 + }, 3322 + "$comment": { 3323 + "type": "string" 3324 + }, 3325 + "minimum": { 3326 + "type": "number" 3327 + }, 3328 + "maximum": { 3329 + "type": "number" 3330 + }, 3331 + "enum": { 3332 + "type": "array", 3333 + "minItems": 1 3334 + }, 3335 + "format": { 3336 + "type": "string" 3337 + }, 3338 + "minLength": { 3339 + "type": "number" 3340 + }, 3341 + "maxLength": { 3342 + "type": "number" 3343 + } 3344 + }, 3345 + "additionalProperties": { 3346 + } 3347 + }, 3348 + { 3349 + "type": "object", 3350 + "properties": { 3351 + "type": { 3352 + "type": "string" 3353 + }, 3354 + "sdfRef": { 3355 + "$ref": "#/definitions/sdf-pointer" 3356 + }, 3357 + "description": { 3358 + "type": "string" 3359 + }, 3360 + "$comment": { 3361 + "type": "string" 3362 + }, 3363 + "minimum": { 3364 + "type": "number" 3365 + }, 3366 + "maximum": { 3367 + "type": "number" 3368 + }, 3369 + "enum": { 3370 + "type": "array", 3371 + "minItems": 1 3372 + }, 3373 + "format": { 3374 + "type": "string" 3375 + }, 3376 + "minLength": { 3377 + "type": "number" 3378 + }, 3379 + "maxLength": { 3380 + "type": "number" 3381 + } 3382 + }, 3383 + "additionalProperties": { 3384 + } 3385 + } 3386 + ] 3387 + }, 3388 + "description": { 3389 + "type": "string" 3390 + }, 3391 + "label": { 3392 + "type": "string" 3393 + }, 3394 + "$comment": { 3395 + "type": "string" 3396 + }, 3397 + "sdfRef": { 3398 + "$ref": "#/definitions/sdf-pointer" 3399 + }, 3400 + "sdfRequired": { 3401 + "$ref": "#/definitions/pointer-list" 3402 + }, 3403 + "units": { 3404 + "type": "string" 3405 + }, 3406 + "unit": { 3407 + "type": "string" 3408 + }, 3409 + "scaleMinimum": { 3410 + "type": "number" 3411 + }, 3412 + "scaleMaximum": { 3413 + "type": "number" 3414 + }, 3415 + "observable": { 3416 + "type": "boolean" 3417 + }, 3418 + "readable": { 3419 + "type": "boolean" 3420 + }, 3421 + "writable": { 3422 + "type": "boolean" 3423 + }, 3424 + "nullable": { 3425 + "type": "boolean" 3426 + }, 3427 + "subtype": { 3428 + "anyOf": [ 3429 + { 3430 + "type": "string", 3431 + "const": "byte-string" 3432 + }, 3433 + { 3434 + "type": "string", 3435 + "const": "unix-time" 3436 + }, 3437 + { 3438 + "type": "string" 3439 + } 3440 + ] 3441 + }, 3442 + "sdfType": { 3443 + "anyOf": [ 3444 + { 3445 + "type": "string", 3446 + "const": "byte-string" 3447 + }, 3448 + { 3449 + "type": "string", 3450 + "const": "unix-time" 3451 + }, 3452 + { 3453 + "type": "string" 3454 + } 3455 + ] 3456 + }, 3457 + "contentFormat": { 3458 + "type": "string" 3459 + } 3460 + }, 3461 + "additionalProperties": { 3462 + } 3463 } 3464 ] 3465 }, 3466 "allowed-types": { 3467 "anyOf": [ 3468 { 3469 "type": "number" 3470 }, 3471 { 3472 "type": "string" 3473 }, 3474 { 3475 "type": "boolean" 3476 }, 3477 { 3478 "type": "null" 3479 }, 3480 { 3481 "type": "array", 3482 "items": { 3483 "type": "number" 3484 } 3485 }, 3486 { 3487 "type": "array", 3488 "items": { 3489 "type": "string" 3490 } 3491 }, 3492 { 3493 "type": "array", 3494 "items": { 3495 "type": "boolean" 3496 } 3497 }, 3498 { 3499 "type": "object", 3500 "additionalProperties": { 3501 } 3502 + }, 3503 + { 3504 } 3505 ] 3506 }, 3507 "actionqualities": { 3508 "type": "object", 3509 "properties": { 3510 "description": { 3511 "type": "string" 3512 }, 3513 "label": { 3514 "type": "string" 3515 }, 3516 "$comment": { 3517 "type": "string" 3518 }, 3519 "sdfRef": { 3520 "$ref": "#/definitions/sdf-pointer" 3521 }, 3522 "sdfRequired": { 3523 "$ref": "#/definitions/pointer-list" 3524 }, 3525 "sdfInputData": { 3526 "$ref": "#/definitions/parameter-list" 3527 }, 3528 + "sdfRequiredInputData": { 3529 + "$ref": "#/definitions/pointer-list" 3530 + }, 3531 "sdfOutputData": { 3532 "$ref": "#/definitions/parameter-list" 3533 }, 3534 "sdfData": { 3535 "type": "object", 3536 "additionalProperties": { 3537 "$ref": "#/definitions/dataqualities" 3538 } 3539 } 3540 }, 3541 - "additionalProperties": false 3542 + "additionalProperties": { 3543 + } 3544 }, 3545 "parameter-list": { 3546 - "$ref": "#/definitions/dataqualities" 3547 + "anyOf": [ 3548 + { 3549 + "$ref": "#/definitions/pointer-list" 3550 + }, 3551 + { 3552 + "$ref": "#/definitions/dataqualities" 3553 + } 3554 + ] 3555 }, 3556 "eventqualities": { 3557 "type": "object", 3558 "properties": { 3559 "description": { 3560 "type": "string" 3561 }, 3562 "label": { 3563 "type": "string" 3564 }, 3565 "$comment": { 3566 "type": "string" 3567 }, 3568 "sdfRef": { 3569 "$ref": "#/definitions/sdf-pointer" 3570 }, 3571 "sdfRequired": { 3572 "$ref": "#/definitions/pointer-list" 3574 }, 3575 "sdfOutputData": { 3576 "$ref": "#/definitions/parameter-list" 3577 }, 3578 "sdfData": { 3579 "type": "object", 3580 "additionalProperties": { 3581 "$ref": "#/definitions/dataqualities" 3582 } 3583 } 3584 }, 3585 - "additionalProperties": false 3586 + "additionalProperties": { 3587 + } 3588 }, 3589 "productqualities": { 3590 "$ref": "#/definitions/thingqualities" 3591 } 3592 } 3593 } 3595 Appendix C. Data Qualities inspired by json-schema.org 3597 Data qualities define data used in SDF affordances at an information 3598 model level. A popular way to describe JSON data at a data model 3599 level is proposed by a number of drafts on json-schema.org (which 3600 collectively are abbreviated JSO here)); for reference to a popular 3601 version we will point here to [I-D.handrews-json-schema-validation]. 3602 As the vocabulary used by JSO is familiar to many JSON modellers, the 3603 present specification borrows some of the terms and ports their 3604 semantics to the information model level needed for SDF. 3606 The main data quality imported is the "type". In SDF, this can take 3607 one of six (text string) values, which are discussed in the following 3608 subsections (note that the JSO type "null" is not supported as a 3609 value of this data quality in SDF). 3611 The additional quality "const" restricts the data to one specific 3612 value (given as the value of the const quality). 3614 Similarly, the additional quality "default" provides data that can be 3615 used in the absence of the data (given as the value of the const 3616 quality); this is mainly documentary and not very well-defined for 3617 SDF as no process is defined that would add default values to an 3618 instance of something. 3620 C.1. type "number", type "integer" 3622 The types "number" and "integer" are associated with floating point 3623 and integer numbers, as they are available in JSON. A type value of 3624 integer means that only integer values of JSON numbers can be used 3625 (note that 10.0 is an integer value, even if it is in a notation that 3626 would also allow non-zero decimal fractions). 3628 The additional data qualities "minimum", "maximum", 3629 "exclusiveMinimum", "exclusiveMaximum" provide number values that 3630 serve as inclusive/exclusive lower/upper bounds for the number. 3631 (Note that the Boolean form of "exclusiveMinimum"/"exclusiveMaximum" 3632 found in earlier JSO drafts is not used.) 3634 The data quality "multipleOf" gives a positive number that constrains 3635 the data value to be an integer multiple of the number given. (Type 3636 "integer" can also be expressed as a "multipleOf" quality of value 1, 3637 unless another "multipleOf" quality is present.) 3639 C.2. type "string" 3641 The type "string" is associated with Unicode text string values as 3642 they are available in JSON. 3644 The length (as measured in characters) can be constrained by the 3645 additional data qualities "minLength" and "maxLength", which are 3646 inclusive bounds. Note that the previous version of the present 3647 document explained text string length values in bytes, which however 3648 is not meaningful unless bound to a specific encoding (which could be 3649 UTF-8, if this unusual behavior is to be restored). 3651 The data quality "pattern" takes a string value that is interpreted 3652 as an [ECMA-262] regular expression in Unicode mode that constrain 3653 the string (note that these are not anchored by default, so unless ^ 3654 and $ anchors are employed, ECMA-262 regular expressions match any 3655 string that _contains_ a match). The JSO proposals acknowledge that 3656 regular expression support is rather diverse in various platforms, so 3657 the suggestion is to limit them to: 3659 * characters; 3660 * character classes in square brackets, including ranges; their 3661 complements; 3662 * simple quantifiers *, +, ?, and range quantifiers {n}, {n,m}, and 3663 {n,}; 3664 * grouping parentheses; 3665 * the choice operator |; 3666 * and anchors (beginning-of-input ^ and end-of-input $). 3668 Note that this subset is somewhat similar to the subset introduced by 3669 iregexps [I-D.bormann-jsonpath-iregexp], which however are anchored 3670 regular expressions, and which include certain backslash escapes for 3671 characters and character classes. 3673 The additional data quality "format" can take one of the following 3674 values. Note that, at an information model level, the presence of 3675 this data quality changes the type from being a simple text string to 3676 the abstract meaning of the format given (i.e., the format "date- 3677 time" is less about the specific syntax employed in [RFC3339] than 3678 about the usage as an absolute point in civil time). 3680 * "date-time", "date", "time": An [RFC3339] date-time, full-date, or 3681 full-time, respectively. 3682 * "uri", "uri-reference": An [RFC3986] URI or URI Reference, 3683 respectively. 3684 * "uuid": An [RFC4122] UUID. 3686 C.3. type "boolean" 3688 The type "boolean" can take the values "true" or "false". 3690 C.4. type "array" 3692 The type "array" is associated with arrays as they are available in 3693 JSON. 3695 The additional quality "items" gives the type that each of the 3696 elements of the array must match. 3698 The number of elements in the array can be constrained by the 3699 additional data qualities "minItems" and "maxItems", which are 3700 inclusive bounds. 3702 The additional data quality "uniqueItems" gives a Boolean value that, 3703 if true, requires the elements to be all different. 3705 C.5. type "object" 3707 The type "object" is associated with maps, from strings to values, as 3708 they are available in JSON ("objects"). 3710 The additional quality "properties" is a map the entries of which 3711 describe entries in the specified JSON object: The key gives an 3712 allowable map key for the specified JSON object, and the value is a 3713 map with a named set of data qualities giving the type for the 3714 corresponding value in the specified JSON object. 3716 All entries specified this way are optional, unless they are listed 3717 in the value of the additional quality "required", which is an array 3718 of string values that give the key names of required entries. 3720 Note that the term "properties" as an additional quality for defining 3721 map entries is unrelated to sdfProperty. 3723 C.6. Implementation notes 3725 JSO-based keywords are also used in the specification techniques of a 3726 number of ecosystems, but some adjustments may be required. 3728 E.g., [OCF] is based on Swagger 2.0 which appears to be based on 3729 "draft-4" [I-D.wright-json-schema] (also called draft-5, but 3730 semantically intended to be equivalent to draft-4). The 3731 "exclusiveMinimum" and "exclusiveMaximum" keywords use the Boolean 3732 form there, so on import to SDF their values have to be replaced by 3733 the values of the respective "minimum"/"maximum" keyword, which are 3734 themselves then removed; the reverse transformation applies on 3735 export. 3737 TBD: add any useful implementation notes we can find for other 3738 ecosystems that use JSO. 3740 Acknowledgements 3742 This draft is based on sdf.md and sdf-schema.json in the old one- 3743 data-model language repository, as well as Ari Keränen's "alt-schema" 3744 from the Ericsson Research ipso-odm repository (which is now under 3745 subdirectory sdflint in the one-data model tools repository). 3747 Contributors 3749 Ari Keränen 3750 Ericsson 3751 FI-02420 Jorvas 3752 Finland 3753 Email: ari.keranen@ericsson.com 3755 Wouter van der Beek 3756 Cascoda Ltd. 3757 Threefield House 3758 Threefield Lane 3759 Southampton 3760 United Kingdom 3761 Email: w.vanderbeek@cascoda.com 3763 Authors' Addresses 3765 Michael Koster (editor) 3766 PassiveLogic 3767 524 H Street 3768 Antioch, CA, 94509 3769 United States of America 3770 Phone: +1-707-502-5136 3771 Email: michaeljohnkoster@gmail.com 3773 Carsten Bormann (editor) 3774 Universität Bremen TZI 3775 Postfach 330440 3776 D-28359 Bremen 3777 Germany 3778 Phone: +49-421-218-63921 3779 Email: cabo@tzi.org