Friday, March 22, 2013

Publishing Data from a Beaglebone with a Java Web Service


I have been experimenting with Java on the Beaglebone. Below are some notes on a simple SOAP-based Web service that returns the current temperature from a TMP102 sensor. A RESTful Web service would probably be even simpler, but I wanted to try it with SOAP.

Looking at material on the Web, I was unclear about how difficult it would be to use Java to read data from the thermometer using I2C. It didn't look very straight forward, so for this round, I decided just to launch a shell from Java and run the Python code I posted before that reads the temperature from a TMP102.  This isn't the most efficient way, but it actually runs quite well for for my use in a low traffic situation.

The RPC-style Web service has just 2 methods, getTempC and getTempF, to report the current temperature in degrees Celsius or degrees Fahrenheit.  Both methods return a float.

I have experimented with running Tomcat 7 on my Beaglebone, and it definitely works, but this sample Web service just uses its own very simple class to publish the service. The publisher is only single threaded, but again the performance is quite adequate for my needs. The publisher could certainly be rewritten to be multithreaded - or one could run an application server like Tomcat.


Java


The first step was to install Java. As of March, 2913, it looks like only Java 6 is available in packages for
Ångström, but this example doesn't need any Java 7 features.

Use opkg to install the following packages:

openjdk-6-java 
openjdk-6-jdk


Code


I wrote and compiled the code on my desktop computer in Netbeans. I then used SCP or WinSCP to copy the resulting JAR file to the Beaglebone for deployment.

Web Service Interface


package tempservice;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface TempService {
    @WebMethod public float getTempC() throws java.io.IOException, 
     java.lang.InterruptedException;
    @WebMethod public float getTempF() throws java.io.IOException, 
     java.lang.InterruptedException;
}

Service Implementation Class


import java.io.IOException;
import java.io.InputStreamReader;
import javax.jws.WebService;

@WebService(endpointInterface = "tempservice.TempService")
public class TempServiceImpl implements TempService {
    @Override
    public float getTempC() throws java.io.IOException, 
     java.lang.InterruptedException {
        // Get runtime
        java.lang.Runtime rt = java.lang.Runtime.getRuntime();
        // Start a new process & run python
        // Use Python to access TMP102 sensor
        java.lang.Process p = rt.exec("/usr/bin/python /home/root/tmp102.py");
        // wait for the process to complete
        p.waitFor();
        // Get process output - its InputStream
        java.io.InputStream is = p.getInputStream();
        java.io.BufferedReader reader = new java.io.BufferedReader(new InputStreamReader(is));
        // And print each line
        String s = null;
        s = reader.readLine();
        return Float.parseFloat(s);
    }

    @Override
    public float getTempF() throws IOException, InterruptedException {
        float c = getTempC();
        return ((c / 5) * 9) + 32;
    }
}

Web Service Publisher Class

package tempservice;

import javax.xml.ws.Endpoint;

public class TempServicePublisher {
    public static void main(String[] args) {
        // 1st argument is the publication URL       
        // 2nd argument is an SIB instance       
        Endpoint.publish("http://192.168.0.106:9876/temp", new TempServiceImpl());
    } 


Starting the service with the command  java -jar TempService.jar > /media/sdhc1/TempSrvcLog.log 2>&1, but the process died every time I closed my session in SSH. Just try to place the process in the background didn't work, nor did any of my attempts with nohup or start-stop-daemon. In the end, I logged in using screen and started the service that way. 

SoapUI is a good way to test the service and see what's happening at the message level. I have also written a quick and easy client in Python 2 that I run from a Raspberry Pi (though the code should run on anything that supports Python).

No comments:

Post a Comment