mirror of
https://github.com/moparisthebest/xeps
synced 2024-11-18 23:35:02 -05:00
729 lines
37 KiB
XML
729 lines
37 KiB
XML
|
<?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>Internet of Things - Events</title>
|
||
|
<abstract>This specification describes an architecture based on the XMPP protocol whereby Things can subscribe to events from other Things based on sensor data available.</abstract>
|
||
|
&LEGALNOTICE;
|
||
|
<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-0030</spec>
|
||
|
<spec>XEP-0323</spec>
|
||
|
<spec>XEP-0324</spec>
|
||
|
<spec>XEP-0326</spec>
|
||
|
</dependencies>
|
||
|
<supersedes/>
|
||
|
<supersededby/>
|
||
|
<shortname>iot-events</shortname>
|
||
|
<author>
|
||
|
<firstname>Peter</firstname>
|
||
|
<surname>Waher</surname>
|
||
|
<email>peter.waher@clayster.com</email>
|
||
|
<jid>peter.waher@jabber.org</jid>
|
||
|
<uri>http://www.linkedin.com/in/peterwaher</uri>
|
||
|
</author>
|
||
|
<revision>
|
||
|
<version>0.0.1</version>
|
||
|
<date>2014-08-13</date>
|
||
|
<initials>pw</initials>
|
||
|
<remark>
|
||
|
<p>First draft.</p>
|
||
|
</remark>
|
||
|
</revision>
|
||
|
</header>
|
||
|
<section1 topic='Introduction' anchor='intro'>
|
||
|
<p>
|
||
|
This document specifies a method whereby devices or applications can subscribe to events from a Thing, based on sensor data, as defined in XEP-0323: &xep0323;. While XEP-0323 defines a method
|
||
|
whereby the device or application can request sensor data information from a Thing when the device or application requires it, this document specifies a method whereby the Thing itself
|
||
|
informs the device or application of desired sensor data, when certain conditions have been met, defined by the device or application.
|
||
|
</p>
|
||
|
<p>
|
||
|
The architecture defined in this document, permits the specification of conditions individually, something that would not be possible, or very difficult to achieve, if a centralized
|
||
|
publish/subscribe or multi-cast pattern would have been used. By allowing individual conditions to be specified, devices or applications can be informed of information that best suit them,
|
||
|
and when it suits them, instead of having to figure out, from the Thing perspective, a common denominator, sufficiently good for all intended devices or applications. Furthermore,
|
||
|
by aligning itself with XEP-0323 and the request/response pattern, the Thing can easily integrate with a provisioning server, as defined in XEP-0324: &xep0324;, to allow for delegation
|
||
|
of trust and allowing detailed provisioning of who is allowed to receive what information. Through the use of attributes defined in XEP-0326: &xep0326; subscriptions can be extended
|
||
|
to underlying nodes controlled by the Thing as well.
|
||
|
</p>
|
||
|
<p>
|
||
|
Internet of Things contains many different architectures and use cases. For this reason, the IoT standards have been divided into multiple XEPs according to the following table:
|
||
|
</p>
|
||
|
<table caption='Internet of Things XEPs'>
|
||
|
<tr>
|
||
|
<th>XEP</th>
|
||
|
<th>Description</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>xep-0000-IoT-BatteryPoweredSensors</td>
|
||
|
<td>Defines how to handle the peculiars related to battery powered devices, and other devices intermittently available on the network.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>xep-0000-IoT-Events</td>
|
||
|
<td>This specification. Defines how Things send events, how event subscription, hysteresis levels, etc., are configured.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>xep-0000-IoT-Interoperability</td>
|
||
|
<td>Defines guidelines for how to achieve interoperability in Internet of Things, publishing interoperability interfaces for different types of devices.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>xep-0000-IoT-Multicast</td>
|
||
|
<td>Defines how sensor data can be multicast in efficient ways.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>xep-0000-IoT-PubSub</td>
|
||
|
<td>Defines how efficient publication of sensor data can be made in Internet of Things.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>xep-0000-IoT-Chat</td>
|
||
|
<td>Defines how human-to-machine interfaces should be constructed using chat messages to be user friendly, automatable and consistent with other IoT extensions and possible underlying architecture.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>XEP-0322</td>
|
||
|
<td>
|
||
|
Defines how to EXI can be used in XMPP to achieve efficient compression of data. Albeit not an Internet of Things specific XEP, this XEP should be considered
|
||
|
in all Internet of Things implementations where memory and packet size is an issue.
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>XEP-0323</td>
|
||
|
<td>
|
||
|
Provides the underlying architecture, basic operations and data structures for sensor data communication over XMPP networks.
|
||
|
It includes a hardware abstraction model, removing any technical detail implemented in underlying technologies. This XEP is used by all other
|
||
|
Internet of Things XEPs.
|
||
|
</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>XEP-0324</td>
|
||
|
<td>Defines how provisioning, the management of access privileges, etc., can be efficiently and easily implemented.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>XEP-0325</td>
|
||
|
<td>Defines how to control actuators and other devices in Internet of Things.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>XEP-0326</td>
|
||
|
<td>Defines how to handle architectures containing concentrators or servers handling multiple Things.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>XEP-0331</td>
|
||
|
<td>Defines extensions for how color parameters can be handled, based on &xep0004;</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>XEP-0336</td>
|
||
|
<td>Defines extensions for how dynamic forms can be created, based on &xep0004;, &xep0122;, &xep0137; and &xep0141;.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>XEP-0347</td>
|
||
|
<td>Defines the peculiars of Thing discovery in Internet of Things. Apart from discovering Things by JID, it also defines how to discover Things based on location, etc.</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
</section1>
|
||
|
<section1 topic='Glossary' anchor='glossary'>
|
||
|
<p>The following table lists common terms and corresponding descriptions.</p>
|
||
|
<dl>
|
||
|
<di>
|
||
|
<dt>Actuator</dt>
|
||
|
<dd>Device containing at least one configurable property or output that can and should be controlled by some other entity or device.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Computed Value</dt>
|
||
|
<dd>A value that is computed instead of measured.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Concentrator</dt>
|
||
|
<dd>Device managing a set of devices which it publishes on the XMPP network.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Field</dt>
|
||
|
<dd>
|
||
|
One item of sensor data. Contains information about: Node, Field Name, Value, Precision, Unit, Value Type, Status, Timestamp, Localization information, etc.
|
||
|
Fields should be unique within the triple (Node ID, Field Name, Timestamp).
|
||
|
</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Field Name</dt>
|
||
|
<dd>Name of a field of sensor data. Examples: Energy, Volume, Flow, Power, etc.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Field Type</dt>
|
||
|
<dd>What type of value the field represents. Examples: Momentary Value, Status Value, Identification Value, Calculated Value, Peak Value, Historical Value, etc.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Historical Value</dt>
|
||
|
<dd>A value stored in memory from a previous timestamp.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Identification Value</dt>
|
||
|
<dd>A value that can be used for identification. (Serial numbers, meter IDs, locations, names, etc.)</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Localization information</dt>
|
||
|
<dd>Optional information for a field, allowing the sensor to control how the information should be presented to human viewers.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Meter</dt>
|
||
|
<dd>A device possible containing multiple sensors, used in metering applications. Examples: Electricity meter, Water Meter, Heat Meter, Cooling Meter, etc.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Momentary Value</dt>
|
||
|
<dd>A momentary value represents a value measured at the time of the read-out.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Node</dt>
|
||
|
<dd>
|
||
|
Graphs contain nodes and edges between nodes. In Internet of Things, sensors, actuators, meters, devices, gateways, etc., are often depicted as nodes whereas links between sensors (friendships)
|
||
|
are depicted as edges. In abstract terms, it's easier to talk about a Node, rather than list different possible node types (sensors, actuators, meters, devices, gateways, etc.).
|
||
|
Each Node has a Node ID.
|
||
|
</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Node ID</dt>
|
||
|
<dd>
|
||
|
An ID uniquely identifying a node within its corresponding context. If a globally unique ID is desired, an architecture should be used using a universally accepted
|
||
|
ID scheme.
|
||
|
</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Parameter</dt>
|
||
|
<dd>
|
||
|
Readable and/or writable property on a node/device. The XEP-0326 &xep0326; deals with reading and writing parameters
|
||
|
on nodes/devices. Fields are not parameters, and parameters are not fields.
|
||
|
</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Peak Value</dt>
|
||
|
<dd>A maximum or minimum value during a given period.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Precision</dt>
|
||
|
<dd>
|
||
|
In physics, precision determines the number of digits of precision. In sensor networks however, this definition is not easily applicable. Instead, precision
|
||
|
determines, for example, the number of decimals of precision, or power of precision. Example: 123.200 MWh contains 3 decimals of precision. All entities parsing and
|
||
|
delivering field information in sensor networks should always retain the number of decimals in a message.
|
||
|
</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Sensor</dt>
|
||
|
<dd>
|
||
|
Device measuring at least one digital value (0 or 1) or analog value (value with precision and physical unit). Examples: Temperature sensor, pressure sensor, etc.
|
||
|
Sensor values are reported as fields during read-out. Each sensor has a unique Node ID.
|
||
|
</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>SN</dt>
|
||
|
<dd>Sensor Network. A network consisting, but not limited to sensors, where transport and use of sensor data is of primary concern. A sensor network may contain actuators, network applications, monitors, services, etc.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Status Value</dt>
|
||
|
<dd>A value displaying status information about something.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Timestamp</dt>
|
||
|
<dd>Timestamp of value, when the value was sampled or recorded.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Token</dt>
|
||
|
<dd>
|
||
|
A client, device or user can get a token from a provisioning server. These tokens can be included in requests to other entities in the network, so these entities can validate
|
||
|
access rights with the provisioning server.
|
||
|
</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Unit</dt>
|
||
|
<dd>Physical unit of value. Example: MWh, l/s, etc.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Value</dt>
|
||
|
<dd>A field value.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Value Status</dt>
|
||
|
<dd>Status of field value. Contains important status information for Quality of Service purposes. Examples: Ok, Error, Warning, Time Shifted, Missing, Signed, etc.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>Value Type</dt>
|
||
|
<dd>Can be numeric, string, boolean, Date & Time, Time Span or Enumeration.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>WSN</dt>
|
||
|
<dd>Wireless Sensor Network, a sensor network including wireless devices.</dd>
|
||
|
</di>
|
||
|
<di>
|
||
|
<dt>XMPP Client</dt>
|
||
|
<dd>Application connected to an XMPP network, having a JID. Note that sensors, as well as applications requesting sensor data can be XMPP clients.</dd>
|
||
|
</di>
|
||
|
</dl>
|
||
|
</section1>
|
||
|
<section1 topic='Use Cases' anchor='usecases'>
|
||
|
<p>
|
||
|
Subscribing to events is performed much the same way as requesting sensor data from a device, as defined in <link url='http://xmpp.org/extensions/xep-0323.html#usecases'>XEP-0323</link>.
|
||
|
Instead of requesting the data using the <strong>req</strong> element of the <strong>urn:xmpp:iot:sensordata</strong> namespace, it is done using the <strong>subscribe</strong> element
|
||
|
of the <strong>urn:xmpp:iot:events</strong> namespace. Much of the syntax of this <strong>subscribe</strong> element coincides with that of the <strong>req</strong> element,
|
||
|
with some differences, as will be described in this document.
|
||
|
</p>
|
||
|
<p>
|
||
|
Responses and sensor data is then sent from the device to the subscriber, in the same way as defined in XEP-0323, with one notable difference: The sequence number <strong>seqnr</strong>
|
||
|
provided in the request, is not forgotten once a readout has been completed, but will be reused every time the Thing reports data to the subscriber. The subscriber must use this sequence
|
||
|
number to correlate incoming sensor data with original request. Furthermore, the subscriber must not reuse the sequence number in other sensor data requests to the Thing, while the subscription
|
||
|
is alive.
|
||
|
</p>
|
||
|
<p>
|
||
|
A subscription is cancelled by the subscriber sending a request with an <strong>unsubscribe</strong> element in it to the Thing. The Thing can also automatically remove subscriptions
|
||
|
if the corresponding friendship ends. Furthermore, event conditions should only be evaluated if the corresponding subscriber is online. This, to avoid offline messages to pile up.
|
||
|
Once a friend comes online, any subscription conditions corresponding to that friend should be evaluated to inform it of the current state of the Thing.
|
||
|
</p>
|
||
|
<section2 topic='Request Subscription of momentary values' anchor='subscribemomentary'>
|
||
|
<p>
|
||
|
The client that wishes to receive momentary values regularly from the sensor initiates the request using the <strong>subscribe</strong> element sent to the device.
|
||
|
In the following example, a subscription is made to receive momentary values every five minutes (specified by the <strong>maxInterval</strong> attribute), with no
|
||
|
field-specific conditions attached.
|
||
|
</p>
|
||
|
<example caption='Subscription request of momentary values from a device'>
|
||
|
<![CDATA[
|
||
|
<iq type='get'
|
||
|
from='client@clayster.com/amr'
|
||
|
to='device@clayster.com'
|
||
|
id='S0001'>
|
||
|
<subscribe xmlns='urn:xmpp:iot:events' seqnr='1' momentary='true' maxInterval='PT5M' req='true'/>
|
||
|
</iq>]]>
|
||
|
</example>
|
||
|
<p>
|
||
|
When the device has received and accepted the request, it responds as follows, using the <strong>accepted</strong> element defined in XEP-0323. Sensor data is later reported
|
||
|
in a way similar to XEP-0323, with the exception that the <strong>seqnr</strong> will be reused every time the event occurs. If the event causes multiple messages to be sent,
|
||
|
the receiver knows which one is the last message, by looking at the <strong>done</strong> attribute. Since the <strong>req</strong> attribute is set to <strong>true</strong>,
|
||
|
an event will be sent back immediately (i.e. emulating a parallel readout request operation).
|
||
|
</p>
|
||
|
<example caption='Subscription request accepted by device'>
|
||
|
<![CDATA[
|
||
|
<iq type='result'
|
||
|
from='device@clayster.com'
|
||
|
to='client@clayster.com/amr'
|
||
|
id='S0001'>
|
||
|
<accepted xmlns='urn:xmpp:iot:sensordata' seqnr='1'/>
|
||
|
</iq>]]>
|
||
|
</example>
|
||
|
</section2>
|
||
|
<section2 topic='Subscription rejected' anchor='subscriptionrejected'>
|
||
|
<p>
|
||
|
If for some reason, the device rejects the subscription request, the communication sequence might look as follows:
|
||
|
</p>
|
||
|
<example caption='Momentary read-out rejected'>
|
||
|
<![CDATA[
|
||
|
<iq type='get'
|
||
|
from='client@clayster.com/amr'
|
||
|
to='device@clayster.com'
|
||
|
id='S0002'>
|
||
|
<subscribe xmlns='urn:xmpp:iot:events' seqnr='1' momentary='true' maxInterval='PT5M'/>
|
||
|
</iq>
|
||
|
|
||
|
<iq type='error'
|
||
|
from='device@clayster.com'
|
||
|
to='client@clayster.com/amr'
|
||
|
id='S0002'>
|
||
|
<error type='cancel'>
|
||
|
<forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
|
||
|
<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' xml:lang='en'>Access denied.</text>
|
||
|
</error>
|
||
|
</iq>]]>
|
||
|
</example>
|
||
|
<p>
|
||
|
Depending on the reason for rejecting the request, different XMPP errors can be returned, according to the description in the following table. The table also
|
||
|
lists recommended error type for each error. Any custom error message is returned in a <strong>text</strong> element, as in the example above.
|
||
|
</p>
|
||
|
<table caption='XMPP Errors when rejecting a subscription request'>
|
||
|
<tr>
|
||
|
<th>Error Type</th>
|
||
|
<th>Error Element</th>
|
||
|
<th>Namespace</th>
|
||
|
<th>Description</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>cancel</td>
|
||
|
<td>forbidden</td>
|
||
|
<td>urn:ietf:params:xml:ns:xmpp-stanzas</td>
|
||
|
<td>If the caller lacks privileges to perform the action.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>cancel</td>
|
||
|
<td>item-not-found</td>
|
||
|
<td>urn:ietf:params:xml:ns:xmpp-stanzas</td>
|
||
|
<td>If an item or data source could not be found.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td>modify</td>
|
||
|
<td>bad-request</td>
|
||
|
<td>urn:ietf:params:xml:ns:xmpp-stanzas</td>
|
||
|
<td>If the request was malformed. Examples can include trying to subscribe to information from a device behind a concentrator, without including node information.</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
</section2>
|
||
|
<section2 topic='Unsubscribing a subscription' anhor='unsubscribe'>
|
||
|
<p>
|
||
|
To unsubscribe a subscription, send the <strong>unsubscribe</strong> element in a request to the Thing with the <strong>seqnr</strong> sequence number corresponding to the
|
||
|
subscription. The Thing responds with an empty response to acknowledge the un-subscription, regardless if the subscription existed or not.
|
||
|
</p>
|
||
|
<example caption='Unsubscribing a subscription'>
|
||
|
<![CDATA[
|
||
|
<iq type='get'
|
||
|
from='client@clayster.com/amr'
|
||
|
to='device@clayster.com'
|
||
|
id='S0003'>
|
||
|
<unsubscribe xmlns='urn:xmpp:iot:events' seqnr='1'/>
|
||
|
</iq>
|
||
|
|
||
|
<iq type='result'
|
||
|
from='device@clayster.com'
|
||
|
to='client@clayster.com/amr'
|
||
|
id='S0003'/>]]>
|
||
|
</example>
|
||
|
</section2>
|
||
|
<section2 topic='Requesting subscription of changes to fields values' anchor='subscribechanges'>
|
||
|
<p>
|
||
|
The client that wishes to receive information when a field or a set fields change, can do so by specifying amount of change allowed in the corresponding
|
||
|
<strong>field</strong> elements in the subscription. It can also provide optional current values from which the change is measured. If current values are not
|
||
|
provided, the Thing uses its corresponding set of current values at the time it receives the request. Current values use the corresponding unit held by the field.
|
||
|
To find out, if unsure, you need to make a sensor data readout first.
|
||
|
</p>
|
||
|
<p>
|
||
|
In the following example, events are sent when light changes by more than 5 units (of a percent), or if a motion detector changes value. Temperature information at the
|
||
|
time of the event is also requested. If the conditions are not met within fifteen minutes, an event is raised anyway (as defined using the <strong>maxInterval</strong>
|
||
|
attribute). The <strong>minInterval</strong> attribute makes sure events are not sent more often than every five seconds.
|
||
|
</p>
|
||
|
<example caption='Requesting subscription of changes to fields values'>
|
||
|
<![CDATA[
|
||
|
<iq type='get'
|
||
|
from='client@clayster.com/amr'
|
||
|
to='device@clayster.com'
|
||
|
id='S0004'>
|
||
|
<subscribe xmlns='urn:xmpp:iot:events' seqnr='1' momentary='true' maxInterval='PT15M' minInterval='PT5S'>
|
||
|
<field name='Light' changedBy='5'/>
|
||
|
<field name='Motion' changedBy='1' currentValue='0'/>
|
||
|
<field name='Temperature'/>
|
||
|
</subscribe>
|
||
|
</iq>]]>
|
||
|
</example>
|
||
|
</section2>
|
||
|
<section2 topic='Requesting subscription of historical data correlated to events' anchor='subscribehistory'>
|
||
|
<p>
|
||
|
Any type of sensor data can be included in an event subscription, including historical data. To limit the amount of historical data to return in an event,
|
||
|
the <strong>maxAge</strong> attribute can be used, instead of the absolute <strong>from</strong> and <strong>to</strong> attributes available in the
|
||
|
corresponding <strong>req</strong> element. The following example requests the last five minutes of historical temperature and light data as soon as the motion detector
|
||
|
detects motion (change upwards of 1).
|
||
|
</p>
|
||
|
<example caption='Requesting subscription of historical data correlated to events'>
|
||
|
<![CDATA[
|
||
|
<iq type='get'
|
||
|
from='client@clayster.com/amr'
|
||
|
to='device@clayster.com'
|
||
|
id='S0005'>
|
||
|
<subscribe xmlns='urn:xmpp:iot:events' seqnr='1' all='true' minInterval='PT1M' maxAge='PT5M'>
|
||
|
<field name='Temperature'/>
|
||
|
<field name='Light'/>
|
||
|
<field name='Motion' changedUp='1'/>
|
||
|
</subscribe>
|
||
|
</iq>]]>
|
||
|
</example>
|
||
|
</section2>
|
||
|
<section2 topic='Requesting subscription of historical data correlated to events' anchor='subscribehistory'>
|
||
|
<p>
|
||
|
Any type of sensor data can be included in an event subscription, including historical data. To limit the amount of historical data to return in an event,
|
||
|
the <strong>maxAge</strong> attribute can be used, instead of the absolute <strong>from</strong> and <strong>to</strong> attributes available in the
|
||
|
corresponding <strong>req</strong> element. The following example requests the last five minutes of historical temperature and light data as soon as the motion detector
|
||
|
detects motion (change upwards of 1).
|
||
|
</p>
|
||
|
<example caption='Requesting subscription of historical data correlated to events'>
|
||
|
<![CDATA[
|
||
|
<iq type='get'
|
||
|
from='client@clayster.com/amr'
|
||
|
to='device@clayster.com'
|
||
|
id='S0006'>
|
||
|
<subscribe xmlns='urn:xmpp:iot:events' seqnr='1' all='true' minInterval='PT1M' maxAge='PT5M'>
|
||
|
<field name='Temperature'/>
|
||
|
<field name='Light'/>
|
||
|
<field name='Motion' changedUp='1'/>
|
||
|
</subscribe>
|
||
|
</iq>]]>
|
||
|
</example>
|
||
|
</section2>
|
||
|
<section2 topic='Requesting subscription of nodes behind a concentrator' anchor='subscribenodes'>
|
||
|
<p>
|
||
|
To subscribe to events from one or more nodes behind a concentrator, the nodes have to be specified using <strong>node</strong> elements in the subscription request.
|
||
|
If more than one node is present, the subscription request is assumed to be made to each node individually. When the subscription conditions are met, the corresponding
|
||
|
node sends its sensor data back to the subscriber. Note that only the node where the conditions are met include data in the message sent to the subscriber. Event subscriptions
|
||
|
are handled individually for each node.
|
||
|
</p>
|
||
|
<p>
|
||
|
In the following example, a subscription of any changes to a sequence of digital inputs handled by a PLC is made.
|
||
|
</p>
|
||
|
<example caption='Requesting subscription of nodes behind a concentrator'>
|
||
|
<![CDATA[
|
||
|
<iq type='get'
|
||
|
from='client@clayster.com/amr'
|
||
|
to='plc@clayster.com'
|
||
|
id='S0007'>
|
||
|
<subscribe xmlns='urn:xmpp:iot:events' seqnr='1' momentary='true' minInterval='PT5S' maxInternval='PT1H'>
|
||
|
<node nodeId='DI1'/>
|
||
|
<node nodeId='DI2'/>
|
||
|
<node nodeId='DI3'/>
|
||
|
<node nodeId='DI4'/>
|
||
|
<field name='State' changeBy='1' currentValue='0'/>
|
||
|
</subscribe>
|
||
|
</iq>]]>
|
||
|
</example>
|
||
|
</section2>
|
||
|
</section1>
|
||
|
<section1 topic='Determining Support' anchor='support'>
|
||
|
<p>If an entity supports the protocol specified herein, it MUST advertise that fact by returning a feature of "urn:xmpp:iot:events" in response to &xep0030; information requests.</p>
|
||
|
<example caption="Service discovery information request">
|
||
|
<![CDATA[
|
||
|
<iq type='get'
|
||
|
from='client@clayster.com/amr'
|
||
|
to='device@clayster.com'
|
||
|
id='disco1'>
|
||
|
<query xmlns='http://jabber.org/protocol/disco#info'/>
|
||
|
</iq>]]>
|
||
|
</example>
|
||
|
<example caption="Service discovery information response">
|
||
|
<![CDATA[
|
||
|
<iq type='result'
|
||
|
from='device@clayster.com'
|
||
|
to='client@clayster.com/amr'
|
||
|
id='disco1'>
|
||
|
<query xmlns='http://jabber.org/protocol/disco#info'>
|
||
|
...
|
||
|
<feature var='urn:xmpp:iot:events'/>
|
||
|
...
|
||
|
</query>
|
||
|
</iq>]]>
|
||
|
</example>
|
||
|
<p>
|
||
|
In order for an application to determine whether an entity supports this protocol, where possible it SHOULD use the dynamic, presence-based profile of service discovery defined
|
||
|
in &xep0115;. However, if an application has not received entity capabilities information from an entity, it SHOULD use explicit service discovery instead.
|
||
|
</p>
|
||
|
</section1>
|
||
|
<section1 topic='Implementation Notes' anchor='impl'>
|
||
|
<section2 topic='Change conditions' anchor='changeconditions'>
|
||
|
<p>
|
||
|
An integral part of conditions, is the measurement of changes of magnitudes of field values. Three attributes available on the <strong>field</strong> element, can be used to define
|
||
|
how to measure changes. The <strong>changedUp</strong> attribute provides a numerical value limiting the amount of upwards change in the field before an event is triggered.
|
||
|
The <strong>changedDown</strong> attributes provides a similar means to control the amount of downwards change in the field, before an event is triggered. If only one of these
|
||
|
are provided, only changes in that direction trigger events. If the <strong>changedBy</strong> attribute is provided, the other two attributes are ignored, and assumed to
|
||
|
be of the same value as the <strong>changedBy</strong> attribute value. All changes are specified using positive numbers.
|
||
|
</p>
|
||
|
<p>
|
||
|
The following table shows how magnitudes are calculated for field values of different types:
|
||
|
</p>
|
||
|
<table caption='Magnitude of change per field type'>
|
||
|
<tr>
|
||
|
<th>Type</th>
|
||
|
<th>Magnitude</th>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>boolean</th>
|
||
|
<td>Magnitude is 0 if false, and 1 if true.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>date</th>
|
||
|
<td>Number of seconds since an implementation specific point in time. Since only changes are measured, actual point in time is not important.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>dateTime</th>
|
||
|
<td>Number of seconds since an implementation specific point in time. Since only changes are measured, actual point in time is not important.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>duration</th>
|
||
|
<td>Corresponding number of seconds.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>enum</th>
|
||
|
<td>Any change to this value, corresponds to a change by 1. If direction of change is important, values are ordered by lexical order.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>int</th>
|
||
|
<td>The value itself.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>long</th>
|
||
|
<td>The value itself.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>numeric</th>
|
||
|
<td>The value itself, without unit. The magnitude specified in any change attributes is assumed to be specified using the same unit as the corresponding field.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>string</th>
|
||
|
<td>Any change to this value, corresponds to a change by 1. If direction of change is important, values are ordered by lexical order.</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<th>time</th>
|
||
|
<td>Corresponding number of seconds.</td>
|
||
|
</tr>
|
||
|
</table>
|
||
|
</section2>
|
||
|
<section2 topic='When to check event conditions' anchor='whentocheck'>
|
||
|
<p>
|
||
|
Event conditions should be checked, if the following conditions are true for the corresponding event:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
One of the following conditions are true:
|
||
|
<ul>
|
||
|
<li>A new value is available.</li>
|
||
|
<li>A subscriber comes online.</li>
|
||
|
<li>The minimum interval timer expires, if specified.</li>
|
||
|
<li>The maximum interval timer expires, if specified.</li>
|
||
|
</ul>
|
||
|
</li>
|
||
|
<li>The corresponding subscriber is online.</li>
|
||
|
<li>
|
||
|
The corresponding event has not been triggered within <strong>minInterval</strong> seconds, if specified.
|
||
|
</li>
|
||
|
</ul>
|
||
|
</section2>
|
||
|
<section2 topic='Removal of friendships' anchor='friendships'>
|
||
|
<p>
|
||
|
If a friendship is lost, i.e. presence information from the corresponding contact is unsubscribed, the Thing has to automatically remove any
|
||
|
event subscriptions available for that contact. If a new friendship is created with the same contact at a later stage, the contact has to request
|
||
|
new subscriptions.
|
||
|
</p>
|
||
|
</section2>
|
||
|
<section2 topic='Power-down and persistence of subscriptions' anchor='persistence'>
|
||
|
<p>
|
||
|
It is up to the thing, if it wants to persist event subscriptions or not. If not persisting event subscriptions, they will automatically be lost if the
|
||
|
Thing rests or restarts for some reason.
|
||
|
</p>
|
||
|
<p>
|
||
|
If the subscriber considers an event subscription important, and wants to make sure a subscription survives any resets of the thing, the <strong>maxInterval</strong>
|
||
|
attribute should be used when requesting the subscription. If an event is not delivered within this time and a margin, the subscriber can assume the subscription
|
||
|
has been lost, and a new subscription can be made.
|
||
|
</p>
|
||
|
</section2>
|
||
|
<section2 topic='Overriding subscriptions' anchor='overriding'>
|
||
|
<p>
|
||
|
A subscriber can only have one active subscription per node on a Thing. If a Thing does not support nodes, each subscriber can only have one active subscription
|
||
|
per corresponding Thing. This means, that a new event subscription automatically overrides (or unsubscribes) any existing subscription on the corresponding node or Thing.
|
||
|
This in turn makes it easier for subscribers to handle restarts and avoids multiplicity problems due to lack of synchronization between subscriber and Thing.
|
||
|
</p>
|
||
|
</section2>
|
||
|
</section1>
|
||
|
<section1 topic='Security Considerations' anchor='security'>
|
||
|
<section2 topic='Re-evaluation of subscription contents' anchor='reevaluation'>
|
||
|
<p>
|
||
|
If a Thing is connected to a provisioning server, as defined in <span class='ref'>
|
||
|
<link url='http://xmpp.org/extensions/xep-0324.html'>XEP-324: Internet of Things - Provisioning</link>
|
||
|
</span>, it should re-evaluate event subscriptions contents if a <strong>clearCache</strong> command is received from the provisioning server.
|
||
|
To be able to do this properly, the contents of the original event subscription should be remembered. Re-evaluating active event subscriptions
|
||
|
after a <strong>clearCache</strong> command enables the owner of the Thing to modify current access rights in the Thing in real-time, including
|
||
|
contents send in events.
|
||
|
</p>
|
||
|
<p>
|
||
|
Existing event subscriptions that are no longer permitted by the new set of rules in the provisioning server, can be removed from memory, without
|
||
|
informing the subscriber about the fact. The subscriber will be informed when re-subscribing, that access rights have been lost.
|
||
|
</p>
|
||
|
</section2>
|
||
|
</section1>
|
||
|
<section1 topic='IANA Considerations' anchor='iana'>
|
||
|
<p>This document requires no interaction with &IANA;.</p>
|
||
|
</section1>
|
||
|
<section1 topic='XMPP Registrar Considerations' anchor='registrar'>
|
||
|
<p>
|
||
|
The <link url="#schema">protocol schema</link> needs to be added to the list of <link url="http://xmpp.org/resources/schemas/">XMPP protocol schemas</link>.
|
||
|
</p>
|
||
|
</section1>
|
||
|
<section1 topic='XML Schema' anchor='schema'>
|
||
|
<code>
|
||
|
<![CDATA[
|
||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||
|
<xs:schema
|
||
|
xmlns:xs='http://www.w3.org/2001/XMLSchema'
|
||
|
targetNamespace='urn:xmpp:iot:events'
|
||
|
xmlns='urn:xmpp:iot:events'
|
||
|
xmlns:sd='urn:xmpp:iot:sensordata'
|
||
|
elementFormDefault='qualified'>
|
||
|
|
||
|
<xs:import namespace='urn:xmpp:iot:sensordata'/>
|
||
|
|
||
|
<xs:element name='subscribe'>
|
||
|
<xs:complexType>
|
||
|
<xs:choice minOccurs='0' maxOccurs='unbounded'>
|
||
|
<xs:element name='node'>
|
||
|
<xs:complexType>
|
||
|
<xs:attribute name='nodeId' type='xs:string' use='required'/>
|
||
|
<xs:attribute name='sourceId' type='xs:string' use='optional'/>
|
||
|
<xs:attribute name='cacheType' type='xs:string' use='optional'/>
|
||
|
</xs:complexType>
|
||
|
</xs:element>
|
||
|
<xs:element name='field'>
|
||
|
<xs:complexType>
|
||
|
<xs:attribute name='name' type='xs:string' use='required'/>
|
||
|
<xs:attribute name='currentValue' type='xs:double' use='optional'/>
|
||
|
<xs:attribute name='changedBy' type='PositiveDouble' use='optional'/>
|
||
|
<xs:attribute name='changedUp' type='PositiveDouble' use='optional'/>
|
||
|
<xs:attribute name='changedDown' type='PositiveDouble' use='optional'/>
|
||
|
</xs:complexType>
|
||
|
</xs:element>
|
||
|
</xs:choice>
|
||
|
<xs:attribute name='seqnr' type='xs:int' use='required'/>
|
||
|
<xs:attributeGroup ref='sd:fieldTypes'/>
|
||
|
<xs:attribute name='all' type='xs:boolean' use='optional' default='false'/>
|
||
|
<xs:attribute name='historical' type='xs:boolean' use='optional' default='false'/>
|
||
|
<xs:attribute name='maxAge' type='xs:duration' use='optional'/>
|
||
|
<xs:attribute name='minInterval' type='xs:duration' use='optional'/>
|
||
|
<xs:attribute name='maxInterval' type='xs:duration' use='optional'/>
|
||
|
<xs:attribute name='serviceToken' type='xs:string' use='optional'/>
|
||
|
<xs:attribute name='deviceToken' type='xs:string' use='optional'/>
|
||
|
<xs:attribute name='userToken' type='xs:string' use='optional'/>
|
||
|
<xs:attribute name='req' type='xs:boolean' use='optional' default='false'/>
|
||
|
</xs:complexType>
|
||
|
</xs:element>
|
||
|
|
||
|
<xs:element name='unsubscribe'>
|
||
|
<xs:complexType>
|
||
|
<xs:attribute name='seqnr' type='xs:int' use='required'/>
|
||
|
</xs:complexType>
|
||
|
</xs:element>
|
||
|
|
||
|
<xs:simpleType name='PositiveDouble'>
|
||
|
<xs:restriction base='xs:double'>
|
||
|
<xs:minExclusive value='0'/>
|
||
|
</xs:restriction>
|
||
|
</xs:simpleType>
|
||
|
|
||
|
</xs:schema>]]>
|
||
|
</code>
|
||
|
</section1>
|
||
|
<section1 topic='For more information' anchor='moreinfo'>
|
||
|
<p>
|
||
|
For more information, please see the following resources:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
<p>
|
||
|
The <link url='http://wiki.xmpp.org/web/Tech_pages/SensorNetworks'>Sensor Network section of the XMPP Wiki</link> contains further information about the
|
||
|
use of the sensor network XEPs, links to implementations, discussions, etc.
|
||
|
</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>
|
||
|
The XEP's and related projects are also available on <link url='https://github.com/joachimlindborg/'>github</link>, thanks to Joachim Lindborg.
|
||
|
</p>
|
||
|
</li>
|
||
|
<li>
|
||
|
<p>
|
||
|
A presentation giving an overview of all extensions related to Internet of Things can be found here:
|
||
|
<link url='http://prezi.com/esosntqhewhs/iot-xmpp/'>http://prezi.com/esosntqhewhs/iot-xmpp/</link>.
|
||
|
</p>
|
||
|
</li>
|
||
|
</ul>
|
||
|
</section1>
|
||
|
</xep>
|