XEP-xxxx: Sensor-Over-XMPP

Abstract:This specification defines a payload format for communicating sensor and actuation information. The payload format is transported using the publish-subscribe mechanism described in XEP-0060.
Authors:Gaurav Bhatia, Anthony Rowe, Mario Berges, Charles Spirakis
Copyright:© 1999 - 2011 XMPP Standards Foundation. SEE LEGAL NOTICES.
Status:ProtoXEP
Type:Standards Track
Version:0.0.18
Last Updated:2011-04-08

WARNING: This document has not yet been accepted for consideration or approved in any official manner by the XMPP Standards Foundation, and this document is not yet an XMPP Extension Protocol (XEP). If this document is accepted as a XEP by the XMPP Council, it will be published at <http://xmpp.org/extensions/> and announced on the <standards@xmpp.org> mailing list.


Table of Contents


1. Overview
2. Requirements
3. Glossary
4. Protocol
    4.1. Devices
    4.2. Device Metadata
       4.2.1. Types
       4.2.2. Units
    4.3. Transducer Values
    4.4. Setting Transducer Values
       4.4.1. Actuation
5. Use Cases
    5.1. Data Logging
    5.2. Home Energy
    5.3. Web Camera
    5.4. Vehicle Information
    5.5. All of the above
6. Internationalization Considerations
    6.1. Field Labels
7. Security Considerations
8. IANA Considerations
9. XMPP Registrar Considerations
    9.1. Protocol Namespaces
10. XML Schema
    10.1. http://jabber.org/protocol/sox

Appendices
    A: Document Information
    B: Author Information
    C: Legal Notices
    D: Relation to XMPP
    E: Discussion Venue
    F: Requirements Conformance
    G: Notes
    H: Revision History


1. Overview

This document defines a payload format for exchanging sensor and actuator data which can be implimented using a generic Publish-Subscribe service as described in XEP-0060. It can be used as a foundation to support a wide variety of applications including: power distribution metering, home automation, monitoring and control of heating and cooling systems, infrastructure monitoring, etc.

2. Requirements

The goal of this XEP is to support ubiquitious, large-scale monitoring, operation and control of infrastructure in a way that is extensible, easy to use and secure. To achive this, the specific requirements are:

  1. Provide a common data structure and access method between producers and consumers to foster interoperability.
  2. Allow multiple consumers of sensor information to access data from resource constrained producers with minimal burdon on the producers.
  3. Provide a mechanism whereby an entity is notified when new sensor data is available (i.e. allow consumers of data to avoid polling).
  4. Provide a mechanism whereby an entity is notified when a control request is made (i.e. allow controllers to avoid polling while waiting for work).
  5. Provide a mechanism whereby an entity that requests an action can get confirmation that the action has occured.
  6. Provide a mechanism whereby an entity is notified that an action has occured (i.e. allow requestors to avoid polling while waiting for confirmation).
  7. Provide security such that an authoritative entity (such as an administrator) can decide which consumers are allowed access to which producers.

3. Glossary

The following terms are used throughout this document to refer to elements, objects, or actions that occur in the context of a transducer using the pubsub service. (Note: Some of these terms are specified in greater detail within the body of this document.)

Sensor
A device that measures a physical quantity.
Actuator
A device for moving or controlling a mechanism or system.
Transducer
A device that is a Sensor or Actuator or both. Transducers can also be virtualized, in the sense that they may not necessarily refer to the physical device that is directly measuring or controlling a phenomena, but rather to a software agent that serves as an intermediary.
PubSub Service
An XMPP server or component that adheres to the protocol defined in Publish-Subscribe [1].
Creator / Owner
An entity that created a node and is automatically a publisher and subscriber.
Subscriber
An entity that is allowed to subscribe to a node.
Publisher
An entity that is allowed to publish items to a node and that is automatically subscribed to the node.
Adapter
An entity that converts native transducer values into XMPP messages and vice-versa.
Agent
An XMPP client that consumes or produces data that is not an adapter. For example a piece of software that collects temperature and humidity data to compute dew-point.

4. Protocol

4.1 Devices

To ensure uniquness, a logical device SHOULD be identified by a universal unique identifier (UUID) as defined by RFC 4122. Consumers of logical device data need information about the transducers on the device (meta data) as well as the data values themselves. If the XMPP service is capable of handling pub-sub collections (XEP-0248: PubSub Collection Nodes), the node id for the collection node SHOULD be the UUID as defined above. The meta data for the device SHOULD be a leaf node child of the collection node with the name "meta" and the data values for the device SHOULD be a leaf node child of the collection node with the name "data".

If the XMPP service is not capable of handling pub-sub collections, the node id for the meta data SHOULD be in the form of the UUID followed by "_" followed by (what would be) the leaf child node id. Thus, for the meta data, the node id would be UUID_meta and the data value node id would be UUID_data.

For the rest of the document, we will assume that the XMPP service is a basic XEP-0060 compliant service only and use the UUID_??? naming scheme for node id.

4.2 Device Metadata

Adapter publishes device meta data:

<iq type='set' 
    to='pubsub.capulet.lit'
    from='heater-capulet@capulet.lit/castle'
    id='publish1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b0-4134-11e0-9207-0800200c9a66_meta'>
      <item id='current'>
        <device xmlns='http://jabber.org/protocol/sox'
            name='Royal Thermostat'
            id='4d4335b0-4134-11e0-9207-0800200c9a66'
            type='hvac'
            serialNumber='slave3'>
          <transducer
           name='current temperature' id='temp' canActuate='false'
           hasOwnNode='false' units='kelvin' unitScalar='0'
           minValue='270' maxValue='320' resolution='0.1'>
          </transducer>
          <transducer
              name='current heating setpoint' id='heat' canActuate='true'
              hasOwnNode='false' units='kelvin' unitScalar='0'
              minValue='280' maxValue='300' resolution='0.1'>
          </transducer>
          <transducer
              name='current fan setting' id='fan' canActuate='true'
              hasOwnNode='true' units='hertz' unitScalar='3'
          </transducer>
        </device>
      </item>
    </publish>
  </pubsub>
</iq>

If the meta node is configured to include payloads, the subscribers will receive payloads with event notifications:

<message
    to='house-capulet@capulet.lit/castle'
    from='pubsub.capulet.lit'
    id='baz1'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='4d4335b0-4134-11e0-9207-0800200c9a66_meta'>
      <item id='current'>
        <device xmlns='http://jabber.org/protocol/sox'
            name='Royal Thermostat'
            id='4d4335b0-4134-11e0-9207-0800200c9a66'
            type='hvac'
            serialNumber='slave3'>
          <transducer
              name='current temperature' id='temp' canActuate='false'
              hasOwnNode='false' units='kelvin' unitScalar='0'
              minValue='270' maxValue='320' resolution='0.1'>
          </transducer>
          <transducer
              name='current heating setpoint' id='heat' canActuate='true'
              hasOwnNode='false' units='kelvin' unitScalar='0'
              minValue='280' maxValue='300' resolution='0.1'>
          </transducer>
          <transducer
              name='current fan setting' id='fan' canActuate='true'
              hasOwnNode='true' units='hertz' unitScalar='3'
          </transducer>
        </device>
      </item>
    </items>
  </event>
</message>

Table 1: Device Attributes

Attribute Description/Purpose
name A human friendly name for the device
id A unique identifier for the logical device. This SHOULD be the UUID that corresponds to the logical device.
type The type of the transducer platform (see below)
timestamp Format as defined in XEP-0082: XMPP Date and Time Profiles.
description A human friendly description of the device
serialNumber A serial number or other unique identifier for the physical device

Table 2: Transducer Attributes

Attribute Description/Purpose
name A human friendly identifier to distinguish between various possible transducers within a device
id A unique identifier for the transducer used within the XML packet to enumerate different transducers within a single packet The tuple (UUID X, transducer id Y) MUST be unique such that a publish operation to a data value node X_data with the transducer id Y unambiguously refers to one and only one transducer.
units Unit of measure (see below)
unitScaler The scale of the unit as a power of 10 (i.e. n for 10 ** n)
canActuate Indicates whether the transducer can be actuated
hasOwnNode Indicates whether the transducer data has its own node or whether it is part of the generic data value node (see below)
transducerTypeName A human readable indication of the type of transducer
manufacturer Manufacturer of the transducer
partNumber Manufacturer's part number of the transducer
serialNumber Manufacturer's serial number of the transducer
minValue The expected minimum value for this transducer
maxValue The expected maximum value for this transducer
resolution The resolution of the values reported by this transducer
precision The precision of the values reported by this transducer
accuracy The accuracy of the values reported by this transducer

4.2.1 Types

To make it easier for agents to sort through available devices and seonsors, it is desirable for implementations to use a common set of types. The following device types are defined:

Table 3: Device Types

Type Description/Purpose
indoor weather Temperature, humidity, etc sensors located indoors (such as in a building)
outdoor weather Temperature, humidity, etc sensors located outdoors (such as a rooftop)
hvac Sensors and controls associated with a Heating, Ventilating and Air Conditioning (HVAC) system
occupancy Sensors and controls associated with occupants (motion sensors, door locks, light switches, etc)
multimedia input Sensors and controls associated with multimedia input (video camera, microphone, etc)
multimedia output Sensors and controls associated with multimedia output (screen, speakers, etc)
scale Sensors and controls associated with measuring weight or mass
vehicle Sensors and controls associated with a vehicle (car, boat, truck, etc)
resource consumption Sensors and controls associated with electricity, gas, water or other resource consumption
resource generation Sensors and controls associated with electricity, gas, water or other resource generation
other Other type that isn't listed above

4.2.2 Units

For the sake of interoperability, implementations SHOULD transform native sensor units into the closest relevant SI form. SI units are defined based on SI conventions as shown in the The Unified Code For Units of Measurement.

After specifying the units of the transducer device, you can then also specify an SI scalar value as powers of 10. The following example shows how to specify a sensor in centimeters.

<device id='01020301' type='other'>
  <transducer name='inchworm movement' id='0001'
      canActuate='false' units='meter' unitScaler='-2'/>
</device>
The following example shows how to specify a sensor in kilograms.

<device id='xyzzy' type='scale'>
  <transducer name='bathroom scale' id='0001'
      canActuate='false' units='gram' unitScaler='3'/>
</device>
The following example shows how to specify a sensor in kilowatt-second with a resolution to the nearest 0.1 kWh.

<device id='windmill087' type='resource generation'>
  <transducer name='home wind generator' id='0001'
      canActuate='false'
      units='watt second' unitScaler='3'
      minValue='-50000' maxValue='0' resolution='0.1'/>
</device>
If no unitScaler value is specified, then a unitScaler of 0 (aka 10**0 = 1) is assumed.

4.3 Transducer Values

Values for a transducer are published via the data value node:

<iq type='set' 
    to='pubsub.capulet.lit'
    from='heater-capulet@capulet.lit/castle'
    id='publish2'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b0-4134-11e0-9207-0800200c9a66_data'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerValue
              id='temp'
              typedValue='293.2'
              timestamp='2011-02-25T17:13:20Z'/>
          <transducerValue
              id='heat'
              typedValue='295.4'
              timestamp='2011-02-25T17:13:20Z'/>
        </data>
      </item>
    </publish>
  </pubsub>
</iq>

If the data value node is configured to include payloads, the subscribers will receive payloads with event notifications:

<message
    to='house-capulet@capulet.lit/castle'
    from='pubsub.capulet.lit'
    id='baz2'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='4d4335b0-4134-11e0-9207-0800200c9a66_data'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerValue
              id='temp'
              typedValue='293.2'
              timestamp='2011-02-25T17:13:20Z'/>
          <transducerValue
              id='heat'
              typedValue='295.4'
              timestamp='2011-02-25T17:13:20Z'/>
        </data>
      </item>
    </items>
  </event>
</message>

Table 4: Transducer Value Attributes

Attribute Description/Purpose
id The transducer id. This MUST correspond to a transducer Id as defined in the transducer packet. The tuple (UUID X, transducer id Y) MUST be unique such that a publish operation to a data value node X_data with the transducer id Y unambiguously refers to one and only one transducer.
typedValue The value representing the transducer data which is in the units as defined in the transducer units attribute
timestamp Format as defined in XEP-0082: XMPP Date and Time Profiles.
rawValue The raw value as seen by the transducer. The rawValue can be used to record a non-unit converted value for record keeping (e.g. a raw ADC value before calibration).

OPTIONAL: Instead of putting all of the transducer values into a single data value node, an adapter MAY want to break up the transducer values into multiple nodes. For example, an adapter may want to do this for reasons of security (allow some entities to subscribe/publish to transducer Y1 and a different set of entities to subscribe/publish to transducer Y2).

As mentioned earlier, if the XMPP service is capable of handling pub-sub collections (XEP-0248: PubSub Collection Nodes), the node id for the collection node SHOULD be the UUID and the leaf child node SHOULD have the same node id as the transducer id listed in the meta node.

If the XMPP service is not capable of handling pub-sub collections, adapters which want to create nodes for individual transducers SHOULD use a node id of the form X_Y where X is the UUID for the device and Y is the transducer id as listed in the UUID_meta node.

<iq type='set' 
    to='pubsub.capulet.lit'
    from='heater-capulet@capulet.lit/castle'
    id='publish3'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b0-4134-11e0-9207-0800200c9a66_fan'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerValue
              id='fan'
              typedValue='1.1'
              timestamp='2011-02-25T18:13:20Z'/>
        </data>
      </item>
    </publish>
  </pubsub>
</iq>

If the fan node is configured to include payloads, the subscribers will receive payloads with event notifications:

<message
    to='juliet@capulet.lit/balcony'
    from='pubsub.capulet.lit'
    id='baz3'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='4d4335b0-4134-11e0-9207-0800200c9a66_fan'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerValue
              id='fan'
              typedValue='1.1'
              timestamp='2011-02-25T18:13:20Z'/>
        </data>
      </item>
    </items>
  </event>
</message>

If an adapter chooses to put the transducer value in its own node, it MUST indicate this in the meta node via the Transducer's hasOwnNode field.

NOTE: For every transducer listed in the UUID_meta node, the transducer value MUST be provided in either the UUID_data node or its own UUID_TransducerId node, but not both. The information in the meta node is used by consumers to determine which node they should subscribe to in order to be notified when new data is available for their chosen transducer.

4.4 Setting Transducer Values

Values for a transducer can also be set by publishing to the data value node.

<iq type='set' 
    to='pubsub.capulet.lit'
    from='house-capulet@capulet.lit/castle'
    id='publish5'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b0-4134-11e0-9207-0800200c9a66_data'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerSetValue
              id='heat'
              typedValue='296.2'/>
        </data>
      </item>
    </publish>
  </pubsub>
</iq>

If the data value node is configured to include payloads, the subscribers will receive payloads with event notifications:

<message
    to='heater-capulet@capulet.lit/balcony'
    from='pubsub.capulet.lit'
    id='baz5'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='4d4335b0-4134-11e0-9207-0800200c9a66_data'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerSetValue
              id='heat'
              typedValue='296.2'/>
        </data>
      </item>
    </items>
  </event>
</message>

Per the optional note above. If a transducer has the "hasOwnNode" attribute set in the UUID_meta node, then the value set would be done via the UUID_TransducerId node as described above.

<iq type='set' 
    to='pubsub.capulet.lit'
    from='juliet@capulet.lit/balcony'
    id='publish6'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b0-4134-11e0-9207-0800200c9a66_fan'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerSetValue
              id='fan'
              typedValue='0'/>
        </data>
      </item>
    </publish>
  </pubsub>
</iq>

If the fan node is configured to include payloads, the subscribers will receive payloads with event notifications:

<message
    to='heater-capulet@capulet.lit/balcony'
    from='pubsub.capulet.lit'
    id='baz6'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='4d4335b0-4134-11e0-9207-0800200c9a66_data'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerSetValue
              id='fan'
              typedValue='0'/>
        </data>
      </item>
    </items>
  </event>
</message>

Table 5: Transducer Set Attributes

Attribute Description/Purpose
id The transducer id. This MUST correspond to a transducer id as defined in the transducer packet. The tuple (UUID X, transducer id Y) MUST be unique such that a publish operation to a data value node X_data with the transducer id Y unambiguously refers to one and only one transducer.
typedValue The value representing the transducer data which is in the units as defined in the transducer units attribute
rawValue The raw value to be passed to the transducer. If the adapter can verify that the raw value is an allowable value for the transducer, it SHOULD allow the raw value to take precedence over the typedValue if provided.

4.4.1 Actuation

Actuation takes place as a split-phase operation with an action signal (publish) followed by a completion callback (subscribed message). First, adapters that support actuators are required to subscribe to their respective actuator nodes. An agent can publish an actuation request to the node which is then translated by the adapter into a native command for the actuator. Once the actuator operation has completed its transaction, a new state value is published back to its node. This last step allows an interested agent to subscribe to this node to confirm the requested action has completed.

There is the possibility of contention if multiple users attempt to actuate the same device. This arbitration SHOULD happen at a higher control layer. Any interested agent can always verify the latest state of the actuator by subscribing to the actuator's node.

5. Use Cases

The use cases below show examples of the publish side of this protocol. Event notifications, errors, etc. are all described in XEP-0060 and are not included in the examples below.

5.1 Data Logging

A data logging agent does not need to create or publish any nodes. Instead, it would use the XMPP pub/sub disco# ability to list available nodes and contact the admin entity to subscribe to nodes of interest. Once subscribed, it can log events, populate an external database (such as MySQL) to allow access to historical information regarding sensors and actuators, provide external notifications based on particular events, etc. Since the mechanism for setting a transducer uses the same pubsub node as showing the transducer's value, logging style entities can also do auditing, independant validation that a device is responding, timing of acutator set/response, etc.

5.2 Home Energy

Lady Capulet has purchased an energy monitoring device for use in her home. The sensor used is accurate to the nearest 10 Wh.

<iq type='set' 
    to='pubsub.capulet.lit'
    from='heater-capulet@capulet.lit/castle'
    id='publish10'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335ba-4134-11e0-9207-0800200c9a66_meta'>
      <item id='current'>
        <device xmlns='http://jabber.org/protocol/sox'
            name='Home energy usage'
            id='4d4335ba-4134-11e0-9207-0800200c9a66'
            type='resource consumption'
            serialNumber='8341gvhv5w9'
          <transducer
              name='house clamps' id='0001' canActuate='false'
              units='watt second' unitScaler='3'
              minValue='0' maxValue='100' resolution='0.01'/>
        </device>
      </item>
    </publish>
  </pubsub>
</iq>

<iq type='set' 
    to='pubsub.capulet.lit'
    from='heater-capulet@capulet.lit/castle'
    id='publish11'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335ba-4134-11e0-9207-0800200c9a66_data'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerValue
              id='0001'
              typedValue='0.44'
              timestamp='2011-01-25T17:13:20Z'/>
        </data>
      </item>
    </publish>
  </pubsub>
</iq>

Later, Lady Capulet adds a second energy sensor to the monitoring device purchased above. The new sensor is more accurate and can measure to the nearest 1 Wh. The adapter provides this additional information in the meta node and data value node.

<iq type='set' 
    to='pubsub.capulet.lit'
    from='heater-capulet@capulet.lit/castle'
    id='publish20'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335ba-4134-11e0-9207-0800200c9a66_meta'>
      <item id='current'>
        <device xmlns='http://jabber.org/protocol/sox'
            name='Home energy usage'
            id='4d4335ba-4134-11e0-9207-0800200c9a66'
            type='resource consumption'
            serialNumber='8341gvhv5w9'
          <transducer
              name='house clamps' id='0001' canActuate='false'
              units='watt second' unitScaler='3'>
              minValue='0' maxValue='100' resolution='0.01'/>
          <transducer
              name='pool clamps' id='0002' canActuate='false'
              units='watt second' unitScaler='3'
              minValue='0' maxValue='100' resolution='0.001'/>
        </device>
      </item>
    </publish>
  </pubsub>
</iq>

<iq type='set' 
    to='pubsub.capulet.lit'
    from='heater-capulet@capulet.lit/castle'
    id='publish21'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335ba-4134-11e0-9207-0800200c9a66_meta'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerValue
              id='0001'
              typedValue='0.39'
              timestamp='2011-02-26T17:13:20Z'/>
          <transducerValue
              id='0002'
              typedValue='1.041'
              timestamp='2011-02-26T17:13:24Z'/>
        </data>
      </item>
    </publish>
  </pubsub>
</iq>

5.3 Web Camera

Lord Montague purchases a web camera which can sense movement and has a light which can be turned on or off. He also has an agent which responds to the camera motion detector by turning on the camera light in the hopes of catching Romeo sneaking out at night. For security reasons, it is desired to allow an agent to publish to the light (i.e. control the light), but not the motion sensor. To provide for this, the adapter implements the OPTIONAL ability that allows a transducer value to have its own node.


<iq type='set' 
    to='pubsub.montague.lit'
    from='camera-montague@montague.lit/moat'
    id='publish40'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b5-4134-11e0-9207-0800200c9a66_meta'>
      <item id='current'>
        <device xmlns='http://jabber.org/protocol/sox'
         name='Moat Cam'
         id='4d4335b5-4134-11e0-9207-0800200c9a66'
         type='multimedia input'
         serialNumber='axis-m1301-w-0041142CA2'
          <transducer
              name='motion sensor' id='tid1' canActuate='false' units='enum'
              minValue='0' maxValue='1'/>
          <transducer
              name='light' id='tid2' canActuate='true' units='enum'
              hasOwnNode='true' minValue='0' maxValue='1'/>
          <property name='adminUrl'
              value='http://example.com/view/viewer_index.shtml'/>
          <property name='videoUrl'
              value='rtsp://example.com/axis-media/media.amp'/>
        </device>
      </item>
    </publish>
  </pubsub>
</iq>

<iq type='set' 
    to='pubsub.montague.lit'
    from='camera-montague@montague.lit/moat'
    id='publish41'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b5-4134-11e0-9207-0800200c9a66_data'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerValue
              id='tid1'
              typedValue='0'
              timestamp='2011-01-25T17:13:19'/>
        </data>
      </item>
    </publish>
  </pubsub>
</iq>

<iq type='set' 
    to='pubsub.montague.lit'
    from='camera-montague@montague.lit/moat'
    id='publish42'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b5-4134-11e0-9207-0800200c9a66_tid2'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerValue
              id='tid2'
              typedValue='0'
              timestamp='2011-01-25T17:13:19.607Z'/>
        </data>
      </item>
    </publish>
  </pubsub>
</iq>

When there is movement, the following would be published by the camera adapter.

Event Node ID: 4d4335b5-4134-11e0-9207-0800200c9a66_data
<iq type='set' 
    to='pubsub.montague.lit'
    from='camera-montague@montague.lit/moat'
    id='publish43'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b5-4134-11e0-9207-0800200c9a66_data'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerValue
              id='tid1'
              typedValue='1'
              timestamp='2011-01-25T20:13:20.314Z'/>
        </data>
      </item>
    </publish>
  </pubsub>
</iq>

Two things to note:

  1. The tuple ('4d4335b5-4134-11e0-9207-0800200c9a66_data', 'tid1') uniquely identifies the motion sensor for this camera adapter.
  2. It is not relevant to the subscriber of this node (the consumer of information) whether the camera has motion detection built in or whether the adapter is capturing images from the camera and using its own methodology for determining motion.

To continue this example further, let's assume an agent is subscribed to the data value node and can also publish to the tid2 node which controls the light. In this case, an agent will receive notification that movement was sensed and can take action. One action could be to turn on the light, in which case the agent would publish:

<iq type='set' 
    to='pubsub.montague.lit'
    from='watcher-montague@montague.lit/agent99'
    id='publish44'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b5-4134-11e0-9207-0800200c9a66_tid2'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerSetValue
              id='tid2'
              typedValue='1'/>
        </data>
      </item>
    </publish>
  </pubsub>
</iq>

In response, the camera adapter would turn on the light and publish an acknowledgement.

<iq type='set' 
    to='pubsub.montague.lit'
    from='camera-montague@montague.lit/moat'
    id='publish45'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b5-4134-11e0-9207-0800200c9a66_tid2'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerValue
              id='tid2'
              typedValue='1'
              timestamp='2011-01-25T17:13:21Z'/>
        </data>
      </item>
    </publish>
  </pubsub>
</iq>

In response to this the agent could start recording the video, send an email, use the XEP-0166 (Jingle) extension to send the video to an XMPP client, etc.

5.4 Vehicle Information

Juliet purchases a smartphone and connects it to the diagnostic bus of her chariot. She is interested in capturing real time information regarding the chariot's location and performance. The smartphone is providing some of the data (accelerometer and GPS) while the chariot diagnostic bus is providing the rest (horsepower, engine information, etc).

Note: it is not relevant to the consumers of the data which sensors are connected to the smartphone and which are not. Consumers only need to know the UUID for the chariot adapter's logical device and the corresponding transducer id's to access the specific transducer data by subscribing to the node(s) of interest. The chariot adapter (potentially running on the smart phone) hides the details of data acquisition.

Note: normally engine information is provided as rotations per minute (rpm), but the "on-wire" format should use the base units provided above - in this case hertz is a measure of cycles (or rotations) per second. Thus, the adapter would be required to convert rpm into hertz (i.e. multiply the rpm value by 60 to get hertz) before publishing and an agent could optionally convert the value back to rpm for display.

<iq type='set' 
    to='pubsub.capulet.lit'
    from='chariot-capulet@capulet.lit/convertible'
    id='publish50'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b6-4134-11e0-9207-0800200c9a66_meta'>
      <item id='current'>
        <device xmlns='http://jabber.org/protocol/sox'
            name='Chariot built for two'
            id='4d4335b6-4134-11e0-9207-0800200c9a66'
            type='vehicle'
            timestamp='2011-01-25T17:03:00Z'>
            serialNumber='license: HI 2ABC123'
          <transducer name='motion X' id='01' canActuate='false'
              units='meter per seconf squared'/>
          <transducer name='motion Y' id='02' canActuate='false'
              units='meter per seconf squared'/>
          <transducer name='motion Z' id='03' canActuate='false'
              units='meter per seconf squared'/>
          <transducer name='GPS lat' id='04' canActuate='false'
              units='lat'/>
          <transducer name='GPS lng' id='05' canActuate='false'
              units='lon'/>
          <transducer name='engine rotation' id='06' canActuate='false'
              units='hertz'/>
          <transducer name='timing advance' id='07' canActuate='true'
              units='radian'/>
          <transducer name='engine fuel' id='08' canActuate='false'
              units='liter'/>
          <transducer name='engine fuel pressure' id='09' canActuate='true'
              units='pascal'/>
          <transducer name='engine coolant' id='10' canActuate='false'
              units='kelvin'/>
        </device>
      </item>
    </publish>
  </pubsub>
</iq>

<iq type='set' 
    to='pubsub.capulet.lit'
    from='chariot-capulet@capulet.lit/convertible'
    id='publish51'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='4d4335b6-4134-11e0-9207-0800200c9a66_data'>
      <item id='current'>
        <data xmlns='http://jabber.org/protocol/sox'>
          <transducerValue
              id='1'
              typedValue='8.7'
              timestamp='2011-01-25T17:13:20Z'/>
          <transducerValue
              id='2'
              typedValue='8.1'
              timestamp='2011-01-25T17:13:20Z'/>
          <transducerValue
              id='3'
              typedValue='9.1'
              timestamp='2011-01-25T17:13:20Z'/>
        </data>
      </item>
    </publish>
  </pubsub>
</iq>

Since the timestamp indicates the time of data collection, the adapter could store some of the sensor values and then batch publish the values to the data value node. Consumers of the data value node information would get delayed results (increased latency), but this mechanism may provide for improved bandwidth (fewer pub/sub notification overhead for each "unit" of data).

NOTE: It is permissible to publish a subset of transducers in the data value node (such as in this example). If an adapter chooses to publish a subset of transducer data (for example, only the changed values), it is possible for consumers who are off line or recently activated to miss older values. There are a variety of ways to handle this depending on the needs of the implementor including (but not limited to):

If an implementaion chooses to put some transducers values into their own nodes (instead of putting them all into the data value node), remember that a transducer value MUST appear in either the data value node or its own node, but not both. The meta node indicates to consumers which node they should subscribe to in order to be notified when new data is available for their chosen transducer.

One could carry this further to allow Lord Capulet to keep track of all the chariots in his fleet. For example, the logging agent described above could be used to keep historical information (including location and performance) for all of the vehicles in his fleet. We will leave it as an exercise for the reader to ponder the implications of allowing chariot transducers to be modified on the fly via non-local agents.

5.5 All of the above

Whether or not additional nodes are needed depends on how the information is combined. For example, an adapter could be written to compute the distance a vehicle is from a particular point and the result could be a published to a new node that other adapters and agents could use in their calculations.

6. Internationalization Considerations

6.1 Field Labels

The Data Forms shown in this specification include English-language labels for various fields; implementations that will display such forms to human users SHOULD provide localized label text for fields that are defined for the registered FORM_TYPEs.

7. Security Considerations

The publication of sensor information is not known to introduce any new security considerations above and beyond those defined in XEP-0060 and XMPP Core.

8. IANA Considerations

This document does not require interaction with the Internet Assigned Numbers Authority (IANA) [2].

9. XMPP Registrar Considerations

9.1 Protocol Namespaces

The XMPP Registrar [3] includes "http://jabber.org/protocol/pubsub" and "http://jabber.org/protocol/pubsub#errors" and "http://jabber.org/protocol/pubsub#event" and "http://jabber.org/protocol/pubsub#owner" in its registry of protocol namespaces.

10. XML Schema

10.1 http://jabber.org/protocol/sox

<?xml version='1.0' encoding='UTF-8'?>
<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/sox'
    xmlns='http://jabber.org/protocol/sox'
    elementFormDefault='qualified'>

  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      XEP-????: http://xmpp.org/extensions/xep-????.html
    </xs:documentation>
  </xs:annotation>

  <xs:element name='device'>
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs='0' maxOccurs='unbounded' ref='transducer'/>
        <xs:element minOccurs='0' maxOccurs='unbounded'
            ref='geoloc' xmlns='http://jabber.org/protocol/geoloc'/>
        <xs:element minOccurs='0' maxOccurs='unbounded' ref='property'/>
      </xs:sequence>
      <xs:attribute name='name' type='xs:string' use='required'/>
      <xs:attribute name='id' type='xs:string' use='required'/>
      <xs:attribute name='type' type='deviceType' use='required'/>
      <xs:attribute name='timestamp' type='xs:datetime' use='optional'/>
      <xs:attribute name='description' type='xs:string' use='optional'/>
      <xs:attribute name='serialNumber' type='xs:string' use='optional'/>
    </xs:complexType>
  </xs:element>

  <xs:simpleType name='deviceType'>
    <xs:restriction base="xs:string">
      <xs:enumeration value='indoor weather'/>
      <xs:enumeration value='outdoor weather'/>
      <xs:enumeration value='hvac'/>
      <xs:enumeration value='occupancy'/>
      <xs:enumeration value='multimedia input'/>
      <xs:enumeration value='multimedia output'/>
      <xs:enumeration value='scale'/>
      <xs:enumeration value='vehicle'/>
      <xs:enumeration value='resource consumption'/>
      <xs:enumeration value='resource generation'/>
      <xs:enumeration value='other'/>
    </xs:restriction>
  </xs:simpleType>

  <xs:element name='transducer'>
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs='0' maxOccurs='1'
            ref='geoloc' xmlns='http://jabber.org/protocol/geoloc'/>
        <xs:element minOccurs='0' maxOccurs='unbounded' ref='property'/>
      </xs:sequence>
      <xs:attribute name='name' type='xs:string' use='required'/>
      <xs:attribute name='id' type='xs:string' use='required'/>
      <xs:attribute name='units' type='allowedUnits' use='required'/>
      <xs:attribute name='unitScaler' type='xs:integer' default='0'/>
      <xs:attribute name='canActuate' type='xs:boolean' default='false'/>
      <xs:attribute name='hasOwnNode' type='xs:boolean' default='false'/>
      <xs:attribute name='transducerTypeName' type='xs:string' use='optional'/>
      <xs:attribute name='manufacturer' type='xs:string' use='optional'/>
      <xs:attribute name='partNumber' type='xs:string' use='optional'/>
      <xs:attribute name='serialNumber' type='xs:string' use='optional'/>
      <xs:attribute name='minValue' type='xs:float' use='optional'/>
      <xs:attribute name='maxValue' type='xs:float' use='optional'/>
      <xs:attribute name='resolution' type='xs:float' use='optional'/>
      <xs:attribute name='precision' type='xs:float' use='optional'/>
      <xs:attribute name='accuracy' type='xs:float' use='optional'/>
    </xs:complexType>
  </xs:element> 

  <xs:simpleType name='allowedUnits'>
    <xs:restriction base="xs:string">
      <xs:enumeration value='meter'/>
      <xs:enumeration value='gram'/>
      <xs:enumeration value='second'/>
      <xs:enumeration value='ampere'/>
      <xs:enumeration value='kelvin'/>
      <xs:enumeration value='mole'/>
      <xs:enumeration value='candela'/>
      <xs:enumeration value='radian'/>
      <xs:enumeration value='steradian'/>
      <xs:enumeration value='hertz'/>
      <xs:enumeration value='newton'/>
      <xs:enumeration value='pascal'/>
      <xs:enumeration value='joule'/>
      <xs:enumeration value='watt'/>
      <xs:enumeration value='coulomb'/>
      <xs:enumeration value='volt'/>
      <xs:enumeration value='farad'/>
      <xs:enumeration value='ohm'/>
      <xs:enumeration value='siemens'/>
      <xs:enumeration value='weber'/>
      <xs:enumeration value='tesla'/>
      <xs:enumeration value='henry'/>
      <xs:enumeration value='lumen'/>
      <xs:enumeration value='lux'/>
      <xs:enumeration value='becquerel'/>
      <xs:enumeration value='gray'/>
      <xs:enumeration value='sievert'/>
      <xs:enumeration value='katal'/>
      <xs:enumeration value='liter'/>
      <xs:enumeration value='square meter'/>
      <xs:enumeration value='cubic meter'/>
      <xs:enumeration value='meter per second'/>
      <xs:enumeration value='meter per second squared'/>
      <xs:enumeration value='reciprocal meter'/>
      <xs:enumeration value='kilogram per cubic meter'/>
      <xs:enumeration value='cubic meter per kilogram'/>
      <xs:enumeration value='ampere per square meter'/>
      <xs:enumeration value='ampere per meter'/>
      <xs:enumeration value='mole per cubic meter'/>
      <xs:enumeration value='candela per square meter'/>
      <xs:enumeration value='kilogram per kilogram'/>
      <xs:enumeration value='volt-ampere reactive'/>
      <xs:enumeration value='volt-ampere'/>
      <xs:enumeration value='watt second'/>
      <xs:enumeration value='percent'/>
      <xs:enumeration value='enum'/>
      <xs:enumeration value='lat'/>
      <xs:enumeration value='lon'/>
    </xs:restriction>
  </xs:simpleType>

  <xs:element name='property'>
    <xs:complexType>
      <xs:attribute name='name' type='xs:string' use='required'/>
      <xs:attribute name='value' type='xs:string' use='required'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='data'>
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs='0' maxOccurs='unbounded' ref='transducerValue'/>
        <xs:element minOccurs='0' maxOccurs='unbounded' ref='transducerSetValue'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name='transducerValue'>
    <xs:complexType>
      <xs:attribute name='id' type='xs:string' use='required'/>
      <xs:attribute name='typedValue' type='xs:string' use='required'/>
      <xs:attribute name='timestamp' type='xs:datetime' use='required'/>
      <xs:attribute name='rawValue' type='xs:string' use='optional'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='transducerSetValue'>
    <xs:complexType>
      <xs:attribute name='id' type='xs:string' use='required'/>
      <xs:attribute name='typedValue' type='xs:string' use='required'/>
      <xs:attribute name='rawValue' type='xs:string' use='optional'/>
    </xs:complexType>
  </xs:element>
</xs:schema>
  

Appendices


Appendix A: Document Information

Series: XEP
Number: xxxx
Publisher: XMPP Standards Foundation
Status: ProtoXEP
Type: Standards Track
Version: 0.0.18
Last Updated: 2011-04-08
Approving Body: XMPP Council
Dependencies: XMPP Core, XEP-0001, XEP-0060, XEP-0082
Supersedes: None
Superseded By: None
Short Name: sox
This document in other formats: XML  PDF


Appendix B: Author Information

Gaurav Bhatia

Email: gauravbhatia@cmu.edu

Anthony Rowe

Email: agr@ece.cmu.edu

Mario Berges

Email: marioberges@cmu.edu

Charles Spirakis

Email: css@google.com


Appendix C: Legal Notices

Copyright

This XMPP Extension Protocol is copyright (c) 1999 - 2011 by the XMPP Standards Foundation (XSF).

Permissions

Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the "Specification"), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.

Disclaimer of Warranty

## NOTE WELL: This Specification is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. In no event shall the XMPP Standards Foundation or the authors of this Specification be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification. ##

Limitation of Liability

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising out of the use or inability to use the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.

IPR Conformance

This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which may be found at <http://www.xmpp.org/extensions/ipr-policy.shtml> or obtained by writing to XSF, P.O. Box 1641, Denver, CO 80201 USA).

Appendix D: Relation to XMPP

The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 3920) and XMPP IM (RFC 3921) specifications contributed by the XMPP Standards Foundation to the Internet Standards Process, which is managed by the Internet Engineering Task Force in accordance with RFC 2026. Any protocol defined in this document has been developed outside the Internet Standards Process and is to be understood as an extension to XMPP rather than as an evolution, development, or modification of XMPP itself.


Appendix E: Discussion Venue

The primary venue for discussion of XMPP Extension Protocols is the <standards@xmpp.org> discussion list.

Discussion on other xmpp.org discussion lists might also be appropriate; see <http://xmpp.org/about/discuss.shtml> for a complete list.

Errata can be sent to <editor@xmpp.org>.


Appendix F: Requirements Conformance

The following requirements keywords as used in this document are to be interpreted as described in RFC 2119: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".


Appendix G: Notes

1. XEP-0060: Publish-Subscribe <http://xmpp.org/extensions/xep-0060.html>.

2. The Internet Assigned Numbers Authority (IANA) is the central coordinator for the assignment of unique parameter values for Internet protocols, such as port numbers and URI schemes. For further information, see <http://www.iana.org/>.

3. The XMPP Registrar maintains a list of reserved protocol namespaces as well as registries of parameters used in the context of XMPP extension protocols approved by the XMPP Standards Foundation. For further information, see <http://xmpp.org/registrar/>.


Appendix H: Revision History

Note: Older versions of this specification might be available at http://xmpp.org/extensions/attic/

Version 0.0.18 (2011-04-08)

Add data element to enclose transducerValue and transducerSetValue.

(css)

Version 0.0.17 (2011-03-25)

Cleanup typo's and wording.

(css)

Version 0.0.16 (2011-03-24)

Move device type and units into the xsd.

(css)

Version 0.0.15 (2011-03-23)

Text and example cleanup.

(css)

Version 0.0.14 (2011-03-22)

First attempt at how/why split.

(css)

Version 0.0.13 (2011-03-10)

Minor cleanup.

(gnb)

Version 0.0.12 (2011-03-10)

Change TransducerValue packet's TypedValue from float to string.

(css)

Version 0.0.11 (2011-03-03)

Grammar cleanup and minor clarifications.

(css)

Version 0.0.10 (2011-03-02)

Move requirements to top. Add optional X_Y event node.

(css)

Version 0.0.9 (2011-03-02)

Expanded definition of Transducer. General cleanup.

(mbg)

Version 0.0.8 (2011-03-01)

More cleanup.

(css)

Version 0.0.7 (2011-03-01)

Adjusted requirements section. More cleanup.

(css)

Version 0.0.6 (2011-02-28)

Clean up typos and examples.

(css)

Version 0.0.5 (2011-02-27)

Added use cases and examples.

(css)

Version 0.0.4 (2011-02-24)

Update xsd and corresponding descriptions.

(css)

Version 0.0.3 (2011-02-23)

Add clarifications.

(css)

Version 0.0.25 (2011-1-23)

Added content to the How it Works section.

(mbg)

Version 0.0.2 (2010-11-18)

Added some use cases.

(agr)

Version 0.0.1 (2010-11-18)

First draft.

(gnb)

END