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.
The personal universal controller (PUC) project's goal is to build a software framework running on top of a personal digital assistant (PDA) or other mobile device 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.
Users of this document may also be interested in documentation of the network protocol that is used by PUCs to communicate with appliances.
Date | Name | Comments |
---|---|---|
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. Also moved the published versions of the DTDs and docs to the pebbles web site, and updated the links in this documentation appropriately. |
10/06/2003 | jwn | Started updating documentation to include all changes to the specification in the last year and a half. This includes significant changes to the group systems, new dependencies, list and union structures, Smart Templates, and some changes to which XML tags are allowed. Updates not completed and new version not released. |
05/19/2004 | jwn | Finished updating the documentation for the new specification language format. Wrote and added an XML Schema for the language, and updated the tag reference. Removed the example specification in Appendix A for now, as this document describes changes that are not actually implemented in any specification language. Once the Mitsubishi DVCR spec is complete, I will add it to the appendix. |
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.
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.
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 all these labels contain the same general information, but vary in terms of length and detail. We also allow the specification designer to designate one label as "preferred" for use in an interface. The interface generator would choose the preferred label or the longest label that fits within the space allocated on the screen. In certain situations, the preferred label may be used as the basis for making layout decisions.
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.
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 is one of the paramters that is used to recognize Smart Templates.
There are currently eight different kinds of types that can be used in the specification:
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 binary type is used for data that cannot be described as a string, e.g. images, sound clips, or video. Unlike the other types, interface generators are not expected to have a default rendering for variables with binary types. A Smart Template must be used in conjunction with a binary state to ensure that the state is rendered.
The list selection type allows the user to specify an item in a list. This is used in locations where it would not make sense to duplicate the list state variables. For more on lists see the lists section.
Older versions of the specification language supported a custom primitive type, which was used for representing domain-specific types. This type is no longer allowed. See the section on Smart Templates later for more information on our current solution for this problem.
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.
Proper structure is a very important part of any user interface. In our language we use a hierarchical "group tree" to specify structure. The leaf nodes in the tree are appliance objects, and the branch nodes are groups. Each node in the tree has a name which must not be the same as any other child of its parent. Thus each node has a locally unique name, and a globally unique name can be constructed by pre-pending the names of all a nodes parents. We use a "." character to separate each name. For example, the locally unique name of a state variable might be "PlayState" but the globally unique name would be "Stereo.CD.PlayState". That same specification could also contain other states like "Stereo.Tape.PlayState". Note that the root name "Stereo" cannot be re-used as a name anywhere in the specification.
It is often necessary to explicitly refer to state variables in a specification. This may be done using any name that starts with a globally unique name. Since the root name is unique, the full name will always work. For the above examples, "Tape.PlayState" and "CD.PlayState" would also work, assuming that there are no other groups or states named "CD" or "Tape".
There are three types of groups: normal, list, and union. A normal group is used for putting related data together, similar to a record in a programming language. List and union groups have special behavior beyond that of normal groups, which are discussed in the next section.
Specifying a list group is similar to specifying an array of records in a programming language, and multiple list groups can be nested to create multi-dimensional lists. Each list group has an implicit length state variable (named "Length") that always contains the length of the current list. If this variable is undefined, then the list currently has no members. The specification may define bounds on the length of the list in order to help the interface generator create a better rendering. An exact size may be specified, or a minimum and/or maximum size may be specified.
List groups also maintain an implicit structure to keep track of one or more list selections. The number of selections allowed may be defined in the specification ("one" and "many" are the only options currently), and the default is one if nothing is specified. If a list allows only one selection, then an implicit "Selection" variable is created which contains the index of the current selection (undefined means no selection). If multiple selections are created, then an implicit list group named "Selection" is created. This group contains a "Length" state (as all list groups do) and an "Index" state which contains all of the selected indices.
A union group is simliar to specifying a union in a programming language; of the children within a union (either groups or appliance objects), only one may be active at a time. An implicit state variable named "ChildUsed" is automatically created within a union group that contains the name of the currently active child.
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).
Five kinds of dependencies can be specified. Each of these dependencies specifies a state that is depended upon, and most specify a value of that state. In those cases where a value must be specified, a pointer to another variable may be used instead with the <refvalue> tag.
These dependencies can be composed into boolean formulas using AND and OR.
Specifying dependencies on list state variables must be done using the special <apply-over> element. This element applies the dependencies it contains over all the elements in a list and returns a value depending on the value of its "true-if" property. This property may be either "all", "any" or "none". If "true-if" is "all", then all of the dependencies contained in the "apply-over" element must be true for elements if true is returned. If "true-if" is "any", then all of the dependencies contained in the "apply-over" must be true for one of the elements. If "true-if" is "none", then the dependencies must not be satisfied by any element to return true.
Smart Templates extend the primitive types of the specification language with high-level semantic information. With a Smart Template, a group in a specification might be marked as "media-controls" for example, and an interface generator could use this information to create an interface that uses the standard play and stop icons that people are accustomed to. More information about Smart Templates is available in this paper.
Documentation about applying and specifying templates and a list of the Smart Templates specified so far is available here.
Our specification language is based on the XML standard from the Worldwide Web Consortium. A Schema for the language is shown below. You may separately download the schema from here. The tag reference and the example specifications in Appendix A may also be helpful for understanding the particulars of our specification language.
<?xml version="1.0" encoding="utf-8" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.cs.cmu.edu/~pebbles/puc/" xmlns="http://www.cs.cmu.edu/~pebbles/puc/" elementFormDefault="qualified"> <!-- Attributes --> <xs:attribute name="name" type="xs:string" /> <xs:attribute name="index" type="xs:string" /> <xs:attribute name="list" type="xs:string" /> <xs:attribute name="state" type="xs:string" /> <xs:attribute name="is-a" type="xs:string" /> <xs:attribute name="text" type="xs:string" /> <xs:attribute name="recording" type="xs:string" /> <xs:attribute name="value" type="xs:string" /> <xs:attribute name="access" default="read-write"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="read-only" /> <xs:enumeration value="read-write" /> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="ignore" default="none"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="none" /> <xs:enumeration value="parent" /> <xs:enumeration value="all" /> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="version"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="PUC/2.0" /> <xs:enumeration value="PUC/2.1" /> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="type-name" default="one"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="one" /> <xs:enumeration value="multiple" /> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="priority" default="0"> <xs:simpleType> <xs:restriction base="xs:integer"> <xs:minInclusive value="0" /> <xs:maxInclusive value="10" /> </xs:restriction> </xs:simpleType> </xs:attribute> <xs:attribute name="true-if" default="any"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="any" /> <xs:enumeration value="all" /> <xs:enumeration value="none" /> </xs:restriction> </xs:simpleType> </xs:attribute> <!-- Simple Elements --> <xs:element name="item-count" type="xs:integer" /> <xs:element name="pointpos" type="xs:integer" /> <xs:element name="label" type="xs:string" /> <xs:element name="phonetic" type="xs:string" /> <!-- State Attribute, No Content Elements --> <xs:complexType name="stateAttribNoContent"> <xs:attribute ref="state" use="required" /> </xs:complexType> <xs:element name="refvalue" type="stateAttribNoContent" /> <xs:element name="refstring" type="stateAttribNoContent" /> <xs:element name="static"> <xs:complexType> <xs:attribute ref="value" use="required"/> </xs:complexType> </xs:element> <!-- Selection Type Element (Two Attrib, No Content) --> <xs:element name="selection-type"> <xs:complexType> <xs:attribute ref="type-name" use="required" /> <xs:attribute ref="access" use="required" /> </xs:complexType> </xs:element> <!-- Dependency Relation Elements --> <xs:complexType name="StaticOrReference"> <xs:choice> <xs:element ref="static" /> <xs:element ref="refvalue" /> </xs:choice> </xs:complexType> <xs:element name="defined" type="stateAttribNoContent" /> <xs:element name="undefined" type="stateAttribNoContent" /> <xs:element name="equals"> <xs:complexType> <xs:complexContent> <xs:extension base="StaticOrReference"> <xs:attribute ref="state" use="required" /> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <xs:element name="lessthan"> <xs:complexType> <xs:complexContent> <xs:extension base="StaticOrReference"> <xs:attribute ref="state" use="required" /> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <xs:element name="greaterthan"> <xs:complexType> <xs:complexContent> <xs:extension base="StaticOrReference"> <xs:attribute ref="state" use="required" /> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <!-- Dependency Operator Relations --> <xs:complexType name="DependencyContent"> <xs:sequence> <xs:choice minOccurs="1" maxOccurs="unbounded"> <xs:element ref="or" /> <xs:element ref="and" /> <xs:element ref="not" /> <xs:element ref="apply-over" /> <xs:element ref="defined" /> <xs:element ref="undefined" /> <xs:element ref="equals" /> <xs:element ref="greaterthan" /> <xs:element ref="lessthan" /> </xs:choice> </xs:sequence> </xs:complexType> <xs:element name="or" type="DependencyContent" /> <xs:element name="and" type="DependencyContent" /> <xs:element name="not"> <xs:complexType> <xs:choice minOccurs="1" maxOccurs="1"> <xs:element ref="or" /> <xs:element ref="and" /> <xs:element ref="apply-over" /> <xs:element ref="defined" /> <xs:element ref="undefined" /> <xs:element ref="equals" /> <xs:element ref="greaterthan" /> <xs:element ref="lessthan" /> </xs:choice> </xs:complexType> </xs:element> <xs:element name="apply-over"> <xs:complexType> <xs:complexContent> <xs:extension base="DependencyContent"> <xs:attribute ref="list" use="required" /> <xs:attribute ref="true-if" use="optional" /> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <xs:element name="active-if"> <xs:complexType> <xs:complexContent> <xs:extension base="DependencyContent"> <xs:attribute ref="ignore" use="optional" /> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <!-- Label Dictionary Elements --> <xs:element name="text-to-speech"> <xs:complexType> <xs:attribute ref="text" /> <xs:attribute ref="recording" /> </xs:complexType> </xs:element> <xs:element name="labels"> <xs:complexType> <xs:sequence> <xs:choice minOccurs="1" maxOccurs="unbounded"> <xs:element ref="label" minOccurs="1" /> <xs:element ref="refstring" /> <xs:element ref="phonetic" /> <xs:element ref="text-to-speech" /> </xs:choice> </xs:sequence> </xs:complexType> </xs:element> <!-- Value Space Elements --> <xs:element name="min" type="StaticOrReference" /> <xs:element name="max" type="StaticOrReference" /> <xs:element name="incr" type="StaticOrReference" /> <xs:element name="average" type="StaticOrReference" /> <xs:element name="binary"> <xs:complexType> <xs:sequence> <xs:any minOccurs="0" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="boolean" /> <xs:element name="enumerated"> <xs:complexType> <xs:sequence> <xs:element ref="item-count" minOccurs="1" maxOccurs="1" /> </xs:sequence> </xs:complexType> </xs:element> <xs:complexType name="NumericParameters"> <xs:sequence> <xs:element ref="min" minOccurs="0" maxOccurs="1" /> <xs:element ref="max" minOccurs="0" maxOccurs="1" /> </xs:sequence> </xs:complexType> <xs:complexType name="NumericIncrParameters"> <xs:complexContent> <xs:extension base="NumericParameters"> <xs:sequence> <xs:element ref="incr" minOccurs="0" maxOccurs="1" /> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> <xs:element name="integer" type="NumericIncrParameters" /> <xs:element name="floatingpt" type="NumericParameters" /> <xs:element name="fixedpt"> <xs:complexType> <xs:complexContent> <xs:extension base="NumericIncrParameters"> <xs:all> <xs:element ref="pointpos" minOccurs="1" maxOccurs="1" /> </xs:all> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <xs:element name="list-selection"> <xs:complexType> <xs:attribute ref="list" /> </xs:complexType> </xs:element> <xs:element name="string"> <xs:complexType> <xs:all> <xs:element ref="min" minOccurs="0" maxOccurs="1" /> <xs:element ref="max" minOccurs="0" maxOccurs="1" /> <xs:element ref="average" minOccurs="0" maxOccurs="1" /> </xs:all> </xs:complexType> </xs:element> <!-- Value Labels Elements --> <xs:element name="map"> <xs:complexType> <xs:all> <xs:element ref="labels" minOccurs="1" maxOccurs="1" /> <xs:element ref="active-if" minOccurs="0" maxOccurs="1" /> </xs:all> <xs:attribute ref="index" /> </xs:complexType> </xs:element> <xs:element name="value-labels"> <xs:complexType> <xs:sequence> <xs:element ref="map" minOccurs="1" maxOccurs="unbounded" /> </xs:sequence> </xs:complexType> </xs:element> <!-- Type Elements --> <xs:element name="type"> <xs:complexType> <xs:sequence> <xs:choice minOccurs="1" maxOccurs="1"> <xs:element ref="binary" /> <xs:element ref="boolean" /> <xs:element ref="enumerated" /> <xs:element ref="fixedpt" /> <xs:element ref="floatingpt" /> <xs:element ref="integer" /> <xs:element ref="list-selection" /> <xs:element ref="string" /> </xs:choice> <xs:element ref="value-labels" minOccurs="0" maxOccurs="1" /> </xs:sequence> <xs:attribute ref="name" use="optional" /> </xs:complexType> </xs:element> <xs:element name="apply-type"> <xs:complexType> <xs:attribute ref="name" use="required" /> </xs:complexType> </xs:element> <!-- Appliance Object Elements --> <xs:attributeGroup name="ApplianceObjectAttribs"> <xs:attribute ref="name" use="required" /> <xs:attribute ref="is-a" use="optional" /> <xs:attribute ref="priority" use="optional" /> </xs:attributeGroup> <xs:element name="state"> <xs:complexType> <xs:sequence> <xs:choice minOccurs="1" maxOccurs="1"> <xs:element ref="type" /> <xs:element ref="apply-type" /> </xs:choice> <xs:element ref="labels" /> <xs:element ref="active-if" /> </xs:sequence> <xs:attributeGroup ref="ApplianceObjectAttribs" /> <xs:attribute ref="access" use="optional" /> </xs:complexType> </xs:element> <xs:element name="command"> <xs:complexType> <xs:sequence> <xs:element ref="labels" /> <xs:element ref="active-if" /> </xs:sequence> <xs:attributeGroup ref="ApplianceObjectAttribs" /> </xs:complexType> </xs:element> <xs:element name="explanation"> <xs:complexType> <xs:sequence> <xs:element ref="labels" /> <xs:element ref="active-if" /> </xs:sequence> <xs:attributeGroup ref="ApplianceObjectAttribs" /> </xs:complexType> </xs:element> <!-- Grouping Elements --> <xs:complexType name="GroupingType"> <xs:sequence> <xs:element ref="labels" minOccurs="0" maxOccurs="1" /> <xs:element ref="active-if" minOccurs="0" maxOccurs="1" /> <xs:choice minOccurs="1" maxOccurs="unbounded"> <xs:element ref="group" /> <xs:element ref="state" /> <xs:element ref="command" /> <xs:element ref="explanation" /> </xs:choice> </xs:sequence> <xs:attributeGroup ref="ApplianceObjectAttribs" /> </xs:complexType> <xs:element name="group" type="GroupingType" /> <xs:element name="union-group"> <xs:complexType> <xs:complexContent> <xs:extension base="GroupingType"> <xs:attribute ref="access"/> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <xs:element name="list-group"> <xs:complexType> <xs:complexContent> <xs:extension base="GroupingType"> <xs:sequence> <xs:choice minOccurs="0" maxOccurs="1"> <xs:sequence> <xs:element ref="min" minOccurs="0" maxOccurs="1" /> <xs:element ref="max" minOccurs="0" maxOccurs="1" /> </xs:sequence> <xs:element ref="item-count" /> </xs:choice> <xs:element ref="selection-type" minOccurs="0" maxOccurs="1" /> </xs:sequence> </xs:extension> </xs:complexContent> </xs:complexType> </xs:element> <!-- Top-Level Elements --> <xs:element name="groupings"> <xs:complexType> <xs:choice minOccurs="1" maxOccurs="unbounded"> <xs:element ref="group" /> <xs:element ref="list-group" /> <xs:element ref="union-group" /> </xs:choice> </xs:complexType> </xs:element> <xs:element name="spec"> <xs:complexType> <xs:sequence> <xs:element ref="labels" /> <xs:element ref="groupings" /> </xs:sequence> <xs:attribute ref="name" /> <xs:attribute ref="version" /> </xs:complexType> </xs:element> </xs:schema>
This section describes all of the tags available in the specification language and how they are used.
<spec name="Sample Specification" version="PUC/2.1"></spec>
<groupings></groupings>
<group name="GroupA" priority="10"></group>
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.
Each group has a unique name that is its local name concatenated with the names of all its parent groups.
<list-group name="ListGroupA" priority="10"></list-group>
A list group has the all the same qualities of a regular group, but also may contain some extra elements for describing the features of the list.
A list group automatically creates two states within itself. The "Length" state stores the current length of the list. If this state has an undefined value, then there are no items in the list. The "Selection" state stores the current selection(s). If multiple selections are allowed, then "Selection" is treated like another list-group, allowing list operators like <apply-over> to be applied to it.
Three elements are provided, item-count, min, and max, to allow the specification writer to pre-specify constraints on the size of the list.
<union-group name="UnionGroupA" access="read-only"></union-group>
A union group has the all the same qualities of a regular group. It does not contain any extra elements for describing the union.
The union group automatically creates one state named "ChildUsed", which defines the active child variable/group. The access parameter of this state is defined by the access attribute of the union group element.
<selection-type type-name="one" access="read-only" />
<state name="StateName" access="read-write" priority="10"></state>
<command name="CommandName" priority="10"></command>
<explanation name="ExplanationName" priority="10"></explanation>
<type name="TypeName"></type>
<apply-type name="TypeName"/>
<binary/>
This type may contain arbitrary tags that act are parameters that particular Smart Templates will recognize.
<boolean/>
<enumerated></enumerated>
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;
<item-count></item-count>
<fixedpt></fixedpt>
<pointpos></pointpos>
<floatingpt></floatingpt>
<integer></integer>
<incr></incr> <max></max> <min></min>
The increment may not be defined for the floating point type.
<string/>
<average></average>
<value-labels></value-labels>
<map index="value"></map>
Certain values of a variable can also be enabled based on dependency information which is specified in the enclosed <active-if> element.
<labels></labels>
<text-to-speech text="<whisper>mute</whisper>" recording="mute.au"/>
<label></label>
<phonetic></phonetic>
<active-if ignore="all" | "parent"></active-if>
<apply-over list="SomeList" true-if="any"></apply-over>
There are three different ways that dependencies can be applied. The apply-over block can be true if the dependencies are true for any item in the list, if they are true for all items in the list, or if they are true for no items in the list. The particular choice is chosen with the true-if attribute.
<defined state="SomeState"/>
<undefined state="SomeState"/>
<equals state="SomeState">value</equals>
<greaterthan state="SomeState">value</greaterthan>
<lessthan state="SomeState">value</lessthan>
<and></and>
<or></or>
<not></not>
<refstring state="StateName"/>
<refvalue state="StateName"/>
<static value="12">
In the future, we are planning to add several new features to the specification language. This section discusses a few of these features.
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.
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.