Wednesday Nov 27, 2013

Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 6)

So, that's a wrap everyone. Hope you enjoyed the Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter!

Leave me feedback on this project in the blog comments (open for 1 week), if you used it for your holiday bird, or if you just followed along and had fun reading. It's good to hear if you ran into any problems or have any questions about using Java SE Embedded for your own Internet of Things project. (Tech support [me] will be open for a few hours tomorrow if you have issues, but response time will vary according to which football game is on) :-)

So remember: Java technology is a great way to rapidly develop your own IoT applications.

Also, send links to your Twitter accounts if you get them working from your Raspberry Pi. I'll be sure to follow your Twitter feed of your own Java SE Embedded IoT device, and be sure to follow mine at: https://twitter.com/iottweet

A very Happy Thanksgiving (and Happy Hanukkah) to all!

Here are the full steps to this project:
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 1)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 2)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 3)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 4)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 5)

Happy Turkey Tweeting!

Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 5)

It's time to pull this all together and wrap it up. Now, that you have your Twitter developer app ready from Part 4, you just need to make your Twitter app "Read and Write" enabled and then copy over the secret app information to the TurkeyTwitter.java source code (fill in variables near the top of the file) which I included a pointer to the entire compilable source file. See: file

To make your Twitter app "Read and Write enabled:

 1. Go to your Twitter app account by signing
  in with our Twitter login info:
    https://dev.twitter.com/
 2. Select your account icon -> My Applications
 3. Click on your Twitter Turkey Tweeter app
    from Part 4.
 4. Click on the Settings tab
 5. In the section "Application Type Access:",
  select "Read and Write"
 6. Check the box for "Allow this application 
  to be used to Sign in with Twitter"
 7. Click "Update this Twitter's app settings"
 8. Click on the Details tab
 9. Refresh your Web browser
10. Make sure the Access level says: 
  "Read and write"
11. Copy the Twitter app information from this
  page into the TurkeyTweeter.java app (Java
  variables near the top of the file):
   OAuth setting: Consumer Key
   OAuth setting: Consumer Secret
   Access token: Access token
   Access token: Access token secret

Download the TurkeyTweeter.java app from: https://java.net/projects/orbit/downloads/download/TurkeyTweeter.java

After you entered your Twitter app secret information, adjust the source code timePeriod for how often you want your TurkeyTweeter to send update message (default is every 120 seconds), then compile the Java source file with javac and test this way:

  javac TurkeyTweeter.java
  java -cp . TurkeyTweeter test
You should see a test "Hello World!" tweet get posted to your Turkey Tweeter account from Part 4. Here is my Turkey Tweeter account that I'll be using which you can follow along as my turkey tweets: https://twitter.com/iottweet

Here's the code from the TurkeyTweeter.java app that sends the Tweet:

// Check if mod every period to send tweet of current temp
if ((loopIndex % timePeriod) == 0) {
    String tweetMessage = null;
            
    // Check if done, then send special Tweet
    if (f > maxTemp) {
	tweetMessage = "TurkeyTweeter "+timedateString+
	    ": Time to eat!  Turkey is done: "+
	    f+" degrees";
	System.out.println("Tweeting message: "+
			   tweetMessage);
	tweetStatus(tweetMessage);
    } else {               
	// Else, send regular temp update Tweet
	tweetMessage = "TurkeyTweeter "+timedateString+
	    ": Turkey is not done yet: "+
	    f+" degrees";
	System.out.println("Tweeting message: "+
			   tweetMessage);
	tweetStatus(tweetMessage);
    }
                
}

*** IMPORTANT ***

Using your heat reflective tape from Part 1, make sure to tape all sides of the black plastic handle of the Vernier Go!Temp temperature probe and keep wrapping up the length of the black USB cable. Make sure none of black plastic or black cable is exposed especially on the handle. The only part that will be in the oven will be the Go!Temp probe itself in the turkey and part of its USB cable that runs out the oven door, so make sure all the black plastic and black cable is properly taped up with heat reflective tape to ensure it will not melt or catch on fire. The metal probe tip should remain exposed and will be mostly inserted into the turkey.

IMPORTANT: The Raspberry Pi must remain outside the oven on a cool counter top or table nearby your oven door. The Go!Temp probe metal portion of the probe must be inserted into the meatiest part of the turkey thigh without hitting any bone. Use a sharp knife to start a pilot hole for the Go!Temp probe if needed. Make sure the Go!Temp metal probe is securely in place in the thigh meat (not touching bone), then run the taped up USB cable that has been wrapped with heat reflective tape out the oven door to the outside counter top or table where the RPi is plugged into a power outlet and is properly networked to the Internet.

You are now ready to start your app.

Start the app with the following command:

  java -cp . TurkeyTweeter
You should see it report to the RPi shell terminal the current temperature every second and also it should tweet to the Twitter account every timePeriod (default 120 seconds).

That's it! You are now using the TurkeyTweeter to tweet your delicious Thanksgiving turkey as it roasts.

Hope you had fun ready this IoT Thanksgiving Special as much as I had fun blogging about it! And, Happy Thanksgiving!

See the full series on the steps to this cool demo:
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 1)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 2)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 3)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 4)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 5)

Monday Nov 25, 2013

Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 4)

Now, on to the next step which is to write the Java SE Embedded code to automatically send an Internet of Things (IoT) tweet from your Raspberry Pi attached to your cooking turkey to a Twitter account. For this part you'll need to create your own Twitter app for your IoT Turkey, which is easy to do. Just follow the steps: here

After you are done with the above steps to create your own Twitter app, make note of the following settings from your Twitter app:

 1. OAuth setting: Consumer Key
 2. OAuth setting: Consumer Secret
 3. Access token: Access token
 4. Access token: Access token secret

You will use your Twitter app values from above in your Java Embedded program. Just replace the above values into the following Java Embedded code:

    // Application Defined Settings
    static String consumerKey = "XXXXXXXXXXXXXXXXXXXXXX";
    static String consumerSecret = 
            "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    static String accessToken = 
            "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    static String accessTokenSecret = 
            "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; 
    
    static String requestURI = "https://api.twitter.com/1.1/statuses/update.json";

Next, here is the code to send the tweet:

    void tweetStatus(String statusStr) {

        boolean verboseFlag = true;
        String requestURIEnc = null;
        
        try {
            requestURIEnc = URLEncoder.encode(requestURI, "UTF-8");
        } catch (UnsupportedEncodingException uee) {
            uee.printStackTrace();
        }
        
        try {

            if (statusStr == null) {
              statusStr = "Tweet, tweet.  Hello world!";
            }

            // Construct encoded string, parameter encoded string, & data
            String statusEncStr = URLEncoder.encode(statusStr, "UTF-8");

            // Param encode status string twice: once for unsafe characters 
            //  String, once for escaping % for Signature base string
            String statusUnsafeEncStr = unsafeEncode(unsafeEncode(statusStr));

            String postData = "status="+statusEncStr;

            // First set the default cookie manager
            CookieHandler.setDefault(new CookieManager(null,
                    CookiePolicy.ACCEPT_ALL));

            // Send postData
            URL url = new URL("https://api.twitter.com/1.1/statuses/update.json");

            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");

            // Get current date time with Calendar()
            Calendar cal = Calendar.getInstance();
            String timeStr = String.
                    valueOf(cal.getTimeInMillis()).substring(0, 10);

            String basestring = "POST&" + requestURIEnc + 
                    "&oauth_consumer_key%3D" + consumerKey + 
                    "%26oauth_nonce%3D5bffa3b2711bbcdaa4f301" + timeStr + 
                    "%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D" 
                    + timeStr + "%26oauth_token%3D" + accessToken + 
                    "%26oauth_version%3D1.0" + "%26status%3D" + 
                    statusUnsafeEncStr;

            String secretsStr = consumerSecret+"&"+accessTokenSecret;
            SecretKeySpec keySpec = 
                    new SecretKeySpec(secretsStr.getBytes(),
                    "HmacSHA1");

            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(keySpec);
            byte[] result = mac.doFinal(basestring.getBytes());

            String signature = URLEncoder.encode(base64Encode(result), "UTF-8");

            String credentials = 
                    "oauth_consumer_key=\"" + consumerKey + "\"," +
                    "oauth_nonce=\"5bffa3b2711bbcdaa4f301" + timeStr + 
                    "\"," +
                    "oauth_signature=\"" + signature + "\"," +
                    "oauth_signature_method=\"HMAC-SHA1\"," +
                    "oauth_timestamp=\"" + timeStr + "\"," +
                    "oauth_token=\"" +
                    accessToken + "\"," +
                    "oauth_version=\"1.0\"";

            conn.addRequestProperty("Authorization", "OAuth " + credentials);

            String lenStr = String.valueOf(postData.length());
            conn.setRequestProperty("Content-Length", lenStr);
            conn.setRequestProperty("Content-Type", 
                    "application/x-www-form-urlencoded");

            // Do as if you're using Firefox 3.6.3
            conn.setRequestProperty("User-Agent", 
                    "Mozilla/5.0 (Windows; U; Windows NT 5.1; "+
                    "en-US; rv:1.9.2.3) Gecko/20100401"); 

            conn.connect();
            OutputStream output = conn.getOutputStream();

            output.write(postData.getBytes("UTF-8"));

            // Get the response
            InputStream response = conn.getInputStream();
            BufferedReader rd =
                    new BufferedReader(new InputStreamReader(response));
            String line;
            while ((line = rd.readLine()) != null) {
                if (verboseFlag) {
                    System.out.println(line);
                }
            }
            rd.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

And, here's some code for the supporting utility methods:

   public static String unsafeEncode(String input) {
        StringBuilder resultStr = new StringBuilder();
        for (char ch : input.toCharArray()) {
            if (isUnsafe(ch)) {
                resultStr.append('%');
                resultStr.append(toHex(ch / 16));
                resultStr.append(toHex(ch % 16));
            } else {
                resultStr.append(ch);
            }
        }
        return resultStr.toString();
    }

    private static char toHex(int ch) {
        return (char) (ch < 10 ? '0' + ch : 'A' + ch - 10);
    }

    private static boolean isUnsafe(char ch) {
        if (ch > 128 || ch < 0) {
            return true;
        }
        return "$&+,/:;=?@ \"<>#%{}|\\^~[]`'!_*".indexOf(ch) >= 0;
    }
    
    
    private final static char[] BASE64CHARS = 
            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
            .toCharArray();

    private static int[]  intChars   = new int[128];
    
     /**
     * Translates the specified byte array into Base64 string.
     *
     * @param inputBuffer byte array (not null)
     * @return the translated Base64 string (not null)
     */
    public static String base64Encode(byte[] inputBuffer){
        
        // Check if intChars array needs to be init'd
        if (intChars.length == 0) {
            for(int index=0; index < BASE64CHARS.length; index++){
                intChars[BASE64CHARS[index]]= index;
            }
        }
        
        int bufferSize = inputBuffer.length;
        char[] charArray = new char[((bufferSize + 2) / 3) * 4];
        int charIndex = 0;
        int inputIndex = 0;
        while(inputIndex < bufferSize){
            byte byte0 = inputBuffer[inputIndex++];
            byte byte1 = (inputIndex < bufferSize) ? 
                    inputBuffer[inputIndex++] : 0;
            byte byte2 = (inputIndex < bufferSize) ? 
                    inputBuffer[inputIndex++] : 0;

            int mask = 0x3F;
            charArray[charIndex++] = BASE64CHARS[(byte0 >> 2) & mask];
            charArray[charIndex++] = BASE64CHARS[((byte0 << 4) | 
                    ((byte1 & 0xFF) >> 4)) & mask];
            charArray[charIndex++] = BASE64CHARS[((byte1 << 2) | 
                    ((byte2 & 0xFF) >> 6)) & mask];
            charArray[charIndex++] = BASE64CHARS[byte2 & mask];
        }
        
        switch(bufferSize % 3){
            case 1: charArray[--charIndex]  = '=';
            case 2: charArray[--charIndex]  = '=';
        }
        
        return new String(charArray);
    }

That's all you need to send tweets to your Twitter app using Java SE Embedded. Easy-peazy! Next, we'll put it all together, so that your Raspberry Pi takes the Vernier Go!Temp temperature readings from your roasting bird, and sends out tweet updates, plus a tweet to tell the Twitterverse when your turkey is done. That's something delicious! :-)

See the full series on the steps to this cool demo:
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 1)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 2)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 3)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 4)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 5)

Thursday Nov 21, 2013

Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 3)

OK, sports fans. You've got your Vernier Go!Temp USB probe connected. It looks good with lsusb and you can see the /dev/ldusb0 device in your Raspberry Pi Linux shell.

So, how do you write a Java SE Embedded app to read in the turkey temp values. Well, as with most things, you search the Web and you can find how it was done previously in other non-Java inferior programming languages. ;-) Here's a great example in Python on the finninday.net site.

See: finniday.net Go!Teamp example in Python

It shows the reverse engineered byte format of the data coming over USB from the Vernier Go!Temp probe. Booyah! That's what we need to write a Java SE Embedded app. And, here it is...

/**
 *
 * @author hinkmond
 * Copyright © 2013 Oracle and/or its affiliates. All rights reserved.
 */
public class TurkeyTweeter {

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        Date date;
        FileInputStream fis = null;
        DataInputStream dis = null;
        byte   b[];
        
        double tempavg, c, f;
        int    samplecount=0, sequence=0, temp1=0, temp2=0, temp3=0;
        
        final double VERNIER_SCALING_FACTOR=126.74;
        final double VERNIER_CALIBRATION_OFFSET=5.4;

        b = new byte[8];

        // Loop to keep reading temperature
        while (true) {
            int available;

            try {
                fis = new FileInputStream("/dev/ldusb0");
                dis = new DataInputStream(fis);
            } catch (FileNotFoundException fnfe) {
                System.out.println("Cannot find temp sensor");
                fnfe.printStackTrace();
                System.exit(-1);
            }

            // Read 8 bytes from Vernier Go!Temp USB probe
            //   Format:
            //     Byte 0:   Sample Count
            //     Byte 1:   Sequence Index
            //     Byte 2-3: First temp sample
            //     Byte 4-5: Second temp sample
            //     Byte 6-7: Third temp sample
            try {
                if (dis != null) {
                    available = dis.read(b, 0, 8);
                    samplecount = b[0];
                    sequence = b[1];
                    temp1 = b[2] + b[3] * 256;
                    temp2 = b[4] + b[5] * 256;
                    temp3 = b[6] + b[7] * 256;
                }
            } catch (IOException ioe1) {
                System.out.println("Unable to get data from temp sensor");
                ioe1.printStackTrace();
            }
            
            tempavg = (temp1 + temp2 + temp3) / 3.0;
            c = tempavg / VERNIER_SCALING_FACTOR - VERNIER_CALIBRATION_OFFSET;
            
            // Convert from Fahrenheit to Celcius
            f = ((9.0/5.0) * c) + 32.0;
            
            double temperature = roundDouble(f);
            
            date = Calendar.getInstance().getTime();

            Format formatter = new SimpleDateFormat("E MMM d kk:mm:ss");
            String timedateString = formatter.format(date);

            System.out.println(timedateString+"  "+temperature);

            try {
                if (dis != null)
                    dis.close();
                if (fis != null)
                    fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }
    }

   public static double roundDouble(double value) {
        double result = value * 100;
        result = Math.round(result);
        result = result / 100;
        return(result);
   }
}

Compile using javac, lather, rinse, repeat. And, here's the output running on the RPi (NOTE: Remember, you must run as root to access the /dev/ldusb0 device):

pi@raspberrypi ~ $ sudo java -jar TurkeyTweeter.jar
Thu Nov 21 16:42:59  71.59
Thu Nov 21 16:43:00  72.39
Thu Nov 21 16:43:01  72.39
Thu Nov 21 16:43:02  72.39
Thu Nov 21 16:43:03  72.39
Thu Nov 21 16:43:04  72.39
Thu Nov 21 16:43:05  72.39
Thu Nov 21 16:43:06  72.39
Thu Nov 21 16:43:07  72.39
Thu Nov 21 16:43:08  72.39
Thu Nov 21 16:43:09  72.39
...
As you can see, it's 72 degrees Fahrenheit in my office. The turkey won't be that temperature roasting in the oven on Thanksgiving, but we have now confirmed this part of the Turkey Tweeter works. Exciting, isn't it? :-) Next up, we will write the Java code to tweet out the values of our poor turkey as it cooks... (Yeah, poor turkey until it's inside my tummy. Then, it's yummy turkey!)

See the full series on the steps to this cool demo:
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 1)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 2)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 3)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 4)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 5)

Monday Nov 18, 2013

Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 2)

By now you should have received your Vernier Go!Temp USB Temperature Probe and it is getting really close now to Turkey Day, so you want kick your Internet of Things (IoT) Turkey Tweeter project into high gear now.

First, we need to test the temperature probe before sticking it into unknown places, namely our delicious IoT bird on Thanksgiving. So, take your Go!Temp USB temperature probe and plug it into your Raspberry Pi device, just like in this photo.

See:

Connect Go!Temp Probe

If all went well on your Raspberry Pi, you should be able to bring up a terminal shell connected to your RPi and type "lsusb" to verify that the Go!Temp probe is now connected.

pi@raspberrypi ~ $ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp.
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 005: ID 08f7:0002 Vernier EasyTemp/Go!Temp

If your output looks like above, especially the last line where it says the Vernier Go!Temp was recognized and is connected as Device 005, you are golden.

One last check before we start to program using a Java SE Embedded app to grab the temperature readings is to make sure the /dev/ldusb0 device is present. So, type this command and make sure your output matches:

pi@raspberrypi ~ $ ls -l /dev/ldusb0
crw------T 1 root root 180, 176 Nov 18 17:25 /dev/ldusb0

If all that looks good, you're ready for the next step which is to write a Java SE Embedded app to read the temperature values, and eventually write code with IoT intelligence to tweet out the status of your turkey while it's cooking so that it becomes an Internet of Things connected bird on Twitter. Look for that in the next part of this series... Mmmmm... I can almost smell that turkey roasting... :-)

See the full series on the steps to this cool demo:
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 1)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 2)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 3)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 4)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 5)

Wednesday Nov 06, 2013

Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 1)

It's time for the Internet of Things (ioT) Thanksgiving Special. This time we are going to work on a special Do-It-Yourself project to create an Internet of Things temperature probe to connect your Turkey Day turkey to the Internet by writing a Thanksgiving Day Java Embedded app for your Raspberry Pi which will send out tweets as it cooks in your oven.

If you're vegetarian, don't worry, you can follow along and just run the simulation of the Turkey Tweeter, or better yet, try a tofu version of the Turkey Tweeter.

Here is the parts list:

 1 Vernier Go!Temp USB Temperature Probe
 1 Uncooked Turkey
 1 Raspberry Pi (not Pumpkin Pie)
 1 Roll thermal reflective tape
You can buy the Vernier Go!Temp USB Temperature Probe for $39 from here: http://www.vernier.com/products/sensors/temperature-sensors/go-temp/. And, you can get the thermal reflective tape from any auto parts store. (Don't tell them what you need it for. Say it's for rebuilding your V-8 engine in your Dodge Hemi. Avoids the need for a long explanation and sounds cooler...) ;-)

The uncooked turkey can be found in your neighborhood grocery store. But, if you're making a vegetarian Tofurkey, you're on your own... The Java Embedded app will be the same, though (Java is vegan). :-)

So, grab all your parts and come back here for the next part of this project...

See the full series on the steps to this cool demo:
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 1)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 2)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 3)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 4)
Internet of Things (IoT) Thanksgiving Special: Turkey Tweeter (Part 5)

About

Hinkmond Wong's blog on making Machine to Machine (M2M) and the Incredible Internet of Things (IoT) smarter with Java Embedded Technologies

Search

Archives
« November 2013 »
SunMonTueWedThuFriSat
     
1
2
3
4
5
7
8
9
10
11
12
13
14
15
16
17
19
20
22
23
24
26
28
29
30
       
Today