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