Saturday, September 26, 2009

Connecting a SensaTronics Model F temperature monitor to Nimbits

Update: A more recent article has a more generic Java Class for reading and writing to Nimbits or any App Engine Project that uses REST web services. Check it our here or enjoy the more rugged code below.



In this post, I'm going to show you how to use a temperature probe connected to your computer and feed that temperature into Nimbits so you can access that reading anywhere in the world. Each time the Fahrenheit temperature is read into the system, we'll automatically convert it to Celsius using the formula engine and set up an alert to email us automatically if the temp goes beyond a certain range.

Before you attempt this, please understand how nimbits SOA keys work. You'll need to create a SOA key by logging into app.nimbits.com. Read more about SOA keys here.


I'm going to cover how this is done in Java using Eclipse on an Ubuntu workstation. If you'd like to accomplish the exact same result using a Windows bases PC and .Net see my other post on this topic.

It's a little more difficult to get things going on your desktop using linux, but IMO it's a much more satisfying result!

This example can be uses as a general purpose tutorial for connecting most serial or USB devices to nimbits. If it produces a number value that changes over time, then it can be done.

Hardware:

As i said, this tutorial can be modified to work with most serial devices. For this post, I'm using a SensaTronics Model F temp monitor available here

I like this monitor becuase it supports multiple probes and they also sell a 50' probe which frees you from having to put the workstation next to whatever you're monitoring.

Since the PC i'm using dosn't have a serial port, i'm using Belkin USB to Serial Adapter which works just fine on Ubuntu without any driver futsing.

Software
I'm not going to go into any great detail on setting up the development environment. One should have Eclipse up and running and follow the instructions for installing RXTX on linux - Thankfully, you can skip to the bottom of these instructions and just do Method 3.

Step 1. Create your project
  • Launch Eclipse and select File - New Java Project
  • Name the project TempProbe
  • Click Finish
  • Right click on the TempProbe Project in Package Explorer and Select New - Class
  • Name the Class runProbe and Check to create a public static void main
  • Right click the project again and select Build Path and then Configure Build Path
  • On the Libraries tab, select to Add An external JAR and browse to where you dowloaded the RXTXcomm.jar file.
Step 2. Gather information

When you connected your Temp Probe USB adapter and new tty device was added to your system. You'll need that port information. Open a terminal and type:
ls /dev/tty*

when i connected my temp probe, i saw a new device called /dev/ttyUSB0 yours may be different.

You'll also need your nimbits.com SOA Key. Using a key allows you to feed data into nimbits from a system that's not logged into google with a google account.

When you log into nimbits you're authenticated using your google account and can access all of your information. When your not logged into google, you need to provide your personal key which is a 64 character string the application assigns to you. It's important you keep this key as private as you keep your google password since anyone who has it can access your Nimbits data via the web services (but not any other information related to your google account)

Log onto Nimbits and select Manage SOA Key at the top menu. Here, you can have your key emailed to the google account your logged in as. Be careful if you choose to get a new key. You can do this at anytime but any software you already have using the nibmits service will need to be updated.

While your logged into Nimbits, let's also create two new Data points under any catagory you like. Call the first point TempF and the next Point TempC

Click on the TempF point. You'll see an empty chart, and above it, the menu for the many ways you can work with this point. Select the point name from the menu to edit it's properties.

Select the calculations tab to edit the calulation. Read more about how calculations work in Nimbits. When your probe writes to the TempF point, it will trigger the calculation, use the new TempF value as the x parameter and send the result into the TempC point.

So the tigger is LabTemF
Formula : (x-32)*(5/9) (converts F to C)
Target: TempC
X= TempF

Save, you should be good to go. In face, if you click test you should get -17.777 because your curret value for the new TempF point is 0.

You'll also want to set the properties of the point. You can enter C and F for the units of measer. Also, note the compression setting. Compression means you'll only record values that are outside the compression range. So if your reading 77 degrees and your compression is set to 0.5, a reading of 77.1 will get ignored but 77.6 will be recorded. This is usefull for filtering out noise and small changes your not interested in. Let's give our temp points a compression of 0.5

Now, paste this code into your class:


public static java.sql.Date Now()
{
Calendar cal1 = Calendar.getInstance();
Date _now = new java.sql.Date((cal1.getTime()).getTime());

return _now;

}
public static void main(String[] s)
{
//System.out.println(getTemp());

while (true)
{

try {
Double v = getTemp();
System.out.println("Got Temp: " + v);

if (v > 0)
{
updatepoint(v);
}

Thread.currentThread();
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (java.lang.NumberFormatException e)
{

}

}


}
private static void updatepoint(double temp)
{
try {
//my SOA key from nimbits.com
String key = "drGcVC5mJOLiCDEFAIKf288yCDighMKtq02mzy0oT0aSiP1vscLlaHABT4GInFmC";

// Construct data
String data = URLEncoder.encode("key", "UTF-8") + "=" + URLEncoder.encode(key, "UTF-8");
data += "&" + URLEncoder.encode("pointname", "UTF-8") + "=" + URLEncoder.encode("TempF", "UTF-8");
data += "&" + URLEncoder.encode("value", "UTF-8") + "=" + temp;
data += "&" + URLEncoder.encode("timestamp", "UTF-8") + "=" + Now().getTime();
// Send data
URL url = new URL("http://app.nimbits.com/nimbits/Service/value");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();

// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
System.out.println(line);
}
wr.close();
rd.close();
} catch (Exception e) {
e.printStackTrace();
}

System.out.println("wrote value " + temp);


}
private static double getTemp()
{
Double TempV = 0.0;
SerialPort serialPort = null;
OutputStream mOutputToPort = null;
InputStream mInputFromPort = null;

try {
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier("/dev/ttyUSB0");

System.out.println(portIdentifier.getName());

serialPort = (SerialPort) portIdentifier.open("ListPortClass", 300);
int b = serialPort.getBaudRate();
System.out.println(Integer.toString(b));
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
serialPort.setDTR(false);
serialPort.setDTR(true);
Thread.sleep(1000);
mOutputToPort = serialPort.getOutputStream();
mInputFromPort = serialPort.getInputStream();
String mValue = "AT\r";

System.out.println("beginning to Write . \r\n");
mOutputToPort.write(mValue.getBytes());
System.out.println("AT Command Written to Port. \r\n");
mOutputToPort.flush();
System.out.println("Waiting for Reply \r\n");
Thread.sleep(1000);
byte mBytesIn [] = new byte[20];


mInputFromPort.read(mBytesIn);
String value = new String(mBytesIn);
String[] s1 = value.split((""+(char)10));
System.out.println(s1[0].trim());
System.out.println("Response from Serial Device: ");
System.out.println(value);
TempV = Double.valueOf(s1[0].trim());



} catch (NoSuchPortException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PortInUseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedCommOperationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
serialPort.setDTR(false);
try {
Thread.sleep(500);
mOutputToPort.close();
mInputFromPort.close();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Closing");

serialPort.close();
}
return TempV ;

}


Run the app. You should start to see temp readings from your probe show up on your nimbits portal.

Now you can:
  • use this temp in a google doc, or excel spreadsheet
  • get an email alert when the temp goes out of a range
  • Get powerful analytics from Wolfram Alpha like a possible formula and continuation for a sequence
  • View this on your android based phone and more!

3 comments:

  1. Is the http://nimbits1.appspot.com/gwt1/Service/value URL out of date perhaps? I'm getting a 404...

    ReplyDelete
  2. Aha, I see a different URL in http://nimbits.blogspot.com/2009/10/basic-java-client-for-reading-and.html - that one doesn't send a 404 :)

    ReplyDelete
  3. Hi Martin! Yes this posting is in a little need of updating. I'd encourage everyone to use the basic java client code i posted. Feel free to contact me if you have any other problems and let me know how you make out.

    - Ben (Bsautner@ google's free email service)

    ReplyDelete