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