-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathsdf.v2v3-23.xml
More file actions
6894 lines (6848 loc) · 305 KB
/
sdf.v2v3-23.xml
File metadata and controls
6894 lines (6848 loc) · 305 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
<!ENTITY nbsp " ">
<!ENTITY zwsp "​">
<!ENTITY nbhy "‑">
<!ENTITY wj "⁠">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.26 (Ruby 3.4.1) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ietf-asdf-sdf-23" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
<!-- xml2rfc v2v3 conversion 3.28.0 -->
<?v3xml2rfc table_borders="light"?>
<front>
<title abbrev="SDF (Semantic Definition Format)">Semantic Definition Format (SDF) for Data and Interactions of Things</title>
<seriesInfo name="Internet-Draft" value="draft-ietf-asdf-sdf-23"/>
<author initials="M." surname="Koster" fullname="Michael Koster" role="editor">
<organization>KTC Control AB</organization>
<address>
<postal>
<street>29415 Alderpoint Road</street>
<city>Blocksburg, CA</city>
<code>95514</code>
<country>USA</country>
</postal>
<phone>+1-707-502-5136</phone>
<email>michaeljohnkoster@gmail.com</email>
</address>
</author>
<author initials="C." surname="Bormann" fullname="Carsten Bormann" role="editor">
<organization ascii="Universitaet Bremen TZI">Universität Bremen TZI</organization>
<address>
<postal>
<street>Postfach 330440</street>
<city>Bremen</city>
<code>D-28359</code>
<country>Germany</country>
</postal>
<phone>+49-421-218-63921</phone>
<email>cabo@tzi.org</email>
</address>
</author>
<author initials="A." surname="Keränen" fullname="Ari Keränen">
<organization>Ericsson</organization>
<address>
<postal>
<city>Jorvas</city>
<code>02420</code>
<country>Finland</country>
</postal>
<email>ari.keranen@ericsson.com</email>
</address>
</author>
<date year="2025" month="March" day="17"/>
<area>Applications</area>
<workgroup>ASDF</workgroup>
<keyword>Internet-Draft</keyword>
<abstract>
<?line 168?>
<t>The Semantic Definition Format (SDF) is concerned with Things,
namely physical objects that are available for interaction over a
network.
SDF is a format for domain experts to
use in the creation and maintenance of data and interaction models
that describe Things.
An SDF specification describes definitions of
SDF Objects/SDF Things and their associated interactions (Events, Actions,
Properties), as well as the Data types for the information exchanged
in those interactions. Tools convert this format to database formats
and other serializations as needed.</t>
</abstract>
<note removeInRFC="true">
<name>About This Document</name>
<t>
Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-ietf-asdf-sdf/"/>.
</t>
<t>
Discussion of this document takes place on the
A Semantic Definition Format for Data and Interactions of Things (ASDF) Working Group mailing list (<eref target="mailto:asdf@ietf.org"/>),
which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/asdf/"/>.
Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/asdf/"/>.
</t>
<t>Source for this draft and an issue tracker can be found at
<eref target="https://github.com/ietf-wg-asdf/SDF"/>.</t>
</note>
</front>
<middle>
<?line 186?>
<section anchor="introduction">
<name>Introduction</name>
<t>The Semantic Definition Format (SDF) is concerned with Things,
namely physical objects that are available for interaction over a
network.
SDF is a format for domain experts to
use in the creation and maintenance of data and interaction models
that describe Things.
An SDF specification describes definitions of
SDF Objects/SDF Things and their associated interactions (Events, Actions,
Properties), as well as the Data types for the information exchanged
in those interactions. Tools convert this format to database formats
and other serializations as needed.</t>
<t>SDF is designed to be an extensible format.
The present document constitutes the base specification for SDF:
"base SDF" for short.
In addition, SDF extensions can be defined, some of which may make use
of extension points specifically defined for this in base SDF.
One area for such extensions would be refinements of SDF's abstract
interaction models into protocol bindings for specific ecosystems
(e.g., <xref target="I-D.bormann-asdf-sdf-mapping"/>).
For the use of certain other extensions, it may be necessary to
indicate in the SDF
document using them that a specific extension is in effect; see
<xref target="information-block"/> for details of the <tt>features</tt> quality that can be
used for such indications.
With extension points and feature indications available,
base SDF does not define a "version" concept for the SDF format itself
(as opposed to version indications within SDF documents indicating
their own evolution, see <xref target="information-block"/>).</t>
<section anchor="structure-of-this-document">
<name>Structure of This Document</name>
<t>After introductory material and an overview (<xref target="overview"/>) over the
elements of the model and over the different kinds of names used,
<xref target="sdf-structure"/> introduces the main components of an SDF model.
<xref target="names-and-namespaces"/> revisits names and structures them into
namespaces.
<xref target="kw-defgroups"/> discusses the inner structure of the Objects defined by
SDF, the sdfObjects, in further detail.
<xref target="high-level-composition"/> discusses how SDF supports composition.
Conventional Sections (<xref format="title" target="iana"/>, <xref format="title" target="seccons"/>,
<xref format="title" target="sec-normative-references"/>, and <xref format="title" target="sec-informative-references"/>)
follow.
The normative <xref target="syntax"/> defines the syntax of SDF in
terms of its JSON structures, employing the Concise Data Definition
Language (CDDL) <xref target="RFC8610"/>.
This is followed by the informative <xref target="jso"/>, a rendition of the SDF
syntax in a "JSON Schema" format as they are defined by
<tt>json-schema.org</tt> (collectively called JSO).
The normative <xref target="jso-inspired"/> defines certain terms ("data qualities")
used at the SDF data model level that were inspired by JSO.
The informative <xref target="composition-examples"/> provides a few
examples for the use of composition in SDF.
Finally, <xref target="earlier"/> provides some historical information that can be
useful in upgrading earlier, pre-standard SDF models and
implementations to SDF base.</t>
</section>
<section anchor="terminology-and-conventions">
<name>Terminology and Conventions</name>
<t>Terms introduced in this section are capitalized when used in this
section; to maintain readability, capitalization is only done when
needed where they are used in the body of this document.</t>
<section numbered="false" anchor="programming-platform-terms">
<name>Programming Platform Terms</name>
<t>The following definitions mention terms that are used with specific
meanings in various programming platforms, but often have an
independent definition for this document, which can be found further
below in this section.</t>
<dl>
<dt>Element:</dt>
<dd>
<t>A generic term used here in its English sense.
Exceptionally, in <xref target="jso-inspired"/>, used explicitly in accordance with
its meaning in the JSON ecosystem, i.e., the elements of JSON
arrays.</t>
</dd>
<dt>Entry:</dt>
<dd>
<t>A key-value pair in a map. (In JSON maps, sometimes also called "member".)</t>
</dd>
<dt>Map:</dt>
<dd>
<t>A collection of entries (key-value pairs), where there are no two
entries with equivalent keys.
(Also known as associative array, dictionary, or symbol table.)</t>
</dd>
<dt>Object:</dt>
<dd>
<t>An otherwise very generic term that JavaScript (and thus JSON) uses
for the kind of maps that were part of the original languages from
the outset.
In this document, Object is used exclusively in its general English
meaning or as the colloquial shorthand for sdfObject, even if the
type name <tt>"object"</tt> is imported with JSON-related semantics from a
data definition language.</t>
</dd>
<dt>Property:</dt>
<dd>
<t>Certain environments use the term "property" for a JSON concept that
JSON calls "member" and is called "entry" here, or sometimes just for the
map key of these.
In this document, the term Property is specifically reserved for a
certain kind of Affordance, even if the map key <tt>"properties"</tt> is
imported with JSON-related semantics from a data definition
language.</t>
</dd>
<dt>Byte:</dt>
<dd>
<t>This document uses the term "byte" in its now-customary sense as a
synonym for "octet".</t>
</dd>
</dl>
</section>
<section numbered="false" anchor="conceptual-terms">
<name>Conceptual Terms</name>
<dl>
<dt>Thing:</dt>
<dd>
<t>A physical item that is also available for interaction over a network.</t>
</dd>
<dt>Element:</dt>
<dd>
<t>A part or an aspect of something abstract; i.e., the term is used
here in its usual English definition.</t>
</dd>
<dt>Affordance:</dt>
<dd>
<t>An element of an interface offered for interaction.
Such an element becomes an Affordance when information is available
(directly or indirectly) that indicates how it can or should be
used.
In the present document, the term is used for the digital
(network-directed) interfaces of a Thing only; as it is a physical
object as well, the Thing might also have physical affordances such
as buttons, dials, and displays.
The specification language offers certain ways to create sets of
related Affordances and combine them into "Groupings" (see below).</t>
</dd>
<dt>Property:</dt>
<dd>
<t>An Affordance that can potentially be used to read, write, and/or
observe state (current/stored information) on a Grouping.</t>
</dd>
<dt>Action:</dt>
<dd>
<t>An Affordance that can potentially be used to perform a named operation on a Grouping.</t>
</dd>
<dt>Event:</dt>
<dd>
<t>An Affordance that can potentially be used to obtain information
about what happened to a Grouping.</t>
</dd>
</dl>
</section>
<section numbered="false" anchor="specification-language-terms">
<name>Specification Language Terms</name>
<dl>
<dt>SDF Document:</dt>
<dd>
<t>Container for SDF Definitions, together with data
about the SDF Document itself (information block).
Represented as a JSON text representing a single JSON map, which is
built from nested maps.</t>
</dd>
<dt>SDF Model:</dt>
<dd>
<t>Definitions and declarations that model the digital interaction
opportunities offered by one or more kinds of Things, represented
by Groupings (sdfObjects and sdfThings).
An SDF Model can be fully contained in a single SDF Document, or it
can be built from an SDF Document that references definitions and
declarations from additional SDF documents.</t>
</dd>
<dt>Block:</dt>
<dd>
<t>One or more entries in a JSON map that is part of an SDF
specification; these entries can be described as a Block to
emphasize that they together serve a specific function.</t>
</dd>
<dt>Group:</dt>
<dd>
<t>An entry in the main JSON map that represents the SDF document, and in
certain nested definitions.
A group
has a Class Name Keyword as its key and a map of named definition
entries (Definition Group) as a value.</t>
</dd>
<dt>Class Name Keyword:</dt>
<dd>
<t>One of <tt>sdfThing</tt>, <tt>sdfObject</tt>, <tt>sdfProperty</tt>, <tt>sdfAction</tt>,
<tt>sdfEvent</tt>, or <tt>sdfData</tt>; the Classes for these type keywords are
capitalized and prefixed with <tt>sdf</tt>.</t>
</dd>
<dt>Class:</dt>
<dd>
<t>Abstract term for the information that is contained in groups
identified by a Class Name Keyword.</t>
</dd>
<dt>Quality:</dt>
<dd>
<t>A metadata item in a definition or declaration which says something
about that definition or declaration. A quality is represented in
SDF as an entry in a JSON map (JSON object) that serves as a definition
or declaration.
(The term "Quality" is used because another popular term,
"Property", already has a different meaning.)</t>
</dd>
<dt>Definition:</dt>
<dd>
<t>An entry in a Definition Group.
The entry creates a new semantic term for use in SDF models and
associates it with a set of qualities.
Unless the Class Name Keyword of the Group also makes it a
Declaration (see <xref target="definitions-block"/>), a definition just defines a
term, it does not create a component item within the enclosing
definition.</t>
</dd>
<dt>Declaration:</dt>
<dd>
<t>A definition within an enclosing
definition that is intended to create a component item within that
enclosing definition. Every declaration can also be used as a
definition for reference elsewhere.</t>
</dd>
<dt>Grouping:</dt>
<dd>
<t>An sdfThing or sdfObject, i.e., (directly or indirectly) a
description for a combination of Affordances.</t>
</dd>
<dt>Object, sdfObject:</dt>
<dd>
<t>A Grouping that contains Affordance declarations (Property, Action,
and Event declarations) only.
It serves as the main "atom" of reusable semantics for model
construction, representing the interaction model for a Thing that is
simple enough to not require nested structure.
sdfObjects are therefore similar to sdfThings but do not allow
nesting, i.e., they cannot contain other Groupings (sdfObjects or
sdfThings).</t>
</dd>
<dt>sdfThing:</dt>
<dd>
<t>A Grouping that can contain nested Groupings (sdfThings and sdfObjects).
Like sdfObject, it can also contain Affordance
declarations (Property, Action, and Event declarations).
(Note that "Thing" has a different meaning from sdfThing and
therefore is not available as a colloquial shorthand of
sdfThing.)</t>
</dd>
<dt>Augmentation Mechanism:</dt>
<dd>
<t>A companion document to a base SDF Model that provides additional
information ("augments" the base specification).
The information may be for use in
a specific ecosystem or with a specific protocol ("Protocol Binding").
No specific Augmentation Mechanisms are defined in base SDF.
A simple mechanism for such augmentations has been discussed as a
"mapping file" <xref target="I-D.bormann-asdf-sdf-mapping"/>.</t>
</dd>
<dt>Protocol Binding:</dt>
<dd>
<t>A companion document to an SDF Model that defines how to map the
abstract concepts in the model into the protocols in use in a
specific ecosystem.
The Protocol Binding might supply URL components, numeric IDs, and
similar details.
Protocol Bindings are one case of an Augmentation Mechanism.</t>
</dd>
</dl>
</section>
<section numbered="false" anchor="conventions">
<name>Conventions</name>
<t>Regular expressions that are used in the text as a "pattern" for some
string are interpreted as per <xref target="RFC9485"/>.
(Note that a form of regular expressions is also used as values of the
quality <tt>pattern</tt>; see <xref target="type-string"/>.)</t>
<t>The term "URI" in this document always refers to "full" URIs ("<tt>URI</tt>" in
Section <xref target="RFC3986" section="3" sectionFormat="bare"/> of RFC 3986 <xref target="STD66"/>), never to relative URI references
("<tt>relative-ref</tt>" in Section <xref target="RFC3986" section="4.1" sectionFormat="bare"/> of RFC 3986 <xref target="STD66"/>), so the term "URI"
does <em>NOT</em> serve as the colloquial abbreviation of "URI-Reference" it is
often used for.
Therefore, the "reference resolution" process defined in Section <xref target="RFC3986" section="5" sectionFormat="bare"/> of RFC 3986 <xref target="STD66"/> is <em>NOT</em> used in this specification.
Where necessary, full URIs are assembled out of substrings by simple
concatenation, e.g. when CURIEs are expanded (<xref target="ref-global"/>), or when a
global name is formed out of a namespace <tt>absolute-URI</tt> (Section <xref target="RFC3986" section="5" sectionFormat="bare"/> of RFC 3986 <xref target="STD66"/>) and a fragment identifier part (<xref target="names-structure"/>).
Note also that URIs are not only used to construct the SDF models,
they are also the <em>subject</em> of SDF models where they are used as data
in actual interactions (and could even be represented as relative
references there); these two usages are entirely separate.</t>
<t>The singular form is chosen as the preferred one for the keywords
defined in this specification.</t>
<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in <xref target="BCP14"/> (<xref target="RFC2119"/>) (<xref target="RFC8174"/>) when, and only when, they
appear in all capitals, as shown here.</t>
<?line -18?>
</section>
</section>
</section>
<section anchor="overview">
<name>Overview</name>
<section anchor="example-definition">
<name>Example Definition</name>
<t>The overview starts with an example for the SDF definition of a simple sdfObject called "Switch" (<xref target="example1"/>).</t>
<figure anchor="example1">
<name>A simple example of an SDF document</name>
<sourcecode type="json" name="example1.sdf.json"><![CDATA[
{
"info": {
"title": "Example document for SDF (Semantic Definition Format)",
"version": "2019-04-24",
"copyright": "Copyright 2019 Example Corp. All rights reserved.",
"license": "https://example.com/license"
},
"namespace": {
"cap": "https://example.com/capability/cap"
},
"defaultNamespace": "cap",
"sdfObject": {
"Switch": {
"sdfProperty": {
"value": {
"description":
"The state of the switch; false for off and true for on.",
"type": "boolean"
}
},
"sdfAction": {
"on": {
"description":
"Turn the switch on; equivalent to setting value to true."
},
"off": {
"description":
"Turn the switch off; equivalent to setting value to false."
},
"toggle": {
"description":
"Toggle the switch; equivalent to setting value to its complement."
}
}
}
}
}
]]></sourcecode>
</figure>
<t>This is a model of a switch.
The state <tt>value</tt> declared in the <tt>sdfProperty</tt> group, represented by a Boolean, will be true for "on" and will be false for "off".
The actions <tt>on</tt> or <tt>off</tt> declared in the <tt>sdfAction</tt> group are redundant with setting the <tt>value</tt> and are in the example to illustrate that there are often different ways of achieving the same effect.
The action <tt>toggle</tt> will invert the value of the sdfProperty value, so that 2-way switches can be created; having such action will avoid the need for first retrieving the current value and then applying/setting the inverted value.</t>
<t>The <tt>sdfObject</tt> group lists the affordances of Things modeled by this sdfObject.
The <tt>sdfProperty</tt> group lists the property affordances described by the model; these represent various perspectives on the state of the sdfObject.
Properties can have additional qualities to describe the state more precisely.
Properties can be annotated to be read, write or read/write; how this is actually done by the underlying transfer protocols is not described in the SDF model but left to companion protocol bindings.
Properties are often used with RESTful paradigms <xref target="I-D.irtf-t2trg-rest-iot"/>, describing state.
The <tt>sdfAction</tt> group is the mechanism to describe other interactions in terms of their names, input, and output data (no data are used in the example), as in a POST method in REST or in a remote procedure call.
The example <tt>toggle</tt> is an Action that
changes the state based on the current state of the Property named <tt>value</tt>.
(The third type of affordance is Events, which are not described in this example.)</t>
<t>In the JSON representation, the <tt>info</tt> group is an exception in that
this group's map has keys taken from the SDF vocabulary.
All other groups (such as <tt>namespace</tt>, <tt>sdfObject</tt>) have maps with
keys that are freely defined by the model writer (<tt>Switch</tt>, <tt>value</tt>,
<tt>on</tt>, etc.); these map keys are therefore called <em>given names</em>.
The groups made up of entries with given names as keys usually use the
<tt>named<></tt> production in the <xref target="syntax">formal syntax of SDF</xref>.
Where the values of these entries are maps, these again use SDF
vocabulary keys, and so on, generally alternating in further nesting.
The SDF-defined vocabulary items used in the hierarchy of such groups
are often, but not always, called <em>quality names</em> or <em>qualities</em>.
See <xref target="member-names"/> for more information about naming in SDF.</t>
</section>
<section anchor="elements-of-an-sdf-model">
<name>Elements of an SDF model</name>
<t>The SDF language uses six predefined Class Name Keywords for modeling connected
Things which are illustrated in <xref target="fig-class-2"/> (limited rendition in
the plaintext form of this document, please use typographic forms for
full information).</t>
<figure anchor="fig-class-2">
<name>Main classes used in SDF models</name>
<artset>
<artwork type="svg" align="center"><svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" height="437px" preserveAspectRatio="none" version="1.1" viewBox="0 0 542 437" width="542px">
<defs/>
<g>
<!--class sdfThing-->
<g id="elem_sdfThing">
<rect fill="white" height="48" id="sdfThing" rx="2.5" ry="2.5" width="93" x="136.13" y="7" stroke="black" stroke-width="0.5"/>
<ellipse cx="151.13" cy="23" fill="white" rx="11" ry="11" stroke="black" stroke-width="1.0"/>
<path d="M153.6031,29.1431 Q153.0221,29.4419 152.3829,29.5913 Q151.7438,29.7407 151.0382,29.7407 Q148.5314,29.7407 147.2115,28.0889 Q145.8917,26.437 145.8917,23.3159 Q145.8917,20.1865 147.2115,18.5347 Q148.5314,16.8828 151.0382,16.8828 Q151.7438,16.8828 152.3912,17.0322 Q153.0387,17.1816 153.6031,17.4805 L153.6031,20.2031 Q152.9723,19.6221 152.3788,19.3523 Q151.7853,19.0825 151.1544,19.0825 Q149.8097,19.0825 149.1249,20.1492 Q148.4401,21.2158 148.4401,23.3159 Q148.4401,25.4077 149.1249,26.4744 Q149.8097,27.541 151.1544,27.541 Q151.7853,27.541 152.3788,27.2712 Q152.9723,27.0015 153.6031,26.4204 Z " fill="black"/>
<text fill="black" font-family="sans-serif" font-size="14" x="165.13" y="28.291">sdfThing</text>
<line x1="137.13" x2="228.13" y1="39" y2="39" stroke="black" stroke-width="0.5"/>
<line x1="137.13" x2="228.13" y1="47" y2="47" stroke="black" stroke-width="0.5"/>
</g>
<!--class sdfObject-->
<g id="elem_sdfObject">
<rect fill="white" height="48" id="sdfObject" rx="2.5" ry="2.5" width="97" x="205.13" y="132" stroke="black" stroke-width="0.5"/>
<ellipse cx="220.13" cy="148" fill="white" rx="11" ry="11" stroke="black" stroke-width="1.0"/>
<path d="M222.6031,154.1431 Q222.0221,154.4419 221.3829,154.5913 Q220.7438,154.7407 220.0382,154.7407 Q217.5314,154.7407 216.2115,153.0889 Q214.8917,151.437 214.8917,148.3159 Q214.8917,145.1865 216.2115,143.5347 Q217.5314,141.8828 220.0382,141.8828 Q220.7438,141.8828 221.3912,142.0322 Q222.0387,142.1816 222.6031,142.4805 L222.6031,145.2031 Q221.9723,144.6221 221.3788,144.3523 Q220.7853,144.0825 220.1544,144.0825 Q218.8097,144.0825 218.1249,145.1492 Q217.4401,146.2158 217.4401,148.3159 Q217.4401,150.4077 218.1249,151.4744 Q218.8097,152.541 220.1544,152.541 Q220.7853,152.541 221.3788,152.2712 Q221.9723,152.0015 222.6031,151.4204 Z " fill="black"/>
<text fill="black" font-family="sans-serif" font-size="14" x="234.13" y="153.291">sdfObject</text>
<line x1="206.13" x2="301.13" y1="164" y2="164" stroke="black" stroke-width="0.5"/>
<line x1="206.13" x2="301.13" y1="172" y2="172" stroke="black" stroke-width="0.5"/>
</g>
<!--class sdfProperty-->
<g id="elem_sdfProperty">
<rect fill="white" height="48" id="sdfProperty" rx="2.5" ry="2.5" width="111" x="29.13" y="257" stroke="black" stroke-width="0.5"/>
<ellipse cx="44.13" cy="273" fill="white" rx="11" ry="11" stroke="black" stroke-width="1.0"/>
<path d="M46.6031,279.1431 Q46.0221,279.4419 45.3829,279.5913 Q44.7438,279.7407 44.0382,279.7407 Q41.5314,279.7407 40.2115,278.0889 Q38.8917,276.437 38.8917,273.3159 Q38.8917,270.1865 40.2115,268.5347 Q41.5314,266.8828 44.0382,266.8828 Q44.7438,266.8828 45.3912,267.0322 Q46.0387,267.1816 46.6031,267.4805 L46.6031,270.2031 Q45.9723,269.6221 45.3788,269.3523 Q44.7853,269.0825 44.1544,269.0825 Q42.8097,269.0825 42.1249,270.1492 Q41.4401,271.2158 41.4401,273.3159 Q41.4401,275.4077 42.1249,276.4744 Q42.8097,277.541 44.1544,277.541 Q44.7853,277.541 45.3788,277.2712 Q45.9723,277.0015 46.6031,276.4204 Z " fill="black"/>
<text fill="black" font-family="sans-serif" font-size="14" x="58.13" y="278.291">sdfProperty</text>
<line x1="30.13" x2="139.13" y1="289" y2="289" stroke="black" stroke-width="0.5"/>
<line x1="30.13" x2="139.13" y1="297" y2="297" stroke="black" stroke-width="0.5"/>
</g>
<!--class sdfAction-->
<g id="elem_sdfAction">
<rect fill="white" height="48" id="sdfAction" rx="2.5" ry="2.5" width="97" x="363.13" y="257" stroke="black" stroke-width="0.5"/>
<ellipse cx="378.13" cy="273" fill="white" rx="11" ry="11" stroke="black" stroke-width="1.0"/>
<path d="M380.6031,279.1431 Q380.0221,279.4419 379.3829,279.5913 Q378.7438,279.7407 378.0382,279.7407 Q375.5314,279.7407 374.2115,278.0889 Q372.8917,276.437 372.8917,273.3159 Q372.8917,270.1865 374.2115,268.5347 Q375.5314,266.8828 378.0382,266.8828 Q378.7438,266.8828 379.3912,267.0322 Q380.0387,267.1816 380.6031,267.4805 L380.6031,270.2031 Q379.9723,269.6221 379.3788,269.3523 Q378.7853,269.0825 378.1544,269.0825 Q376.8097,269.0825 376.1249,270.1492 Q375.4401,271.2158 375.4401,273.3159 Q375.4401,275.4077 376.1249,276.4744 Q376.8097,277.541 378.1544,277.541 Q378.7853,277.541 379.3788,277.2712 Q379.9723,277.0015 380.6031,276.4204 Z " fill="black"/>
<text fill="black" font-family="sans-serif" font-size="14" x="392.13" y="278.291">sdfAction</text>
<line x1="364.13" x2="459.13" y1="289" y2="289" stroke="black" stroke-width="0.5"/>
<line x1="364.13" x2="459.13" y1="297" y2="297" stroke="black" stroke-width="0.5"/>
</g>
<!--class sdfEvent-->
<g id="elem_sdfEvent">
<rect fill="white" height="48" id="sdfEvent" rx="2.5" ry="2.5" width="90" x="175.63" y="257" stroke="black" stroke-width="0.5"/>
<ellipse cx="190.63" cy="273" fill="white" rx="11" ry="11" stroke="black" stroke-width="1.0"/>
<path d="M193.1031,279.1431 Q192.5221,279.4419 191.8829,279.5913 Q191.2438,279.7407 190.5382,279.7407 Q188.0314,279.7407 186.7115,278.0889 Q185.3917,276.437 185.3917,273.3159 Q185.3917,270.1865 186.7115,268.5347 Q188.0314,266.8828 190.5382,266.8828 Q191.2438,266.8828 191.8912,267.0322 Q192.5387,267.1816 193.1031,267.4805 L193.1031,270.2031 Q192.4723,269.6221 191.8788,269.3523 Q191.2853,269.0825 190.6544,269.0825 Q189.3097,269.0825 188.6249,270.1492 Q187.9401,271.2158 187.9401,273.3159 Q187.9401,275.4077 188.6249,276.4744 Q189.3097,277.541 190.6544,277.541 Q191.2853,277.541 191.8788,277.2712 Q192.4723,277.0015 193.1031,276.4204 Z " fill="black"/>
<text fill="black" font-family="sans-serif" font-size="14" x="204.63" y="278.291">sdfEvent</text>
<line x1="176.63" x2="264.63" y1="289" y2="289" stroke="black" stroke-width="0.5"/>
<line x1="176.63" x2="264.63" y1="297" y2="297" stroke="black" stroke-width="0.5"/>
</g>
<!--class sdfData-->
<g id="elem_sdfData">
<rect fill="white" height="48" id="sdfData" rx="2.5" ry="2.5" width="84" x="236.63" y="382" stroke="black" stroke-width="0.5"/>
<ellipse cx="251.63" cy="398" fill="white" rx="11" ry="11" stroke="black" stroke-width="1.0"/>
<path d="M254.1031,404.1431 Q253.5221,404.4419 252.8829,404.5913 Q252.2438,404.7407 251.5382,404.7407 Q249.0314,404.7407 247.7115,403.0889 Q246.3917,401.437 246.3917,398.3159 Q246.3917,395.1865 247.7115,393.5347 Q249.0314,391.8828 251.5382,391.8828 Q252.2438,391.8828 252.8912,392.0322 Q253.5387,392.1816 254.1031,392.4805 L254.1031,395.2031 Q253.4723,394.6221 252.8788,394.3523 Q252.2853,394.0825 251.6544,394.0825 Q250.3097,394.0825 249.6249,395.1492 Q248.9401,396.2158 248.9401,398.3159 Q248.9401,400.4077 249.6249,401.4744 Q250.3097,402.541 251.6544,402.541 Q252.2853,402.541 252.8788,402.2712 Q253.4723,402.0015 254.1031,401.4204 Z " fill="black"/>
<text fill="black" font-family="sans-serif" font-size="14" x="265.63" y="403.291">sdfData</text>
<line x1="237.63" x2="319.63" y1="414" y2="414" stroke="black" stroke-width="0.5"/>
<line x1="237.63" x2="319.63" y1="422" y2="422" stroke="black" stroke-width="0.5"/>
</g>
<!--link sdfThing to sdfObject-->
<g id="link_sdfThing_sdfObject">
<path d="M196.16,55.42 C207.75,75.52 224.51,104.54 236.94,126.08 " fill="none" id="sdfThing-to-sdfObject" stroke="black" stroke-width="1.0"/>
<polygon fill="black" points="239.41,130.35,238.3726,120.5559,236.9093,126.0203,231.445,124.557,239.41,130.35" stroke="black" stroke-width="1.0"/>
<text fill="black" font-family="sans-serif" font-size="13" x="222.63" y="98.5684">hasObject</text>
<text fill="black" font-family="sans-serif" font-size="13" x="216.4021" y="121.1091">0+</text>
</g>
<!--link sdfThing to sdfThing-->
<g id="link_sdfThing_sdfThing">
<path d="M229.53,19.35 C248.35,18.69 264.13,22.58 264.13,31 C264.13,38.44 251.83,42.33 236,42.69 " fill="none" id="sdfThing-to-sdfThing" stroke="black" stroke-width="1.0"/>
<polygon fill="black" points="231.05,42.66,240.027,46.7114,236.0499,42.6886,240.0727,38.7115,231.05,42.66" stroke="black" stroke-width="1.0"/>
<text fill="black" font-family="sans-serif" font-size="13" x="270.13" y="36.0684">hasThing</text>
<text fill="black" font-family="sans-serif" font-size="13" x="237.0416" y="40.7969">0+</text>
</g>
<!--link sdfThing to sdfProperty-->
<g id="link_sdfThing_sdfProperty">
<path d="M136,47.85 C99.23,63.1 50.46,90.1 27.63,132 C6,171.7 35.57,221.37 59.56,251.88 " fill="none" id="sdfThing-to-sdfProperty" stroke="black" stroke-width="1.0"/>
<polygon fill="black" points="62.41,255.43,59.8985,245.9068,59.2813,251.5298,53.6582,250.9127,62.41,255.43" stroke="black" stroke-width="1.0"/>
<text fill="black" font-family="sans-serif" font-size="13" x="28.63" y="161.0684">hasProperty</text>
<text fill="black" font-family="sans-serif" font-size="13" x="37.9817" y="246.443">0+</text>
</g>
<!--link sdfThing to sdfAction-->
<g id="link_sdfThing_sdfAction">
<path d="M229.41,49.61 C250.34,58.6 274.73,70.67 294.63,85 C357.14,129.99 385.89,138.55 414.63,210 C419.75,222.7 419.78,237.77 418.22,250.67 " fill="none" id="sdfThing-to-sdfAction" stroke="black" stroke-width="1.0"/>
<polygon fill="black" points="417.55,255.31,422.7961,246.9746,418.2651,250.3614,414.8783,245.8304,417.55,255.31" stroke="black" stroke-width="1.0"/>
<text fill="black" font-family="sans-serif" font-size="13" x="400.63" y="161.0684">hasAction</text>
<text fill="black" font-family="sans-serif" font-size="13" x="398.4969" y="246.285">0+</text>
</g>
<!--link sdfThing to sdfEvent-->
<g id="link_sdfThing_sdfEvent">
<path d="M164.06,55.38 C136.18,93.53 90.16,170.57 123.63,227 C129.23,236.43 149.15,248 169.5,257.92 " fill="none" id="sdfThing-to-sdfEvent" stroke="black" stroke-width="1.0"/>
<polygon fill="black" points="173.87,260.02,167.4833,252.5226,169.3613,257.8587,164.0252,259.7366,173.87,260.02" stroke="black" stroke-width="1.0"/>
<text fill="black" font-family="sans-serif" font-size="13" x="121.63" y="161.0684">hasEvent</text>
<text fill="black" font-family="sans-serif" font-size="13" x="149.5914" y="254.3466">0+</text>
</g>
<!--link sdfObject to sdfProperty-->
<g id="link_sdfObject_sdfProperty">
<path d="M204.71,177.95 C186.9,186.64 167.11,197.61 150.63,210 C134.71,221.98 119.28,238.01 107.36,251.7 " fill="none" id="sdfObject-to-sdfProperty" stroke="black" stroke-width="1.0"/>
<polygon fill="black" points="104.12,255.48,113.0049,251.2306,107.3657,251.6767,106.9196,246.0374,104.12,255.48" stroke="black" stroke-width="1.0"/>
<text fill="black" font-family="sans-serif" font-size="13" x="151.63" y="223.5684">hasProperty</text>
<text fill="black" font-family="sans-serif" font-size="13" x="87.5644" y="246.0715">0+</text>
</g>
<!--link sdfObject to sdfAction-->
<g id="link_sdfObject_sdfAction">
<path d="M283.72,180.42 C310.19,201.03 348.73,231.03 376.58,252.71 " fill="none" id="sdfObject-to-sdfAction" stroke="black" stroke-width="1.0"/>
<polygon fill="black" points="380.46,255.73,375.8181,247.0436,376.5155,252.6573,370.9019,253.3548,380.46,255.73" stroke="black" stroke-width="1.0"/>
<text fill="black" font-family="sans-serif" font-size="13" x="342.63" y="223.5684">hasAction</text>
<text fill="black" font-family="sans-serif" font-size="13" x="353.6739" y="246.1091">0+</text>
</g>
<!--link sdfObject to sdfEvent-->
<g id="link_sdfObject_sdfEvent">
<path d="M247.35,180.42 C242,200.34 234.3,229.05 228.54,250.53 " fill="none" id="sdfObject-to-sdfEvent" stroke="black" stroke-width="1.0"/>
<polygon fill="black" points="227.29,255.2,233.4711,247.5323,228.5765,250.3684,225.7404,245.4738,227.29,255.2" stroke="black" stroke-width="1.0"/>
<text fill="black" font-family="sans-serif" font-size="13" x="239.63" y="223.5684">hasEvent</text>
<text fill="black" font-family="sans-serif" font-size="13" x="208.2004" y="246.1091">0+</text>
</g>
<!--link sdfAction to sdfData-->
<g id="link_sdfAction_sdfData">
<path d="M380.17,305.36 C368.69,314.29 355.78,324.78 344.63,335 C330.27,348.17 315.29,363.87 303.24,377.07 " fill="none" id="sdfAction-to-sdfData" stroke="black" stroke-width="1.0"/>
<polygon fill="black" points="299.96,380.69,308.97,376.7126,303.3198,376.9871,303.0453,371.3369,299.96,380.69" stroke="black" stroke-width="1.0"/>
<text fill="black" font-family="sans-serif" font-size="13" x="345.63" y="348.5684">hasInputData</text>
<text fill="black" font-family="sans-serif" font-size="13" x="283.8382" y="371.2976">0+</text>
</g>
<!--link sdfAction to sdfData-->
<g id="link_sdfAction_sdfData">
<path d="M429.32,305.37 C437.95,319.82 444.54,338.17 434.63,352 C410.38,385.85 363.27,398.34 327.13,402.82 " fill="none" id="sdfAction-to-sdfData-1" stroke="black" stroke-width="1.0"/>
<polygon fill="black" points="322.48,403.35,331.8779,406.2961,327.4473,402.779,330.9644,398.3484,322.48,403.35" stroke="black" stroke-width="1.0"/>
<text fill="black" font-family="sans-serif" font-size="13" x="439.63" y="348.5684">hasOutputData</text>
<text fill="black" font-family="sans-serif" font-size="13" x="328.522" y="399.6454">0+</text>
</g>
<!--link sdfEvent to sdfData-->
<g id="link_sdfEvent_sdfData">
<path d="M209.17,305.42 C203.95,319.53 200.38,337.53 207.63,352 C213.04,362.77 221.78,371.92 231.32,379.42 " fill="none" id="sdfEvent-to-sdfData" stroke="black" stroke-width="1.0"/>
<polygon fill="black" points="235.15,382.28,230.3303,373.691,231.1431,379.2892,225.545,380.102,235.15,382.28" stroke="black" stroke-width="1.0"/>
<text fill="black" font-family="sans-serif" font-size="13" x="208.63" y="348.5684">hasOutputData</text>
<text fill="black" font-family="sans-serif" font-size="13" x="210.5093" y="376.1409">0+</text>
</g>
<!--link sdfProperty to sdfData-->
<g id="link_sdfProperty_sdfData">
<path d="M89.02,305.4 C93.01,320.6 100.38,339.79 113.63,352 C145.64,381.48 194.15,394.57 230.3,400.38 " fill="none" id="sdfProperty-to-sdfData" stroke="black" stroke-width="1.0"/>
<polygon fill="black" points="234.94,401.08,226.6344,395.7868,229.9955,400.3369,225.4455,403.698,234.94,401.08" stroke="black" stroke-width="1.0"/>
<text fill="black" font-family="sans-serif" font-size="13" x="114.63" y="348.5684">isInstanceOf</text>
<text fill="black" font-family="sans-serif" font-size="13" x="220.5011" y="396.8099">1</text>
</g>
<!--SRC=[ZP7D2i8m48Jl-nIXLoderOCWwC5JFVW2CKrjHTBItGeYlhisc_u45knjTlYIcMKnBovbvMugJNSgMQyIXNcHNU_MaDggKYDhG8bZnsDUojIvhHlRqel1OPBPlQ6gTaoobhdZqxfGq4k0gVQoR06MmmLGJ0-lvzn1asRiv9gE-l4lcNKqe316BKB7NJszcSFLhm2ITiPc1O1vQCJfVc_upBomRcoENyTsM2GskN7i-HgzzGK0]-->
</g>
</svg>
</artwork>
<artwork type="ascii-art" align="center"><![CDATA[ ,--------.
|sdfThing|------.
,--------------|--------| | hasThing
| |--------|<-----'
| `--------'
| | | |
| hasObject | | \
| v | \
| ,---------. | \
| |sdfObject| | \
| |---------| | \
,--------|---------|---------.
| `---------' | |
has|Property | hasAction | hasEvent
v v v v
,-----------. ,---------. ,--------.
|sdfProperty| |sdfAction| |sdfEvent|
|-----------| |---------| |--------|
|-----------| |---------| |--------|
`-----------' `---------' `--------'
| hasInput| |hasOutput |
| Data| |Data |
| v v |
| ,-------. |
| isInst |sdfData| hasOutp |
`----------->|-------|<----------'
anceOf |-------| utData
`-------'
]]></artwork>
</artset>
</figure>
<t>The six main Class Name Keywords are discussed below.</t>
<section anchor="sdfobject">
<name>sdfObject</name>
<t>sdfObjects, the items listed in an <tt>sdfObject</tt> definition group, are
the main "atom" of reusable semantics for model construction.
The concept aligns in scope with common definition items from many IoT modeling
systems, for example ZigBee Clusters <xref target="ZCL"/>, OMA SpecWorks LwM2M
Objects <xref target="OMA"/>, OCF Resource Types <xref target="OCF"/>, and W3C Web of Things <xref target="WoT"/>.</t>
<t>An sdfObject definition contains a set of <tt>sdfProperty</tt>, <tt>sdfAction</tt>, and
<tt>sdfEvent</tt> definitions that describe the interaction affordances
associated with some scope of functionality.</t>
<t>For the granularity of definition, sdfObject definitions are meant
to be kept narrow enough in scope to enable broad reuse and
interoperability.
For example, defining a light bulb using separate sdfObject
definitions for on/off control, dimming, and color control affordances
will enable interoperable functionality to be configured for diverse
product types.
An sdfObject definition for a common on/off control may be used to
control many different kinds of Things that require on/off control.</t>
<t>The presence of one or both of the optional qualities "<tt>minItems</tt>" and
"<tt>maxItems</tt>" defines the sdfObject as an array, i.e., all the
affordances defined for the sdfObject exist a number of times, indexed
by a number constrained to be between <tt>minItems</tt> and <tt>maxItems</tt>,
inclusive, if given.
(Note: Setting "<tt>minItems</tt>" to zero and leaving out "<tt>maxItems</tt>" puts the
minimum constraints on that array.)</t>
</section>
<section anchor="sdfproperty">
<name>sdfProperty</name>
<t><tt>sdfProperty</tt> is used to model elements of state within Things modeled
by the enclosing grouping.</t>
<t>A named definition entry in an sdfProperty may be associated with some protocol
affordance to enable the application to obtain the state variable and,
optionally, modify the state variable.
Additionally, some protocols provide for in-time reporting of state
changes.
(These three aspects are described by the qualities <tt>readable</tt>,
<tt>writable</tt>, and <tt>observable</tt> defined for an sdfProperty.)</t>
<t>Definitions in <tt>sdfProperty</tt> groups look like the definitions in
<tt>sdfData</tt> groups.
However, they actually also declare that a Property
with the given qualities potentially is present in the containing sdfObject.</t>
<t>For definitions in <tt>sdfProperty</tt> and <tt>sdfData</tt>, SDF provides qualities
that can constrain the structure and values of data allowed in the
interactions modeled by them.
It also provides qualities that associate semantics to these
data, such as engineering units and unit scaling information.</t>
<t>For the data definition within <tt>sdfProperty</tt> or <tt>sdfData</tt>, SDF borrows
some vocabulary proposed for the drafts 4 <xref target="JSO4"/> <xref target="JSO4V"/> and 7
<xref target="JSO7"/> <xref target="JSO7V"/> of the json-schema.org "JSON Schema" format
(collectively called JSO here), enhanced by qualities that are
specific to SDF.
Details about the JSO-inspired vocabulary are in <xref target="jso-inspired"/>.
For base SDF, data are constrained to be of
simple types (number, string, Boolean),
JSON maps composed of named data, and arrays of these types.
Syntax extension points are provided that can be used to provide
richer types in a future extension of this specification (possibly more
of which can be borrowed from json-schema.org).</t>
<t>Note that sdfProperty definitions (and sdfData definitions in
general) are not intended to constrain the formats of data used for
communication over network interfaces.
Where needed, data definitions for payloads of protocol messages are
expected to be part of the protocol binding.</t>
</section>
<section anchor="sdfaction-overview">
<name>sdfAction</name>
<t>The <tt>sdfAction</tt> group contains declarations of Actions, which
model affordances that, when triggered,
have an effect that can go beyond just reading, updating, or observing Thing
state.
Actions often result in some outward physical effect (which, itself,
cannot be modeled in SDF). From a programmer's perspective, they
might be considered to be roughly analogous to method calls.</t>
<t>Actions may have data parameters: these are modeled as a single item of input
data and output data, each. Where multiple parameters need to be
modeled, an <tt>"object"</tt> type can be used to combine these parameters
into one; for an example see <xref target="example-obj-type"/> in <xref target="type-object"/>.</t>
<t>Actions may be long-running, that is to say that the effects may not
take place immediately as would be expected for an update to an
sdfProperty; the effects may play out over time and emit action
results.
Actions may also not always complete and may result in application
errors, such as an item blocking the closing of an automatic door.</t>
<t>One idiom for giving an action initiator status and control about the
ongoing action is to provide a URI for an ephemeral "action resource"
in the sdfAction output data, allowing the action to deliver
immediate feedback (including errors that prevent the action from
starting) and the action initiator to use the action resource
for further observation or modification of the ongoing action
(including canceling it).
Base SDF does not provide any tailored support for describing such
action resources; an extension for modeling links in more detail
(for instance, <xref target="I-D.bormann-asdf-sdftype-link"/>) may be all that is needed to fully enable modeling
them.</t>
<t>Actions may have (or lack) the characteristics of idempotence and side-effect
safety (see Section <xref target="RFC9110" section="9.2" sectionFormat="bare"/> of RFC 9110 <xref target="STD97"/> for more on these terms).</t>
<t>Base SDF only provides data constraint modeling and semantics for the input and output data of definitions in <tt>sdfAction</tt> groups.
Again, data definitions for payloads of protocol messages, and
detailed protocol settings for invoking the action, are expected to be
part of the protocol binding.</t>
</section>
<section anchor="sdfevent-overview">
<name>sdfEvent</name>
<t>The <tt>sdfEvent</tt> group contains declarations of Events, which model
affordances that inform about "happenings" associated with a Thing
modeled by the enclosing sdfObject; these may result in a signal being
stored or emitted as a result.</t>
<t>Note that there is a trivial overlap with sdfProperty state changes,
which may also be defined as events but are not generally required to
be defined as such.
However, Events may exhibit certain ordering, consistency, and
reliability requirements that are expected to be supported in various
implementations of sdfEvent that do distinguish sdfEvent from
sdfProperty.
For instance, while a state change may simply be superseded by another
state change, some events are "precious" and need to be preserved even
if further events follow.</t>
<t>Base SDF only provides data constraint modeling and
semantics for the output data of Event affordances.
Again, data definitions for payloads of protocol messages, and
detailed protocol settings for soliciting the event, are expected to be
part of the protocol binding.</t>
</section>
<section anchor="sdfdata">
<name>sdfData</name>
<t>Definitions in <tt>sdfData</tt> groups do not themselves specify affordances.
These definitions
are provided separately from those in
sdfProperty groups to enable common
modeling patterns, data constraints, and semantic anchor concepts to
be factored out for data items that make up sdfProperty items and
serve as input and output data for sdfAction and sdfEvent items.
The data types defined in sdfData definitions only spring to life by being referenced in
one of these contexts (directly or indirectly via some other sdfData
definitions).</t>
<t>It is a common use case for such a data definition to be shared
between an sdfProperty item and input or output parameters of an
sdfAction or output data provided by an sdfEvent.
sdfData definitions also enable factoring out extended application
data types such as mode and machine state enumerations to be reused
across multiple definitions that have similar basic characteristics
and requirements.</t>
</section>
<section anchor="sdfthing">
<name>sdfThing</name>
<t>Back at the top level, the <tt>sdfThing</tt> group enables definition of models for
complex devices that will use one or more sdfObject definitions.
Like sdfObject, sdfThing groups allow for the inclusion of interaction
affordances, sdfData, as well as "<tt>minItems</tt>" and "<tt>maxItems</tt>" qualities.
Therefore, they can be seen as a superset of sdfObject groups, additionally
allowing for composition.</t>
<t>As a result, an sdfThing directly or indirectly contains a set of sdfProperty, sdfAction, and
sdfEvent definitions that describe the interaction affordances
associated with some scope of functionality.</t>
<t>A definition in an sdfThing group can refine the metadata of the definitions it
is composed of: other definitions in sdfThing groups or definitions in sdfObject groups.</t>
</section>
</section>
<section anchor="member-names">
<name>Member names: Given Names and Quality Names</name>
<t>SDF documents are JSON maps that mostly employ JSON maps as
member values, which in turn mostly employ JSON maps as their
member values, and so on.
This nested structure of JSON maps creates a tree, where the edges
are the member names (map keys) used in these JSON maps.
(In certain cases, where member names are not needed, JSON arrays may
be interspersed in this tree.)</t>
<section anchor="given-names-and-quality-names">
<name>Given Names and Quality Names</name>
<t>For any particular JSON map in an SDF document, the set of member
names that are used is either of:</t>
<ul spacing="normal">
<li>
<t>A set of "<em>Quality Names</em>", where the entries in the map are
Qualities. Quality Names are defined by the present specification
and its extensions, together with specific semantics to be
associated with the member value given with a certain Quality Name.</t>
</li>
<li>
<t>A set of "<em>Given Names</em>", where the entries in the map are separate
entities (definitions, declarations, etc.) that each have names that
are chosen by the SDF document author in order that these names can be
employed by a user of that model.</t>
</li>
</ul>
<t>In a path from the root of the tree to any leaf, Quality Names and
Given Names roughly alternate (with the information block,
<xref target="information-block"/>, as a prominent exception).</t>
<t>The meaning of the JSON map that is the member value associated
with a Given Name is derived from the Quality Name that was used as
the member name associated to the parent.
In the CDDL grammar given in <xref target="syntax"/>, JSON maps with member names that are
Given Names are defined using the CDDL generic rule reference <tt>named<membervalues></tt>,
where <tt>membervalues</tt> is in turn the structure of the member values of the
JSON map, i.e., the value of the member named by the Given Name.
As quality-named maps and given-named maps roughly alternate in
a path down the tree, <tt>membervalues</tt> is usually a map built from
Quality Names as keys.</t>
</section>
<section anchor="hierarchical-names">
<name>Hierarchical Names</name>
<t>From the outside of a specification, Given Names are usually used as
part of a hierarchical name that looks like a JSON pointer <xref target="RFC6901"/>,
itself generally rooted in (used as the fragment identifier in) an
outer namespace that looks like an <tt>https://</tt> URL (see <xref target="names-and-namespaces"/>).</t>
<t>As Quality Names and Given Names roughly alternate in a path into the
model, the JSON pointer part of the hierarchical name also alternates
between Quality Names and Given Names.</t>
<t>Note that the actual Given Names may need to be encoded when specified
via the JSON pointer fragment identifier syntax, and that there are
two layers of such encoding: tilde encoding of <tt>~</tt> and <tt>/</tt> as per
<xref section="3" sectionFormat="of" target="RFC6901"/>, and then percent encoding of the
tilde-encoded name into a valid URI fragment as per <xref section="6" sectionFormat="of" target="RFC6901"/>.
For example, when a model is using the Given Name</t>
<artwork><![CDATA[
warning/danger alarm
]]></artwork>
<t>(with an embedded slash and a space) for an
sdfObject, that sdfObject may need to be referenced as</t>
<artwork><![CDATA[
#/sdfObject/warning~1danger%20alarm
]]></artwork>
<t>To sidestep potential interoperability problems, it is probably wise
to avoid characters in Given Names that need such encoding (Quality
Names are already defined in such a way that they never do).</t>
</section>
<section anchor="gnqn">
<name>Extensibility of Given Names and Quality Names</name>
<t>In SDF, both Quality Names and Given Names are <em>extension points</em>.
This is more obvious for Quality Names: Extending SDF is mostly done
by defining additional qualities. To enable non-conflicting third
party extensions to SDF, qualified names (names with an embedded
colon) can be used as Quality Names.</t>
<t>A nonqualified Quality Name is composed of ASCII letters, digits, and
<tt>$</tt> signs, starting with a lower case letter or a <tt>$</tt> sign (i.e.,
using a pattern of "<tt>[a-z$][A-Za-z$0-9]*</tt>").
Names with <tt>$</tt> signs are intended to be used for functions separate
from most other names; for instance, in this specification <tt>$comment</tt>
is used for the comment quality (the presence or absence of a
<tt>$comment</tt> quality does not change the meaning of the SDF model).
Names that are composed of multiple English words can use the
"lowerCamelCase" convention <xref target="CamelCase"/> for indicating the word
boundaries; no other use is intended for upper case letters in quality
names.</t>
<t>A qualified Quality Name is composed of a Quality Name Prefix, a <tt>:</tt>
(colon) character, and a nonqualified Quality Name.
Quality Name Prefixes are registered in the "Quality Name Prefixes"
registry in the "Semantic Definition Format (SDF)" registry group (<xref target="qnp"/>).
They are
composed of lower case ASCII letters and digits, starting with a lower
case ASCII letter (i.e., using a pattern of "<tt>[a-z][a-z0-9]*</tt>").</t>
<t>Given Names are not restricted by the formal SDF syntax.
To enable non-surprising name translations in tools, combinations of
ASCII alphanumeric characters and <tt>-</tt> (ASCII hyphen/minus) are preferred,
typically employing kebab-case for names constructed out of multiple
words <xref target="KebabCase"/>. ASCII hyphen/minus can then unambiguously be
translated to an ASCII <tt>_</tt> underscore character and back depending on
the programming environment.
Some styles also allow a dot ("<tt>.</tt>") in given names.
Given Names are often sufficiently self-explanatory that they can be
used in place of the <tt>label</tt> quality if that is not given.
In turn, if a given name turns out too complicated, a more elaborate
<tt>label</tt> can be given and the given name kept simple.
As given names are "programmers' names", base SDF does not address
internationalization of given names.
(More likely qualities to receive localizable equivalents by
exercising the quality name extension point are <tt>label</tt> and
<tt>description</tt>).</t>
<t>Further, to enable Given Names to have a more powerful role in building
global hierarchical names, an extension is planned that makes use of
qualified names for Given Names.
So, until that extension is defined, Given Names with one or more
embedded colons are reserved and <bcp14>MUST NOT</bcp14> be used in an SDF document.</t>
<t>All names in SDF are case-sensitive.</t>
</section>
</section>
</section>
<section anchor="sdf-structure">
<name>SDF structure</name>
<t>SDF definitions are contained in SDF documents, together with data
about the SDF document itself (information block).
Definitions and declarations from additional SDF documents can be
referenced; together with the definitions and declarations in the
referencing SDF document they build the SDF model expressed by that
SDF document.</t>
<t>Each SDF document is represented as a single JSON map.
This map can be thought of as having three blocks: the information
block, the namespaces block, and the definitions block.
These blocks contain zero or more JSON name/value pairs, the names of
which are quality names and the values of which mostly are (nested)
maps (the exception defined in SDF base is the defaultNamespace
quality, the value of which is a text string).
An empty nested map of this kind is equivalent to not having the
quality included at all.</t>
<section anchor="information-block">
<name>Information block</name>
<t>The information block contains generic metadata for the SDF document
itself and all included definitions.
To enable tool integration, the information block is optional in the grammar
of SDF; most processes for working with SDF documents will have policies
that only SDF documents with an info block can be processed.
It is therefore <bcp14>RECOMMENDED</bcp14> that SDF validator tools emit a warning
when no information block is found.</t>
<t>The keyword (map key) that defines an information block is "info". Its
value is a JSON map in turn, with a set of entries that represent qualities that apply to the included definition.</t>
<t>Qualities of this map are shown in <xref target="infoblockqual"/>.
None of these qualities are required or have default values that are
assumed if the quality is absent.</t>
<table anchor="infoblockqual">
<name>Qualities of the Information Block</name>
<thead>
<tr>
<th align="left">Quality</th>
<th align="left">Type</th>
<th align="left">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">title</td>
<td align="left">string</td>
<td align="left">A short summary to be displayed in search results, etc.</td>
</tr>
<tr>
<td align="left">description</td>
<td align="left">string</td>
<td align="left">Long-form text description (no constraints)</td>
</tr>
<tr>
<td align="left">version</td>
<td align="left">string</td>
<td align="left">The incremental version of the definition</td>
</tr>
<tr>
<td align="left">modified</td>
<td align="left">string</td>
<td align="left">Time of the latest modification</td>
</tr>
<tr>
<td align="left">copyright</td>
<td align="left">string</td>
<td align="left">Link to text or embedded text containing a copyright notice</td>
</tr>
<tr>
<td align="left">license</td>
<td align="left">string</td>
<td align="left">Link to text or embedded text containing license terms</td>
</tr>
<tr>
<td align="left">features</td>