Getting Started

The following description is outdated. We are now preparing easy-to-follow getting started!

Basic Information

SFCity open smart city platform is based on XMPP PubSub mechanism. Thus, we basically follow XMPP PubSub protocol (XEP-0060: Publish-Subscribe http://www.xmpp.org/extensions/xep-0060.html ). Please see the detail in above link.

For extending the PubSub mechanism for publishing/subscribing sensor data, we use sensor-over-xmpp which is originally developed by Sensor Andrew Project in Carnegie Mellon University.
Please see the detail:
XEP-xxxx: Sensor-Over-XMPP http://xmpp.org/extensions/inbox/sensors.html
Sensor Andrew: http://www.ices.cmu.edu/censcir/resources/SensorAndrew-Tech-Report.pdf

We extended SOX for treating WEB sensing, participatory sensing and etc. Please see the extended schema in appendix.

Process

The process of virtual sensor data delivery is as following: 1) creating virtual sensor node as a pair of meta node and event node, 2) defining meta information to meta node, 3) publish sensor data to data node, and 4)subscribe the sensor node and getting data.

1) Creating virtual sensor node
Firstly, we create two PubSub event nodes in XMPP server for virtual sensor node. We use a pair of two pubsub event nodes (name_meta node and name_data node) as a virtual sensor. The name_meta node is used for storing meta information of the sensor, and the name_data node is used for delivering actual sensor data.

Example: Creating “example” sensor node which has three sensors – GPS sensor, temperature and humidity sensor. At the first step, we simply create two pubsub nodes.

Send message to XMPP server:


<auth mechanism="DIGEST-MD5" xmlns="urn:ietf:params:xml:ns:xmpp-sasl"></auth>
<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">Y2hhcnNldD11dGYtOC...</response>
<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl"></response>  //this is common message to communicate with XMPP server by specific user name and password

<iq id='2qFcS-9' to='pubsub.sox.ht.sfc.keio.ac.jp' type='set'>
<pubsub xmlns="http://jabber.org/protocol/pubsub">
       <create node='example_meta'/>   //create pubsub node named ‘example_meta’
</pubsub>
</iq>

<iq id='2qFcS-10' to='pubsub.sox.ht.sfc.keio.ac.jp' type='set'>
<pubsub xmlns="http://jabber.org/protocol/pubsub">
       <create node='example_data'/> //create pubsub node named ‘example_data’
</pubsub>
</iq>

We can also define access model to the node. For example, anyone(or limited users) can publish/subscribe the nodes. In this case, we set open access and publish model to two nodes.

Send message to XMPP server:


<iq id='2qFcS-11' to='pubsub.sox.ht.sfc.keio.ac.jp' type='set'>
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
      <configure node='example_meta'>
         <x xmlns='jabber:x:data' type='submit'><field var='pubsub#access_model' type='list-  single'><value>open</value></field><field var='pubsub#max_items' type='text-single'><value>1</value></field><field var='pubsub#publish_model' type='list-single'><value>open</value></field></x>
      </configure>
</pubsub>
</iq>
<iq id='2qFcS-12' to='pubsub.sox.ht.sfc.keio.ac.jp' type='set'>
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
     <configure node='example_data'>
       <x xmlns='jabber:x:data' type='submit'><field var='pubsub#access_model' type='list-single'><value>open</value></field><field var='pubsub#max_items' type='text-single'><value>1</value></field><field var='pubsub#publish_model' type='list-single'><value>open</value></field></x>
    </configure>
</pubsub>
</iq>

2) Defining meta information to meta node
After two pubsub nodes for virtual sensor node are created, we define meta information to the sensor node.

Example: define “GPS sensor, temperature and humidity sensor” to “example” sensor node.

Send message to XMPP server:


<iq id='2qFcS-13' to='pubsub.sox.ht.sfc.keio.ac.jp' type='set'>
<pubsub xmlns="http://jabber.org/protocol/pubsub">
     <publish node='example_meta'> //send below message to example_meta node
           <item>
               <device name="example" id="example" type="outdoor weather"> //set device name and device type
                                    <transducer name="temperature" id="temperature" units="celius" minValue="-30.0"             maxValue="100.0" resolution="0.1"/> //set temperature sensor with meta information
                                   <transducer name="humidity" id="humidity" units="percent" minValue="0.0" maxValue="100.0"/>  //set humidity sensor with meta information
                                   <transducer name="longitude" id="longitude" units="longitude"/> //set longitude sensor with meta information
                                   <transducer name="latitude" id="latitude" units="latitude"/> //set latitude sensor with meta information
                              </device>
                          </item>
                     </publish>
                  </pubsub>
</iq>

This meta information is stored to example_meta node. Thus, when a user would like to use the “example” sensor node, the user can understand what kinds of sensors are mounted to the node by getting above meta information from example_meta node.

By using our Java library, we can achieve 1) creating node, and 2) define meta information processes by following simple code.


SoxConnection con = new SoxConnection("sox.ht.sfc.keio.ac.jp", "guest", "miroguest", true);

String nodeName = "example";
		
//set device info and it's transducer meta data
Device device = new Device();
device.setId(nodeName);
device.setDeviceType(DeviceType.OUTDOOR_WEATHER);
device.setName(nodeName);
		
List<Transducer> transducers = new ArrayList<Transducer>();
Transducer t = new Transducer();
t.setName("temperature");
t.setId("temperature");
t.setUnits("celius");
t.setMinValue(-30f);
t.setMaxValue(100f);
t.setResolution(0.1f);
transducers.add(t);
		
Transducer t2 = new Transducer();
t2.setName("humidity");
t2.setId("humidity");
t2.setUnits("percent");
t2.setMinValue(0f);
t2.setMaxValue(100f);
t.setResolution(0.1f);
transducers.add(t2);
		
Transducer t3 = new Transducer();
t3.setName("longitude");
t3.setId("longitude");
t3.setUnits("longitude");
transducers.add(t3);
		
Transducer t4 = new Transducer();
t4.setName("latitude");
t4.setId("latitude");
t4.setUnits("latitude");
transducers.add(t4);
		
device.setTransducers(transducers);

//create node
con.createNode(nodeName, device, AccessModel.open,PublishModel.open);

3) Publish sensor data to the virtual sensor node
After defining sensor meta information, actual sensor node (or corresponding process) sends sensor data to the virtual sensor node by publishing the data to name_data pubsub node).

Example: publishing GPS sensor, temperature and humidity sensor data to “example” sensor node.

Send message to XMPP server:


<iq id='292Ef-9' to='pubsub.sox.ht.sfc.keio.ac.jp' type='set'>
<pubsub xmlns="http://jabber.org/protocol/pubsub">
     <publish node='example_data'>
          <item>
               <data>
   	                    <transducerValue id="temperature" typedValue="27.5" timestamp="2015-02-22T02:47Z+09:00" rawValue="27.5"/>
  	                     <transducerValue id="humidity" typedValue="85.1" timestamp="2015-02-22T02:47Z+09:00" rawValue="85.1"/>
   	                    <transducerValue id="latitude" typedValue="35.30024" timestamp="2015-02-22T02:47Z+09:00" rawValue="35.30024"/>
   	                    <transducerValue id="longitude" typedValue="139.479467" timestamp="2015-02-22T02:47Z+09:00" rawValue="139.479467"/>
               </data>
          </item>
     </publish>
</pubsub>
</iq>

By using our Java library, we can achieve publishing the data by following simple code.


SoxConnection con = new SoxConnection("sox.ht.sfc.keio.ac.jp",  true);
SoxDevice soxDevice = new SoxDevice(con, "example");
List<TransducerValue> values = new ArrayList<TransducerValue>();

TransducerValue tValue1 = new TransducerValue();
tValue1.setId("temperature");
tValue1.setRawValue("27.5");
tValue1.setTypedValue("27.5");
tValue1.setCurrentTimestamp();
values.add(tValue1);

TransducerValue tValue2 = new TransducerValue();
tValue2.setId("humidity");
tValue2.setRawValue("80.3");
tValue2.setTypedValue("80.3");
tValue2.setCurrentTimestamp();
values.add(tValue2);

TransducerValue tValue3 = new TransducerValue();
tValue3.setId("latitude");
tValue3.setRawValue("35.30024");
tValue3.setTypedValue("35.30024");
tValue3.setCurrentTimestamp();
values.add(tValue3);
			
TransducerValue tValue4 = new TransducerValue();
tValue4.setId("longitude");
tValue4.setRawValue("139.479467");
tValue4.setTypedValue("139.479467");
tValue4.setCurrentTimestamp();
values.add(tValue4);

//publish the data			
soxDevice.publishValues(values);

4) Subscribe the sensor node and getting data

Once a user subscribe the sensor node, sensor data will be delivered automatic to the user from name_data pubsub node. User also can understand the detail of meta information of the data by getting the information from name_meta pubsub node.

Example: getting meta information and subscribing “example” sensor node.

Send message to XMPP server:


<iq id='z5rL8-10' to='pubsub.sox.ht.sfc.keio.ac.jp' type='get'>
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<items node='example_meta' max_items='1'/> //get meta information from example_meta node
</pubsub>
</iq>
<iq id='z5rL8-14' to='pubsub.sox.ht.sfc.keio.ac.jp' type='set'>
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<subscribe node='example_data' jid='guest@sox.ht.sfc.keio.ac.jp/Smack'/> //subscribe 
</pubsub>
</iq>

Recieve message from XMPP server:
//Getting meta information from example_meta node
<iq from='pubsub.sox.ht.sfc.keio.ac.jp' to='guest@sox.ht.sfc.keio.ac.jp/Smack' id='z5rL8-10' type='result'>
     <pubsub xmlns='http://jabber.org/protocol/pubsub'>
          <items node='example_meta'>
               <item id='59082EF3956D4'>
                    <device name='example' id='example' type='outdoor weather'>
                       <transducer name='temperature' id='temperature' units='celius' minValue='-30.0' maxValue='100.0' resolution='0.1'/>
                       <transducer name='humidity' id='humidity' units='percent' minValue='0.0' maxValue='100.0'/>
                       <transducer name='longitude' id='longitude' units='double'/>
                       <transducer name='latitude' id='latitude' units='double'/>
                    </device>
               </item>
          </items>
     </pubsub>
</iq>

…

//will receive published message from subscribed example_data node
<message from='pubsub.sox.ht.sfc.keio.ac.jp' to='guest@sox.ht.sfc.keio.ac.jp/Smack' type='headline'>
     <event xmlns='http://jabber.org/protocol/pubsub#event'>
          <items node='example_data'>
               <item id='590844C2C89F8'>
                    <data>
                       <transducerValue id='temperature' typedValue='27.5' timestamp='2015-02-22T03:09Z+09:00' rawValue='27.5'/>
                       <transducerValue id='humidity' typedValue='85.1' timestamp='2015-02-22T03:09Z+09:00' rawValue='85.1'/>
                       <transducerValue id='latitude' typedValue='35.30024' timestamp='2015-02-22T03:09Z+09:00' rawValue='35.30024'/>
                       <transducerValue id='longitude' typedValue='139.479467' timestamp='2015-02-22T03:09Z+09:00' rawValue='139.479467'/>
               </data>
          </item>
     </items>
</event>

By using our Java library, we can achieve to subscribe the sensor node and receive the data by following simple code.


public Subscribe() throws Exception {

		
		SoxConnection con = new SoxConnection("sox.ht.sfc.keio.ac.jp", "guest","miroguest", true);
		SoxDevice soxDevice = new SoxDevice(con, "example");

		soxDevice.subscribe();
		soxDevice.addSoxEventListener(this); 
		
		
}

public void handlePublishedSoxEvent(SoxEvent e) {
		Device device = e.getDevice();
		Transducer transducer = e.getTransducer();
		TransducerValue value = e.getTransducerValue();
		if (transducer != null && device != null && value != null) {
			System.out.println("Device[name:" + device.getName() + ", type:"
					+ device.getDeviceType().toString() + "]");
			System.out.println("Transducer[name:" + transducer.getName()
					+ ", id:" + transducer.getId() + ", unit:"
					+ transducer.getUnits() + "]");
			System.out.println("TransducerValue[id:" + value.getId()
					+ ", rawValue:" + value.getRawValue() + ", typedValue:"
					+ value.getTypedValue() + ", timestamp:"
					+ value.getTimestamp() + "]");
		}
		
}

Result of above program:

-----------------------
Device[name:example, type:OUTDOOR_WEATHER]
Transducer[name:temperature, id:temperature, unit:celius]
TransducerValue[id:temperature, rawValue:27.5, typedValue:27.5, timestamp:2015-02-22T03:09Z+09:00]
-----------------------
Device[name:example, type:OUTDOOR_WEATHER]
Transducer[name:humidity, id:humidity, unit:percent]
TransducerValue[id:humidity, rawValue:85.1, typedValue:85.1, timestamp:2015-02-22T03:09Z+09:00]
-----------------------
Device[name:example, type:OUTDOOR_WEATHER]
Transducer[name:latitude, id:latitude, unit:double]
TransducerValue[id:latitude, rawValue:35.30024, typedValue:35.30024, timestamp:2015-02-22T03:09Z+09:00]
-----------------------
Device[name:example, type:OUTDOOR_WEATHER]
Transducer[name:longitude, id:longitude, unit:double]
TransducerValue[id:longitude, rawValue:139.479467, typedValue:139.479467, timestamp:2015-02-22T03:09Z+09:00]
-----------------------