Personal Universal Controller
Appliance Specification Language Documentation

Documention originally written by Jeffrey Nichols and Mathilde Pignol.

Language design by the personal universal controller working group: Michael Higgins, Joe Hughes, Peter Lucas, Brad A. Myers, Jeffrey Nichols, and Mathilde Pignol. Speech interface contributions by Thomas K. Harris.



Table of Contents

  1. Introduction
  2. Revision History
  3. Conceptual Basis
  4. Language Description
  5. DTD
  6. Tag Reference
  7. Future Work
  8. Appendix A. Example Specification
  9. References

Introduction

The personal universal controller (PUC) project's goal is to build a software framework running on top of a personal digital assistant (PDA) that is capable of providing an interface that will allow users to control any appliance within their environment. In essence, the PUC is a device-independent, appliance-independent, user-dependent remote control device.

Because of the universal nature of the PUC, it is not reasonable to pre-program the controller device with an interface for every appliance that might be encountered. Similarly, it is not reasonable to require each appliance to provide hard-coded interfaces for several device form factors, and expect the controller devices to interpolate to their actual form factor. This approach ignores user interface conventions that may differ among controller platforms, which cannot easily be interpolated between. For example, certain platforms may not have support for certain types of widgets, and it is possible to imagine a future device that would differ significantly from the devices of today (e.g. a watch with a circular display that uses several physical dials for input).

We have chosen to automatically generate user interfaces on the controller device from an interface-independent specification language. This specification language describes the functions of the appliance and provides knowledge about how these functions relate to each other. We hope that many different kinds of interfaces can be generated from this specification, including interfaces for handhelds, WAP cellular phones, and future devices with new and different interaction styles. We also plan to explore the use of our specification with the automatic generation of speech interfaces.

This document describes the specification language that we have designed for supporting automatic generation of user interfaces. It begins with a description of the conceptual basis for the language, and then defines the language in concrete terms. The document concludes with a section detailing planned additions to the specification language. An example specification is also included in the first appendix.

Users of this document may also be interested in documentation of the network protocol that is used by PUCs to communicate with appliances.

Revision History

DateNameComments
02/22/2002 jwn Fixed typos and added information about new tags for supporting the creation of speech interfaces from the specification language. See <phonetic> tag and the label dictionary explanation.
02/23/2002 jwn Made priority a parameter of <group>, <state>, <command>, and <explanation> instead of having its own tag.
02/27/2002 jwn Made changes to support the DTD and its formatting requirements. Added the DTD section. Updated the example spec to reflect all of the recent language revisions. Added the <apply-type> and <object-ref> tags to support the reuse of type declarations and multiple occurences of the same object within the group tree. This was previously included as a feature that was incompatible with the restrictions of the DTD. Added the <number> tag to make numeric values symmetrical with the use of <refvalue>, again for DTD conformance. Also removed the recording parameter from the <map> and <labels> elements. Instead, each of these elements may now contain multiple <text-to-speech> elements that may specify similar information.
03/11/2002 jwn Added a reference to the new protocol documentation.

Conceptual Basis

The design of the specification language was based upon prototyping interfaces for a phone and a stereo appliance on a standard handheld form factor (we tried both Palm and PocketPC). These prototypes taught us several things about the functions of appliances:

Each of these items are described in more detail below.

Appliance Objects

Three types of appliance objects are supported in the specification language.

Although there are differences between states, commands and explanations, they also share a common property of being enabled. When an object is enabled (or active), the user interface widgets that correspond to that object can be manipulated by the user. Knowing the circumstances in which an object will be enabled or disabled can provide a helpful hint for structuring the interface, because items that are active in similar situations can be grouped, and items can be placed on panels such that the widgets are not visible when the object would not be active. Specifying the prior knowledge of the enabled property is discussed in more detail in the Dependency Information sub-section.

Label Information

Another common property of appliance objects is the need to specify rich labeling information for flexibility when generating interfaces in different form factors.

To support specifying labeling information, we use the concept of a label dictionary. At any place in the specification where a label can be entered, more than one label may be provided. It is expected that these labels would all contain the same general information, but vary in terms of length and detail. The interface generator would choose the longest label that fit within the space allocated on the screen.

Labels can be specified for any appliance object, and also be linked with particular values of an appliance state's type.

This language also supports the specification of label information for speech interfaces. This support is for both recognition and text-to-speech. Label dictionaries can store phonetic information to help recognizers interpret label names. Multiple pronunciations can be specified for robustness, just as multiple labels can be specified. To assist text-to-speech engines, each label dictionary can be associated with a URL that points to an audio recording of the label.

State Variable Types

Every appliance state has a type object associated with it. The type information is used to determine what kinds of widgets can be used to manipulate the state and may be used in the future as one method of determining whether a standard widget configuration should be used in certain circumstances.

There are currently eight different kinds of types that can be used in the specification:

Italicized types have not yet been implemented.

Each of these types has a different set of parameters that can be specified for it. For a complete list of those parameters, see the tag reference.

The custom type is used for defining domain-specific types that can be used by the interface generator in situations where domain-specific information or widgets are available. This is a first cut at providing a means of referring to domain-specific information that is shared a priori by the controller and the appliance. In the future, we anticipate providing a way for the controller to download this information from the appliance when it is not understood. For example, if a controller does not understand a particular custom type, it would be able to request the appliance to send it the basic type components of the custom type.

The specification language contains a provision for re-using type declarations in subsequently defined state variables via the <apply-type> element. This allows two or more state variables to have the same type without specifying that information multiple times in a specification. No data is shared between those state variables.

Dependency Information

Dependency information is specified for each appliance object as a boolean equation. This information gives the interface generator some approximate a priori knowledge of when the object will be enabled (see the Appliance Objects section for more information).

Three kinds of dependencies can be specified. Each of these dependencies specifies a state that is depended upon, and a value of that state.

These dependencies can be composed into boolean formulas using AND and OR.

Dependency information is used for determining the structure of the generated user interface. We believe that it is possible to determine all of the important structural information from the dependency information alone.

The Group Tree

It is not always sufficient to use only dependency information for determining the structure of the user interface however, because the resolution of the structure found from the dependency information may not be fine enough for the form factor of the user interface. To improve the resolution of the structure choices, the specification also includes a human-designed group tree, which tells the user interface generator how to split widgets across screens when dependency information does not exist to make the decision otherwise.

In some cases, it may be useful to place an appliance object at multiple locations in the group tree. This is allowed is the specification via the <object-ref> element.

Language Description

Our specification language is based on the XML standard from the Worldwide Web Consortium. Most XML document formats have a DTD or a Schema, which define their structure. We have created a DTD for our language and we may specify a Schema in the future. For specific formatting information about our language, please refer to the DTD. The tag reference and the example specification in Appendix A may also be helpful for understanding the particulars of our specification language.

All appliance specification should contain the following line as a part of the XML prolog.

<!DOCTYPE spec SYSTEM "http://www.cs.cmu.edu/~jeffreyn/controller/pucspec.dtd">

DTD

<!-- This is version 0.1 of the Personal Universal Controller -->
<!-- Appliance Specification Document Type Definition -->

<!ENTITY % PRIORITY '(1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10)'>

<!ELEMENT spec (groupings)>
<!ATTLIST spec name CDATA #REQUIRED>

<!ELEMENT groupings (group+)>

<!ELEMENT group (active-if?, labels?, (command | explanation | group | state | object-ref)+)>
<!ATTLIST group priority %PRIORITY; #IMPLIED>

<!ELEMENT active-if (and | or | (equals | greaterthan | lessthan)+)>
<!ATTLIST active-if ignore (parent | all) #IMPLIED>

<!ELEMENT command (labels?, active-if?)>
<!ATTLIST command name ID #REQUIRED 
                  priority %PRIORITY; #IMPLIED>

<!ELEMENT explanation (labels, active-if?)>
<!ATTLIST explanation name CDATA #REQUIRED priority %PRIORITY; #IMPLIED>

<!ELEMENT labels ((label | refstring | phonetic | text-to-speech)+)>
<!ATTLIST labels recording CDATA #IMPLIED>

<!ELEMENT state ((type | apply-type), labels?, active-if?)>
<!ATTLIST state name ID #REQUIRED 
                access (ReadOnly | WriteOnly) #IMPLIED 
		priority %PRIORITY; #IMPLIED>

<!ELEMENT object-ref EMPTY>
<!ATTLIST object-ref name IDREF #REQUIRED>

<!ELEMENT and ((equals | greaterthan | lessthan)+)>

<!ELEMENT equals (#PCDATA)>
<!ATTLIST equals state IDREF #REQUIRED>

<!ELEMENT greaterthan (#PCDATA)>
<!ATTLIST greaterthan state IDREF #REQUIRED>

<!ELEMENT lessthan (#PCDATA)>
<!ATTLIST lessthan state IDREF #REQUIRED>

<!ELEMENT or ((equals | greaterthan | lessthan)+)>

<!ELEMENT label (#PCDATA)>

<!ELEMENT phonetic (#PCDATA)>

<!ELEMENT text-to-speech EMPTY>
<!ATTLIST text-to-speech text CDATA #REQUIRED 
                         recording CDATA #IMPLIED>

<!ELEMENT type (valueSpace, expectedValues?, valueLabels?)>
<!ATTLIST type name ID #IMPLIED>

<!ELEMENT apply-type EMPTY>
<!ATTLIST apply-type name IDREF #REQUIRED>

<!ELEMENT refstring EMPTY>
<!ATTLIST refstring state IDREF #REQUIRED>

<!ELEMENT expectedValues (boolean | custom | enumerated | fixedpt | integer | string | floatingpt)>

<!ELEMENT valueLabels (map+)>

<!ELEMENT valueSpace (boolean | custom | enumerated | fixedpt | integer | string | floatingpt)>

<!ELEMENT boolean EMPTY>

<!ELEMENT custom (#PCDATA)>

<!ELEMENT enumerated (items+)>

<!ELEMENT fixedpt (incr?, max?, min?)>

<!ELEMENT integer (incr?, max?, min?)>

<!ELEMENT floatingpt (max?, min?)>

<!ELEMENT string EMPTY>

<!ELEMENT map ((label | phonetic | refstring | text-to-speech)+)>
<!ATTLIST map index CDATA #REQUIRED 
              enable CDATA #IMPLIED>

<!ELEMENT items (#PCDATA)>

<!ELEMENT incr (number | refvalue)>

<!ELEMENT max (number | refvalue)>

<!ELEMENT min (number | refvalue)>

<!ELEMENT number (#PCDATA)>

<!ELEMENT refvalue EMPTY>
<!ATTLIST refvalue state IDREF #REQUIRED>

Tag Reference

This section describes all of the tags available in the specification language and how they are used.

Tag Index

<active-if>
Contains dependency information for an appliance object or a group of objects. Defines an and relation with all dependencies that are contained within, unless they are grouped within a logical operation block, such as <and> or <or> tags.
<and>
Defines an and relation with the dependencies that are contained within.
<apply-type>
Allows the re-use of an existing type block within a specification.
<boolean/>
Boolean type - takes on true or false values.
<command>
Defines a command appliance object.
<custom>
Defines a custom value space. The string within this tag defines the name of the custom space.
<enumerated>
Enumerated type - Define the number of items in the enumeration using the <items> tag. Labels can be defined within the <valueLabels> tag.
<equals>
Used in conjunction with the <active-if> tag to define equals dependency information for this state variable.
<expectedValues>
Similar to the <valueSpace> tag, but defines the most likely space of the variable rather than its definite limits. The interface generator may use this information to pick a different widget than it would have otherwise.
<explanation>
Defines an explanation appliance object.
<fixedpt>
Fixed Point type - for variables that take the form of decimal values with a fixed decimal point location. Minimum, maximum and increment values can be defined using the <min>, <max>, and <incr> tags.
<floatingpt>
Floating Point type - for variables that take the form of decimal values. Minimum and maximum values can be defined using the <min> and <max> tags.
<greaterthan>
Used in conjunction with the <active-if> tag to define greaterthan dependency information for this state variable.
<group>
Used to define the nodes of the group tree.
<groupings>
Defines the section that includes the group tree.
<incr>
Defines the increment that an integer or fixed point variable must use. This restriction means that the variable must have a value equals to its minimum + n * increment, where n is an integer.
<items>
Used to denote how many values there are in an <enumerated> type. Labels for the items can be defined within the <valueLabels> tag.
<integer>
Integer type - for variables that take the form of integers. Minimum, maximum and increment values can be defined using the <min>, <max>, and <incr> tags.
<label>
Defines a label to be included within a label dictionary.
<labels>
Defines a label dictionary for an appliance object or group. The <map> tag specifies a dictionary to be associated with the specific value of a variable.
<lessthan>
Used in conjunction with the <active-if> tag to define lessthan dependency information for this state variable.
<map>
Specifies a label dictionary for the specific value of a variable.
<min>
Defines the minimum value a numeric variable may take.
<max>
Defines the maximum value a numeric variable may take.
<number>
Used to define a numeric value for any of the value space parameter tags except the pointpos tag. This block must contain a number.
<object-ref>
Allows an object to be placed in more than one location within the group tree. Any object (state, command, or explanation) may be referenced with the object-ref element.
<or>
Defines an or relation with the dependencies that are contained within.
<phonetic>
Provides pronunciation information for speech interfaces that are based upon this specification language. Many pronunciations may be included in a label dictionary.
<pointpos>
Defines the position of the decimal point for a fixed point type.
<refstring>
Used to define a string for a <label> tag that depends on the value of state variable with a string type.
<refvalue>
Used to define a numeric value for any of the value space parameter tags except the pointpos tag that depends on the value of a numeric state variable. E.g. a refvalue can be used to set the maximum of a numeric state variable to be the value of another state variable.
<spec>
Every specification begins with this tag.
<state>
Defines a state variable appliance object.
<string/>
String type - for variables that take the form of strings.
<text-to-speech>
Defines a text-to-speech entry to be included within a label dictionary.
<type>
Describes the value space of a state variable (ex: Boolean, Integer, etc...), its expected space and the labels that its values take.
<valueLabels>
Contains one or more <map> tags that provide label dictionaries for specific values that the variable might have.
<valueSpace>
Defines the space of values that a state variable must be within.

Tag Descriptions

<spec>
<spec name="Sample Specification"></spec>
Every specification begins with this tag

Placement:
First tag of the spec after the required XML header (E.g. <?xml version="1.0" encoding="UTF-8"?>)
Parameters:
  • name - required The name of the appliance defined in this specification
May Contain:
<groupings>

<groupings>

<groupings></groupings>
Contains the entire group tree.

Placement:
Inside the <spec> tag
May Contain:
<group>

<group>

<group priority=10></group>
Defines the nodes of the group tree.

Group nodes may be assigned a label dictionary with the <labels> tag. Group nodes may also specify dependencies for all their members using the <active-if> tag. These dependencies are applied to the rest of the member's dependencies with an AND logical operation.

Placement:
Inside the <spec> tag
Parameters:
  • priority - The priority this group should be assigned relative to other objects in its parent group.
May Contain:
<active-if>, <labels>, <command>, <explanation>, <group>, <state> <object-ref>

<object-ref>

<object-ref name="ObjectName"/>
Allows an object to be placed in more than one location within the group tree. Any object (state, command, or explanation) may be referenced with the object-ref element. The object must have been declared earlier in the specification document.

Placement:
Inside a <group> tag
Parameters:
  • name - required The name of the appliance object to reference.

<state>

<state name="StateName" access="ReadOnly" | "WriteOnly" priority=10></state>
Defines a state variable appliance object.

Placement:
Inside a <group> tag
Parameters:
  • name - required The name of the state variable.
  • priority - The priority this state should be assigned relative to other objects in the same group.
  • access - defines how users interact with this state variable. Possible options are ReadOnly and WriteOnly.
May Contain:
<active-if>, <labels>, <type>

<command>

<command name="CommandName" priority=10></command>
Defines a command appliance object.

Placement:
Inside a <group> tag
Parameters:
  • name - required The name of the command.
  • priority - The priority this state should be assigned relative to other objects in the same group.
May Contain:
<active-if>, <labels>,

<explanation>

<explanation name="ExplanationName" priority=10></explanation>
Defines a explanation appliance object. The labels block, which is required for an explanation object, defines the text that will be used for the explanation.

Placement:
Inside a <group> tag
Parameters:
  • name - required The name of the explanation.
  • priority - The priority this state should be assigned relative to other objects in the same group.
May Contain:
<active-if>, <labels>,

<type>

<type name="TypeName"></type>
<type name="TypeName"/>
Describes the value space of a state variable (ex: Boolean, Integer, etc...), its expected space and the labels that its values take.

Placement:
Inside the <state> tag
Parameters:
  • name - The name of the type object.
May Contain:
<expectedValues>, <valueLabels>, <valueSpace>

<apply-type>

<apply-type name="TypeName"/>
Allows the re-use of an existing type block within a specification. Using this element is exactly the same as cutting and pasting the type block. No data will be shared with other states that apply the same type. The type must have been declared earlier in the specification document.

Placement:
Inside a <group> tag
Parameters:
  • name - required The name of the appliance object to reference.

<valueSpace>

<valueSpace></valueSpace>
Defines the space of values that a state variable may be within.

Placement:
Inside the <type> tag
May Contain:
<boolean/>, <custom>, <enumerated>, <fixedpt>, <floatingpt>, <integer>, <string/>

<expectedValues>

<expectedValues></expectedValues>
Similar to the <valueSpace> tag, but defines the most likely space of the variable rather than its definite limits. The interface generator may use this information to pick a different widget than it would have otherwise.

Placement:
Inside the <type> tag
May Contain:
<boolean/>, <custom>, <enumerated>, <fixedpt>, <floatingpt>, <integer>, <string/>

<boolean/>

<boolean/>
Boolean type - takes on true or false values.

Placement:
Inside the <valueSpace> or <expectedValues> tag

<custom/>

<custom/>
Defines a custom value space. The string within this tag defines the name of the custom space.

Placement:
Inside the <valueSpace> or <expectedValues> tag

<enumerated>

<enumerated></enumerated>
Enumerated type - Define the number of items this composite type contains using the <items> tag. Note: the <valueLabels> tag must contain <map> tags that map each of the enumerated values with a label. So if there are 5 enumerated values in a particular enumerated type (denoted by <items>5<items/>) the valueLabels section must contain 5 different mappings of values to labels.

Enumerated type values are treated as integers that range between 1 and the number of items in the type. Zero is not a valid value for an enumerated type. This is important when you specify an index to the <map> tag;

Placement:
Inside the <valueSpace> or <expectedValues> tag
May Contain:
<items>

<items>

<items></items>
Used to denote how many enumerated values there are in an <enumerated> type. Labels for the items can be defined within the <valueLabels> tag.

Placement:
Inside the <enumerated> tag

<fixedpt>

<fixedpt></fixedpt>
Fixed Point type - for variables that take the form of decimal values with a fixed decimal point. Minimum, maximum, and increment values can be defined using the <min>, <max>, and <incr> tags.

Placement:
Inside the <valueSpace> or <expectedValues> tag
May Contain:
<incr>, <max>, <min>

<pointpos>

<pointpos></pointpos>
Defines the position of the decimal point for a fixed point type.

Placement:
Inside the <fixedpt> tag

<floatingpt>

<floatingpt></floatingpt>
Floating Point type - for variables that take the form of decimal values. Minimum and maximum values can be defined using the <min> and <max> tags.

Placement:
Inside the <valueSpace> or <expectedValues> tag
May Contain:
<max>, <min>

<integer>

<integer></integer>
Integer type - for variables that take the form of integers. Minimum, maximum, and increment values can be defined using the <min>, <max>, and <incr> tags.

Placement:
Inside the <valueSpace> or <expectedValues> tag
May Contain:
<incr>, <max>, <min>

<incr> ... <max> ... <min>

<incr></incr>
<max></max>
<min></min>
Describe minimum, maximum and increment values that the variable may take.

The increment may not be defined for the floating point type.

Placement:
Inside the <fixedpt>, <floatingpt> (except for incr), and <integer> tags.
May Contain:
<number> <refvalue>

<string/>

<string/>
String type - for variables that take the form of strings.

Placement:
Inside the <valueSpace> or <expectedValues> tag

<valueLabels>

<valueLabels></valueLabels>
Contains one or more <map> tags that provide label dictionaries for specific values that the variable might have.

Placement:
Inside the <type> tag
May Contain:
<map>

<map>

<map index="value" enable="StateName"  recording="URL"></map>
Specifies a label dictionary for the specific value of a variable (specified by the index parameter).

Certain values of a variable can also be enabled based on the state of another boolean state variable, as specified in the enable parameter. This parameter may also start with an ! symbol, which indicates that the enable should be based on the inverse of that states value.

Placement:
Inside the <valueLabels> tag.
Parameters:
  • index - required The value to associate this dictionary with
  • enable - The name of a state variable, possibly preceeded by an exclamation point
May Contain:
<label>, <refstring>, <phonetic>, <text-to-speech>

<labels>

<labels recording="URL"></labels>
Defines a label dictionary for an appliance object or group. The <map> tag specifies a dictionary to be associated with the specific value of a variable.

Placement:
Inside the <command>, <explanation>, <group>, or <state> tag.
May Contain:
<label>, <refstring>, <phonetic>, <text-to-speech>

<text-to-speech>

<text-to-speech text="<whisper>mute</whisper>" recording="mute.au"/>
Defines a text-to-speech entry to be included within a label dictionary. The text parameter may contain embedded SABLE markup tags.

Placement:
Inside the <labels> or <map> tags
Parameters:
  • text - required the text to be spoken. May contain embedded SABLE tags.
  • recording - a recording of the text, if available

<label>

<label></label>
Defines a label to be included within a label dictionary.

Placement:
Inside the <labels> or <map> tags
May Contain:
string

<phonetic>

<phonetic></phonetic>
Defines a pronunciation to be included within a label dictionary.

Placement:
Inside the <labels> or <map> tags
May Contain:
string of phonemes using the arpabet representation

<active-if>

<active-if ignore="all" | "parent"></active-if>
Contains dependency information for an appliance object or group of objects. Defines an and relation with all dependencies that are contained within, unless they are grouped within a logical operation block, such as <and> or <or> tags.

Placement:
Inside the <command>, <explanation>, <group>, or <state> tag.
Parameters:
  • ignore - stop dependency inheritance through the group tree. The possible options are to omit the option, parent, and all
May Contain:
<and>, <equals>, <greaterthan>, <lessthan>, <or>

<equals>

<equals state="SomeState">value</equals>
Used in conjunction with the <active-if> tag to define equals dependency information for this state variable.

Placement:
Inside the <active-if> tag.
Parameters:
  • state - required The name of the state that is depended upon
May Contain:
value

<greaterthan>

<greaterthan state="SomeState">value</greaterthan>
Used in conjunction with the <active-if> tag to define greater-than dependency information for this state variable.

Placement:
Inside the <active-if> tag.
Parameters:
  • state - required The name of the state that is depended upon
May Contain:
value

<lessthan>

<lessthan state="SomeState">value</lessthan>
Used in conjunction with the <active-if> tag to define less-than dependency information for this state variable.

Placement:
Inside the <active-if> tag.
Parameters:
  • state - required The name of the state that is depended upon
May Contain:
value

<and>

<and></and>
Defines an and relation with the dependencies that are contained within.

Placement:
Inside the <active-if> tag.
May Contain:
<equals>, <greaterthan>, <lessthan>,

<or>

<or></or>
Defines an or relation with the dependencies that are contained within.

Placement:
Inside the <active-if> tag.
May Contain:
<equals>, <greaterthan>, <lessthan>,

<refstring>

<refstring state="StateName"/>
Used to define a string for a <label dictionary> that depends on the value of a state variable with a string type.

Placement:
Inside the <labels> or <map> tags.
Parameters:
  • state - required The name of a state variable with a string type

<refvalue>

<refvalue state="StateName"/>
Used to define a numeric value for any of the value space parameter tags, except the <pointpos> tag, that depends on the value of a numeric state variable. E.g. a refvalue can be used to set the maximum of a numer state variable to be the value of another state variable.

Placement:
Inside the <max>, <min>, and <incr> tags.
Parameters:
  • state - required The name of a state variable with a numeric type

<number>

<number>12</number>
Used to define a numeric value for any of the value space parameter tags, except the <pointpos> tag. This block must contain a number.

Placement:
Inside the <max>, <min>, and <incr> tags.
Must Contain:
A numeric value

Future Work

In the future, we are planning to add several new features to the specification language. This section discusses a few of these features.

Hints

Sometimes when defining a particular function of an appliance, it seems useful to give the interface generator a hint of how to appropriately render that function. For example, the balance of the output between the right and left speakers has an inherent horizontal quality that should be maintained in the user interface. Currently, there is no way for the specification designer to provide the interface generator with this kind of meta-information that may be critical to generating a good interface. Hints are a generic solution to this problem.

Unfortunately, the idea of a hint is a little too generic to support within the spec. While it is useful to have this information, the language should avoid allowing the specification designer to over-specify a device. This keeps the size of a device specification from getting excessively large, and also relieves the programmers of an interface generator from writing code to interpret a generic hint. A happy medium will need to be achieved.

Standard Widget Arrangements

One type of hint that is particularly important are hints about standard arrangements of widgets. For example, the control buttons for a CD or Tape player are typically arranged in two rows, with a large play button on top, adjacent to smaller pause and stop button. The bottom row usually consists of the fast-forward and rewind buttons, which are usually larger than the stop and pause buttons, but smaller than the play button. It may also be valuable to duplicate control arrangements from the appliance, if the transfer of interface knowledge from the appliance to the controller would be useful.

In the future, we will work on methods of communicating this information and understanding the trade-offs between when available layout information should be used and when it should not.

Command/State Relationships

Some commands have an implicit relationship with state variables on the device. For example, the seek button on a radio must be represented as a command, because its affect on the radio station state variable can not be known a priori. However, it does affect a state variable in some way and this information could useful to the user interface. This will be included in an upcoming revision of the specification language.

Lists

Lists are important part of many user interfaces. MP3 players have a list of songs that they play from, and radios may have a list of preset stations that can be jumped to. Earlier in this document, we specified lists as one of the types that would be supported by the PUC in the future. It turns out that supporting lists is more difficult than supporting the other basic types, because there are many different types of list operations, and not every list operation makes sense in every instance of a list in a user interface. How do we specify which list operations are available?

One method that might be used for supporting lists in a more general way is a task model. To date, many user interface generation researchers have used task models to aid in the development of interface generators. We haven't used a task model so far, because the typical tasks that we have encountered are typically one or two steps deep and multiple tasks may have operations that interleave with each other. This seems less likely to occur with a list, with the added benefit that the description of the operations on the list would be reduced to the tasks that the user will want to perform.

Appendix A. Example Specification

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE spec SYSTEM "http://www.cs.cmu.edu/~jeffreyn/controller/pucspec.dtd">

<!-- Note: This file is best viewed in Internet Explorer. --> 

<!-- This is specification of the Audiophase home stereo that was used
     for the PDG annual meeting on 02/15/2002. -->
<spec name="Audiophase 5 CD Stereo">

  <groupings>

  <group>
    <state name="PowerState" priority="10">
      <type name="OnOffType">
        <valueSpace>
          <boolean/>
        </valueSpace>
        <valueLabels>
          <map index="false">
            <label>Off</label>
          </map>
          <map index="true">
            <label>On</label>
	  </map>
	</valueLabels>
      </type>

      <labels>
        <label>Stereo Power</label>
        <label>Power</label>
	<label>Powr</label>
	<label>Pwr</label>
      </labels>
    </state>

    <group>

      <active-if>
	<equals state="PowerState">true</equals>
      </active-if>

      <labels>
        <label>Volume</label>
	<label>Vol</label>
      </labels>

      <command name="VolumeUp" priority="10">
        <labels>
          <label>Volume Up</label>
          <label>Vol. Up</label>
	  <label>^</label>
        </labels>
      </command>

      <command name="VolumeDn" priority="10">
        <labels>
	  <label>Volume Down</label>
	  <label>Vol. Down</label>
	  <label>Down</label>
	  <label>v</label>
        </labels>
      </command>
    </group>

    <state name="XBassState" priority="5">
      <type>
        <valueSpace>
	  <boolean/>
	</valueSpace>
      </type>

      <labels>
        <label>X-Bass</label>
      </labels>

      <active-if>
	<equals state="PowerState">true</equals>
      </active-if>
    </state>

<group>
      <active-if>
	<equals state="PowerState">true</equals>
      </active-if>

<state name="ModeState">
  <type>
    <valueSpace>
      <enumerated>
        <items>4</items>
      </enumerated>
    </valueSpace>
    <valueLabels>
      <map index="1">
        <label>Tape</label>
      </map>
      <map index="2">
        <label>CD</label>
      </map>
      <map index="3">
        <label>AUX</label>
      </map>
      <map index="4">
        <label>Tuner</label>
      </map>
    </valueLabels>
  </type>

  <labels>
    <label>Output Mode</label>
    <label>Mode</label>
  </labels>
</state>

<group>
  <active-if>
    <equals state="ModeState">1</equals>
  </active-if>

  <explanation name="TapeExpl">
    <labels>
      <label>Tape not controllable.</label>
    </labels>
  </explanation>
</group>

<group>
  <active-if>
    <equals state="ModeState">3</equals>
  </active-if>

  <explanation name="AUXExpl">
    <labels>
      <label>AUX not controllable.</label>
    </labels>
  </explanation>
</group>

<group>
  <active-if>
    <equals state="ModeState">4</equals>
  </active-if>

  <labels>
    <label>Tuner</label>
  </labels>

  <state name="RadioBandState">
    <type>
      <valueSpace>
        <boolean/>
      </valueSpace>
      <valueLabels>
        <map index="true">
	  <label>FM</label>
	</map>
	<map index="false">
	  <label>AM</label>
	</map>
      </valueLabels>
    </type>

    <labels>
      <label>Radio Band</label>
      <label>Band</label>
    </labels>
  </state>

  <group>
    <command name="SeekForward">
      <labels>
        <label>Seek Forward</label>
	<label>Seek -></label>
	<label>>></label>
      </labels>
    </command>

    <command name="SeekReverse">
      <labels>
        <label>Seek Reverse</label>
	<label><-Seek</label>
	<label><<</label>
      </labels>
    </command>
  </group>

  <group>
    <active-if>
      <equals state="RadioBandState">true</equals>
    </active-if>

    <state name="FMStation">
      <type name="FMType">
        <valueSpace>
	  <custom>radio/station-fm</custom>
	</valueSpace>
      </type>
      
      <labels>
        <label>Radio Station</label>
	<label>Station</label>
      </labels>
    </state>

    <state name="FMPresetNumber">
      <type name="FMPresetType">
        <valueSpace>
	  <enumerated>
	    <items>5</items>
	  </enumerated>
	</valueSpace>
        <valueLabels>
          <map index="1">
	    <refstring state="FMPresetValue1"/>
	  </map>
	  <map index="2">
	    <refstring state="FMPresetValue2"/>
	  </map>
	  <map index="3">
	    <refstring state="FMPresetValue3"/>
	  </map>	
          <map index="4">
	    <refstring state="FMPresetValue4"/>
	  </map>
	  <map index="5">
	    <refstring state="FMPresetValue5"/>
	  </map>
        </valueLabels>
      </type>
      
      <labels>
        <label>Presets</label>
      </labels>
    </state>
    
    <state name="FMPresetValue1" access="ReadOnly">
      <type>
        <valueSpace>
	  <string/>
	</valueSpace>
      </type>
    </state>

    <state name="FMPresetValue2" access="ReadOnly">
      <type>
        <valueSpace>
	  <string/>
	</valueSpace>
      </type>
    </state>

    <state name="FMPresetValue3" access="ReadOnly">
      <type>
        <valueSpace>
	  <string/>
	</valueSpace>
      </type>
    </state>

    <state name="FMPresetValue4" access="ReadOnly">
      <type>
        <valueSpace>
	  <string/>
	</valueSpace>
      </type>
    </state>

    <state name="FMPresetValue5" access="ReadOnly">
      <type>
        <valueSpace>
	  <string/>
	</valueSpace>
      </type>
    </state>
  </group>

  <group>
    <active-if>
      <equals state="RadioBandState">false</equals>
    </active-if>

    <state name="AMStation">
      <type name="AMType">
        <valueSpace>
	  <custom>radio/station-am</custom>
        </valueSpace>
      </type>

      <labels>
        <label>Radio Station</label>
        <label>Station</label>
      </labels>
    </state>

    <state name="AMPresetNumber">
      <type name="AMPresetType">
        <valueSpace>
	  <enumerated>
	    <items>5</items>
	  </enumerated>
	</valueSpace>
	<valueLabels>
          <map index="1">
	    <refstring state="AMPresetValue1"/>
	  </map>
	  <map index="2">
	    <refstring state="AMPresetValue2"/>
	  </map>
	  <map index="3">
	    <refstring state="AMPresetValue3"/>
	  </map>	
          <map index="4">
	    <refstring state="AMPresetValue4"/>
	  </map>
	  <map index="5">
	    <refstring state="AMPresetValue5"/>
	  </map>
        </valueLabels>
      </type>
      
      <labels>
        <label>Presets</label>
      </labels>
    </state>

    <state name="AMPresetValue1" access="ReadOnly">
      <type>
        <valueSpace>
	  <string/>
	</valueSpace>
      </type>
    </state>

    <state name="AMPresetValue2" access="ReadOnly">
      <type>
        <valueSpace>
	  <string/>
	</valueSpace>
      </type>
    </state>

    <state name="AMPresetValue3" access="ReadOnly">
      <type>
        <valueSpace>
	  <string/>
	</valueSpace>
      </type>
    </state>

    <state name="AMPresetValue4" access="ReadOnly">
      <type>
        <valueSpace>
	  <string/>
	</valueSpace>
      </type>
    </state>

    <state name="AMPresetValue5" access="ReadOnly">
      <type>
        <valueSpace>
	  <string/>
	</valueSpace>
      </type>
    </state>
  </group>
</group>

<group>
  <active-if>
    <equals state="ModeState">2</equals>
  </active-if>

  <labels>
    <label>CD</label>
  </labels>

  <state name="CDPlayMode">
    <type>
      <valueSpace>
        <custom>playcontrol</custom>
      </valueSpace>
    </type>

    <labels>
      <label>CD Status</label>
      <label>Status</label>
    </labels>
  </state>

  <group>
    <labels>
      <label>Discs</label>
    </labels>

    <state name="CDDiscActive">
      <type>
        <valueSpace>
	  <enumerated>
	    <items>5</items>
	  </enumerated>
	</valueSpace>
	<valueLabels>
	  <map index="1" enable="Disc1Avail">
	    <label>1</label>
	  </map>
	  <map index="2" enable="Disc2Avail">
	    <label>2</label>
	  </map>
	  <map index="3" enable="Disc3Avail">
	    <label>3</label>
	  </map>
	  <map index="4" enable="Disc4Avail">
	    <label>4</label>
	  </map>
	  <map index="5" enable="Disc5Avail">
	    <label>5</label>
	  </map>
	</valueLabels>
      </type>

      <labels>
        <label>Disc</label>
      </labels>
    </state>

    <state name="Disc1Avail" access="ReadOnly">
      <type name="DiscType">
        <valueSpace>
	  <boolean/>
	</valueSpace>
	<valueLabels>
	  <map index="true">
	    <label>Active</label>
	  </map>
	  <map index="false">
	    <label>Not Active</label>
	  </map>
	</valueLabels>
      </type>

      <labels>
        <label>Disc 1</label>
	<label>1</label>
      </labels>
    </state>

    <state name="Disc2Avail" access="ReadOnly">
      <apply-type name="DiscType"/>

      <labels>
        <label>Disc 2</label>
	<label>2</label>
      </labels>
    </state>

    <state name="Disc3Avail" access="ReadOnly">
      <apply-type name="DiscType"/>

      <labels>
        <label>Disc 3</label>
	<label>3</label>
      </labels>
    </state>

    <state name="Disc4Avail" access="ReadOnly">
      <apply-type name="DiscType"/>

      <labels>
        <label>Disc 4</label>
	<label>4</label>
      </labels>
    </state>

    <state name="Disc5Avail" access="ReadOnly">
      <apply-type name="DiscType"/>

      <labels>
        <label>Disc 5</label>
	<label>5</label>
      </labels>
    </state>
  </group>

  <group>


    <command name="CDPrevTrack">
      <labels>
        <label>Prev</label>
        <label><</label>
      </labels>
    </command>

    <state name="CDTrackState" access="ReadOnly">
      <type>
        <valueSpace>
          <string/>
	</valueSpace>
      </type>

      <labels>
        <label>Track</label>
      </labels>
    </state>

    <command name="CDNextTrack">
      <labels>
        <label>Next</label>
        <label>></label>
      </labels>
    </command>
  </group>

  <state name="CDRandomState">
    <type>
      <valueSpace>
        <boolean/>
      </valueSpace>
    </type>

    <labels>
      <label>Random</label>
    </labels>

    <active-if>
      <equals state="CDPlayMode">1</equals>
    </active-if>
  </state>

  <state name="CDRepeatState">
    <type>
      <valueSpace>
        <enumerated>
	  <items>5</items>
	</enumerated>
      </valueSpace>
      <valueLabels>
        <map index="1">
	  <label>Off</label>
	</map>
        <map index="2">
	  <label>One Track</label>
	  <label>One</label>
	</map>
	<map index="3" enable="CDRandomState">
	  <label>All Tracks</label>
	  <label>All</label>
	</map>
        <map index="4" enable="!CDRandomState">
	  <label>One Disc</label>
	  <label>1 Disc</label>
	</map>
        <map index="5" enable="!CDRandomState">
	  <label>All Discs</label>
	  <label>All</label>
	</map>
      </valueLabels>
    </type>

    <labels>
      <label>Repeat</label>
    </labels>
  </state>

</group>
</group>
</group>
  </groupings>

</spec>