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