1
0
mirror of https://github.com/moparisthebest/xeps synced 2024-11-10 03:15:00 -05:00
xeps/inbox/sensors.xml

1584 lines
71 KiB
XML
Raw Normal View History

2011-03-10 16:10:25 -05:00
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE xep SYSTEM 'xep.dtd' [
<!ENTITY % ents SYSTEM 'xep.ent'>
%ents;
]>
<?xml-stylesheet type='text/xsl' href='xep.xsl'?>
<xep>
<header>
<title>Sensor-Over-XMPP</title>
<abstract>This specification provides a description of a communication protocol for a sensing and actuation system. Data is transported using the XMPP publish-subscribe mechanism described in XEP-0060.</abstract>
<legal>
<copyright>This XMPP Extension Protocol is copyright (c) 1999 - 2011 by the XMPP Standards Foundation (XSF).</copyright>
<permissions>Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the &quot;Specification&quot;), 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.</permissions>
<warranty>## NOTE WELL: This Specification is provided on an &quot;AS IS&quot; 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. ##</warranty>
<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.</liability>
<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 &lt;<link url='http://www.xmpp.org/extensions/ipr-policy.shtml'>http://www.xmpp.org/extensions/ipr-policy.shtml</link>&gt; or obtained by writing to XSF, P.O. Box 1641, Denver, CO 80201 USA).</conformance>
</legal>
<number>xxxx</number>
<status>ProtoXEP</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
<spec>XEP-0001</spec>
<spec>XEP-0004</spec>
<spec>XEP-0060</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>sox</shortname>
<author>
<firstname>Gaurav</firstname>
<surname>Bhatia</surname>
<email>gauravbhatia@cmu.edu</email>
</author>
<author>
<firstname>Anthony</firstname>
<surname>Rowe</surname>
<email>agr@ece.cmu.edu</email>
</author>
<author>
<firstname>Mario</firstname>
<surname>Berges</surname>
<email>marioberges@cmu.edu</email>
</author>
<author>
<firstname>Charles</firstname>
<surname>Spirakis</surname>
<email>css@google.com</email>
</author>
<revision>
<version>0.0.11</version>
<date>2011-03-03</date>
<initials>css</initials>
<remark><p>Grammar cleanup and minor clarifications.</p></remark>
</revision>
<revision>
<version>0.0.10</version>
<date>2011-03-02</date>
<initials>css</initials>
<remark><p>Move requirements to top. Add optional X_Y event node.</p></remark>
</revision>
<revision>
<version>0.0.9</version>
<date>2011-03-02</date>
<initials>mbg</initials>
<remark><p>Expanded definition of Transducer. General cleanup.</p></remark>
</revision>
<revision>
<version>0.0.8</version>
<date>2011-03-01</date>
<initials>css</initials>
<remark><p>More cleanup.</p></remark>
</revision>
<revision>
<version>0.0.7</version>
<date>2011-03-01</date>
<initials>css</initials>
<remark><p>Adjusted requirements section. More cleanup.</p></remark>
</revision>
<revision>
<version>0.0.6</version>
<date>2011-02-28</date>
<initials>css</initials>
<remark><p>Clean up typos and examples.</p></remark>
</revision>
<revision>
<version>0.0.5</version>
<date>2011-02-27</date>
<initials>css</initials>
<remark><p>Added use cases and examples.</p></remark>
</revision>
<revision>
<version>0.0.4</version>
<date>2011-02-24</date>
<initials>css</initials>
<remark><p>Update xsd and corresponding descriptions.</p></remark>
</revision>
<revision>
<version>0.0.3</version>
<date>2011-02-23</date>
<initials>css</initials>
<remark><p>Add clarifications.</p></remark>
</revision>
<revision>
<version>0.0.25</version>
<date>2011-1-23</date>
<initials>mbg</initials>
<remark><p>Added content to the How it Works section.</p></remark>
</revision>
<revision>
<version>0.0.2</version>
<date>2010-11-18</date>
<initials>agr</initials>
<remark><p>Added some use cases.</p></remark>
</revision>
<revision>
<version>0.0.1</version>
<date>2010-11-18</date>
<initials>gnb</initials>
<remark><p>First draft.</p></remark>
</revision>
</header>
<section1 topic='Overview' anchor='overview'>
<p> This document specifies a format for exchanging sensor and actuator data. The schema described here is a specialized context (“profile”) of the XMPP Publish-Subscribe extension described in <link url='http://www.xmpp.org/extensions/xep-0060.html'><cite>XEP-0060</cite></link>. The purpose of this document is to outline the schema and describe various expected usage scenarios. This schema focuses on describing the transducers and their data rather than the physical phenomenon that they sense or control. This 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. </p>
</section1>
<section1 topic='Requirements' anchor='reqs'>
<p>
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:
</p>
<ol>
<li>Provide a common data structure and access method between producers and consumers to foster interoperability.
</li>
<li>Allow multiple consumers of sensor information to access data from resource constrained producers with minimal burdon on the producers.
</li>
<li>Provide a mechanism whereby an entity is notified when new sensor data is available (i.e. allow consumers of data to avoid polling).
</li>
<li>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).
</li>
<li>Provide a mechanism whereby an entity that requests an action can get confirmation that the action has occured.
</li>
<li>Provide a mechanism whereby an entity is notified that an action has occured (i.e. allow requestors to avoid polling while waiting for confirmation).
</li>
<li>Provide security such that an authoritative entity (such as an administrator) can decide which consumers are allowed access to which producers.
</li>
</ol>
</section1>
<section1 topic='Glossary' anchor='glossary'>
<p>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.)</p>
<dl>
<di><dt>Sensor </dt><dd> A device that measures a physical quantity.</dd></di>
<di><dt>Actuator </dt><dd> A device for moving or controlling a mechanism or system. </dd></di>
<di><dt>Transducer </dt><dd> 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.</dd></di>
<di><dt>PubSub Service </dt><dd> An XMPP server or component that adheres to the protocol defined in &xep0060;.</dd></di>
<di><dt>Event Node</dt><dd>An entity that represents a transducer address used to facilitate data transfer.</dd></di>
<di><dt>Creator / Owner</dt><dd>An entity that created an event node and is automatically a publisher and subscriber.</dd></di>
<di><dt>Subscriber</dt><dd>An entity that is allowed to subscribe to a node.</dd></di>
<di><dt>Publisher</dt><dd>An entity that is allowed to publish items to a node and that is automatically subscribed to the node.</dd></di>
<di><dt>Adapter</dt><dd>An entity that converts native transducer values into XMPP messages and vice-versa.</dd></di>
<di><dt>Agent</dt><dd>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.</dd></di>
</dl>
</section1>
<section1 topic='Basic Structure' anchor='struct'>
<p>The basic structure revolves around the XMPP Publish-Subscribe mechanism as described in <link url='http://www.xmpp.org/extensions/xep-0060.html'><cite>XEP-0060</cite></link>. There are multiple types of entities involved. Event nodes are used to supply information that need to be shared. Publishers and Subscribers act as producers and consumers of the information. These are described in more detail in this section.
</p>
<section2 topic='Motivation' anchor='intro-motivation'>
<p>There are a growing number of Internet connected devices that sense and actuate physical elements in the environment. A variety of applications exist that would benefit from sharing information between these types of devices. XMPP provides an easy-to-use, decentralized and secure communication mechanism that is ideal for supporting these types of sensing and control applications. </p>
<p>The “publish-subscribe” design philosophy is very well suited for interfacing with sensor and actuator systems for the following reasons. First, subscription-based data dissemination shelters resource-constrained devices from external requests. In many cases, a transducer exists at the leaf-node of a system that is resource constrained (i.e. a temperature sensor as part of a BACnet network) and could not practically push or reply to tens or hundreds of data requests. Second, presence information as well as push-based asynchronous distribution of data helps decouple timing requirements between data producers and consumers. Devices can easily declare that they are active and then push data to subscribers at their preferred rate. Finally, XMPPs provides decentralized addressing, authentication, encrypted communication as well as per-node access control for these devices. With the addition of a common messaging schema, this provides an ideal platform for the sharing of sensor data. </p>
</section2>
<section2 topic='How it works' anchor='intro-how-it-works'>
<p>Internet-connected devices that interface with transducers can leverage XMPP communication infrastructure to allow remote monitoring and control of physical phenomena. Each one of these devices can be associated with one or more XMPP event nodes through which it is able to communicate with XMPP users following the access control rules defined by the XMPP server. Without the extension described herein, there are a couple of obstacles to doing this. The first, is the need for a common and extensible messaging schema for describing the properties of the transducer as well as the data that is being communicated. Such a sechema is defined in this document in later sections. The second, equally important, issue is that for this to work properly there needs to be a set of recommended guidelines to follow when developing the software components required to produce and consume the data being exchanged.</p>
<p>In general terms, the exchange of information can be described very briefly. In the case of sensing, a transducer (e.g., a temperature sensor, a power meter) is interfacing with an internet-enabled device (e.g., a smart phone, a computer) through a software entity running on this device, that is able to collect measurements from the transducer, perform some local processing and publish a value of interest to a pre-specified XMPP event node. We refer to this piece of software as the adapter. At the other end of the communication channel, software agents that are subscribed (and have proper access) to this event node will receive the pushed message and, given that it is using a common schema, will be able to parse it and process the data however they choose to.</p>
<p>For actuation, a similar process is followed. A transducer, in this case an actuator, is interfacing with an internet-enabled device running an adapter. This adapter is able to communicate with both the XMPP server and the actuator. An XMPP event node is used to communicate the actuation commands as well as the state of the actuator. By default, the adapter will be subscribed to this event node. When an actuation message is published to the event node, the adapter will receive the message, parse it, and issue the appropriate actuation command. The resulting state of the transducer or controlled element after this actuation will then be published back to the same event node by the adapter. In this way, the software agent that originally issued the actuation command can receive an acknolwedgement through the same XMPP event node.</p>
<p>In essence, one can look at the device/adapter model described here as being analogous to the device/device driver model used by operating systems.
In the case of an operating system, device drivers work with physical devices (i.e. keyboards, serial ports, disk drives, etc) as well as software-only devices (i.e. ramdisks, loopback devices, etc) to create a common access method (i.e. block and character devices).
In this case, adapters work with devices that have a variety of device specific access controls, attributes and access methodologies to create a common access method - specifically the common access method described here.
Continuing this anaolgy, an agent is an entity that interacts with the information provided by one or more adapters in much the same way that an application interacts with information provided by one or more device drivers.</p>
</section2>
<section2 topic='Event node' anchor='struct-node'>
<p>An event node is a pubsub node created for any piece of information that needs to be broadcast to multiple users or observers.
The most common use case is an event node for each Device that consists of multiple sensors and actuators.
An event node can also be created for each transducer if such granularity is desired.
Event nodes are created with specific IDs which serve as unique identifiers.
</p>
</section2>
<section2 topic='User types' anchor='struct-users'>
<p>There are two types of XMPP accounts that are involved: Admin and Users.</p>
<p>Users are entities that serve as publishers or subscribers of information being exchanged through an Event Node. A Publisher sends information to an event node, and a Subscriber receives information from an event node, in accordance with the definitions within the pubsub protocol. In this context, "user" may not be associated with a person, but rather is used as a way to provide security so that one can define which entities are allowed to access and/or control other entities.</p>
<p>Admin is the entity that has the ability to choose which users are allowed to communicate with which other users.
For example, if one user is a temperature sensor, a second user is a heater control and a third user is a thermostat agent, the admin would setup access so that the temperature sensor JID is a publisher for an event node T, the heater control JID is a subscriber for event node H, and the thermostat agent JID is a subscriber to event node T and a publisher to event node H.</p>
</section2>
<section2 topic='Device' anchor='struct-device'>
<p>
The "Device" is a top-level encapsulation entity that contains a list of transducers or transducer properties.</p>
<p> This data tends to change infrequently.
</p>
<code><![CDATA[
<xs:element name="Device">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="Transducer"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="Location"/>
<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="xs:string" use="required"/>
<xs:attribute name="timestamp" type="xs:datetime" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="deviceID" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
]]></code>
<table caption="Device Attributes">
<tbody>
<tr>
<th>
Attribute
</th>
<th>
Description/Purpose
</th>
</tr>
<tr>
<td>
name
</td>
<td>
A human friendly name for the device
</td>
</tr>
<tr>
<td>
id
</td>
<td>
A unique identifier for the device. This SHOULD be the same as the device event node idor the base string for event nodes for this device (see below).
</td>
</tr>
<tr>
<td>
type
</td>
<td>
The type of the transducer platform (see below)
</td>
</tr>
<tr>
<td>
timestamp
</td>
<td>
Timestamp in the format described below
</td>
</tr>
<tr>
<td>
description
</td>
<td>
A human friendly description of the device
</td>
</tr>
<tr>
<td>
deviceID
</td>
<td>
An identifier for the device itself (such as a serial number)
</td>
</tr>
</tbody>
</table>
</section2>
<section2 topic='Transducer' anchor='struct-transudcer'>
<p>The "Transducer" element contains information about a particular transducer. A "Device" can contain multiple transducers which may or may not have a physical counterpart. For instance, a thermistor is a transducer (a sensor) that directly measures a physical phenomena (temperature). However, other transducers such as an occupancy sensor, a dew point sensor or a mobile robot, exist as virtual transducers given that the relationship between them and the physical phenomena being measured and control is not straightforward.</p>
<p>This data tends to change infrequently.
</p>
<code><![CDATA[
<xs:element name="Transducer">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="Location"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="Property"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="TransducerCommand"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="TransducerValue"/>
</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="xs:string" use="required"/>
<xs:attribute name="unitScalarPrefix" type="xs:string" use="optional"/>
<xs:attribute name="canActuate" type="xs:boolean" default="false"/>
<xs:attribute name="hasOwnEventNode" 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="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>
]]></code>
<table caption="Transducer Attributes">
<tbody>
<tr>
<th>
Attribute
</th>
<th>
Description/Purpose
</th>
</tr>
<tr>
<td>
name
</td>
<td>
A human friendly identifier to distinguish between various possible transducers within a device
</td>
</tr>
<tr>
<td>
id
</td>
<td>
A unique identifier for the transducer used within the XML packet to enumerate different transducers within a single packet
The tuple (event node id X, transducer id Y) MUST be unique such that a publish operation to an event node X with the transducer id Y unambiguously refers to one and only one transducer.
</td>
</tr>
<tr>
<td>
units
</td>
<td>
Unit of measure (see below)
</td>
</tr>
<tr>
<td>
unitScalerPrefix
</td>
<td>
Prefix for the unit of measure (see below)
</td>
</tr>
<tr>
<td>
canActuate
</td>
<td>
Indicates whether the transducer can be actuated
</td>
</tr>
<tr>
<td>
hasOwnEventNode
</td>
<td>
Indicates whether the transducer has its own event node or whether it is part of a larger data node (see below)
</td>
</tr>
<tr>
<td>
transducerTypeName
</td>
<td>
<br/>
A human readable indication of the type of transducer
</td>
</tr>
<tr>
<td>
manufacturer
</td>
<td>
Manufacturer of the transducer
</td>
</tr>
<tr>
<td>
partNumber
</td>
<td>
Manufacturer's part number of the transducer
</td>
</tr>
<tr>
<td>
minValue
</td>
<td>
The expected minimum value for this transducer
</td>
</tr>
<tr>
<td>
maxValue
</td>
<td>
The expected maximum value for this transducer
</td>
</tr>
<tr>
<td>
resolution
</td>
<td>
The resolution of the values reported by this transducer
</td>
</tr>
<tr>
<td>
precision
</td>
<td>
The precision of the values reported by this transducer
</td>
</tr>
<tr>
<td>
accuracy
</td>
<td>
The accuracy of the values reported by this transducer
</td>
</tr>
</tbody>
</table>
<section3 topic='TransducerValue' anchor='struct-transudcervalue'>
<p>The "TransducerValue" is an element that captures the latest value of the transducer.
This is a dynamic parameter that has been optimized for size, which is why there are no associated descriptions of the value.
Information about the value (like the units, scale, etc) are stored as relatively static information in the "Transducer" packets which are generally only transferred as part of a setup operation and are not repeated within every value packet.
</p>
<code><![CDATA[
<xs:element name="TransducerValue">
<xs:complexType>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="typedValue" type="xs:float" use="required"/>
<xs:attribute name="timestamp" type="xs:datetime" use="required"/>
<xs:attribute name="rawValue" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
]]></code>
<table caption="Transducer Value Attributes">
<tbody>
<tr>
<th>
Attribute
</th>
<th>
Description/Purpose
</th>
</tr>
<tr>
<td>
id
</td>
<td>
The transducer id.
This MUST correspond to a transducer ID as defined in the transducer packet.
The tuple (event node id X, transducer id Y) MUST be unique such that a publish operation to an event node X with the transducer id Y unambiguously refers to one and only one transducer.
</td>
</tr>
<tr>
<td>
typedValue
</td>
<td>
The value representing the transducer data which is in the units as defined in the transducer units attribute
</td>
</tr>
<tr>
<td>
timestamp
</td>
<td>
The timestamp of when the value for this transducer was obtained in the format as described below
</td>
</tr>
<tr>
<td>
rawValue
</td>
<td>
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).
</td>
</tr>
</tbody>
</table>
</section3>
<section3 topic='TransducerCommand' anchor='struct-transudcercommand'>
<code><![CDATA[
<xs:element name="TransducerCommand">
<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>
]]></code>
<table caption="Transducer Command Attributes">
<tbody>
<tr>
<th>
Attribute
</th>
<th>
Description/Purpose
</th>
</tr>
<tr>
<td>
id
</td>
<td>
The transducer id.
This MUST correspond to a transducer ID as defined in the transducer packet.
The tuple (event node id X, transducer id Y) MUST be unique such that a publish operation to an event node X with the transducer id Y unambiguously refers to one and only one transducer.
</td>
</tr>
<tr>
<td>
typedValue
</td>
<td>
The value representing the transducer data which is in the units as defined in the transducer units attribute
</td>
</tr>
<tr>
<td>
rawValue
</td>
<td>
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.
</td>
</tr>
</tbody>
</table>
</section3>
</section2>
<section2 topic='Location' anchor='struct-location'>
<p> The protocol documentation for the Location type is defined in <link url='http://www.xmpp.org/extensions/xep-0080.html'><cite>XEP-0080</cite></link>. </p>
</section2>
<section2 topic='Property' anchor='struct-property'>
<p> It is possible to define new name-value pairs to extend the protocol if required. Only use this if no other schema value captures the property since other clients will not understand custom data in these fields.
For example, CMU uses a "dataHandlerId" property name to provides a way to tie the transducers and the devices to an application-specific meta-data repository.
Specifically, the "dataHandlerId" property value contains a unique database key for logging individual transducer values.
</p>
<code><![CDATA[
<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>
]]></code>
</section2>
</section1>
<section1 topic='Use Cases' anchor='usecases'>
<p>
The following are example use cases which this XEP would enable.
Example data structures for implementing these use cases is given in a later section.
</p>
<section2 topic='Data Logging' anchor='datalogging'>
<p>An agent could be created that subscribes to all event nodes in the system and populates an external database (such as MySQL) so that others can look at historical information regarding sensors and actuators.
Since this is an agent, there is no event node that it owns, but instead it scans a list of available event nodes and subscribes to all of them.</p>
</section2>
<section2 topic='Home Energy' anchor='homeenergy'>
<p>A consumer has purchased an energy monitoring device for use in her home.
An adapter is written to grab data from the device and presents it in the format described in this document.</p>
<p>
NOTE: How the adapter gets the data is irrelevant.
It could be reading values from a usb port, it could be scraping a web page provided by the device, it could be something else.
The details for getting the data are the responsibility of the adapter and are not relevant to the consumers of the data.
</p>
<p>A month later, the same consumer adds a second energy sensor to the monitoring device purchased above.
The adapter can then include the additional information.
</p>
</section2>
<section2 topic='Building Automation' anchor='buildingautomation'>
<p>The occupant of a building wants to automate the temperature control for his building.
There are two temperature sensors indoors and a weather station on the roof.
The heating unit has a simple on/off control.
The A/C unit has four settings: off, low, medium and high.
An agent will be used to combine the various temperature sensors to turn the heater on/off and the setting for the A/C unit.
</p>
</section2>
<section2 topic='Web Camera' anchor='webcamera'>
<p>A consumer has a web camera which can sense movement and has a light which can be turned on or off.
An agent will be used to monitor when motion has occured, turn on the light, and, using <link url='http://www.xmpp.org/extensions/xep-0166.html'><cite>XEP-0166</cite></link> (Jingle), initiate a connection to an XMPP client to allow a human to watch the motion.
</p>
</section2>
<section2 topic='Vehicle Information' anchor='carinfo'>
<p>A car enthusiast purchases an iPhone and connects it to the OBDII diagnostic bus of her car.
An adapter is run on the iPhone to capture sensor data from the iPhone as well as sensor data from the car and send it wirelessly to her home XMPP server.
This example is unusual in that data which is normally thought of as relatively static (location) is actually very dynamic (lat/long of the car).
</p>
<p>This example is also similar to a business owner interested in tracking the performace of a fleet of vehicles.
Instead of capturing and transmitting the information for a single car, the fleet owner would capture and transmit information for each vehicle.
</p>
</section2>
<section2 topic='All of the above' anchor='all'>
<p>A single XMPP server is likely to be able to handle all of the above interactions and more.
Further, as more adapters are added, additional capabilites become available.
For example, a "nearby" adapter could subscribe to vehicle information event nodes and publish to its own event nodes the distance to the vehicles from a know point (such as a home).
A home automation system could then subscribe to the "nearby" event information and make decisions related to heating and cooling as well as energy conservation (for example, as the occupents get closer to the home, the home automation system could start adjusting the temperature, turn on lights, etc).
A data logger as described above would allow data logging of all the events in the system.
Even as new adapters, agents and events are added, the adapters and agents would not need to implement their own logging mechanism.
</p>
</section2>
</section1>
<section1 topic='Implementation Notes' anchor='impl'>
In this section we address conventions required to implement an interoperable system using the Sensor Over XMPP schema. This includes conventions related to units, scaling, timestamps, and naming of event nodes.
<section2 topic="Data and Meta-data" anchor="data-meta">
<p>To reduce the amount of information being exchanged and allow for more efficient software development, we recommend creating pairs of event nodes instead of single event nodes for each device or transducer. The pair would consist of a "data" event node, and a "meta-data" event node. The former, would be restricted to messages that communicate data values from sensors and actuation commands (the dynamic part of the schema), weheras the "meta-data" nodes will be restricted to messages utilizing the other parts of the schema (the relatively static part) which describes the transducers and their properties.</p>
</section2>
<section2 topic='Naming Conventions' anchor='namingconventions'>
<p>For the sake of interoperability, we suggest the following naming conventions for event nodes:</p>
<ul>
<li>Each event node SHOULD be composed of a universal unique identifier (UUID) as defined by <link url="http://tools.ietf.org/html/rfc4122"><cite>RFC 4122</cite></link>.</li>
<li>Additionally, if the above implementation note is followed, this UUID SHOULD be followed by either "_data" or "_meta".</li>
</ul>
We suggest using this naming scheme to simplify storage of relatively static and relatively dynamic data about transducers in a way that is compatible with current pub/sub implementations.
<p>Thus, for the schema shown above, the Device and Transducer would all be part of the UUID_meta event node and the TransducerValue and TransducerCommand would be part of a corresponding UUID_data event node.</p>
<p>OPTIONAL: Instead of putting all of the transducer values into a single UUID_data event node, an adapter MAY want to break up the transducer values into multiple event 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).
Since the tuple (event node id X, transducer id Y) MUST be unique (see above), adapters which want to create event nodes for individual transducers MUST use an event node 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 event node.
</p>
<p>
If an adapter chooses to put the transducer value in its own event node, it MUST indicate this in the UUID_meta node via the Transducer's hasOwnEventNode field.
</p>
<p>NOTE: For every transducer listed in the UUID_meta node, the transducer value MUST be provided in either the UUID_data event node or its own UUID_TransducerID event node, but not both.
The _meta data indicates to consumers which event node it should subscribe to in order to be notified when new data is available for their chosen transducer.
</p>
<p>
To expand on the example provided above where there is a temperature event node T and a heater control node H, there would actually be 4 event nodes:
<ol>
<li>Event node T_meta which contains the device and transducer XML information for the temperature sensor.</li>
<li>Event node T_data which contains the transducer value XML information for the temperature sensor.</li>
<li>Event node H_meta which contains the device and transducer XML information for the heater control.</li>
<li>Event node H_data which contains the transducer value and transducer command XML information for the heater control.</li>
</ol>
Further:
<ul>
<li>The temperature sensor adapter would be a publisher for T_meta and T_data.</li>
<li>The heater control adapter would be a publisher for H_meta and a subscriber to H_data.</li>
<li>The thermostat agent would be a subscriber to T_meta, T_data, H_meta and would be a publisher to H_data.</li>
</ul>
</p>
</section2>
<section2 topic='Types' anchor='types'>
<p>To make it easier for agents to sort through available adapters, it is desirable for implementations to use a common set of types.
The following are recommended types:
</p>
<table caption="Device Types">
<tbody>
<tr>
<th>
Type
</th>
<th>
Description/Purpose
</th>
</tr>
<tr>
<td>
indoor weather
</td>
<td>
Temperature, humidity, etc sensors located indoors (such as in a building)
</td>
</tr>
<tr>
<td>
outdoor weather
</td>
<td>
Temperature, humidity, etc sensors located outdoors (such as a rooftop)
</td>
</tr>
<tr>
<td>
hvac
</td>
<td>
Sensors and controls associated with a Heating, Ventilating and Air Conditioning (HVAC) system
</td>
</tr>
<tr>
<td>
occupancy
</td>
<td>
Sensors and controls associated with occupants (motion sensors, door locks, light switches, etc)
</td>
</tr>
<tr>
<td>
video camera
</td>
<td>
Sensors and controls associated with a video camera
</td>
</tr>
<tr>
<td>
still camera
</td>
<td>
Sensors and controls associated with a still (non-video) camera
</td>
</tr>
<tr>
<td>
scale
</td>
<td>
Sensors and controls associated with measuring weight or mass
</td>
</tr>
<tr>
<td>
vehicle
</td>
<td>
Sensors and controls associated with a vehicle (car, boat, truck, etc)
</td>
</tr>
<tr>
<td>
resource consumption
</td>
<td>
Sensors and controls associated with electricity, gas, water or other resource consumption
</td>
</tr>
<tr>
<td>
resource generation
</td>
<td>
Sensors and controls associated with electricity, gas, water or other resource generation
</td>
</tr>
<tr>
<td>
other
</td>
<td>
Other type that isn't listed above
</td>
</tr>
</tbody>
</table>
</section2>
<section2 topic='Units' anchor='units'>
<p>For the sake of interoperability, it is desirable for implementations to transform native sensor units into the closest relevant SI form.
In order to avoid multiple instances of the same unit name, we suggest using the SI conventions for units shown in the <link url='http://aurora.regenstrief.org/~ucum/ucum.html'>The Unified Code For Units of Measurement</link>.
When listing the units for each sensor, please include only the name and do not use the symbols (they are listed below just for reference). The following table summarizes frequently used units:
</p>
<table caption='Typical SI Units'>
<tr>
<th>Base Quantity</th>
<th>Name</th>
<th>Symbol</th>
</tr>
<tr> <td>length</td> <td>meter</td> <td>m</td> </tr>
<tr> <td>mass</td> <td>gram</td> <td>g</td> </tr>
<tr> <td>volume</td> <td>liter</td> <td>l</td> </tr>
<tr> <td>time</td> <td>second</td> <td>s</td> </tr>
<tr> <td>thermodynamic temperature</td> <td>celsius</td> <td>&amp;deg;C</td> </tr>
<tr> <td>amount of substance</td> <td>mole</td> <td>mol</td> </tr>
<tr> <td>luminous intensity</td> <td>candela</td> <td>cd</td> </tr>
<tr> <td>Illuminance</td> <td>lux</td> <td>lx</td> </tr>
<tr> <td>luminous flux</td> <td>lumen</td> <td>lm</td> </tr>
<tr> <td>energy</td> <td>joule</td> <td>J</td> </tr>
<tr> <td>force</td> <td>newton</td> <td>N</td> </tr>
<tr> <td>pressure,stress</td> <td>pascal</td> <td>Pa</td> </tr>
<tr> <td>electric real power</td> <td>watt</td> <td>W</td> </tr>
<tr> <td>electric reactive power</td> <td>volt-amp reactive</td> <td>Var</td> </tr>
<tr> <td>electric complex power</td> <td>volt-amp</td> <td>VA</td> </tr>
<tr> <td>electric apparent power</td> <td>volt-amp</td> <td>VA</td> </tr>
<tr> <td>electric voltage</td> <td>volt</td> <td>V</td> </tr>
<tr> <td>electric current</td> <td>ampere</td> <td>A</td> </tr>
<tr> <td>electric current phase</td> <td>radian</td> <td>rad</td> </tr>
<tr> <td>electric energy</td> <td>watt hour</td> <td>Wh</td> </tr>
<tr> <td>magnetic field</td> <td>tesla</td> <td>T</td> </tr>
<tr> <td>inductance</td> <td>henry</td> <td>H</td> </tr>
<tr> <td>electric charge</td> <td>coulomb</td> <td>C</td> </tr>
<tr> <td>electric capacitance</td> <td>farad</td> <td>F</td> </tr>
<tr> <td>electric conductance</td> <td>siemens</td> <td>S</td> </tr>
<tr> <td>magnetic flux</td> <td>weber</td> <td>Wb</td> </tr>
<tr> <td>electric resistance</td> <td>ohm</td> <td> &amp;omega;</td> </tr>
<tr> <td>radioactivity</td> <td>becquerel</td><td>Bq</td> </tr>
<tr> <td>frequency</td> <td>hertz</td><td>Hz</td> </tr>
<tr> <td>catalytic activity</td> <td>katal</td><td>kat</td> </tr>
<tr> <td>plane angle</td> <td>radian</td><td>rad</td> </tr>
<tr> <td>solid angle</td> <td>steradian</td><td>sr</td> </tr>
<tr> <td>percentage</td> <td>percent</td><td>%</td> </tr>
<tr> <td>enumeration of values</td> <td>enum</td><td></td> </tr>
<tr> <td>location latitude</td> <td>latitude</td><td></td> </tr>
<tr> <td>location longitude</td> <td>longitude</td><td></td> </tr>
<tr> <td>velocity (meters/second)</td> <td>velocity</td><td>m/s</td> </tr>
<tr> <td>acceleration (meters/second^2)</td> <td>acceleration</td><td>m/s2</td> </tr>
</table>
<p>
After specifying the units of the transducer device, you can then also specify an SI scalar prefix value. The following example shows how to specify a sensor in centimeters.
<code><![CDATA[
<Device id="01020301" type="other">
<Transducer name="inchworm movement" id="0001" canActuate="false"
units="meter" unitScalarPrefix="centi">
</Transducer>
</Device>
]]></code>
The following example shows how to specify a sensor in kilograms.
<code><![CDATA[
<Device id="xyzzy" type="scale">
<Transducer name="bathroom scale" id="0001" canActuate="false"
units="gram" unitScalarPrefix="kilo">
</Transducer>
</Device>
]]></code>
The following example shows how to specify a sensor in kilowatt-hours with a resolution to the nearest 0.1 kWh.
<code><![CDATA[
<Device id="windmill087" type="resource generation">
<Transducer name="home wind generator" id="0001" canActuate="false"
units="watt hour" unitScalarPrefix="kilo"
minValue="-50000" maxValue="0" resolution="0.1">
</Transducer>
</Device>
]]></code>
If no prefix value is specified, then a base scalar of 1 is assumed. The following table contains the common SI scalar prefix names:
<table caption='SI Conversion Chart'>
<tr>
<th>Prefix</th>
<th>Abberviation</th>
<th>Factor</th>
<th>Example</th>
</tr>
<tr> <td>yotta</td> <td>Y</td> <td>1 000 000 000 000 000 000 000 000</td> <td> </td> </tr>
<tr> <td>zeta</td> <td>Z</td> <td>1 000 000 000 000 000 000 000</td> <td> </td> </tr>
<tr> <td>exa</td> <td>E</td> <td>1 000 000 000 000 000 000</td> <td> </td> </tr>
<tr> <td>peta</td> <td>P</td> <td>1 000 000 000 000 000</td> <td> </td> </tr>
<tr> <td>tera</td> <td>T</td> <td>1 000 000 000 000</td> <td> </td> </tr>
<tr> <td>giga</td> <td>G</td> <td>1 000 000 000</td> <td> </td> </tr>
<tr> <td>mega</td> <td>M</td> <td>1 000 000</td> <td> </td> </tr>
<tr> <td>kilo</td> <td>k</td> <td>1 000</td> <td>kilogram, 1 kg = 1,000 g </td> </tr>
<tr> <td>hecto</td> <td>h</td> <td>100</td> <td>hectoliter, 1 hL = 100 L </td> </tr>
<tr> <td>deka</td> <td>da</td> <td>10</td> <td>dekameter, 1 dam = 10 m</td> </tr>
<tr> <td> </td> <td> </td> <td>1</td> <td> meter, liter</td> </tr>
<tr> <td>deci</td> <td>d</td> <td>.1</td> <td>decigram, 1 dg = 0.1 g</td> </tr>
<tr> <td>centi</td> <td>c</td> <td>.01</td> <td>centimeter, 1 cm = 0.01 m</td> </tr>
<tr> <td>milli</td> <td>m</td> <td>.001</td> <td>milliliter, 1 mL = 0.001 L</td> </tr>
<tr> <td>micro</td> <td>u</td> <td>.000 001</td> <td>micrometer, 1 μm = 0.000 001 m</td> </tr>
<tr> <td>nano</td> <td>n</td> <td>.000 000 001</td> <td></td> </tr>
<tr> <td>pico</td> <td>p</td> <td>.000 000 000 001</td> <td></td> </tr>
<tr> <td>femto</td> <td>f</td> <td>.000 000 000 000 001</td> <td></td> </tr>
<tr> <td>atto</td> <td>a</td> <td>.000 000 000 000 000 001</td> <td></td> </tr>
<tr> <td>zepto</td> <td>z</td> <td>.000 000 000 000 000 000 001</td> <td></td> </tr>
<tr> <td>yocto</td> <td>y</td> <td>.000 000 000 000 000 000 000 001</td> <td></td> </tr>
</table>
</p>
</section2>
<section2 topic='Timestamps' anchor='timestamps'>
<p>Timestamps MUST be expressed as UTC values in one of the two formats described below.
Adapters and agents are expected to convert between local time and UTC time if needed.</p>
<p>
Timestamp values can be provided in a subset of the format defined in
<link url="http://tools.ietf.org/html/rfc3339"><cite>RFC 3339</cite></link>.
If using the RFC 3339 style format, timestamps MUST be provided only in the form YYYY-MM-DDThh:mm:ss.sssZ where:
<ul>
<li>YYYY is the four digit year</li>
<li>MM is a two digit month</li>
<li>DD is the two digit day</li>
<li>T is the literal character 'T' to separate the date from the time</li>
<li>hh is the 24 hour-per-day hour</li>
<li>mm is the minutes</li>
<li>ss.sss is the seconds with optional fractional seconds</li>
<li>Z is the literal character 'Z' to indicate the timestamps are UTC</li>
</ul>
For example December 7th, 2010 at 3:32pm UTC in the afternoon would be: 2010-12-07T15:32:00Z.
</p>
<code><![CDATA[
<TransducerValue id="003" typedValue="28.7" timestamp="2010-12-07T15:32:00Z"/>
]]></code>
<p>
As an alternative, the timestamp can be formatted as a 64-bit sensor value composed of 32-bits of seconds and 32-bits of nanoseconds represented in hexidecimal form since the Unix epoch (aka seconds since Jan 1, 1970).
If using this format, it MUST be encoded in the following form: SSSSSSSSnnnnnnnn where:
<ul>
<li> SSSSSSSS represents the 4-byte hex value of seconds since the Unix time epoch</li>
<li> nnnnnnnn represents the 4-byte additional nanoseconds value</li>
</ul>
For example February 2nd, 2011 19:53:35 UTC (1296676415 decimal seconds since the Unix epoch) and 0 nano-seconds would be 0x4D49B63F00000000 (since the nano-seconds is zero, the lower 4 byts are all zero).
</p>
<code><![CDATA[
<TransducerValue id="000" typedValue="4.1" timestamp="4D49B63F00000000"/>
]]></code>
<p>
Consumers of the timestamp data SHOULD look for the literal character 'T' in the eleventh position of the timestamp string to determine if a subset of RFC 3339 format was used or the 64-bit hex format.
</p>
</section2>
<section2 topic='Actuation' anchor='actuation'>
<p> 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 event nodes.
An agent can publish an actuation request to the event 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 event node.
This last step allows an interested agent to subscribe to this event node to confirm the requested action has completed.
</p>
<p>
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 event node.
</p>
<p>
To complete the example provided above where there are temperature event nodes T_meta and T_data and heater control nodes H_meta and H_data, the heater control adapter would also be a publisher for event node H_data so that it can publish the fact that it has turned the heater on or off.
Finally, the thermostat agent could choose to subscribe to event node H_data so that it can confirm that the heater control has acted upon its request.</p>
</section2>
</section1>
<section1 topic='Use Cases - Implementation' anchor='usecasesrevisited'>
<section2 topic='Data Logging' anchor='dataloggingrevisited'>
<p>A data logging agent does not need to create or publish any event nodes. Instead, it would use the XMPP pub/sub disco# ability to list available event nodes and contact the admin entity to subscribe to the nodes of interest.
</p>
</section2>
<section2 topic='Home Energy' anchor='homeenergyrevisited'>
<p>A consumer has purchased an energy monitoring device for use in her home.
The sensor used is accurate to the nearest 10 Wh.
Below are example data structures for an energy node E_meta and E_data where E is a UUID value (4d4335b0-4134-11e0-9207-0800200c9a66 in this example).
</p>
<code><![CDATA[
Evnet Node ID:
4d4335b0-4134-11e0-9207-0800200c9a66_meta
Example data published to the _meta node:
<Device
name="Home energy usage"
id="4d4335b0-4134-11e0-9207-0800200c9a66"
type="resource consumption"
timestamp="2011-01-25T17:03:00">
deviceID="8341gvhv5w9"
<Transducer name="house clamps" id="0001" canActuate="false"
units="watt hour" unitScalarPrefix="kilo"
minValue="0" maxValue="100" resolution="0.01">
</Transducer>
</Device>
Event Node ID:
4d4335b0-4134-11e0-9207-0800200c9a66_data
Example data published to the _data node:
<TransducerValue
id="0001"
typedValue="0.44"
timestamp="2011-01-25T17:13:20">
</TransducerValue>
]]></code>
<p>Later, the same consumer 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 the additional information in the _meta and _data nodes.
</p>
<code><![CDATA[
Evnet Node ID: 4d4335b0-4134-11e0-9207-0800200c9a66_meta
Example data published to the _meta node:
<Device
name="Home energy usage"
id="4d4335b0-4134-11e0-9207-0800200c9a66"
type="resource consumption"
timestamp="2011-02-25T17:03:00">
deviceID="8341gvhv5w9"
<Transducer name="house clamps" id="0001" canActuate="false"
units="watt hour" unitScalarPrefix="kilo">
minValue="0" maxValue="100" resolution="0.01">
</Transducer>
<Transducer name="pool clamps" id="0002" canActuate="false"
units="watt hour" unitScalarPrefix="kilo"
minValue="0" maxValue="100" resolution="0.001">
</Transducer>
</Device>
Event Node ID: 4d4335b0-4134-11e0-9207-0800200c9a66_data
Example data published to the _data node:
<TransducerValue
id="0001"
typedValue="0.39"
timestamp="2011-02-25T17:13:20">
</TransducerValue>
<TransducerValue
id="0002"
typedValue="1.041"
timestamp="2011-02-25T17:13:24">
</TransducerValue>
]]></code>
</section2>
<section2 topic='Building Automation' anchor='buildingautomationrevisited'>
<p>The occupant of a building wants to automate the temperature control for his building.
Below is one possible way for the event nodes to be created.
</p>
<code><![CDATA[
Evnet Node ID: 4d4335b1-4134-11e0-9207-0800200c9a66_meta
Example data published to the _meta node:
<Device
name="Indoor Sensors"
id="4d4335b1-4134-11e0-9207-0800200c9a66"
type="indoor weather"
timestamp="2011-02-25T17:03:00">
<Transducer name="boss office" id="0001" canActuate="false" units="celcius">
</Transducer>
<Transducer name="cafeteria" id="0002" canActuate="false" units="celcius">
</Transducer>
</Device>
Event Node ID: 4d4335b1-4134-11e0-9207-0800200c9a66_data
Example data published to the _data node:
<TransducerValue
id="0001"
typedValue="22"
timestamp="2011-02-25T17:13:20">
</TransducerValue>
<TransducerValue
id="0002"
typedValue="21"
timestamp="2011-02-25T17:13:24">
</TransducerValue>
Evnet Node ID: 4d4335b2-4134-11e0-9207-0800200c9a66_meta
Example data published to the _meta node:
<Device
name="Rooftop weather"
id="4d4335b2-4134-11e0-9207-0800200c9a66"
type="outdoor weather"
timestamp="2011-02-25T17:03:00">
<Transducer name="weather temp" id="0001" canActuate="false" units="celcius">
</Transducer>
<Transducer name="weather humidity" id="0002" canActuate="false"
units="percent">
</Transducer>
</Device>
Event Node ID: 4d4335b2-4134-11e0-9207-0800200c9a66_data
Example data published to the _data node:
<TransducerValue
id="0001"
typedValue="32.314"
timestamp="2011-02-25T17:13:20">
</TransducerValue>
<TransducerValue
id="0002"
typedValue="67"
timestamp="2011-02-25T17:13:20">
</TransducerValue>
Evnet Node ID: 4d4335b3-4134-11e0-9207-0800200c9a66_meta
Example data published to the _meta node:
<Device
name="Legacy Heater"
id="4d4335b3-4134-11e0-9207-0800200c9a66"
type="hvac"
timestamp="2011-02-25T17:03:00">
<Transducer name="B1000 heater" id="1142114" canActuate="true" units="enum">
minValue="0" maxValue="1">
</Transducer>
</Device>
Event Node ID: 4d4335b3-4134-11e0-9207-0800200c9a66_data
Example data published to the _data node (heater is off):
<TransducerValue
id="1142114"
typedValue="0"
timestamp="2011-02-25T17:13:20">
</TransducerValue>
Evnet Node ID: 4d4335b4-4134-11e0-9207-0800200c9a66_meta
Example data published to the _meta node:
<Device
name="New A/C unit"
id="4d4335b4-4134-11e0-9207-0800200c9a66"
type="hvac"
timestamp="2011-02-25T17:03:00">
<Transducer name="X9000 super duper delux a/c" id="310" canActuate="true"
units="enum" minValue="0" maxValue="3">
</Transducer>
</Device>
Event Node ID: 4d4335b4-4134-11e0-9207-0800200c9a66_data
Example data published to the _data node (A/C is at medium):
<TransducerValue
id="310"
typedValue="2"
timestamp="2011-02-25T17:03:00"
</TransducerValue>
]]></code>
</section2>
<section2 topic='Web Camera' anchor='webcamerarevisited'>
<p>A consumer has a web camera which can sense movement and has a light which can be turned on or off.
The consumer also has an agent which responds to the camera motion detector by turning on the camera light.
For security reasons, it is desired to allow an entity 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 event node.
Below are example data structures for a camera node C_meta and C_data as well as a transducer specific event node C_tid2
where C is a UUID value (4d4335b5-4134-11e0-9207-0800200c9a66 in this example).
</p>
<code><![CDATA[
Evnet Node ID: 4d4335b5-4134-11e0-9207-0800200c9a66_meta
Example data published to the _meta node:
<Device
name="front door camera"
id="4d4335b5-4134-11e0-9207-0800200c9a66"
type="video camera"
deviceID="axis-m1301-w-0041142CA2"
<Transducer name="motion sensor" id="tid1" canActuate="false" units="enum"
minValue="0" maxValue="1">
</Transducer>
<Transducer name="light" id="tid2" canActuate="true" units="enum"
hasOwnEventNode="true" minValue="0" maxValue="1">
</Transducer>
<Property
name="adminUrl" value="http://example.com/view/viewer_index.shtml"
name="videoUrl" value="rtsp://example.com/axis-media/media.amp"
</Property>
</Device>
Event Node ID: 4d4335b5-4134-11e0-9207-0800200c9a66_data
Example data published to the _data node (no movement):
<TransducerValue
id="tid1"
typedValue="0"
timestamp="2011-01-25T17:13:20">
</TransducerValue>
Event Node ID: 4d4335b5-4134-11e0-9207-0800200c9a66_tid2
Example data published to the _tid2 node (light is off):
<TransducerValue
id="tid2"
typedValue="0"
timestamp="2011-01-25T17:13:20">
</TransducerValue>
]]></code>
<p>When there is movement, the following would be published by the camera adapter.
</p>
<code><![CDATA[
Event Node ID: 4d4335b5-4134-11e0-9207-0800200c9a66_data
Example data published to the _data node (movement seen):
<TransducerValue
id="tid1"
typedValue="1"
timestamp="2011-01-25T17:13:20">
</TransducerValue>
]]></code>
<p>Two things to note:
<ol>
<li>The tuple ("4d4335b5-4134-11e0-9207-0800200c9a66_data", "tid1") uniquely identifies the motion sensor for this camera adapter.</li>
<li>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.</li>
</ol>
</p>
<p>
To continue this example further, let's assume an agent is subscribed to the _data 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:
</p>
<code><![CDATA[
Event Node ID: 4d4335b5-4134-11e0-9207-0800200c9a66_tid2
Example data published to the _tid2 node (turn on light):
<TransducerCommand
id="tid2"
typedValue="1"
</TransducerValue>
]]></code>
<p>
In response, the camera adapter would turn on the light and publish an acknowledgement.
</p>
<code><![CDATA[
Event Node ID: 4d4335b5-4134-11e0-9207-0800200c9a66_tid2
Example data published to the _tid2 node (light is on):
<TransducerValue
id="tid2"
typedValue="1"
timestamp="2011-01-25T17:13:20">
</TransducerValue>
]]></code>
<p>
In response to this the agent could start recording the video, send an email, use the <link url='http://www.xmpp.org/extensions/xep-0166.html'><cite>XEP-0166</cite></link> (Jingle) extension to send the video to an XMPP client, etc.
</p>
</section2>
<section2 topic='Vehicle Information' anchor='vehicleinformationrevisited'>
<p>A car enthusiast purchases an iPhone and connects it to the diagnostic bus of her car.
Below are example data structures for an vehicle node V_meta and V_data where V is a UUID value (4d4335b6-4134-11e0-9207-0800200c9a66 in this example).<br/>
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 (rotations per second) (i.e. multiply the rpm value by 60 to get hertz) before publishing and an agent could optionally convert the value back to rpm (i.e. divide the hertz value by 60 to get back to rpm) for display.
</p>
<code><![CDATA[
Evnet Node ID: 4d4335b6-4134-11e0-9207-0800200c9a66_meta
Example data published to the _meta node:
<Device
name="My car"
id="4d4335b6-4134-11e0-9207-0800200c9a66"
type="vehicle"
timestamp="2011-01-25T17:03:00">
deviceID="license: HI 2ABC123"
<Transducer name="motion X" id="01" canActuate="false"
units="acceleration">
</Transducer>
<Transducer name="motion Y" id="02" canActuate="true"
units="acceleration">
</Transducer>
<Transducer name="motion Z" id="03" canActuate="false"
units="acceleration">
</Transducer>
<Transducer name="GPS lat" id="04" canActuate="false"
units="latitude">
</Transducer>
<Transducer name="GPS lng" id="05" canActuate="false"
units="longitude">
</Transducer>
<Transducer name="engine rotation" id="06" canActuate="false"
units="hertz">
</Transducer>
<Transducer name="timing advance" id="07" canActuate="true"
units="radian">
</Transducer>
<Transducer name="engine fuel" id="08" canActuate="false"
units="liter">
</Transducer>
<Transducer name="engine fuel pressure" id="09" canActuate="true"
units="pascal">
</Transducer>
<Transducer name="engine coolant" id="10" canActuate="false"
units="celcius">
</Transducer>
</Device>
Event Node ID: 4d4335b6-4134-11e0-9207-0800200c9a66_data
Example data published to the _data node:
<TransducerValue
id="1"
typedValue="8.7"
timestamp="2011-01-25T17:13:20">
</TransducerValue>
<TransducerValue
id="2"
typedValue="8.1"
timestamp="2011-01-25T17:13:20">
</TransducerValue>
<TransducerValue
id="3"
typedValue="9.1"
timestamp="2011-01-25T17:13:20">
</TransducerValue>
]]></code>
<p>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 node.
Consumers of the _data 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).</p>
<p>
NOTE: It is permissible to publish a subset of transducers in the _data event 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):
<ul>
<li>
Increase the history size of the event node in the xmpp server so old entries can be obtained
</li>
<li>
Have the adapter periodicly update all values in the _data node
</li>
<li>
Put infrequent events in their own event nodes and use _data for frequent events
</li>
<li>
Put frequent events in their own event nodes and use _data for infrequent events
</li>
</ul>
If an implementaion chooses to put some transducers values into their own event nodes
(instead of putting them all into the _data event node), remember that a transducer value MUST appear in either the _data node or its own event node, but not both.
The _meta data indicates to consumers which event node it should subscribe to in order to be notified when new data is available for their chosen transducer.
</p>
<p>Finally, in the case of a fleet owner, the logging agent described above could be used to keep historical information (including location and performance) for all of the vehicles in the fleet.
We will leave it as an exercise for the reader to ponder the implications of allowing automotive transducers to be modified on the fly via non-local agents.</p>
</section2>
<section2 topic='All of the above' anchor='allrevisited'>
<p>Whether or not additional event 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 event node that other adapters and agents could use in their calculations.</p>
</section2>
</section1>
<section1 topic='Internationalization Considerations' anchor='i18n'>
<section2 topic='Field Labels' anchor='fli18n'>
<p>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.</p>
</section2>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p> The data published to a pubsub node might contain sensitive information (e.g., a user's occupancy data) or allow control of a device (e.g., a power outlet switch). Therefore, node owners SHOULD exercise care in approving subscription requests. Security considerations regarding particular kinds of information are the responsibility of the "using protocol". XMPP networks use TLS (&rfc4346;) for channel encryption, SASL (&rfc4422;) for authentication, and the Domain Name System (&rfc1034;) for weak validation of server hostnames; these technologies help to ensure the identity of sending entities and to encrypt XML streams.</p>
<section2 topic='Access Control' anchor='security-acl'>
<p>Each event node contains access control in the form of Affiliations similar to those described in Multi-User Chat (<link url='http://www.xmpp.org/extensions/xep-0045.html'><cite>XEP-0045</cite></link>). All affiliations MUST be based on a bare JID &BAREJID; of a full JID &FULLJID;. By default the “owner” of a node has both publish and subscribe permissions. Access control over newly created nodes is server and client implementation specific. As a general rule, clients SHOULD NOT allow open publish access by default. Below are the relevant JID affiliations and their access models: </p>
<table caption='Relavent Affiliations and their Privileges'>
<tr>
<th>Affiliation</th>
<th>Subscribe</th>
<th>Retrieve Items</th>
<th>Publish Items</th>
<th>Delete Single Item</th>
<th>Purge Node</th>
<th>Configure Node</th>
<th>Delete Node</th>
</tr>
<tr>
<td>Creator (Owner)</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
</tr>
<tr>
<td>Publisher</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes *</td>
<td>Yes *</td>
<td>No</td>
<td>No</td>
</tr>
<tr>
<td>Subscriber (Member)</td>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
</tr>
<tr>
<td>None</td>
<td>Yes</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
</tr>
<tr>
<td>Outcast</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>No</td>
</tr>
</table>
<p>
* Note: see <link url='http://www.xmpp.org/extensions/xep-0060.html'><cite>XEP-0060</cite></link> (Publish-Subscribe) for details regarding affiliations and their privileges.
</p>
</section2>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
<p>This document does not require interaction with &IANA;.</p>
</section1>
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
<section2 topic='Protocol Namespaces' anchor='registrar-ns'>
<p>The &REGISTRAR; 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.</p>
</section2>
</section1>
<section1 topic='XML Schema' anchor='schema'>
<code><![CDATA[
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Device">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="Transducer"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="Location"/>
<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="xs:string" use="required"/>
<xs:attribute name="timestamp" type="xs:datetime" use="optional"/>
<xs:attribute name="description" type="xs:string" use="optional"/>
<xs:attribute name="deviceID" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:element name="Transducer">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" ref="Location"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="Property"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="TransducerCommand"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="TransducerValue"/>
</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="xs:string" use="required"/>
<xs:attribute name="unitScalarPrefix" type="xs:string" use="optional"/>
<xs:attribute name="canActuate" type="xs:boolean" default="false"/>
<xs:attribute name="hasOwnEventNode" 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="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:element name="TransducerValue">
<xs:complexType>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="typedValue" type="xs:float" 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="TransducerCommand">
<xs:complexType>
<xs:attribute name="id" type="xs:string" use="required"/>
<xs:attribute name="typedValue" type="xs:float" use="required"/>
<xs:attribute name="rawValue" type="xs:string" use="optional"/>
</xs:complexType>
</xs:element>
<xs:annotation>
<xs:documentation>
The protocol documented in the Location type is defined in
XEP-0080: http://www.xmpp.org/extensions/xep-0080.html
</xs:documentation>
</xs:annotation>
<xs:element name="Location">
<xs:complexType>
<xs:sequence minOccurs="0">
<xs:element name="alt" minOccurs="0" type="xs:decimal"/>
<xs:element name="area" minOccurs="0" type="xs:string"/>
<xs:element name="bearing" minOccurs="0" type="xs:decimal"/>
<xs:element name="building" minOccurs="0" type="xs:string"/>
<xs:element name="country" minOccurs="0" type="xs:string"/>
<xs:element name="datum" minOccurs="0" type="xs:string"/>
<xs:element name="description" minOccurs="0" type="xs:string"/>
<xs:element name="error" minOccurs="0" type="xs:decimal"/>
<xs:element name="floor" minOccurs="0" type="xs:string"/>
<xs:element name="lat" minOccurs="0" type="xs:decimal"/>
<xs:element name="locality" minOccurs="0" type="xs:string"/>
<xs:element name="lon" minOccurs="0" type="xs:decimal"/>
<xs:element name="postalcode" minOccurs="0" type="xs:string"/>
<xs:element name="region" minOccurs="0" type="xs:string"/>
<xs:element name="room" minOccurs="0" type="xs:string"/>
<xs:element name="speed" minOccurs="0" type="xs:decimal"/>
<xs:element name="street" minOccurs="0" type="xs:string"/>
<xs:element name="text" minOccurs="0" type="xs:string"/>
<xs:element name="timestamp" minOccurs="0" type="xs:datetime"/>
<xs:element name="uri" minOccurs="0" type="xs:anyURI"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<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:schema>
]]></code>
</section1>
</xep>