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