u-stem Documentation

What is u-stem

u-stem is an OSGi based UPnP service that based on simple or nested condition evaluation generates a UPnP event about the result of the evaluation and even executes a set of actions on one or more UPnP devices when the evaluation is true.

Building and Installation

u-stem is an OSGi bundle. You can use the prebuilt bundle from the sourceforge page or build it manually.

The bundle has been developed with Eclipse using the PDE extension. SVN support and PAX runner Eclipse plugin are required for building the bundle.

Check out the code through Eclipse, update the project build path with the location of the felix.jar and org.osgi.compendium.jar files, as well as the Java VM runtime environment. Then create a target platform in eclipse and add the runtime required bundles (see below). If building with Java 1.4, a Xerces bundle is required. Then, open the manifest file and build the bundle using the "Export Wizard" link.

To use u-stem, install it in an Apache Felix OSGi framework. It requires the additional installation of UPnP Base Driver, the UPnP Extra and the OSGi Compendium bundles at runtime. The last one is not provided prebuilt by the Apache felix project, but it can be easily built by checking out the Felix code and following the building instructions for that project (see "Building Felix").

Functional Description

u-stem basically operates on UPnP devices/services in a home network. Architectural wise, although u-stem could be a simple OSGi service, it follows a network approach and is a UPnP service itself, so that other UPnP services in the same network can use it. It is planned however to provide an OSGi service API in the near future.

The two main concepts of u-stem are the scene and the trigger.

A scene is a set of actions that can be performed in one or more devices. The actions are described using unmodified UPnP identifiers of the participating devices, so that users of u-stem can easily construct them. For functional reasons, each scene has its own unique Id.Thus, it is possible to create, modify and delete a scene.

A trigger is a set of rules, that when the total evaluation turns true an event is generated that notifes that this specific trigger is true. If the trigger is associated with one or more scenes, then these scenes are executed. A rule is set of simple or nested AND and OR conditions. The conditions compare state variable values of a UPnP device with state variable values of the same or other UPnP device or with arbitrary values of the same UPnP data type. This is achieved with a recursive logical evaluation function.

Just like the scenes, triggers also have a unique ID that is used for their creation, modification or removal or association/deassociation with a scene.

In order to be able to evaluate conditions, u-stem subscribes to the services of the devices that are included in the conditions of the various triggers. When an updated value for a state variable that is used in a condition arrives, u-stem re-evaluates the condition and as a result the whole trigger. If the total evaluation turns true, an event containing the trigger id and the status true value is generated and sent to the listeners that have subscribed to u-stem's service. If the result of the evaluation is false, an event with the trigger id and the false status value is sent.

u-stem by itself is not a UPnP control point, so it is not aware of the available devices. The OSGi UPnP basedriver is responsible for discovering available UPnP devices and updating them or removing lost ones. Using the OSGi API of the OSGi UPnP basedriver, u-stem finally becomes aware of the various devices. When a u-stem user adds a scene or a trigger, these are validated against the existing UPnP devices. If a device included in a scene or trigger does not exist, or a wrong service or action or state variable is used, then the trigger/scene is discarded.

u-stem UPnP Description

Action addScene

This UPnP action is responsible for adding a new or modifying an existing scene.
Its argument is a String state variables that encapsulates the scene description
message, which is in XML format.
It is responsibility of the entity using u-stem to delete unused scenes,
in order to avoid excessive memory usage and performance degradation.

Scene Description XML

Each scene has a unique ID. This is a String. This id is used to run, delete,
or overwrite a scene. The scene ID is declared with the id attribute of the
scene element.
A scene is composed of actions performed on various devices. Thus, a scene
element contains device elements.

A device element contains an ID attribute, id, which holds the device UDN.
Each device element includes a service element. This element describes in
its id attribute the identification name of the service that includes the action
that will be performed on the device.
Accordingly, the service elements contains one or more action elements.
The action element has only one attribute called id, that holds the UPnP
action name and includes one or more statevar elements. The statevar elements describe the type and the value that will be set for the state variable upon
invokation of the action. Thus it includes three attributes, the state variable
name id, the state variable UPnP type type and the assigned value value.
Below follows an example of a scene which handles two binary lights:

:::xml

<xml>
  <scene id="scene1">
    <device id="uuid:UPnPROCobZW 0000000702">
      <service id="urn:schemas-upnp-org:serviceId:SwitchPower:1">
         <action id="SetTarget">
            <statevar id="NewTargetValue" type="boolean" value="true"/>
         </action>
      </service>
    </device>
    <device id="uuid:TestLight+004fecde">
      <service id="urn:schemas-upnp-org:serviceId:SwitchPower:1">
         <action id="SetTarget">
            <statevar id="NewTargetValue" type="boolean" value="false"/>
         </action>
      </service>
    </device>
   </scene>
</xml>

Action runScene

The runsScene action runs an already defined scene. This is achieved by using
a String state variable, that its value must be the scene ID of the scene to run.
The ID is the one defined when adding the scene.

Action deleteScene

The deleteScene action deletes an already defined scene. This is achieved by using
a String state variable, that its value must be the scene ID of the scene to delete.
The ID is the one defined when adding the scene.

Action addTrigger

u-stem supports evaluation of nested conditions. Each condition may compare
a state variable value of one device with an arbitrary value or with the value of
a relative state variable of another device (or even of the same device).

Trigger Description XML

Each trigger has its own unique id. This is the first element that is declared in
the trigger

::::xml
<xml>
   <trigger id = "testTrigger"/>
</xml>

This id is used to create, delete, or overwrite a trigger
A trigger is defined by the logical operator (OR, AND) and the conditions
that are operands to the selected operator. Logical operators can by nested,
for example two conditions are or-ed with the result of boolean AND for two
other conditions:

::::xml

<xml>
  <trigger id = "testTrigger">
    <logic operator="OR">
      <condition/>
      <condition/>
      <logic operator="AND">
        <condition/>
        <condition/>
      </logic>
    </logic>
  </trigger>
</xml>

The result of the composed logic is the result of the top level condition. If no
logic element exist in the XML, the default is assumed to be AND.
A condition is composed of the comparators and the relation between them. A
condition supports the following operands:

  • equals eq
  • not nt
  • greater than gt
  • less than lt
  • greater equal ge
  • less equal le

A comparator in a condition can be either the value of a state variable of a
device or an arbitrary value. To define a comparator for the value of the state
variable the following things have to be defined:

  • the device UDN
  • The service ID of the service to which the state variable belongs
  • The state variable id

Putting all the pieces together, the final XML description of conditions should
be like:

::::xml
<xml>
  <trigger id = "testTrigger">
    <logic operator="OR">
      <condition operator="ge">
        <lcomparator type="upnp" device="uuid:org-upnp:testdevice1"
             service="urn:org-upnp:testservice" statevar="level"/>  
        <rcomparator type="value" vartype="Integer" value="12"/>
      </condition>
      <logic operator="AND">
        <condition operator="eq">
           <lcomparator type="upnp" device="uuid:org-upnp:testdevice2"
                service="urn:org-upnp:testservice" statevar="Status"/>
           <rcomparator type="upnp" device="uuid:org-upnp:testdevice3"
                service="urn:org-upnp:testservice" statevar="Status"/>
        </condition>
        <condition operator="nt">
           <lcomparator type="upnp" device="uuid:org-upnp:testdevice4"
                service="urn:org-upnp:testservice" statevar="Status"/>
           <rcomparator type="value" vartype="Boolean" value="true"/>
        </condition>
      </logic>
    </logic>
  </trigger>
</xml>

Action delTrigger

The delTrigger action deletes an already defined trigger. This is achieved by using
a String state variable, that its value must be the trigger ID of the trigger to delete.
The ID is the one defined when adding the trigger.

Action associate

This action associates an already defined scene with an already defined trigger. A trigger may be associated
with one or more scenes. The action uses a String UPnP state variable. The content of the state variable value is an XML
that contains a single element ''association'' with the following attributes:

  • scene The id of the scene to associate/deassociate
  • trigger The id of the trigger to associate/deassociate
  • type Denotes if the action will associate or deassociate a trigger with a scene. It takes two possible values; associate and deassociate

The XML for an association action would be like

::::xml

<xml>
    <association trigger="test1" scene="scene1" type="associate"/>
</xml>