24 Nov 2015

IOT : Sensing & Controlling an Android Device through MQTT Messages

In two earlier posts, we had explored how to create (a) LightWatch - an IOT proof-of-concept  for an ambient light sensor based on Android and the XMPP chat protocol and (b) LightWatchMQ - which would essentially do the same thing but use the more popular MQTT protocol. In each case we were essentially trying to simulate an IOT system based on the Android platform that will use native (or external ) sensors attached to the Android device to communicate with a central "controller" machine. This machine could be a simple Android device with the XMPP or MQTT client or could be running a Python program that listens for messages, extracts data and stores the same in a SQL database.

In this application, we, in a sense close the loop! Not only does the Android device transmit data from its sensors but in term it can be controlled to perform a physical activity -- sound a bell or flash its LED light when "instructed" to do so by the central machine.


The sequence of events is as follows :
  1. A custom built app IOT7939 is started on the remote Android device. This measures the ambient light near the device and publishes two messages on the IOT79 topic of a publicly hosted MQTT webserver, eg http:/broker.hivemq.com:1883 or http://test.mosquitto.org:1883
  2. A central MQTT client subscribes to this topic, IOT79, using, for example a websockets client available at http://www.hivemq.com/demos/websocket-client/ or http://test.mosquitto.org/ws.html Both these clients can Publish or Subscribe to their respective brokers. However any third party MQTT client can also be used. Hence data from the Android machine is received here.
  3. If the central MQTT client wants to initiate an activity on the Android device, it publishes a message on the IOT39 topic. The remote Android machine has subscribed to this topic and listens for a message. When the message arrives, three things happen : 
    1. Another publishing activity is triggered on the Android App, as a kind of acknowledgment for the message received and also to transfer fresh sensor data.
    2. A bell mp3 file is played. If the message contains the world "siren" a different alarm mp3 file is played.
    3. The LED flash on the Android is activated for 5 seconds.
While the Publish and Subscribe activities are reasonable easy to build into the app, the flashing light constitutes a challenge. While there are many webposts that explain how to operate the flash on an Android device and even give the sample code,  almost all of them are based on the deprecated camera class of Android and samples with the new camera2 class are not easily available. What this means is that code that runs on one machine may not run on another. For example, the Flashlight code that was used in this application runs happily on my Motorola with Android 5.1 but did not run on my Micromax with Android 6!

Rather than breaking our head on this, what we did was to de-couple the LED-flashing code from the general MQTT Pub/Sub code and created two apps. The LED Flashlight app is a very simple app that "OnStart" switches on the LED, waits for 5 second, switches the LED off and then exits. This app can easily be replaced with any more rugged Flashlight app that has an inbuilt feature to turn-on itself during the start. This LED flashlight app can be called from the main App with a few lines of code, provided we know the package and the activity name.

    String ExternalAppPackage = "org.iothub.flashlight";
    String ExternalAppActivity = "org.iothub.flashlight.MainActivity";
 
    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.setComponent(new ComponentName(ExternalAppPackage,ExternalAppActivity));
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);


Another very interesting feature of this app is that each device on which this app is run, automatically gets its own id derived from the Android ID . This is Published. So messages Published by the central server can contain this Android ID and the app can be modified to parse subscribed message so that each machine ONLY responds to messages that contains its own Android ID. So in effect, the broadcast can be converted into a narrow-cast and target only specific machines.


This screen-shot shows the WebSockets client on the central machine that receives message on IOT79 topic and these messages contain the Android ID as the first field. Also note that when it Publishes on the IOT39 topic, the message is trapped on the Android app and published "back". Since the message can be trapped, it can be parsed and acted upon "intelligently" with a simple if-then-else construct.

In fact, any third party MQTT client can be used to subscribe to and publish messages on the IOT79, IOT39 topics as shown in this screen capture here



The entire code for the main MQTT Pub/Sub app IOT7939 and the auxiliary Flashlight app is available in GitHub code repository.

Android is one of the most widely used platforms in the world and it is very likely that The Smartphone and the Internet of Things will get very closely tied to each in the future. Hence it makes sense to learn and explore how the key features of IOT can be implemented with Android. This was the motivation for building this proof-of-concept. 

19 Nov 2015

LightWatchMQ : IOT with MQTT / PubSub and Android

The LightWatch application described in the previous post demonstrated a full cycle IOT application with an Android client picking up data from the built-in Android light sensor and then sending the data to a remote machine using an XMPP chat server as a message broker. However the Publish / Subscribe ( PubSub ) model of the MQTT message broker offers a potentially simpler and "cleaner" way of doing the same. One big advantage of the PubSub model is that that there is no need to create userid/passwords for each Android device that is being used as sensor / transmitter. This can become a bottleneck if the number of deployments is very large. 

Getting Started with MQTT on Android

There is no immediate need to download, install or otherwise implement an MQTT server. The easiest way is to use the free HiveMQ server available for testing applications. We also assume that you have a Linux based Android application development environment with Eclipse and the Android SDK already installed. If not, please read through this blog post on Android Programming with Eclipse.

To get started on the Android end, first clone this Git repository into your machine and then follow these instructions. If you are not familiar with Maven, take a deep breath and then go through this tutorial. Basically, you need to successfully execute just two steps, mvn clean install  for the two directories org.eclipse.paho.android.service and org.eclipse.paho.client.mqttv3 to create two critical jar files :  org.eclipse.paho.android.service-1.0.2.jar and org.eclipse.paho.client.mqttv3-1.0.2.jar. Then import the  org.eclipse.paho.android.service.sample application into Eclipse, drop in the two jar files into the lib and you should have a working MQTT client for Android that  will demonstrate all aspects of MQTT technology.

Building your own application

The sample application built in the previous step is full service MQTT client with lots of smart features but modifying it to meet the requirements of our IOT system is very complicated. A simpler sample is available at git dobermai / android-mqtt-push  where the Thermometer.java is a very useful sample to model our application on.

The LightWatchMQ application is basically a port of the original LightWatch2 application with the XMPP calls being replaced with corresponding MQTT calls. The current prototype also demonstrates all the essential components of an IOT system, namely
  • A physical sensor : In this case, the light sensor built into an Android device that measures the lux intensity of ambient light.
  • A "publish" function implemented with an Android App
  • A central message broking service : In this case the HiveMQ server that supports the MQTT pub/sub protocol.
  • Two "subscription" options : implemented through (a) WebSocket Client and (b) a Python listener program that reads data and pushes it into a SQLite database for future processing.

The entire code of the application, including the MQTT jars is available in the GitHub repository LightWatchMQ, as an Eclipse project export and can be downloaded and imported directly into the Eclipse workspace. If the Android SDK has been set up properly, it should compile and execute on any Android machine higher than 4.4.

In addition to the replacement of the XMPP calls with MQTT calls, there are few differences from the original LightWatch2 application and these are as follows :
  • Since there is no userid/password in the PubSub model of MQTT, we are using the Android_ID of the Android device to identify the source of data. This is being published into the broker and is available to the subscriber applications.
  • The two buttons for Start, Stop have been replaced by one single button that changes cleverly changes functionality and behave either as Start or as a Stop button depending on whether the Service is Stopped or already Running. This clever piece of code taken from  dobermai / android-mqtt-push.
  • There is an upper limit on the number of times data can be published by the app. This is more of a debugging feature designed to prevent run-away loops during the development process. In reality, this can be set to a very high number or deleted completely.

Testing the application

The application is designed to connect to the free MQTT broker available at http://broker.hivemq.com:1883 and publish on the topic iothub.



Once the app is loaded, the Publish activity can be started by pressing the Start Service button. To see the output, we login at HiveMQ websocket client and subscribe to the topic : iothub with Quality of Service set to 0 and see the data coming in :



On would notice that when the Android sensor device was covered with a piece of cloth, the lux value dropped from 74 to 13 and when the cloth was removed, the lux value went back to where it was. The Android_ID of the device is also being reported as the long alphanumeric string separated from the lux value with a semicolon.

The data can also be checked with a listener program written in Python, taken from the Paho sample library and then modified to store the data in a SQLite database.


Here again we see the Lux values reported by the client and we see that the intensity reported goes down ( to 2) when the device is covered by hand.

This test was carried out with the Android device [ A Motorola phone ] connected to the WiFi, but it has also been tested with Micromax phones and tablets working with a simple 2G data network. It works!

What have we achieved ?

We have shown how to build a simple Android app that can integrate an Android device into an IOT system. We demonstrate the use of the Light Sensor, but other sensors available on Android can be used as well, to measure the intensity of ambient light and "publish" the information into an MQTT broker. This information can be downloaded by any "subscriber" and displayed on a screen, stored in a database or processed further.

MQTT is one of the most popular protocols used in the IOT environment and Android devices with sensors are widely available. Using this combination helps us to get started with simple IOT projects without too much trouble.

30 Oct 2015

Lightwatch : An IOT prototype using XMPP and Android

In two earlier posts, we have shown how to build (a) an XMPP chat client in Python that can listen for incoming messages and, where applicable, store the data in an SQLite database and (b) a XMPP chat client for Android that can transmit data from an Android device. With these two components we are now in a position to build a realistic prototype of an IOT system that will continuously transmit information about ambient light conditions from an Android device.

This prototype will demonstrate all the essential components of an IOT system namely
  • A  physical sensor - in this the light sensor built into an Android device that measures the lux intensity of ambient light
  • A central message broking service -- in this case an Ignite Openfire server that runs an XMPP protocol based messaging service. This is commonly known as an Instant Messaging or Chat server. XMPP is one of the standard protocols used in IOT.
  • A way to securely pass information across multiple devices. Security is established through the userid and password of the logged in users
  • A SQL compliant RDBMS that receives the light intensity data and stores it for future processing.
[ What is IOT ? Ooops ... sorry, please check out this or this :-) to understand why we are doing any of this ! ]

The overall architecture is as follows :


Any Android device has a set of physical sensors, that can be accessed from a program and these can be identified through any standard utility app, like Sensor Box. In this example, we build a sensor app that accesses the light sensor, one of the most widely available sensors, to determine the level of ambient light near the device.

The sensor app opens an XMPP chat dialogue with a controller device, which is any device that supports a generic XMPP chat client, and waits for a signal to transmit data. Once this signal is received, the sensor app opens a second XMPP chat dialogue with the Python listener and keeps sending ambient light data every 5 seconds, in the format that the listener will accept and store in the SQLite database. This continues until the controller device sends a hold signal, when the data transmission is paused. The transmission can be resumed or paused as and when required. Finally, when the controller sends a quit message, the sensor app shuts down.

To build this app, we broadly follow the instructions given in the earlier post on how to build an XMPP chat client for Android. In addition, the code to handle the light sensor is adapted from this page. In this case, the application is called LightWatch and the key files that need to be changed / modified are as follows 
  1. src/org/iothub/lightwatch/LightWatch.java
  2. res/layout/activity_light_watch.xml
  3. res/values/strings.xml
  4. res/drawable/iothub0.9.png
  5. AndroidManifest.xml
All these files are available in GitHub

To test out the application we need three Internet connected devices
  1. A Unix machine running the ChatIOT.py application as described in this post. This needs to be started with a XMPP userid / password [ referred to as the ReporterID in the LightWatch.java file]
  2. A controller device (Android, Unix, Windows whatever ) that has a chat client that is logged in with another XMPP userid / password [ referred to as the Controller ID]
  3. An Android device where the LightWatch application is installed. This application needs a third userid / password.
All three userids should be in the same XMPP server, which in our case is adastra.re and should be defined as each others chat "contacts". Otherwise messages will never be delivered or accepted.

If everything works well, the sensor app will send a message to the controller device announcing its presence. From the controller device, the message "xmit" needs to be sent back. This will initiate the transmission of a set of messages like "PUSH <lux value>" to the data store. The data store should accept these and store them in the SQLite database. If you cover the Android device with the LightWatch app with a piece of paper, you will notice a sharp fall in the lux value that is being transmitted. This was the humble goal of this application.

Everything has been tested on a Motorola phone and an Xioami tablet and it all works. 





One problem that happens is when the LightWatch gets paused, the flow of data stops! To overcome this, the app was redesigned with the bulk of the activity migrated into an Android Service. This is the LightWatch2 application that can be built with the following files -- that are available in Github. [ Actually, the entire project itself can be downloaded from here.]
  1. src/org/iothub/lightwatch/LightWatch2.java
  2. src/org/iothub/lightwatch/LightWatchService.java
  3. res/layout/activity_light_watch2.xml
  4. res/values/strings.xml
  5. res/drawable/iothub0.9.png
  6. AndroidManifest.xml
  7. res/drawable/pmbutton.xml
Both the applications work very similarly except that in the case of LightWatch2, the service has to started and stopped by pressing buttons on the main screen. After that the behaviour is similar to the LightWatch.

Building a trivial app for Android is easy but one that involves using XMPP libraries and accessing sensor data is a little more complicated. The initial effort required in setting up the process is significant, but once this done, the rest follows relatively smoothly. If you want to set up a small IOT system that is described here, follow the sequence of posts given in this blog.

  1. Build the python chat listener - chatiot.py
  2. Set up your Eclipse environment for Android
  3. Build a basic XMPP client app for Android
  4. Then do what is explained in this blog!
Where can this technology be used ?

One obvious application is in smart cities, where we can measure parameters like air pollution on a continuous basis using tools like Aircast as explained in this blog post.

17 Oct 2015

DIY IOT - XMPP Chat client for Android

In an earlier blog post we had explained how a public XMPP chat server can be used to transmit messages between two computers. In that post we had shown how we can build a chatbot listener in Python that waits for messages and when messages arrive, there was a some simple logic that allowed it to either ring an alarm ( sound a bell tone) or insert the data into an SQLite database.

This chatbot -- ChatIOT -- was tested  by sending messages from a Xabber, a free XMPP chat client using two userids registered on a free, public XMPP server available at adastra.re. This post shows how to build a basic XMPP client for Android, from scratch, using Java and the Smack XMPP library from the Openfire opensource project.

Non-trivial Android app development is not for the faint hearted. If one has never developed an Android application in the past, it would be good idea to look through this post Building an Android App -- Getting Started.

Start Eclipse and create a new Android project with the following parameters :

Use the default options on the next couple of screens and then choose the template for Blank Activity


Click through the rest of screens until the project is created and is visible on the Package Explorer panel on the left of the Eclipse Screen.

Two files would have been opened in the Editor panel, but if not, open the file ChatIOT > res > layout > activity_main.xml Replace the contents of the file with the following code :
activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
   android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
   
   <TextView
      android:id="@+id/textView1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@string/Heading1text"
      android:layout_alignParentTop="true"
      android:textColor="#104E8B"
      android:layout_centerHorizontal="true"
      android:textSize="30dp" />
   
   <ImageButton
        android:id="@+id/imageButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginTop="15dp"
        android:layout_marginBottom="30dp"
        android:layout_centerHorizontal="true"
        android:src="@drawable/iotlogo_v1" />
   
   <Button
        android:id="@+id/button1"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/imageButton"
        android:onClick="startCon"
        android:layout_marginBottom="10dp"
        android:layout_centerHorizontal="true"
        android:background="@drawable/pmbutton"
        android:text="@string/button1text" />
   
    <Button
        android:id="@+id/button2"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1"
        android:layout_marginBottom="10dp"
        android:layout_centerHorizontal="true"
        android:onClick="pushData"
        android:background="@drawable/pmbutton"
        android:text="@string/button2text" />
    
    <Button
        android:id="@+id/button3"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button2"
        android:layout_marginBottom="10dp"
        android:layout_centerHorizontal="true"
        android:onClick="stopCon"
        android:background="@drawable/pmbutton"
        android:text="@string/button3text" />
    
    <TextView
         android:id="@+id/textView2"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:text="@string/Heading2text"
         android:textColor="#104E8B"
         android:textSize="20dp"
         android:layout_below="@+id/button3"
         android:layout_centerHorizontal="true"
         android:layout_marginBottom="40dp" />

</RelativeLayout>



This will show many errors because many of the required resources, artifacts are still missing.

Next, open the file ChatIOT > res > values > strings.xml and replace the contents with this code
strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">ChatIOT</string>
    <string name="action_settings">Settings</string>
    <string name="button1text">Connect</string>
    <string name="button2text">Send</string>
    <string name="button3text">Disconnect</string>
    <string name="Heading2text">xmpp chat for IOT</string>
    <string name="Heading1text">chatIOT</string>

</resources>


Create a new folder in ChatIOT > res and name it drawable. Inside this folder, create new, empty file called ChatIOT > res > drawable > pmbutton.xml. Replace the default contents of the file with the following code :

pmbutton.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
 <item android:state_pressed="true" >
     <shape android:shape="rectangle"  >
         <corners android:radius="3dip" />
         <stroke android:width="1dip" android:color="#5e7974" />
         <gradient android:angle="-90" android:startColor="#345953" android:endColor="#689a92"  />            
     </shape>
 </item>
<item android:state_focused="true">
     <shape android:shape="rectangle"  >
         <corners android:radius="3dip" />
         <stroke android:width="1dip" android:color="#5e7974" />
         <solid android:color="#58857e"/>       
     </shape>
 </item>  
<item >
    <shape android:shape="rectangle"  >
         <corners android:radius="3dip" />
         <stroke android:width="1dip" android:color="#5e7974" />
         <gradient android:angle="-90" android:startColor="#8dbab3" android:endColor="#58857e" />            
     </shape>
 </item>
</selector>


Finally download this 9.png image file
and store it in the folder ChatIOT > res > drawable-hdpi with the name iotlogo_v1.9.png Make sure that all files have been saved, then right click on project ChatIOT and press Refresh. After this the layout should be free of errors, though there will be some warnings.  The screen will now look like this :


Open the MainActivity.java file located in ChatIOT > src > com.yantrajaal.chatiot > MainActivity.java and replace the contents of file with the following code :

MainActivity.java

package com.yantrajaal.chatiot;

import java.io.IOException;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;

import android.util.Log;
import android.view.View;
import android.widget.Toast;
// Smack libraries 
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.chat.ChatManager;
import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.chat.ChatMessageListener;
import org.jivesoftware.smack.AbstractXMPPConnection;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;

import java.util.Random; // required for Random Number Generation

public class MainActivity extends Activity {
 String msg = "PM1139 : ";
 
 XMPPTCPConnectionConfiguration configChatIOT = XMPPTCPConnectionConfiguration.builder()
            .setUsernameAndPassword("uid2", "password2")
            .setServiceName("adastra.re")
            .setHost("adastra.re")
            .setPort(5222)
            .setResource("chatIOT")
            .build();
    
    AbstractXMPPConnection conxChatIOT = new XMPPTCPConnection(configChatIOT);
 /** Called when the activity is first created. **/
 
 @Override
    public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       SmackConfiguration.setDefaultPacketReplyTimeout(10000);
       Log.d(msg, "The onCreate() event");
    }

 private class pmConnect extends AsyncTask<Void, Void, Void> {
      protected Void doInBackground(Void...dummy) {
       
       try {
        conxChatIOT.connect();
        conxChatIOT.login();
    } catch (SmackException | IOException | XMPPException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    } 
         return null;
      }
/*
// this piece of code is kept just for the sake of completeness of Async Tasks
      protected void onProgressUpdate(Void...progress) {
         // setProgressPercent(progress[0]);
      }

      protected void onPostExecute(Void...result) {
          //showDialog("Downloaded  bytes");
      }
*/
  }
 private class pmSend extends AsyncTask<Void, Void, Void> {
      protected Void doInBackground(Void...dummy) {
       Random randomGenerator = new Random();
       int pseudoSensorData;
        
   // Assume we've created an XMPPConnection name "conxChatIOT"._
    ChatManager chatmanager = ChatManager.getInstanceFor(conxChatIOT);
    
    Chat ChatIOT = chatmanager.createChat("uid3@adastra.re", new ChatMessageListener() {
     public void processMessage(Chat chat, Message message) {
      System.out.println("Received message: " + message);
     }
    });
    
    for(int i=0 ; i < 4 ; i++)
    {
        
     try {
      if (i==0){
       ChatIOT.sendMessage("Sound 2");
      } else {
      // this data needs to be generated from some Android physical sensor
       // instead of using a random number generator
       pseudoSensorData = randomGenerator.nextInt(100);
       String payLoad = "Push " + String.valueOf(pseudoSensorData);
      ChatIOT.sendMessage(payLoad);
      }
    } catch (NotConnectedException e1) {
     // TODO Auto-generated catch block
     e1.printStackTrace();
    }
     try {
         Thread.sleep(5000);                 //1000 milliseconds is one second.
     } catch(InterruptedException ex) {
         Thread.currentThread().interrupt();
     }
    }
         return null;
      }

  }
 
    //Method to start the Connection
    public void startCon(View view) {
     Toast.makeText(this, "Connecting", Toast.LENGTH_LONG).show();
     new pmConnect ().execute();
    }
    
  //Method to start the Connection
    public void pushData(View view) {
     Toast.makeText(this, "Push Data", Toast.LENGTH_LONG).show();
     new pmSend ().execute();
    }
    
  //Method to Quit 
    public void stopCon(View View) {
     Toast.makeText(this, "Disconnection", Toast.LENGTH_LONG).show();
     conxChatIOT.disconnect(); 
    }
  
}


This will immediately, throw lots and lots of errors because the Smack/XMPP libraries have not been loaded as yet. To get the libraries perform the following steps 

1. Go to the Smack 4.1 Readme and Upgrade Guide and go to the part for Using Eclipses Android Development Tools (ADT) Ant Based Build
2. Download a python script getMavenArtifactsNG.py  This is in Python 3. Hopefully you have that!
3. Create an artifacts.csv file with the text information given in the paragraph
4. Execute the command ./getMavenArtifactsNG.py -f artifacts.csv -p <path_to_Eclipse_Workspace_Directory>/ChatIOT which is the project directory. This will populate the libs and libs-sources directory with a zooful of jar files!

Refresh the project and this will remove all errors EXCEPT on the lines that refer to the ChatManager. For some reason, the script given above does not load the smack-IM libraries!

5. Go to the downloads section of the Smack library and download the smack-4.1.4.zip file. Unzip this file, locate ONE file smack-im-4.1.4.jar and copy it into ChatIOT/libs directory.

This should remove all compile time errors.

Finally, open the AndroidManifest.xml file located in the ChatIOT project folder and insert one line on permission to access the Internet :
AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yantrajaal.chatiot"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="19" />

    <uses-permission android:name="android.permission.INTERNET" />
    
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


Now if the MainActivity.java program is Run as an Android Application, it should show up on the Emulator like this :

To test the program we need to do the following tasks

  1. This test assumes that we have two registered userid at the xmpp server adastra.re.  So create two IDs say uid2 and uid3. In principle you can choose any public XMPP server but this program has been tested at AdAstra.
  2. Set up the ChatIOT listener chatbot by following these instructions and and start the chatbot using the uid3 userid and its corresponding password.
  3. Start the ChatIOT app either in the Emulator or in a physical Android device
  4. Press the Connect button -- this will connect to the AdAstra server and login as uid2
  5. Press the Send button -- this will first send a message to the listener that contains the text "SOUND 2". This will cause an alarm sound. Next it will send three messages consisting of the word PUSH followed by a random number. These three random numbers would be stored in the SQLite database on the listener machine. There will be a 5 second gap between the messages
  6. The Send button can be pressed repeatedly.
  7. The Disconnect button will cause a logout.
  8. Finally for uid2 to be able to send a message to uid3, the two users must be in each others contact lists! Please use a standard IM client like Pidgin or Xabber to first establish this contact. Otherwise no message will ever be relayed.
  9. You may be wondering why we have used uid2, uid3 as users. Actually there is another user uid1 through which we can keep a check on when uid2 and uid3 are logged in and able to communicate.
In this program we are simply transmitting numbers generated at random. In a real IOT case, these numbers will be generated by physical sensors connected to the Android device. [ this is explained in a subsequent post, where we see how to sense and report illumination levels ]

Java programming on Eclipse is a treacherous business because more often than not the libraries cannot be located and loaded. With Android and Smack there is another level of complexity. Hopefully the steps given here will work. If there is a problem, you can always download the entire project from GitHub, with all libraries in place, and import the same into Eclipse.



16 Oct 2015

Android Programming with Eclipse & Java - Tutorial

In an earlier post we had shown how a generic XMPP chat client (Xabber), running on an Android machine could be used as an IOT component to transmit data and commands, through a publicly hosted XMPP chat server, that can be stored or executed on a distant machine that hosts a python chatbot listener program.

However for any meaningful IOT task to be performed, we need a custom built XMPP chat client that will pick up up data from sensors and transmit it to the listener program. This would be a rather minimal XMPP client, without the bells and whistles required for a full fledged interactive chat client. All that it needs to do is to connect to a XMPP server, login with its userid/password credentials and transmit a IM message to the chatbot listener. Such a program for the Android program needs to be written in Java but BEFORE you begin typing "public static void main(string args) ...etc" you need to get your machine ready for Android programming ...

and believe me, that is not for the faint hearted!

However, don't panic! do not lose heart. I did it and so can you!

There are many tools that will help you build Android apps very quickly using a browser based GUI with drag and drop tools. One such is the AppInventor from MIT for which a decent tutorial is available in the StudyTonight website. Using this, you can build nice, quirky apps that will amuse your friends and give you bragging rights for being an Android developer. But these are just for toys. If you want do serious stuff, you need to go through what we are about to describe in this post.

First question, would you want to work in Windows or Linux ?

Most hardcore application developers, particularly the geeky nerds, prefer working with Linux. My machine has dual boot configuration with one Windows 7 partition and one Ubuntu 14.04 partition and I do most of my development in Ubuntu. However from Windows 8 onwards, dual boot is very difficult if not impossible. So the only option would be download the Oracle VirtualBox software into your Windows machine and install a free Ubuntu image by following instructions given on this page.

All this assumes that you want to develop on Linux. If you prefer the Windows platform then this post may not be relevant for you, except for pure academic interest.

The next decision is about which IDE ( Integrated Development Environment ) to use. Google offers the Android Studio that you can download and then you can Build Your First App by following the instructions. I went down this path and built my first HelloWorld program but realized that most people prefer the Eclipse option and so most of the samples and examples are based on Eclipse. Hence I also abandoned the Android Studio and joined the Eclipse bandwagon. Going forward, we shall stick to the Eclipse option.

I had already installed Eclipse v 3.8 on my Ubuntu partition for an earlier Hadoop project and so it was already there on my machine. However you may read about How to Install Latest Eclipse on Ubuntu by searching for the same on Google. Once Eclipse is installed it may be a good idea to write and run a Hello World program in Java/Eclipse. Just to make sure that things are good to go.

Now for the real stuff -- Java for Android on Eclipse!

First make sure that your development environment is adequate, and then set up the Android SDK. There are four tasks here, namely (a) Download the SDK, (b) Install Eclipse -- not necessary if you already have Eclipse, (c) Setup the Android Development Tool Plug In and (d) Create an Android Virtual device for you to test your Android Apps -- all of which are explained in the link given above. This download takes a while, read every screen carefully and generally go with the defaults.

Now you may go over and create your first hello world Android application. Do not forget to check out the various other excellent tutorials on the left side-bar.

If everything goes well, you will see the Android Virtual Device being launched. It will look like any Android phone and you can click on the usual Android buttons and even browse the web or take pictures with it -- if you have configured it correctly. For the Hello World program, the sequence of screens will look like this.





Our application name is HelloWorld0851 ( located in the third row, right side) and when clicked it shows a little fragment of text "Namaskar 0851 Emulator".

If at this point, you go to the Linux terminal and run the command the Android Device Bridge (adb) command  >adb devices.

We will see only one Android Devices Connected to the machine -- this is the Emulator



Now we need to move from the Simulator to some real Android devices and I connect my Motorola Phone and Micromax Xiaomi tablet to the USB ports of the laptop. When connected, these devices show up on the adb command as follows:



The TA is the Motorola device and the 13E is the Micromax device. Now when you execute the HelloWorld program, you will be prompted to choose the device where it will be installed and run.

So are we done ? Well, I wish I could say so ... but NO,  it is not very easy for the external devices to get connected to the Eclipse development environment.

So how do you connect an Android device to the Eclipse Development Environment ?

Step 1 : USB debugging mode.

When an Android device is connected to the USB port of a computer it is usually in the "media mode" that means that you can only transfer files (including .APK ). For serious work, the machine needs to be put in USB debug mode. Usually, the USB debug mode is hidden from lay users and has be discovered and activated and the process is different for each version of Android.

For the Motorola phone  running Android 5.1 you need to go to :
Settings > About Phone > Build Number and press it 7 times.

For the Micromax Tablet running Android 4.4.4 you need to go to
Settings > About Pad > MIUI version and press 7 times

This is "Khulja Sim Sim" to the Alladin's cave of Android development and a new option called Developer Options will appear on Settings menu and within this there will be another option called USB debug mode. Both Developer Options and USB debug mode needs to be activated. When you do this for the first time, there may be a security warning and  you need to accept the warning and allow the process to move forward. Denying the request will put your device in the limbo as far as application development is concerned.

For the specific device that you are using, you will have to Google for the steps involved or arrive their by trial and error!

In many cases, this is adequate. One needs to stop, restart the adb service by simply
>sudo adb kill-server
>sudo adb start-server
and hopefully the device will be detected.

But very often than not, this is not enough. Even after activating USB debug mode, the device may not be recognized. So now

Step 2 : Android-Rules

You need to create a file called 51-android-rules in the /etc/udev/rules.d directory as described in this post How to fix ADB no permissions, and explained in context in Stackoverflow. This will solve the problem for most common Android vendors, including Motorola, but unfortunately that does not include Micromax!

To identify the ID of the USB connected Micromax device, we executed the lsusb command :

This shows the ID of the various devices connected to the USB ports, most of which are recognizable from the descriptions.

For example ID 22b8-2382 is the Motorola Device and it is duly visible in the original file that we downloaded. So the there is a good chance that the unknown device with ID 271-066B must be the Micromax device. So we append on extra dummy line at the bottom of the 51-android-rules file with one extra line

SUBSYSTEM=="usb", ATTRS{idVendor}=="2717", MODE="0666"

and that does the trick! After creating the file with the extra line and executing the commands given in the two posts, both the Android devices are clearly visible with the adb command and are available for testing the application.

Update : My new Micromax Android One running Android 6 was recognised by the Android SDK without any problem. Just set it in USB debugging mode and you are done!

Now we are finally ready!

Go back to Eclipse and run the "MainActivity" java file of the HelloWorld program. There will be a prompt to choose the device which could be any one of the three devices, the emulator, the Motorola phone or the Micromax tablet. Once a physical device is chosen, the application will be installed on the device, started and will also be available like any other downloaded app.

The final hurdle to this happy state of affairs is Android Security does not allow apps to be installed from an unknown source, that is anything other than Google Play. This can be addressed by a simple configuration change that allows App Installs from Unknown Sources.

At the end of all this, we are finally ready to start building a real useful app for the XMPP client. That presents its own set of challenges with the Smack library that connects to the Ignite Openfire server. But that is another post for another day. Keep watching this space!


P.S. If you find this USB debug mode and the Android-Rules to be too much for you, you can always copy the APK file manually into the device while it is connected in the simple media-mode and install it by tapping the file twice in a file browser. See here.

15 Sep 2015

DIY IOT : XMPP Chatbot in Python

A key challenge in building the "Internet of Things" is to be able to connect a device to a computer over the internet and to use as simple and lightweight an infrastructure as possible. In this post we demonstrate how a public XMPP chat server can be used to transmit data and commands from one device to another using a chat client at one end and a python "bot" sitting on the other end. We will demonstrate the ability to INSERT data into an SQLite database, SELECT records from the same, play a variety of .wav files and execute any system commands on a "central" machine from any distant machine that supports an XMPP chat client.



Before starting on this exercise, we searched the web for prior activity in this area and we came across this webpage that suggests a similar approach for controlling devices over the internet, but the strategy explained here is simpler to code and implement.

We looked for a list of public XMPP chat servers and selected the Ad Astra service, perhaps because it was the first on the list! We next registered two userids, say x1@adastra.re and x2@adastra.re to be used on the two different machines using the web-registration form, because the in-band registration does not work!

We next installed the Pidgin chat client on two different Ubuntu machines and verified that text messages where being sent and received through the Ad Astra server without any problem.

Since working with two machines on a desktop is difficult, we configured our experimental setup as one Android phone acting as the distant machine and an Ubuntu 14.04 laptop acting as the central server. Commands transmitted from the Android phone using the Xabber chat app would be received on the server and acted upon.

For the server side we configured a chatting robot, or chatbot with Python using the xmppy library and using the code for the sample bot as a starting point. The sample bot program has a number of sample "handlers" that perform some simple tasks. These were modified to perform the following tasks
  • PUSH - to insert a piece of data into an SQLite database
  • PULL - to select a record from the SQLite database
  • SOUND - to play a selection of .wav files using the aplay command available in Ubuntu
These tasks were to be executed by calling a shell program and passing the relevant parameters through the python subprocess command.

There were three other handlers
  • EXESYS - to execute any system command on the central machine
  • TEST - to echo the command received back to the sender as a debugging measure
  • HELP - that lists all the possible commands.
Before the chatbot starts, we need to install SQLite, create a database and within it, an rdbms table. 

The chatbot ("chatIOT") is a python script that needs to be started with the userid@servername.com and the password as the parameters. It then listens for text messages and responds as appropriate to the six commands listed above.


The Xabber chat client on the Android phone is now used to send messages as follows



In the left hand image of a screenshot of the Xabber client on the Android phone, we see that the value PULLed from the database is 100.4. Then we PUSH 51.29 into the database and the subsequent PULL shows two values namely 100.4, 51.29 that were stored in the persistent database.

The second, right hand image, shows how the unix command ls for directory listing is executed and the data is returned. We note the three .wav files that could be played by sending the SOUND command along with a number that indicates which file is to be played.

How realistic is this setup in simulating a real IOT scenario ?

All that the distant device needs is a chat client. If it is an Arduino board then it is possible to create a chat client for the same as explained here and elsewhere. If the Arduino is connected to Raspberry Pi2, then life is even simpler because with python it is very easy to create a simple chat client - xmit.py

If one is not comfortable with messages being transmitted through a public chat server then one can build one's one chat server using the free and opensource OpenFire software and host it on a secure but publicly visible IP address. But even otherwise the usage of standard userid, password mechanism of a public chat server offers decent security.

What we have demonstrated in this exercise is how to build a secure data transport mechanism using publicly available components and with minimal programming. IOT developers and enthusiasts can focus on the behaviour of the edge devices without having to worry about the "plumbing" that will move the data from one machine to another.


The following files are available at Github :
  • the main python "bot" script, chatIOT.py and the shell script kmd.sh that is called by chatIOT.py to execute the SQLite and sound commands.
  • createIOTdata.sh and viewIOTdata.sh to create the SQLite tables and view the data
  • three .wav files for the three sounds
  • xmit.py - a lightweight xmpp chat client for sending text messages

11 Sep 2015

MQTT with Mosquitto: A beginner's tutorial



Using MQTT on Mosquitto and Paho

In the current tutorial, I shall describe the usage of one of the most widely used protocols named “MQTT” using open source server/broker and clients. I have used my Windows 7 machine for running the tutorial.

MQTT

MQTT( Message Queue Telemetry Transport) is used for device data collection. As its name suggests, its main purpose is telemetry, or remote monitoring. Its goal is to collect data from many devices and transport that data to the IT infrastructure. It targets large networks of small devices that need to be monitored or controlled from the cloud. MQTT uses a hub-and-spoke architecture, where all the devices connect to a data concentrator server. The protocol works on top of TCP, which provides a simple, reliable stream of data. MQTT works in “publish subscribe” mode and is a very good means of low power transfer of data from devices to broker with reliability. The messages' payloads are just a sequence of bytes, up to 256MB, with a fixed header of two bytes to most messages. The clients can subscribe to these messages and get updated by the broker when new messages arrive. MQTT lets clients and brokers set a "Quality of Service" on messages basis from "fire and forget" to "confirmed delivery".
Please refer to <http://mqtt.org/faq> for more information on the specific protocol.

Paho

MQTT needs client implementations. The Eclipse Paho project is part of the Eclipse Foundation's M2M (Machine to Machine) mission to provide high quality implementations of M2M libraries and tools. Under the Paho banner, open source client libraries for MQTT are being developed.  MQTT C and Java libraries with Lua, Python, C++ and JavaScript are at various stages of development. In this article we'll be showing how to use the Paho Java MQTT libraries to publish and subscribe.

Mosquitto

In order to receive published messages and send them on to any clients who have subscribed, we need a broker. Mosquitto is one of such brokers which is easy to configure and run for MQTT messages. Mosquitto is open source, so you can download it and run it on your own system, on different operating systems like Windows, Mac OS X, Linux or many other platforms. The Mosquitto broker code is also being contributed to Eclipse as part of a new project.

Mosquitto's default configuration means it is set up to not use username/password authentication and it accepts all connections on port 1883. It also comes with two clients, mosquitto_pub and mosquitto_sub. mosquitto_pub client is used for publishing simple messages, while the later is for subscribing to a topic and printing the message that it received. It is also widely used for debugging applications. We shall see the usage of both these clients in the tutorial.

We shall test out the following configuration using mosquitto and the code snippets.



Downloads required

You need to download the following.

Eclipse IDE for Java developers: Source <https://eclipse.org/downloads/>, select the 32 bit or 64 bit version as compatible to your system.

Install eclipse as per the guidelines. Make sure a version of JRE is installed in your machine and eclipse should point to the same JRE folder for execution


Mosquitto: Source <http://mosquitto.org/download/> . I have used the binary installation as follows.

mosquitto-1.4.3-install-win32.exe (~200 kB) (Native build, Windows Vista and up)

At the time of installation, you will be prompted to install additional dlls (for win 32) as follows

libeay32.dll, ssleay32.dll  and  pthreadVC2.dll

You need to get the dlls from the URLs specified during download process (on clicking the links, you will be taken to the sources of the dlls directly). You need to copy the dlls is the directory where mosquito is installed. These dlls are mandatory for running mosquito.

Add the path of the folder where Mosquitto executables are copied using the System Properties-> Environment variables (on Windows 7). This will make sure that mosquito executable will run from any place. 


Paho : Source : <http://git.eclipse.org/c/paho/org.eclipse.paho.mqtt.java.git/

Download the following and extract in a folder (can be under eclipse). I used the “zip” version.


After extraction, add the path of the downloaded files in your CLASSPATH through System Properties-> Environment variables (on Windows 7). Specifically, the following folder should be added to the CLASSPATH for the current exercise.

java-1.0.2\org.eclipse.paho.client.mqttv3


Running the application

On the Eclipse IDE

Open the Eclipse IDE, create a new Java project and then select Configure Convert to Maven project.

Since the Paho MQTT code isn't in Maven Central, we need to include its repository. This needs to be done on the pom.xml file from Eclipse IDE.

Open the pom.xml file and after </version> add

<repositories>
<repository>
<id>paho-mqtt-client</id>
<name>Paho MQTT Client</name>
<url>https://repo.eclipse.org/content/repositories/paho-releases/</url>
</repository>
</repositories>

Then we need to add the dependency for the Mqtt-client code. On the pom.xml file, after </build>, add

<dependencies>
<dependency>
<groupId>org.eclipse.paho</groupId>
<artifactId>mqtt-client</artifactId>
<packaging>jar</packaging>
<version>0.4.0</version>
</dependency>
</dependencies>

From Command Prompt

Run Mosquitto.exe (type “mosquitto” from command prompt). One screen will open up



To make sure (or check) whether mosquitto  is running, you can open another command prompt window and run “netstat –an”.  You should be able to see the following screen with boxed line (showing Listening at port 1883).



 
Now we have made sure that MQTT broker is running and is listening to port 1883.
Open another command prompt and run the following command. With the options used, the messages are dumped on the screen.

mosquitto_sub -t "#" –v


Go back to Eclipse IDE and create a new class called PahoDemo. Add the following lines of code.

import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;

public class PahoDemo {

         MqttClient client;
        
         public PahoDemo() {}

         public static void main(String[] args) {
           new PahoDemo().doDemo();
         }

         public void doDemo() {
           try {
             client = new MqttClient("tcp://localhost:1883", "pahomqttpublish1");
             client.connect();
             MqttMessage message = new MqttMessage();
             message.setPayload("A single message from first program".getBytes());
             client.publish("pahodemo/test", message);
             client.disconnect();
           } catch (MqttException e) {
             e.printStackTrace();
           }
         }
       }


Output:

You will be able to see the message “pahodemo/test A single message from first program” on the mosquitto_sub screen.



Also if you open another command prompt and type the following.
mosquitto_pub -t "mosquittodemo/test" -m "Hello"

You will get the same message echoed at the mosquitto_sub screen as follows.



Thus, we managed to get a basic Paho MQTT client running. The messages are displayed both from the Java Application as well as the mosquitto_pub client