idnits 2.17.1 draft-ietf-asdf-sdf-04.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 46 instances of too long lines in the document, the longest one being 100 characters in excess of 72. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (6 March 2021) is 1147 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 1054 -- Looks like a reference, but probably isn't: '2' on line 1054 -- Looks like a reference, but probably isn't: '3' on line 1054 ** Downref: Normative reference to an Informational draft: draft-handrews-json-schema-validation (ref. 'I-D.handrews-json-schema-validation') == Outdated reference: A later version (-07) exists of draft-ietf-cbor-cddl-control-02 -- Possible downref: Non-RFC (?) normative reference: ref. 'SPDX' == Outdated reference: A later version (-13) exists of draft-irtf-t2trg-rest-iot-07 Summary: 4 errors (**), 0 flaws (~~), 4 warnings (==), 5 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 T2TRG M. Koster, Ed. 3 Internet-Draft Dogtiger Labs 4 Intended status: Standards Track C. Bormann, Ed. 5 Expires: 7 September 2021 Universität Bremen TZI 6 6 March 2021 8 Semantic Definition Format (SDF) for Data and Interactions of Things 9 draft-ietf-asdf-sdf-04 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 7 September 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 . . . . . . . . . . . . . . . . . . . . . . . 76 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 "currentTemperature", 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/sdfProperty/currentTemperature", 769 "#/sdfObject/temperatureWithAlarm/sdfEvent/overTemperatureEvent" 770 ], 771 "sdfData":{ 772 "temperatureData": { 773 "type": "number" 774 } 775 }, 776 "sdfProperty": { 777 "currentTemperature": { 778 "sdfRef": "#/sdfObject/temperatureWithAlarm/sdfData/temperatureData" 779 } 780 }, 781 "sdfEvent": { 782 "overTemperatureEvent": { 783 "sdfOutputData": { 784 "type": "object", 785 "properties": { 786 "alarmType": { 787 "sdfRef": "cap:/sdfData/alarmTypes/quantityAlarms", 788 "const": "OverTemperatureAlarm" 789 }, 790 "temperature": { 791 "sdfRef": "#/sdfObject/temperatureWithAlarm/sdfData/temperatureData" 792 } 793 } 794 } 795 } 796 } 797 } 798 } 799 } 801 Figure 4: Using sdfRequired 803 4.6. Common Qualities 805 Definitions in SDF share a number of qualities that provide metadata 806 for them. These are listed in Table 3. None of these qualities are 807 required or have default values that are assumed if the quality is 808 absent. If a label is required for an application and no label is 809 given in the SDF model, the last part ("reference-token", Section 3 810 of [RFC6901]) of the JSON pointer to the definition can be used. 812 +=============+==============+===================================+ 813 | Quality | Type | Description | 814 +=============+==============+===================================+ 815 | description | text | long text (no constraints) | 816 +-------------+--------------+-----------------------------------+ 817 | label | text | short text (no constraints) | 818 +-------------+--------------+-----------------------------------+ 819 | $comment | text | source code comments only, no | 820 | | | semantics | 821 +-------------+--------------+-----------------------------------+ 822 | sdfRef | sdf-pointer | (see Section 4.4) | 823 +-------------+--------------+-----------------------------------+ 824 | sdfRequired | pointer-list | (see Section 4.5, applies to | 825 | | | qualities of properties, of data) | 826 +-------------+--------------+-----------------------------------+ 828 Table 3: Common Qualities 830 4.7. Data Qualities 832 Data qualities are used in "sdfData" and "sdfProperty" definitions, 833 which are named sets of data qualities (abbreviated as "named-sdq"). 835 Table 4 lists data qualities borrowed from 836 [I-D.handrews-json-schema-validation]; the intention is that these 837 qualities retain their semantics from the versions of the json- 838 schema.org proposal they were imported from. A description that 839 starts with a parenthesized term means the quality is only applicable 840 when "type" has the value of the term. 842 Table 5 lists data qualities defined specifically for the present 843 specification. 845 The term "allowed types" stands for primitive JSON types, JSON maps 846 ("objects")" as well as homogeneous arrays of numbers, text, 847 Booleans, or maps. (This list might be extended in a future version 848 of SDF.) An "allowed value" is a value allowed for one of these 849 types. 851 +================+==========+=======================================+ 852 |Quality |Type |Description | 853 +================+==========+=======================================+ 854 |type |"number" /|JSON data type (note 1) | 855 | |"string" /| | 856 | |"boolean" | | 857 | |/ | | 858 | |"integer" | | 859 | |/ "array" | | 860 | |/ "object"| | 861 +----------------+----------+---------------------------------------+ 862 |const |allowed |specifies a constant value for a data | 863 | |value |item or property | 864 +----------------+----------+---------------------------------------+ 865 |default |allowed |specifies the default value for | 866 | |value |initialization | 867 +----------------+----------+---------------------------------------+ 868 |minimum |number |(number) lower limit of value | 869 +----------------+----------+---------------------------------------+ 870 |maximum |number |(number) upper limit of value | 871 +----------------+----------+---------------------------------------+ 872 |exclusiveMinimum|number or |(number) lower limit of value | 873 | |boolean | | 874 | |(jso draft| | 875 | |7/4) | | 876 +----------------+----------+---------------------------------------+ 877 |exclusiveMaximum|number or |(number) lower limit of value | 878 | |boolean | | 879 | |(jso draft| | 880 | |7/4) | | 881 +----------------+----------+---------------------------------------+ 882 |multipleOf |number |(number) resolution of the number | 883 | | |[NEEDED?] | 884 +----------------+----------+---------------------------------------+ 885 |minLength |integer |(string) shortest length string in | 886 | | |octets | 887 +----------------+----------+---------------------------------------+ 888 |maxLength |integer |(string) longest length string in | 889 | | |octets | 890 +----------------+----------+---------------------------------------+ 891 |pattern |string |(string) regular expression to | 892 | | |constrain a string pattern | 893 +----------------+----------+---------------------------------------+ 894 |format |"date- |(string) JSON Schema formats as per | 895 | |time" / |[I-D.handrews-json-schema-validation], | 896 | |"date" / |Section 7.3 | 897 | |"time" / | | 898 | |"uri" / | | 899 | |"uri- | | 900 | |reference"| | 901 | |/ "uuid" | | 902 +----------------+----------+---------------------------------------+ 903 |minItems |number |(array) Minimum number of items in | 904 | | |array | 905 +----------------+----------+---------------------------------------+ 906 |maxItems |number |(array) Maximum number of items in | 907 | | |array | 908 +----------------+----------+---------------------------------------+ 909 |uniqueItems |boolean |(array) if true, requires items to be | 910 | | |all different | 911 +----------------+----------+---------------------------------------+ 912 |items |(subset of|(array) constraints on array items | 913 | |common/ | | 914 | |data | | 915 | |qualities;| | 916 | |see | | 917 | |Appendix A| | 918 +----------------+----------+---------------------------------------+ 919 |required |array of |(object) names of properties (note 2) | 920 | |strings |that are required in the JSON map | 921 | | |("object") | 922 +----------------+----------+---------------------------------------+ 923 |properties |named set |(object) entries allowed for the JSON | 924 | |of data |map ("object") | 925 | |qualities | | 926 +----------------+----------+---------------------------------------+ 928 Table 4: Qualities of sdfProperty and sdfData borrowed from json- 929 schema.org 931 (1) A type value of "integer" means that only integral values of JSON 932 numbers can be used. 934 (2) Note that the term "properties" as used for map entries in 935 [I-D.handrews-json-schema-validation] is unrelated to sdfProperty. 937 +===============+===========+===========================+=========+ 938 | Quality | Type | Description | Default | 939 +===============+===========+===========================+=========+ 940 | (common) | | Section 4.6 | | 941 +---------------+-----------+---------------------------+---------+ 942 | unit | string | SenML unit name as per | N/A | 943 | | | [IANA.senml], subregistry | | 944 | | | SenML Units (note 3) | | 945 +---------------+-----------+---------------------------+---------+ 946 | scaleMinimum | number | lower limit of value in | N/A | 947 | | | units given by unit | | 948 +---------------+-----------+---------------------------+---------+ 949 | scaleMaximum | number | upper limit of value in | N/A | 950 | | | units given by unit | | 951 +---------------+-----------+---------------------------+---------+ 952 | readable | boolean | Reads are allowed | true | 953 +---------------+-----------+---------------------------+---------+ 954 | writable | boolean | Writes are allowed | true | 955 +---------------+-----------+---------------------------+---------+ 956 | observable | boolean | flag to indicate | true | 957 | | | asynchronous notification | | 958 | | | is available | | 959 +---------------+-----------+---------------------------+---------+ 960 | nullable | boolean | indicates a null value is | true | 961 | | | available for this type | | 962 +---------------+-----------+---------------------------+---------+ 963 | contentFormat | string | content type (IANA media | N/A | 964 | | | type string plus | | 965 | | | parameters), encoding | | 966 +---------------+-----------+---------------------------+---------+ 967 | sdfType | string | sdfType enumeration | N/A | 968 | | (Section | (extensible) | | 969 | | 4.7.1) | | | 970 +---------------+-----------+---------------------------+---------+ 971 | sdfChoice | named set | named alternatives | N/A | 972 | | of data | | | 973 | | qualities | | | 974 +---------------+-----------+---------------------------+---------+ 975 | enum | array of | abbreviation for string- | N/A | 976 | | strings | valued named alternatives | | 977 +---------------+-----------+---------------------------+---------+ 979 Table 5: SDF-defined Qualities of sdfProperty and sdfData 981 (3) note that the quality "unit" was called "units" in SDF 1.0. 983 4.7.1. sdfType 985 SDF defines a number of basic types beyond those provided by JSON or 986 [I-D.handrews-json-schema-validation]. These types are identified by 987 the "sdfType" quality, which is a text string from a set of type 988 names defined by SDF. 990 To aid interworking with [I-D.handrews-json-schema-validation] 991 implementations, it is RECOMMENDED that "sdfType" is always used in 992 conjunction with the "type" quality inherited from 993 [I-D.handrews-json-schema-validation], in such a way as to yield a 994 common representation of the type's values in JSON. 996 Values for "sdfType" that are defined in SDF 1.1 are shown in 997 Table 6. This table also gives a description of the semantics of the 998 sdfType, the conventional value for "type" to be used with the 999 "sdfType" value, and a conventional JSON representation for values of 1000 the type. 1002 +=============+=============+========+==========================+ 1003 | sdfType | Description | type | JSON Representation | 1004 +=============+=============+========+==========================+ 1005 | byte-string | A sequence | string | base64url without | 1006 | | of zero or | | padding (Section 3.4.5.2 | 1007 | | more bytes | | of [RFC8949]) | 1008 +-------------+-------------+--------+--------------------------+ 1009 | unix-time | A point in | number | POSIX time | 1010 | | civil time | | (Section 3.4.2 of | 1011 | | (note 1) | | [RFC8949]) | 1012 +-------------+-------------+--------+--------------------------+ 1014 Table 6: Values defined in SDF 1.1 for sdfType quality 1016 (1) Note that the definition of "unix-time" does not imply the 1017 capability to represent points in time that fall on leap seconds. 1018 More date/time-related sdfTypes are likely to be added in future 1019 versions of this specification. 1021 In SDF 1.0, a similar concept was called "subtype". 1023 4.7.2. sdfChoice 1025 Data can be a choice of named alternatives, called "sdfChoice". Each 1026 alternative is identified by a name (string, key in the JSON object 1027 used to represent the choice) and a set of dataqualities (object, the 1028 value in the JSON object used to represent the choice). 1030 sdfChoice merges the functions of two constructs found in 1031 [I-D.handrews-json-schema-validation]: 1033 * "enum" 1035 What would have been 1037 "enum": ["foo", "bar", "baz"] 1039 in SDF 1.0, is often best represented as: 1041 "sdfChoice": { 1042 "foo": { "description": "This is a foonly"}, 1043 "bar": { "description": "As defined in the second world congress"}, 1044 "baz": { "description": "From zigbee foobaz"} 1045 } 1047 This allows the placement of other dataqualities such as 1048 "description" in the example. 1050 If an enum needs to use a data type different from text string, 1051 e.g. what would have been 1053 "type": "number", 1054 "enum": [1, 2, 3] 1056 in SDF 1.0, is represented as: 1058 "type": "number", 1059 "sdfChoice": { 1060 "a-better-name-for-alternative-1": { "const": 1 }, 1061 "alternative-2": { "const": 2 }, 1062 "the-third-alternative": { "const": 3 } 1063 } 1065 where the string names obviously would be chosen in a way that is 1066 descriptive for what these numbers actually stand for; sdfChoice 1067 also makes it easy to add number ranges into the mix. 1069 (Note that "const" can also be used for strings as in the previous 1070 example, e.g., if the actual string value is indeed a crucial 1071 element for the data model.) 1073 * anyOf 1075 [I-D.handrews-json-schema-validation] provides a type union called 1076 "anyOf", which provides a choice between anonymous alternatives. 1078 What could have been 1080 "anyOf": [ 1081 {"type": "array", "minItems": 3, "maxItems": "3", "items": { 1082 "sdfRef": "rgbVal"}} 1083 {"type": "array", "minItems": 4, "maxItems": "4", "items": { 1084 "sdfRef": "cmykVal"}} 1085 ] 1087 in [I-D.handrews-json-schema-validation] can be more descriptively 1088 notated in SDF as: 1090 "sdfChoice": { 1091 "rgb": {"type": "array", "minItems": 3, "maxItems": "3", "items": { 1092 "sdfRef": "rgbVal"}} 1093 "cmyk": {"type": "array", "minItems": 4, "maxItems": "4", "items": { 1094 "sdfRef": "cmykVal"}} 1095 ] 1097 Note that there is no need in SDF for the type intersection construct 1098 "allOf" or the peculiar type-xor construct "oneOf" found in 1099 [I-D.handrews-json-schema-validation]. 1101 As a simplification for readers of SDF specifications accustomed to 1102 the [I-D.handrews-json-schema-validation] enum keyword, this is 1103 retained, but limited to a choice of text string values, such that 1105 "enum": ["foo", "bar", "baz"] 1107 is syntactic sugar for 1109 "sdfChoice": { 1110 "foo": { "const": "foo"}, 1111 "bar": { "const": "bar"}, 1112 "baz": { "const": "baz"} 1113 } 1115 5. Keywords for definition groups 1117 The following SDF keywords are used to create definition groups in 1118 the target namespace. All these definitions share some common 1119 qualities as discussed in Section 4.6. 1121 5.1. sdfObject 1123 The sdfObject keyword denotes a group of zero or more Object 1124 definitions. Object definitions may contain or include definitions 1125 of Properties, Actions, Events declared for the object, as well as 1126 data types (sdfData group) to be used in this or other Objects. 1128 The qualities of an sdfObject include the common qualities, 1129 additional qualities are shown in Table 7. None of these qualities 1130 are required or have default values that are assumed if the quality 1131 is absent. 1133 +=============+===========+=============================+ 1134 | Quality | Type | Description | 1135 +=============+===========+=============================+ 1136 | (common) | | Section 4.6 | 1137 +-------------+-----------+-----------------------------+ 1138 | sdfProperty | property | zero or more named property | 1139 | | | definitions for this object | 1140 +-------------+-----------+-----------------------------+ 1141 | sdfAction | action | zero or more named action | 1142 | | | definitions for this object | 1143 +-------------+-----------+-----------------------------+ 1144 | sdfEvent | event | zero or more named event | 1145 | | | definitions for this object | 1146 +-------------+-----------+-----------------------------+ 1147 | sdfData | named-sdq | zero or more named data | 1148 | | | type definitions that might | 1149 | | | be used in the above | 1150 +-------------+-----------+-----------------------------+ 1152 Table 7: Qualities of sdfObject 1154 5.2. sdfProperty 1156 The sdfProperty keyword denotes a group of zero or more Property 1157 definitions. 1159 Properties are used to model elements of state. 1161 The qualities of a Property definition include the data qualities 1162 (and thus the common qualities), see Section 4.7. 1164 5.3. sdfAction 1166 The sdfAction keyword denotes a group of zero or more Action 1167 definitions. 1169 Actions are used to model commands and methods which are invoked. 1170 Actions have parameter data that are supplied upon invocation. 1172 The qualities of an Action definition include the common qualities, 1173 additional qualities are shown in Table 8. 1175 +===============+===========+============================+ 1176 | Quality | Type | Description | 1177 +===============+===========+============================+ 1178 | (common) | | Section 4.6 | 1179 +---------------+-----------+----------------------------+ 1180 | sdfInputData | map | data qualities of the | 1181 | | | input data for an Action | 1182 +---------------+-----------+----------------------------+ 1183 | sdfOutputData | map | data qualities of the | 1184 | | | output data for an Action | 1185 +---------------+-----------+----------------------------+ 1186 | sdfData | named-sdq | zero or more named data | 1187 | | | type definitions that | 1188 | | | might be used in the above | 1189 +---------------+-----------+----------------------------+ 1191 Table 8: Qualities of sdfAction 1193 "sdfInputData" defines the input data of the action. "sdfOutputData" 1194 defines the output data of the action. As discussed in 1195 Section 2.2.3, a set of data qualities with type "object" can be used 1196 to substructure either data item, with optionality indicated by the 1197 data quality "required". 1199 5.4. sdfEvent 1201 The sdfEvent keyword denotes zero or more Event definitions. 1203 Events are used to model asynchronous occurrences that may be 1204 communicated proactively. Events have data elements which are 1205 communicated upon the occurrence of the event. 1207 The qualities of sdfEvent include the common qualities, additional 1208 qualities are shown in Table 9. 1210 +===============+===========+============================+ 1211 | Quality | Type | Description | 1212 +===============+===========+============================+ 1213 | (common) | | Section 4.6 | 1214 +---------------+-----------+----------------------------+ 1215 | sdfOutputData | map | data qualities of the | 1216 | | | output data for an Event | 1217 +---------------+-----------+----------------------------+ 1218 | sdfData | named-sdq | zero or more named data | 1219 | | | type definitions that | 1220 | | | might be used in the above | 1221 +---------------+-----------+----------------------------+ 1223 Table 9: Qualities of sdfEvent 1225 "sdfOutputData" defines the output data of the action. As discussed 1226 in Section 2.2.4, a set of data qualities with type "object" can be 1227 used to substructure the output data item, with optionality indicated 1228 by the data quality "required". 1230 5.5. sdfData 1232 The sdfData keyword denotes a group of zero or more named data type 1233 definitions (named-sdq). 1235 An sdfData definition provides a reusable semantic identifier for a 1236 type of data item and describes the constraints on the defined type. 1237 It is not itself a declaration, i.e., it does not cause any of these 1238 data items to be included in an affordance definition. 1240 The qualities of sdfData include the data qualities (and thus the 1241 common qualities), see Section 4.7. 1243 6. High Level Composition 1245 The requirements for high level composition include the following: 1247 * The ability to represent products, standardized product types, and 1248 modular products while maintaining the atomicity of Objects. 1250 * The ability to compose a reusable definition block from Objects, 1251 for example a single plug unit of an outlet strip with on/off 1252 control, energy monitor, and optional dimmer objects, while 1253 retaining the atomicity of the individual objects. 1255 * The ability to compose Objects and other definition blocks into a 1256 higher level thing that represents a product, while retaining the 1257 atomicity of objects. 1259 * The ability to enrich and refine a base definition to have 1260 product-specific qualities and quality values, e.g. unit, range, 1261 and scale settings. 1263 * The ability to reference items in one part of a complex definition 1264 from another part of the same definition, for example to summarize 1265 the energy readings from all plugs in an outlet strip. 1267 6.1. Paths in the model namespaces 1269 The model namespace is organized according to terms that are defined 1270 in the definition files that are present in the namespace. For 1271 example, definitions that originate from an organization or vendor 1272 are expected to be in a namespace that is specific to that 1273 organization or vendor. There is expected to be an SDF namespace for 1274 common SDF definitions used in OneDM. 1276 The structure of a path in a namespace is defined by the JSON 1277 Pointers to the definitions in the files in that namespace. For 1278 example, if there is a file defining an object "Switch" with an 1279 action "on", then the reference to the action would be 1280 "ns:/sdfObject/Switch/sdfAction/on" where "ns" is the namespace 1281 prefix (short name for the namespace). 1283 6.2. Modular Composition 1285 Modular composition of definitions enables an existing definition 1286 (could be in the same file or another file) to become part of a new 1287 definition by including a reference to the existing definition within 1288 the model namespace. 1290 6.2.1. Use of the "sdfRef" keyword to re-use a definition 1292 An existing definition may be used as a template for a new 1293 definition, that is, a new definition is created in the target 1294 namespace which uses the defined qualities of some existing 1295 definition. This pattern will use the keyword "sdfRef" as a quality 1296 of a new definition with a value consisting of a reference to the 1297 existing definition that is to be used as a template. 1299 In the definition that uses "sdfRef", new qualities may be added and 1300 existing qualities from the referenced definition may be overridden. 1301 (Note that JSON maps (objects) do not have a defined order, so the 1302 SDF processor may see these overrides before seeing the "sdfRef".) 1304 As a convention, overrides are intended to be used only for further 1305 restricting the set of data values, as shown in Figure 5: any value 1306 for a "cable-length" also is a valid value for a "length", with the 1307 additional restriction that the length cannot be smaller than 5 cm. 1308 (This is labeled as a convention as it cannot be checked in the 1309 general case; a quality of implementation consideration for a tool 1310 might be to provide at least some form of checking.) Note that a 1311 description is provided that overrides the description of the 1312 referenced definition; as this quality is intended for human 1313 consumption there is no conflict with the intended goal. 1315 "sdfData": 1316 "length" : { 1317 "type": "number", 1318 "minimum": 0, 1319 "unit": "m" 1320 "description": "There can be no negative lengths." 1321 } 1322 ... 1323 "cable-length" : { 1324 "sdfRef": "#/sdfData/length" 1325 "minimum": 0.05, 1326 "description": "Cables must be at least 5 cm." 1327 } 1329 Figure 5 1331 6.3. sdfThing 1333 An sdfThing is a set of declarations and qualities that may be part 1334 of a more complex model. For example, the object declarations that 1335 make up the definition of a single socket of an outlet strip could be 1336 encapsulated in an sdfThing, and the socket-thing itself could be 1337 used in a declaration in the sdfThing definition for the outlet 1338 strip. 1340 sdfThing definitions carry semantic meaning, such as a defined 1341 refrigerator compartment and a defined freezer compartment, making up 1342 a combination refrigerator-freezer product. 1344 An sdfThing may be composed of sdfObjects and other sdfThings. 1346 The qualities of sdfThing are shown in Table 10. 1348 +===========+========+=============+ 1349 | Quality | Type | Description | 1350 +===========+========+=============+ 1351 | (common) | | Section 4.6 | 1352 +-----------+--------+-------------+ 1353 | sdfThing | thing | | 1354 +-----------+--------+-------------+ 1355 | sdfObject | object | | 1356 +-----------+--------+-------------+ 1358 Table 10: Qualities of sdfThing 1359 and sdfProduct 1361 6.4. sdfProduct 1363 An sdfProduct provides the level of abstraction for representing a 1364 unique product or a profile for a standardized type of product, for 1365 example a "device type" definition with required minimum 1366 functionality. 1368 Products may be composed of Objects and Things at the high level, and 1369 may include their own definitions of Properties, Actions, and Events 1370 that can be used to extend or complete the included Object 1371 definitions. 1373 Product definitions may set optional defaults and constant values for 1374 specific use cases, for example units, range, and scale settings for 1375 properties, or available parameters for Actions. 1377 The qualities of sdfProduct are the same as for sdfThing and are 1378 shown in Table 10. 1380 7. References 1382 7.1. Normative References 1384 [I-D.handrews-json-schema-validation] 1385 Wright, A., Andrews, H., and B. Hutton, "JSON Schema 1386 Validation: A Vocabulary for Structural Validation of 1387 JSON", Work in Progress, Internet-Draft, draft-handrews- 1388 json-schema-validation-02, 17 September 2019, 1389 . 1392 [I-D.ietf-cbor-cddl-control] 1393 Bormann, C., "Additional Control Operators for CDDL", Work 1394 in Progress, Internet-Draft, draft-ietf-cbor-cddl-control- 1395 02, 22 February 2021, . 1398 [IANA.senml] 1399 IANA, "Sensor Measurement Lists (SenML)", 1400 . 1402 [RFC0020] Cerf, V., "ASCII format for network interchange", STD 80, 1403 RFC 20, DOI 10.17487/RFC0020, October 1969, 1404 . 1406 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1407 Requirement Levels", BCP 14, RFC 2119, 1408 DOI 10.17487/RFC2119, March 1997, 1409 . 1411 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 1412 Resource Identifier (URI): Generic Syntax", STD 66, 1413 RFC 3986, DOI 10.17487/RFC3986, January 2005, 1414 . 1416 [RFC6901] Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed., 1417 "JavaScript Object Notation (JSON) Pointer", RFC 6901, 1418 DOI 10.17487/RFC6901, April 2013, 1419 . 1421 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1422 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1423 May 2017, . 1425 [RFC8610] Birkholz, H., Vigano, C., and C. Bormann, "Concise Data 1426 Definition Language (CDDL): A Notational Convention to 1427 Express Concise Binary Object Representation (CBOR) and 1428 JSON Data Structures", RFC 8610, DOI 10.17487/RFC8610, 1429 June 2019, . 1431 [RFC8949] Bormann, C. and P. Hoffman, "Concise Binary Object 1432 Representation (CBOR)", STD 94, RFC 8949, 1433 DOI 10.17487/RFC8949, December 2020, 1434 . 1436 [SPDX] "SPDX License List", . 1438 [W3C.NOTE-curie-20101216] 1439 Birbeck, M. and S. McCarron, "CURIE Syntax 1.0", World 1440 Wide Web Consortium NOTE NOTE-curie-20101216, 16 December 1441 2010, . 1443 7.2. Informative References 1445 [I-D.irtf-t2trg-rest-iot] 1446 Keranen, A., Kovatsch, M., and K. Hartke, "RESTful Design 1447 for Internet of Things Systems", Work in Progress, 1448 Internet-Draft, draft-irtf-t2trg-rest-iot-07, 22 February 1449 2021, . 1452 [OCF] "OCF Resource Type Specification", 1453 . 1456 [OMA] "OMA LightweightM2M (LwM2M) Object and Resource Registry", 1457 . 1460 [RFC3339] Klyne, G. and C. Newman, "Date and Time on the Internet: 1461 Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002, 1462 . 1464 [ZCL] "The ZigBee Cluster Library", Zigbee Wireless 1465 Networking pp. 239-271, 1466 DOI 10.1016/b978-0-7506-8597-9.00006-9, 2008, 1467 . 1469 Appendix A. Formal Syntax of SDF 1471 This appendix describes the syntax of SDF using CDDL [RFC8610]. Note 1472 that this appendix was derived from Ari Keranen's "alt-schema" and 1473 Michael Koster's "schema", with a view of covering the syntax that is 1474 currently in use at the One Data Model "playground" repository. 1476 This appendix shows the framework syntax only, i.e., a syntax with 1477 liberal extension points. Since this syntax is nearly useless in 1478 finding typos in an SDF specification, a second syntax, the 1479 validation syntax, is defined that does not include the extension 1480 points. The validation syntax can be generated from the framework 1481 syntax by leaving out all lines containing the string "EXTENSION- 1482 POINT"; as this is trivial, the result is not shown here. 1484 This appendix makes use of CDDL "features" as defined in Section 4 of 1485 [I-D.ietf-cbor-cddl-control]. A feature named "1.0" is used to 1486 indicate parts of the syntax being deprecated towards SDF 1.1, and a 1487 feature named "1.1" is used to indicate new syntax intended for SDF 1488 1.1. Features whose names end in "-ext" indicate extension points 1489 for further evolution. 1491 start = sdf-syntax 1493 sdf-syntax = { 1494 info: sdfinfo ; don't *require* this in flexible syntax, though 1495 ? namespace: named 1496 ? defaultNamespace: text 1497 ? sdfThing: named ; Thing is a composition of objects that work together in some way 1498 ? sdfProduct: named ; Product is a composition of things and objects that can model a SKU-level instance of a product 1499 ? sdfObject: named ; Object is a set of Properties, Actions, and Events that together perform a particular function 1500 ? sdfProperty: named ; Property represents the state of an instance of an object 1501 ? sdfAction: named ; Action is a directive to invoke an application layer verb associated with an object 1502 ? sdfEvent: named ; Event represents an occurence of something associated with an object 1503 ? 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 1504 EXTENSION-POINT<"top-ext"> 1505 } 1507 sdfinfo = { 1508 title: text 1509 version: text 1510 copyright: text 1511 license: text 1512 EXTENSION-POINT<"info-ext"> 1513 } 1515 ; Shortcut for a map that gives names to instances of X (has text keys and values of type X) 1516 named = { * text => X } 1518 EXTENSION-POINT = ( * (text .feature f) => any ) ; only used in framework syntax 1520 sdf-pointer = text ; .regexp curie-regexp -- TO DO! 1521 pointer-list = [* sdf-pointer] ; ISSUE: no point in having an empty list, no? but used for sdfRequired in odmobject-multiple_axis_joystick.sdf.json 1523 commonqualities = ( 1524 ? description: text ; long text (no constraints) 1525 ? label: text ; short text (no constraints); default to key 1526 ? $comment: text ; source code comments only, no semantics 1527 ? sdfRef: sdf-pointer 1528 ? sdfRequired: pointer-list ; applies to qualities of properties, of data 1529 ) 1531 ; for building hierarchy 1532 thingqualities = { 1533 commonqualities, 1534 ? sdfObject: named 1535 ? sdfThing: named 1536 EXTENSION-POINT<"thing-ext"> 1537 } 1539 productqualities = thingqualities ; ISSUE: get rid of sdfProduct? 1541 ; for single objects 1542 objectqualities = { 1543 commonqualities, 1544 ? sdfProperty: named 1545 ? sdfAction: named 1546 ? sdfEvent: named 1547 ? sdfData: named 1548 EXTENSION-POINT<"object-ext"> 1549 } 1551 propertyqualities = dataqualities ; the definitions in sdfData are declarations in sdfProperty 1553 parameter-list = 1554 pointer-list .feature (["1.0", "pointerlist-as-parameter"]) / 1555 dataqualities .feature (["1.1", "dataqualities-as-parameter"]) 1557 actionqualities = { 1558 commonqualities, 1559 ? sdfInputData: parameter-list ; sdfRequiredInputData applies here (a bit redundant) 1560 ? ("sdfRequiredInputData" .feature "1.0") => pointer-list 1561 ? sdfOutputData: parameter-list ; sdfRequired applies here 1562 ? sdfData: named ; zero or more named data type definitions that might be used in the above 1563 EXTENSION-POINT<"action-ext"> 1564 } 1566 eventqualities = { 1567 commonqualities 1568 ? sdfOutputData: parameter-list ; sdfRequired applies here 1569 ? sdfData: named ; zero or more named data type definitions that might be used in the above 1570 EXTENSION-POINT<"event-ext"> 1571 } 1573 dataqualities = { ; also propertyqualities 1574 commonqualities, 1575 jsonschema, 1576 ? ("units" .feature "1.0") => text 1577 ? ("unit" .feature "1.1") => text 1578 ? scaleMinimum: number 1579 ? scaleMaximum: number 1580 ? observable: bool 1581 ? readable: bool 1582 ? writable: bool 1583 ? nullable: bool 1584 ? ("subtype" .feature "1.0") => "byte-string" / "unix-time" 1585 / (text .feature "subtype-ext") ; EXTENSION-POINT 1586 ? ("sdfType" .feature "1.1") => "byte-string" / "unix-time" 1587 / (text .feature "sdftype-ext") ; EXTENSION-POINT 1588 ? contentFormat: text 1589 EXTENSION-POINT<"data-ext"> 1590 } 1592 allowed-types = number / text / bool / null 1593 / [* number] / [* text] / [* bool] 1594 / {* text => any} 1595 / (any .feature "allowed-ext") ; EXTENSION-POINT 1597 compound-type = ( 1598 "type" => ("object" .feature "1.1"), 1599 ? required: [+text], 1600 ? properties: named, 1601 ) 1603 choice-type = ( 1604 ("sdfChoice" .feature "1.1") => named 1605 ) 1607 jsonschema = ( 1608 ? (("type" => "number" / "string" / "boolean" / "integer" / "array") 1609 // compound-type 1610 // choice-type 1611 // (type: text .feature "type-ext") ; EXTENSION-POINT 1612 ) 1613 ? "enum" => [+ text] ; limited to text strings in SDF 1.1 1614 ? ("enum" .feature "1.0") => [+ allowed-types] ; should validate against type 1615 ? const: allowed-types ; should validate against type 1616 ? default: allowed-types ; should validate against type 1617 ; number/integer constraints 1618 ? minimum: number 1619 ? maximum: number 1620 ? exclusiveMinimum: bool / number ; jso draft 4/7 1621 ? exclusiveMaximum: bool / number ; jso draft 4/7 1622 ? multipleOf: number ; ISSUE: Do we need this? 1623 ; text string constraints 1624 ? minLength: number 1625 ? maxLength: number 1626 ? pattern: text ; regexp 1627 ? format: "date-time" / "date" / "time" 1628 / "uri" / "uri-reference" / "uuid" 1629 / (text .feature "format-ext") ; EXTENSION-POINT 1630 ; array constraints 1631 ? minItems: number 1632 ? maxItems: number 1633 ? uniqueItems: bool 1634 ? items: { ;;; ultimately, this will be mostly recursive, but, for now 1635 ;;; let's find out what we actually need 1636 ? sdfRef: sdf-pointer ; import limited to the subset that we allow here... 1637 ? description: text ; long text (no constraints) 1638 ? $comment: text ; source code comments only, no semantics 1639 ; commonqualities, ; -- ISSUE: should leave this out for non-complex data types, but need the above three 1640 ? ((type: "number" / "string" / "boolean" / "integer") ; no "array" 1641 // compound-type 1642 // choice-type ; do we really need arrays of choices? 1643 // (type: text .feature "itemtype-ext") ; EXTENSION-POINT 1644 ) 1645 ; jso subset 1646 ? minimum: number 1647 ? maximum: number 1648 ? "enum" => [+ text] ; limited to text strings in SDF 1.1 1649 ? ("enum" .feature "1.0") => [+ any] 1650 ? format: text 1651 ? minLength: number 1652 ? maxLength: number 1653 EXTENSION-POINT<"items-ext"> 1654 } 1655 ) 1657 Appendix B. json-schema.org Rendition of SDF Syntax 1659 This appendix describes the syntax of SDF defined in Appendix A, but 1660 using a version of the description techniques advertised on json- 1661 schema.org [I-D.handrews-json-schema-validation]. 1663 The appendix shows both the validation and the framework syntax. 1664 Since most of the lines are the same between these two files, those 1665 lines are shown only once, with a leading space, in the form of a 1666 unified diff. Lines leading with a "-" are part of the validation 1667 syntax, and lines leading with a "+" are part of the framework 1668 syntax. 1670 { 1671 - "title": "sdf-validation.cddl", 1672 + "title": "sdf-framework.cddl", 1673 "$schema": "http://json-schema.org/draft-07/schema#", 1674 "$ref": "#/definitions/sdf-syntax", 1675 "definitions": { 1676 "sdf-syntax": { 1677 "type": "object", 1678 "required": [ 1679 "info" 1680 ], 1681 "properties": { 1682 "info": { 1683 "$ref": "#/definitions/sdfinfo" 1684 }, 1685 "namespace": { 1686 "type": "object", 1687 "additionalProperties": { 1688 "type": "string" 1689 } 1690 }, 1691 "defaultNamespace": { 1692 "type": "string" 1693 }, 1694 "sdfThing": { 1695 "type": "object", 1696 "additionalProperties": { 1697 "$ref": "#/definitions/thingqualities" 1698 } 1699 }, 1700 "sdfProduct": { 1701 "type": "object", 1702 "additionalProperties": { 1703 "$ref": "#/definitions/productqualities" 1704 } 1705 }, 1706 "sdfObject": { 1707 "type": "object", 1708 "additionalProperties": { 1709 "$ref": "#/definitions/objectqualities" 1710 } 1711 }, 1712 "sdfProperty": { 1713 "type": "object", 1714 "additionalProperties": { 1715 "$ref": "#/definitions/propertyqualities" 1716 } 1717 }, 1718 "sdfAction": { 1719 "type": "object", 1720 "additionalProperties": { 1721 "$ref": "#/definitions/actionqualities" 1722 } 1723 }, 1724 "sdfEvent": { 1725 "type": "object", 1726 "additionalProperties": { 1727 "$ref": "#/definitions/eventqualities" 1728 } 1729 }, 1730 "sdfData": { 1731 "type": "object", 1732 "additionalProperties": { 1733 "$ref": "#/definitions/dataqualities" 1734 } 1735 } 1736 }, 1737 - "additionalProperties": false 1738 + "additionalProperties": { 1739 + } 1740 }, 1741 "sdfinfo": { 1742 "type": "object", 1743 "required": [ 1744 "title", 1745 "version", 1746 "copyright", 1747 "license" 1748 ], 1749 "properties": { 1750 "title": { 1751 "type": "string" 1752 }, 1753 "version": { 1754 "type": "string" 1755 }, 1756 "copyright": { 1757 "type": "string" 1758 }, 1759 "license": { 1760 "type": "string" 1761 } 1762 }, 1763 - "additionalProperties": false 1764 + "additionalProperties": { 1765 + } 1766 }, 1767 "thingqualities": { 1768 "type": "object", 1769 "properties": { 1770 "description": { 1771 "type": "string" 1773 }, 1774 "label": { 1775 "type": "string" 1776 }, 1777 "$comment": { 1778 "type": "string" 1779 }, 1780 "sdfRef": { 1781 "$ref": "#/definitions/sdf-pointer" 1782 }, 1783 "sdfRequired": { 1784 "$ref": "#/definitions/pointer-list" 1785 }, 1786 "sdfObject": { 1787 "type": "object", 1788 "additionalProperties": { 1789 "$ref": "#/definitions/objectqualities" 1790 } 1791 }, 1792 "sdfThing": { 1793 "type": "object", 1794 "additionalProperties": { 1795 "$ref": "#/definitions/thingqualities" 1796 } 1797 } 1798 }, 1799 - "additionalProperties": false 1800 + "additionalProperties": { 1801 + } 1802 }, 1803 "sdf-pointer": { 1804 "type": "string" 1805 }, 1806 "pointer-list": { 1807 "type": "array", 1808 "items": { 1809 "$ref": "#/definitions/sdf-pointer" 1810 } 1811 }, 1812 "objectqualities": { 1813 "type": "object", 1814 "properties": { 1815 "description": { 1816 "type": "string" 1817 }, 1818 "label": { 1819 "type": "string" 1820 }, 1821 "$comment": { 1822 "type": "string" 1823 }, 1824 "sdfRef": { 1825 "$ref": "#/definitions/sdf-pointer" 1826 }, 1827 "sdfRequired": { 1828 "$ref": "#/definitions/pointer-list" 1829 }, 1830 "sdfProperty": { 1831 "type": "object", 1832 "additionalProperties": { 1833 "$ref": "#/definitions/propertyqualities" 1834 } 1835 }, 1836 "sdfAction": { 1837 "type": "object", 1838 "additionalProperties": { 1839 "$ref": "#/definitions/actionqualities" 1840 } 1841 }, 1842 "sdfEvent": { 1843 "type": "object", 1844 "additionalProperties": { 1845 "$ref": "#/definitions/eventqualities" 1846 } 1847 }, 1848 "sdfData": { 1849 "type": "object", 1850 "additionalProperties": { 1851 "$ref": "#/definitions/dataqualities" 1852 } 1853 } 1854 }, 1855 - "additionalProperties": false 1856 + "additionalProperties": { 1857 + } 1858 }, 1859 "propertyqualities": { 1860 "$ref": "#/definitions/dataqualities" 1861 }, 1862 "dataqualities": { 1863 "anyOf": [ 1864 { 1865 "type": "object", 1866 "properties": { 1867 "type": { 1868 "type": "string", 1869 "enum": [ 1870 "number", 1871 "string", 1872 "boolean", 1873 "integer", 1874 "array" 1875 ] 1876 }, 1877 "enum": { 1878 "type": "array", 1879 "items": { 1880 - "type": "string" 1881 + "$ref": "#/definitions/allowed-types" 1882 }, 1883 "minItems": 1 1884 }, 1885 "const": { 1886 "$ref": "#/definitions/allowed-types" 1887 }, 1888 "default": { 1889 "$ref": "#/definitions/allowed-types" 1890 }, 1891 "minimum": { 1892 "type": "number" 1893 }, 1894 "maximum": { 1895 "type": "number" 1896 }, 1897 "exclusiveMinimum": { 1898 "anyOf": [ 1899 { 1900 "type": "boolean" 1901 }, 1902 { 1903 "type": "number" 1904 } 1905 ] 1906 }, 1907 "exclusiveMaximum": { 1908 "anyOf": [ 1909 { 1910 "type": "boolean" 1911 }, 1912 { 1913 "type": "number" 1914 } 1915 ] 1916 }, 1917 "multipleOf": { 1918 "type": "number" 1919 }, 1920 "minLength": { 1921 "type": "number" 1922 }, 1923 "maxLength": { 1924 "type": "number" 1925 }, 1926 "pattern": { 1927 "type": "string" 1928 }, 1929 "format": { 1930 - "type": "string", 1931 - "enum": [ 1932 - "date-time", 1933 - "date", 1934 - "time", 1935 - "uri", 1936 - "uri-reference", 1937 - "uuid" 1938 + "anyOf": [ 1939 + { 1940 + "type": "string", 1941 + "const": "date-time" 1942 + }, 1943 + { 1944 + "type": "string", 1945 + "const": "date" 1946 + }, 1947 + { 1948 + "type": "string", 1949 + "const": "time" 1950 + }, 1951 + { 1952 + "type": "string", 1953 + "const": "uri" 1954 + }, 1955 + { 1956 + "type": "string", 1957 + "const": "uri-reference" 1958 + }, 1959 + { 1960 + "type": "string", 1961 + "const": "uuid" 1962 + }, 1963 + { 1964 + "type": "string" 1965 + } 1966 ] 1967 }, 1968 "minItems": { 1969 "type": "number" 1970 }, 1971 "maxItems": { 1972 "type": "number" 1973 }, 1974 "uniqueItems": { 1975 "type": "boolean" 1976 }, 1977 "items": { 1978 "anyOf": [ 1979 { 1980 "type": "object", 1981 "properties": { 1982 "type": { 1983 "type": "string", 1984 "enum": [ 1985 "number", 1986 "string", 1987 "boolean", 1988 "integer" 1989 ] 1990 }, 1991 "sdfRef": { 1992 "$ref": "#/definitions/sdf-pointer" 1993 }, 1994 "description": { 1995 "type": "string" 1996 }, 1997 "$comment": { 1998 "type": "string" 1999 }, 2000 "minimum": { 2001 "type": "number" 2002 }, 2003 "maximum": { 2004 "type": "number" 2005 }, 2006 "enum": { 2007 "type": "array", 2008 - "items": { 2009 - "type": "string" 2010 - }, 2011 "minItems": 1 2012 }, 2013 "format": { 2014 "type": "string" 2015 }, 2016 "minLength": { 2017 "type": "number" 2018 }, 2019 "maxLength": { 2020 "type": "number" 2021 } 2022 }, 2023 - "additionalProperties": false 2024 + "additionalProperties": { 2025 + } 2026 }, 2027 { 2028 "type": "object", 2029 "properties": { 2030 "type": { 2031 "type": "string", 2032 "const": "object" 2033 }, 2034 "required": { 2035 "type": "array", 2036 "items": { 2037 "type": "string" 2038 }, 2039 "minItems": 1 2040 }, 2041 "properties": { 2042 "type": "object", 2043 "additionalProperties": { 2044 "$ref": "#/definitions/dataqualities" 2045 } 2046 }, 2047 "sdfRef": { 2048 "$ref": "#/definitions/sdf-pointer" 2049 }, 2050 "description": { 2051 "type": "string" 2052 }, 2053 "$comment": { 2054 "type": "string" 2055 }, 2056 "minimum": { 2057 "type": "number" 2058 }, 2059 "maximum": { 2060 "type": "number" 2062 }, 2063 "enum": { 2064 "type": "array", 2065 - "items": { 2066 - "type": "string" 2067 - }, 2068 "minItems": 1 2069 }, 2070 "format": { 2071 "type": "string" 2072 }, 2073 "minLength": { 2074 "type": "number" 2075 }, 2076 "maxLength": { 2077 "type": "number" 2078 } 2079 }, 2080 - "additionalProperties": false 2081 + "additionalProperties": { 2082 + } 2083 }, 2084 { 2085 "type": "object", 2086 "properties": { 2087 "sdfChoice": { 2088 "type": "object", 2089 "additionalProperties": { 2090 "$ref": "#/definitions/dataqualities" 2091 } 2092 }, 2093 "sdfRef": { 2094 "$ref": "#/definitions/sdf-pointer" 2095 }, 2096 "description": { 2097 "type": "string" 2098 }, 2099 "$comment": { 2100 "type": "string" 2101 }, 2102 "minimum": { 2103 "type": "number" 2104 }, 2105 "maximum": { 2106 "type": "number" 2107 }, 2108 "enum": { 2109 "type": "array", 2111 - "items": { 2112 - "type": "string" 2113 - }, 2114 "minItems": 1 2115 }, 2116 "format": { 2117 "type": "string" 2118 }, 2119 "minLength": { 2120 "type": "number" 2121 }, 2122 "maxLength": { 2123 "type": "number" 2124 } 2125 }, 2126 - "additionalProperties": false 2127 + "additionalProperties": { 2128 + } 2129 + }, 2130 + { 2131 + "type": "object", 2132 + "properties": { 2133 + "type": { 2134 + "type": "string" 2135 + }, 2136 + "sdfRef": { 2137 + "$ref": "#/definitions/sdf-pointer" 2138 + }, 2139 + "description": { 2140 + "type": "string" 2141 + }, 2142 + "$comment": { 2143 + "type": "string" 2144 + }, 2145 + "minimum": { 2146 + "type": "number" 2147 + }, 2148 + "maximum": { 2149 + "type": "number" 2150 + }, 2151 + "enum": { 2152 + "type": "array", 2153 + "minItems": 1 2154 + }, 2155 + "format": { 2156 + "type": "string" 2157 + }, 2158 + "minLength": { 2159 + "type": "number" 2160 + }, 2161 + "maxLength": { 2162 + "type": "number" 2163 + } 2164 + }, 2165 + "additionalProperties": { 2166 + } 2167 } 2168 ] 2169 }, 2170 "description": { 2171 "type": "string" 2172 }, 2173 "label": { 2174 "type": "string" 2175 }, 2176 "$comment": { 2177 "type": "string" 2178 }, 2179 "sdfRef": { 2180 "$ref": "#/definitions/sdf-pointer" 2181 }, 2182 "sdfRequired": { 2183 "$ref": "#/definitions/pointer-list" 2184 }, 2185 + "units": { 2186 + "type": "string" 2187 + }, 2188 "unit": { 2189 "type": "string" 2190 }, 2191 "scaleMinimum": { 2192 "type": "number" 2193 }, 2194 "scaleMaximum": { 2195 "type": "number" 2196 }, 2197 "observable": { 2198 "type": "boolean" 2199 }, 2200 "readable": { 2201 "type": "boolean" 2202 }, 2203 "writable": { 2204 "type": "boolean" 2205 }, 2206 "nullable": { 2207 "type": "boolean" 2208 }, 2209 + "subtype": { 2210 + "anyOf": [ 2211 + { 2212 + "type": "string", 2213 + "const": "byte-string" 2214 + }, 2215 + { 2216 + "type": "string", 2217 + "const": "unix-time" 2218 + }, 2219 + { 2220 + "type": "string" 2221 + } 2222 + ] 2223 + }, 2224 "sdfType": { 2225 - "type": "string", 2226 - "enum": [ 2227 - "byte-string", 2228 - "unix-time" 2229 + "anyOf": [ 2230 + { 2231 + "type": "string", 2232 + "const": "byte-string" 2233 + }, 2234 + { 2235 + "type": "string", 2236 + "const": "unix-time" 2237 + }, 2238 + { 2239 + "type": "string" 2240 + } 2241 ] 2242 }, 2243 "contentFormat": { 2244 "type": "string" 2245 } 2246 }, 2247 - "additionalProperties": false 2248 + "additionalProperties": { 2249 + } 2250 }, 2251 { 2252 "type": "object", 2253 "properties": { 2254 "type": { 2255 "type": "string", 2256 "const": "object" 2257 }, 2258 "required": { 2259 "type": "array", 2260 "items": { 2261 "type": "string" 2262 }, 2263 "minItems": 1 2264 }, 2265 "properties": { 2266 "type": "object", 2267 "additionalProperties": { 2268 "$ref": "#/definitions/dataqualities" 2269 } 2270 }, 2271 "enum": { 2272 "type": "array", 2273 "items": { 2274 - "type": "string" 2275 + "$ref": "#/definitions/allowed-types" 2276 }, 2277 "minItems": 1 2278 }, 2279 "const": { 2280 "$ref": "#/definitions/allowed-types" 2281 }, 2282 "default": { 2283 "$ref": "#/definitions/allowed-types" 2284 }, 2285 "minimum": { 2286 "type": "number" 2287 }, 2288 "maximum": { 2289 "type": "number" 2290 }, 2291 "exclusiveMinimum": { 2292 "anyOf": [ 2293 { 2294 "type": "boolean" 2295 }, 2296 { 2297 "type": "number" 2298 } 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" 2400 }, 2401 "enum": { 2402 "type": "array", 2403 - "items": { 2404 - "type": "string" 2405 - }, 2406 "minItems": 1 2407 }, 2408 "format": { 2409 "type": "string" 2410 }, 2411 "minLength": { 2412 "type": "number" 2413 }, 2414 "maxLength": { 2415 "type": "number" 2416 } 2417 }, 2418 - "additionalProperties": false 2419 + "additionalProperties": { 2420 + } 2421 }, 2422 { 2423 "type": "object", 2424 "properties": { 2425 "type": { 2426 "type": "string", 2427 "const": "object" 2428 }, 2429 "required": { 2430 "type": "array", 2431 "items": { 2432 "type": "string" 2433 }, 2434 "minItems": 1 2435 }, 2436 "properties": { 2437 "type": "object", 2438 "additionalProperties": { 2439 "$ref": "#/definitions/dataqualities" 2440 } 2441 }, 2442 "sdfRef": { 2443 "$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" 2492 }, 2493 "$comment": { 2494 "type": "string" 2495 }, 2496 "minimum": { 2497 "type": "number" 2498 }, 2499 "maximum": { 2500 "type": "number" 2501 }, 2502 "enum": { 2503 "type": "array", 2504 - "items": { 2505 - "type": "string" 2506 - }, 2507 "minItems": 1 2508 }, 2509 "format": { 2510 "type": "string" 2511 }, 2512 "minLength": { 2513 "type": "number" 2514 }, 2515 "maxLength": { 2516 "type": "number" 2517 } 2518 }, 2519 - "additionalProperties": false 2520 + "additionalProperties": { 2521 + } 2522 + }, 2523 + { 2524 + "type": "object", 2525 + "properties": { 2526 + "type": { 2527 + "type": "string" 2528 + }, 2529 + "sdfRef": { 2530 + "$ref": "#/definitions/sdf-pointer" 2531 + }, 2532 + "description": { 2533 + "type": "string" 2534 + }, 2535 + "$comment": { 2536 + "type": "string" 2537 + }, 2538 + "minimum": { 2539 + "type": "number" 2540 + }, 2541 + "maximum": { 2542 + "type": "number" 2543 + }, 2544 + "enum": { 2545 + "type": "array", 2546 + "minItems": 1 2547 + }, 2548 + "format": { 2549 + "type": "string" 2550 + }, 2551 + "minLength": { 2552 + "type": "number" 2553 + }, 2554 + "maxLength": { 2555 + "type": "number" 2556 + } 2557 + }, 2558 + "additionalProperties": { 2559 + } 2560 } 2561 ] 2562 }, 2563 "description": { 2564 "type": "string" 2565 }, 2566 "label": { 2567 "type": "string" 2568 }, 2569 "$comment": { 2570 "type": "string" 2571 }, 2572 "sdfRef": { 2573 "$ref": "#/definitions/sdf-pointer" 2574 }, 2575 "sdfRequired": { 2576 "$ref": "#/definitions/pointer-list" 2577 }, 2578 + "units": { 2579 + "type": "string" 2580 + }, 2581 "unit": { 2582 "type": "string" 2583 }, 2584 "scaleMinimum": { 2585 "type": "number" 2586 }, 2587 "scaleMaximum": { 2588 "type": "number" 2589 }, 2590 "observable": { 2591 "type": "boolean" 2593 }, 2594 "readable": { 2595 "type": "boolean" 2596 }, 2597 "writable": { 2598 "type": "boolean" 2599 }, 2600 "nullable": { 2601 "type": "boolean" 2602 }, 2603 + "subtype": { 2604 + "anyOf": [ 2605 + { 2606 + "type": "string", 2607 + "const": "byte-string" 2608 + }, 2609 + { 2610 + "type": "string", 2611 + "const": "unix-time" 2612 + }, 2613 + { 2614 + "type": "string" 2615 + } 2616 + ] 2617 + }, 2618 "sdfType": { 2619 - "type": "string", 2620 - "enum": [ 2621 - "byte-string", 2622 - "unix-time" 2623 + "anyOf": [ 2624 + { 2625 + "type": "string", 2626 + "const": "byte-string" 2627 + }, 2628 + { 2629 + "type": "string", 2630 + "const": "unix-time" 2631 + }, 2632 + { 2633 + "type": "string" 2634 + } 2635 ] 2636 }, 2637 "contentFormat": { 2638 "type": "string" 2639 } 2640 }, 2642 - "additionalProperties": false 2643 + "additionalProperties": { 2644 + } 2645 }, 2646 { 2647 "type": "object", 2648 "properties": { 2649 "sdfChoice": { 2650 "type": "object", 2651 "additionalProperties": { 2652 "$ref": "#/definitions/dataqualities" 2653 } 2654 }, 2655 "enum": { 2656 "type": "array", 2657 "items": { 2658 - "type": "string" 2659 + "$ref": "#/definitions/allowed-types" 2660 }, 2661 "minItems": 1 2662 }, 2663 "const": { 2664 "$ref": "#/definitions/allowed-types" 2665 }, 2666 "default": { 2667 "$ref": "#/definitions/allowed-types" 2668 }, 2669 "minimum": { 2670 "type": "number" 2671 }, 2672 "maximum": { 2673 "type": "number" 2674 }, 2675 "exclusiveMinimum": { 2676 "anyOf": [ 2677 { 2678 "type": "boolean" 2679 }, 2680 { 2681 "type": "number" 2682 } 2683 ] 2684 }, 2685 "exclusiveMaximum": { 2686 "anyOf": [ 2687 { 2688 "type": "boolean" 2689 }, 2690 { 2691 "type": "number" 2692 } 2693 ] 2694 }, 2695 "multipleOf": { 2696 "type": "number" 2697 }, 2698 "minLength": { 2699 "type": "number" 2700 }, 2701 "maxLength": { 2702 "type": "number" 2703 }, 2704 "pattern": { 2705 "type": "string" 2706 }, 2707 "format": { 2708 - "type": "string", 2709 - "enum": [ 2710 - "date-time", 2711 - "date", 2712 - "time", 2713 - "uri", 2714 - "uri-reference", 2715 - "uuid" 2716 + "anyOf": [ 2717 + { 2718 + "type": "string", 2719 + "const": "date-time" 2720 + }, 2721 + { 2722 + "type": "string", 2723 + "const": "date" 2724 + }, 2725 + { 2726 + "type": "string", 2727 + "const": "time" 2728 + }, 2729 + { 2730 + "type": "string", 2731 + "const": "uri" 2732 + }, 2733 + { 2734 + "type": "string", 2735 + "const": "uri-reference" 2736 + }, 2737 + { 2738 + "type": "string", 2739 + "const": "uuid" 2740 + }, 2741 + { 2742 + "type": "string" 2743 + } 2744 ] 2745 }, 2746 "minItems": { 2747 "type": "number" 2748 }, 2749 "maxItems": { 2750 "type": "number" 2751 }, 2752 "uniqueItems": { 2753 "type": "boolean" 2754 }, 2755 "items": { 2756 "anyOf": [ 2757 { 2758 "type": "object", 2759 "properties": { 2760 "type": { 2761 "type": "string", 2762 "enum": [ 2763 "number", 2764 "string", 2765 "boolean", 2766 "integer" 2767 ] 2768 }, 2769 "sdfRef": { 2770 "$ref": "#/definitions/sdf-pointer" 2771 }, 2772 "description": { 2773 "type": "string" 2774 }, 2775 "$comment": { 2776 "type": "string" 2777 }, 2778 "minimum": { 2779 "type": "number" 2780 }, 2781 "maximum": { 2782 "type": "number" 2783 }, 2784 "enum": { 2785 "type": "array", 2787 - "items": { 2788 - "type": "string" 2789 - }, 2790 "minItems": 1 2791 }, 2792 "format": { 2793 "type": "string" 2794 }, 2795 "minLength": { 2796 "type": "number" 2797 }, 2798 "maxLength": { 2799 "type": "number" 2800 } 2801 }, 2802 - "additionalProperties": false 2803 + "additionalProperties": { 2804 + } 2805 }, 2806 { 2807 "type": "object", 2808 "properties": { 2809 "type": { 2810 "type": "string", 2811 "const": "object" 2812 }, 2813 "required": { 2814 "type": "array", 2815 "items": { 2816 "type": "string" 2817 }, 2818 "minItems": 1 2819 }, 2820 "properties": { 2821 "type": "object", 2822 "additionalProperties": { 2823 "$ref": "#/definitions/dataqualities" 2824 } 2825 }, 2826 "sdfRef": { 2827 "$ref": "#/definitions/sdf-pointer" 2828 }, 2829 "description": { 2830 "type": "string" 2831 }, 2832 "$comment": { 2833 "type": "string" 2834 }, 2835 "minimum": { 2836 "type": "number" 2837 }, 2838 "maximum": { 2839 "type": "number" 2840 }, 2841 "enum": { 2842 "type": "array", 2843 - "items": { 2844 - "type": "string" 2845 - }, 2846 "minItems": 1 2847 }, 2848 "format": { 2849 "type": "string" 2850 }, 2851 "minLength": { 2852 "type": "number" 2853 }, 2854 "maxLength": { 2855 "type": "number" 2856 } 2857 }, 2858 - "additionalProperties": false 2859 + "additionalProperties": { 2860 + } 2861 }, 2862 { 2863 "type": "object", 2864 "properties": { 2865 "sdfChoice": { 2866 "type": "object", 2867 "additionalProperties": { 2868 "$ref": "#/definitions/dataqualities" 2869 } 2870 }, 2871 "sdfRef": { 2872 "$ref": "#/definitions/sdf-pointer" 2873 }, 2874 "description": { 2875 "type": "string" 2876 }, 2877 "$comment": { 2878 "type": "string" 2879 }, 2880 "minimum": { 2881 "type": "number" 2882 }, 2883 "maximum": { 2884 "type": "number" 2885 }, 2886 "enum": { 2887 "type": "array", 2888 - "items": { 2889 - "type": "string" 2890 - }, 2891 "minItems": 1 2892 }, 2893 "format": { 2894 "type": "string" 2895 }, 2896 "minLength": { 2897 "type": "number" 2898 }, 2899 "maxLength": { 2900 "type": "number" 2901 } 2902 }, 2903 - "additionalProperties": false 2904 + "additionalProperties": { 2905 + } 2906 + }, 2907 + { 2908 + "type": "object", 2909 + "properties": { 2910 + "type": { 2911 + "type": "string" 2912 + }, 2913 + "sdfRef": { 2914 + "$ref": "#/definitions/sdf-pointer" 2915 + }, 2916 + "description": { 2917 + "type": "string" 2918 + }, 2919 + "$comment": { 2920 + "type": "string" 2921 + }, 2922 + "minimum": { 2923 + "type": "number" 2924 + }, 2925 + "maximum": { 2926 + "type": "number" 2927 + }, 2928 + "enum": { 2929 + "type": "array", 2930 + "minItems": 1 2931 + }, 2932 + "format": { 2933 + "type": "string" 2934 + }, 2935 + "minLength": { 2936 + "type": "number" 2937 + }, 2938 + "maxLength": { 2939 + "type": "number" 2940 + } 2941 + }, 2942 + "additionalProperties": { 2943 + } 2944 } 2945 ] 2946 }, 2947 "description": { 2948 "type": "string" 2949 }, 2950 "label": { 2951 "type": "string" 2952 }, 2953 "$comment": { 2954 "type": "string" 2955 }, 2956 "sdfRef": { 2957 "$ref": "#/definitions/sdf-pointer" 2958 }, 2959 "sdfRequired": { 2960 "$ref": "#/definitions/pointer-list" 2961 }, 2962 + "units": { 2963 + "type": "string" 2964 + }, 2965 "unit": { 2966 "type": "string" 2967 }, 2968 "scaleMinimum": { 2969 "type": "number" 2970 }, 2971 "scaleMaximum": { 2972 "type": "number" 2973 }, 2974 "observable": { 2975 "type": "boolean" 2976 }, 2977 "readable": { 2978 "type": "boolean" 2980 }, 2981 "writable": { 2982 "type": "boolean" 2983 }, 2984 "nullable": { 2985 "type": "boolean" 2986 }, 2987 - "sdfType": { 2988 - "type": "string", 2989 - "enum": [ 2990 - "byte-string", 2991 - "unix-time" 2992 + "subtype": { 2993 + "anyOf": [ 2994 + { 2995 + "type": "string", 2996 + "const": "byte-string" 2997 + }, 2998 + { 2999 + "type": "string", 3000 + "const": "unix-time" 3001 + }, 3002 + { 3003 + "type": "string" 3004 + } 3005 ] 3006 }, 3007 - "contentFormat": { 3008 - "type": "string" 3009 - } 3010 - }, 3011 - "additionalProperties": false 3012 - } 3013 - ] 3014 - }, 3015 + "sdfType": { 3016 + "anyOf": [ 3017 + { 3018 + "type": "string", 3019 + "const": "byte-string" 3020 + }, 3021 + { 3022 + "type": "string", 3023 + "const": "unix-time" 3024 + }, 3025 + { 3026 + "type": "string" 3027 + } 3028 + ] 3029 + }, 3030 + "contentFormat": { 3031 + "type": "string" 3032 + } 3033 + }, 3034 + "additionalProperties": { 3035 + } 3036 + }, 3037 + { 3038 + "type": "object", 3039 + "properties": { 3040 + "type": { 3041 + "type": "string" 3042 + }, 3043 + "enum": { 3044 + "type": "array", 3045 + "items": { 3046 + "$ref": "#/definitions/allowed-types" 3047 + }, 3048 + "minItems": 1 3049 + }, 3050 + "const": { 3051 + "$ref": "#/definitions/allowed-types" 3052 + }, 3053 + "default": { 3054 + "$ref": "#/definitions/allowed-types" 3055 + }, 3056 + "minimum": { 3057 + "type": "number" 3058 + }, 3059 + "maximum": { 3060 + "type": "number" 3061 + }, 3062 + "exclusiveMinimum": { 3063 + "anyOf": [ 3064 + { 3065 + "type": "boolean" 3066 + }, 3067 + { 3068 + "type": "number" 3069 + } 3070 + ] 3071 + }, 3072 + "exclusiveMaximum": { 3073 + "anyOf": [ 3074 + { 3075 + "type": "boolean" 3076 + }, 3077 + { 3078 + "type": "number" 3079 + } 3080 + ] 3081 + }, 3082 + "multipleOf": { 3083 + "type": "number" 3084 + }, 3085 + "minLength": { 3086 + "type": "number" 3087 + }, 3088 + "maxLength": { 3089 + "type": "number" 3090 + }, 3091 + "pattern": { 3092 + "type": "string" 3093 + }, 3094 + "format": { 3095 + "anyOf": [ 3096 + { 3097 + "type": "string", 3098 + "const": "date-time" 3099 + }, 3100 + { 3101 + "type": "string", 3102 + "const": "date" 3103 + }, 3104 + { 3105 + "type": "string", 3106 + "const": "time" 3107 + }, 3108 + { 3109 + "type": "string", 3110 + "const": "uri" 3111 + }, 3112 + { 3113 + "type": "string", 3114 + "const": "uri-reference" 3115 + }, 3116 + { 3117 + "type": "string", 3118 + "const": "uuid" 3119 + }, 3120 + { 3121 + "type": "string" 3122 + } 3123 + ] 3124 + }, 3125 + "minItems": { 3126 + "type": "number" 3127 + }, 3128 + "maxItems": { 3129 + "type": "number" 3130 + }, 3131 + "uniqueItems": { 3132 + "type": "boolean" 3133 + }, 3134 + "items": { 3135 + "anyOf": [ 3136 + { 3137 + "type": "object", 3138 + "properties": { 3139 + "type": { 3140 + "type": "string", 3141 + "enum": [ 3142 + "number", 3143 + "string", 3144 + "boolean", 3145 + "integer" 3146 + ] 3147 + }, 3148 + "sdfRef": { 3149 + "$ref": "#/definitions/sdf-pointer" 3150 + }, 3151 + "description": { 3152 + "type": "string" 3153 + }, 3154 + "$comment": { 3155 + "type": "string" 3156 + }, 3157 + "minimum": { 3158 + "type": "number" 3159 + }, 3160 + "maximum": { 3161 + "type": "number" 3162 + }, 3163 + "enum": { 3164 + "type": "array", 3165 + "minItems": 1 3166 + }, 3167 + "format": { 3168 + "type": "string" 3169 + }, 3170 + "minLength": { 3171 + "type": "number" 3172 + }, 3173 + "maxLength": { 3174 + "type": "number" 3175 + } 3176 + }, 3177 + "additionalProperties": { 3178 + } 3179 + }, 3180 + { 3181 + "type": "object", 3182 + "properties": { 3183 + "type": { 3184 + "type": "string", 3185 + "const": "object" 3186 + }, 3187 + "required": { 3188 + "type": "array", 3189 + "items": { 3190 + "type": "string" 3191 + }, 3192 + "minItems": 1 3193 + }, 3194 + "properties": { 3195 + "type": "object", 3196 + "additionalProperties": { 3197 + "$ref": "#/definitions/dataqualities" 3198 + } 3199 + }, 3200 + "sdfRef": { 3201 + "$ref": "#/definitions/sdf-pointer" 3202 + }, 3203 + "description": { 3204 + "type": "string" 3205 + }, 3206 + "$comment": { 3207 + "type": "string" 3208 + }, 3209 + "minimum": { 3210 + "type": "number" 3211 + }, 3212 + "maximum": { 3213 + "type": "number" 3214 + }, 3215 + "enum": { 3216 + "type": "array", 3217 + "minItems": 1 3218 + }, 3219 + "format": { 3220 + "type": "string" 3221 + }, 3222 + "minLength": { 3223 + "type": "number" 3224 + }, 3225 + "maxLength": { 3226 + "type": "number" 3227 + } 3228 + }, 3229 + "additionalProperties": { 3230 + } 3231 + }, 3232 + { 3233 + "type": "object", 3234 + "properties": { 3235 + "sdfChoice": { 3236 + "type": "object", 3237 + "additionalProperties": { 3238 + "$ref": "#/definitions/dataqualities" 3239 + } 3240 + }, 3241 + "sdfRef": { 3242 + "$ref": "#/definitions/sdf-pointer" 3243 + }, 3244 + "description": { 3245 + "type": "string" 3246 + }, 3247 + "$comment": { 3248 + "type": "string" 3249 + }, 3250 + "minimum": { 3251 + "type": "number" 3252 + }, 3253 + "maximum": { 3254 + "type": "number" 3255 + }, 3256 + "enum": { 3257 + "type": "array", 3258 + "minItems": 1 3259 + }, 3260 + "format": { 3261 + "type": "string" 3262 + }, 3263 + "minLength": { 3264 + "type": "number" 3265 + }, 3266 + "maxLength": { 3267 + "type": "number" 3268 + } 3269 + }, 3270 + "additionalProperties": { 3271 + } 3272 + }, 3273 + { 3274 + "type": "object", 3275 + "properties": { 3276 + "type": { 3277 + "type": "string" 3278 + }, 3279 + "sdfRef": { 3280 + "$ref": "#/definitions/sdf-pointer" 3281 + }, 3282 + "description": { 3283 + "type": "string" 3284 + }, 3285 + "$comment": { 3286 + "type": "string" 3287 + }, 3288 + "minimum": { 3289 + "type": "number" 3290 + }, 3291 + "maximum": { 3292 + "type": "number" 3293 + }, 3294 + "enum": { 3295 + "type": "array", 3296 + "minItems": 1 3297 + }, 3298 + "format": { 3299 + "type": "string" 3300 + }, 3301 + "minLength": { 3302 + "type": "number" 3303 + }, 3304 + "maxLength": { 3305 + "type": "number" 3306 + } 3307 + }, 3308 + "additionalProperties": { 3309 + } 3310 + } 3311 + ] 3312 + }, 3313 + "description": { 3314 + "type": "string" 3315 + }, 3316 + "label": { 3317 + "type": "string" 3318 + }, 3319 + "$comment": { 3320 + "type": "string" 3321 + }, 3322 + "sdfRef": { 3323 + "$ref": "#/definitions/sdf-pointer" 3324 + }, 3325 + "sdfRequired": { 3326 + "$ref": "#/definitions/pointer-list" 3327 + }, 3328 + "units": { 3329 + "type": "string" 3330 + }, 3331 + "unit": { 3332 + "type": "string" 3333 + }, 3334 + "scaleMinimum": { 3335 + "type": "number" 3336 + }, 3337 + "scaleMaximum": { 3338 + "type": "number" 3339 + }, 3340 + "observable": { 3341 + "type": "boolean" 3342 + }, 3343 + "readable": { 3344 + "type": "boolean" 3345 + }, 3346 + "writable": { 3347 + "type": "boolean" 3348 + }, 3349 + "nullable": { 3350 + "type": "boolean" 3351 + }, 3352 + "subtype": { 3353 + "anyOf": [ 3354 + { 3355 + "type": "string", 3356 + "const": "byte-string" 3357 + }, 3358 + { 3359 + "type": "string", 3360 + "const": "unix-time" 3361 + }, 3362 + { 3363 + "type": "string" 3364 + } 3365 + ] 3366 + }, 3367 + "sdfType": { 3368 + "anyOf": [ 3369 + { 3370 + "type": "string", 3371 + "const": "byte-string" 3372 + }, 3373 + { 3374 + "type": "string", 3375 + "const": "unix-time" 3376 + }, 3377 + { 3378 + "type": "string" 3379 + } 3380 + ] 3381 + }, 3382 + "contentFormat": { 3383 + "type": "string" 3384 + } 3385 + }, 3386 + "additionalProperties": { 3387 + } 3388 + } 3389 + ] 3390 + }, 3391 "allowed-types": { 3392 "anyOf": [ 3393 { 3394 "type": "number" 3395 }, 3396 { 3397 "type": "string" 3398 }, 3399 { 3400 "type": "boolean" 3401 }, 3402 { 3403 "type": "null" 3404 }, 3405 { 3406 "type": "array", 3407 "items": { 3408 "type": "number" 3409 } 3410 }, 3411 { 3412 "type": "array", 3413 "items": { 3414 "type": "string" 3415 } 3416 }, 3417 { 3418 "type": "array", 3419 "items": { 3420 "type": "boolean" 3421 } 3422 }, 3423 { 3424 "type": "object", 3425 "additionalProperties": { 3426 } 3427 + }, 3428 + { 3429 } 3430 ] 3431 }, 3432 "actionqualities": { 3433 "type": "object", 3434 "properties": { 3435 "description": { 3436 "type": "string" 3437 }, 3438 "label": { 3439 "type": "string" 3440 }, 3441 "$comment": { 3442 "type": "string" 3443 }, 3444 "sdfRef": { 3445 "$ref": "#/definitions/sdf-pointer" 3446 }, 3447 "sdfRequired": { 3448 "$ref": "#/definitions/pointer-list" 3449 }, 3450 "sdfInputData": { 3451 "$ref": "#/definitions/parameter-list" 3452 }, 3453 + "sdfRequiredInputData": { 3454 + "$ref": "#/definitions/pointer-list" 3455 + }, 3456 "sdfOutputData": { 3457 "$ref": "#/definitions/parameter-list" 3458 }, 3459 "sdfData": { 3460 "type": "object", 3461 "additionalProperties": { 3462 "$ref": "#/definitions/dataqualities" 3463 } 3464 } 3465 }, 3466 - "additionalProperties": false 3467 + "additionalProperties": { 3468 + } 3469 }, 3470 "parameter-list": { 3471 - "$ref": "#/definitions/dataqualities" 3472 + "anyOf": [ 3473 + { 3474 + "$ref": "#/definitions/pointer-list" 3475 + }, 3476 + { 3477 + "$ref": "#/definitions/dataqualities" 3478 + } 3479 + ] 3480 }, 3481 "eventqualities": { 3482 "type": "object", 3483 "properties": { 3484 "description": { 3485 "type": "string" 3486 }, 3487 "label": { 3488 "type": "string" 3489 }, 3490 "$comment": { 3491 "type": "string" 3492 }, 3493 "sdfRef": { 3494 "$ref": "#/definitions/sdf-pointer" 3495 }, 3496 "sdfRequired": { 3497 "$ref": "#/definitions/pointer-list" 3498 }, 3499 "sdfOutputData": { 3500 "$ref": "#/definitions/parameter-list" 3501 }, 3502 "sdfData": { 3503 "type": "object", 3504 "additionalProperties": { 3505 "$ref": "#/definitions/dataqualities" 3506 } 3507 } 3509 }, 3510 - "additionalProperties": false 3511 + "additionalProperties": { 3512 + } 3513 }, 3514 "productqualities": { 3515 "$ref": "#/definitions/thingqualities" 3516 } 3517 } 3518 } 3520 Acknowledgements 3522 This draft is based on "sdf.md" and "sdf-schema.json" in the old one- 3523 data-model "language" repository, as well as Ari Keranen's "alt- 3524 schema" from the Ericsson Research "ipso-odm" repository (which is 3525 now under subdirectory "sdflint" in the one-data model "tools" 3526 repository). 3528 Contributors 3530 Ari Keränen 3531 Ericsson 3532 FI-02420 Jorvas 3533 Finland 3535 Email: ari.keranen@ericsson.com 3537 Wouter van der Beek 3538 Cascoda Ltd. 3539 Threefield House 3540 Threefield Lane 3541 Southampton 3542 United Kingdom 3544 Email: w.vanderbeek@cascoda.com 3546 Authors' Addresses 3548 Michael Koster (editor) 3549 Dogtiger Labs 3550 524 H Street 3551 Antioch, CA, 94509 3552 United States of America 3554 Phone: +1-707-502-5136 3555 Email: michaeljohnkoster@gmail.com 3557 Carsten Bormann (editor) 3558 Universität Bremen TZI 3559 Postfach 330440 3560 D-28359 Bremen 3561 Germany 3563 Phone: +49-421-218-63921 3564 Email: cabo@tzi.org